diff --git a/examples/bare5.rs b/examples/bare5.rs
index f3e63082833b990f4779a864fb5a4bb4646ea904..8d5b12289f0f3d46886ab5822808c360f9b7e5e3 100644
--- a/examples/bare5.rs
+++ b/examples/bare5.rs
@@ -128,24 +128,25 @@ fn main() {
 
 // user application
 fn idle(rcc: &mut RCC, gpioa: &mut GPIOA) {
+    let rcc_copy = &rcc;
     // power on GPIOA
-    let r = (*rcc).AHB1ENR.read(); // read
-    (*rcc).AHB1ENR.write(r | 1 << (0)); // set enable
+    let r = rcc.AHB1ENR.read(); // read
+    rcc.AHB1ENR.write(r | 1 << (0)); // set enable
 
     // configure PA5 as output
-    let r = (*gpioa).MODER.read() & !(0b11 << (5 * 2)); // read and mask
-    (*gpioa).MODER.write(r | 0b01 << (5 * 2)); // set output mode
+    let r = gpioa.MODER.read() & !(0b11 << (5 * 2)); // read and mask
+    gpioa.MODER.write(r | 0b01 << (5 * 2)); // set output mode
 
     // and alter the data output through the BSRR register
     // this is more efficient as the read register is not needed.
 
     loop {
         // set PA5 high
-        (*gpioa).BSRRH.write(1 << 5); // set bit, output hight (turn on led)
+        gpioa.BSRRH.write(1 << 5); // set bit, output hight (turn on led)
         wait(10_000);
 
         // set PA5 low
-        (*gpioa).BSRRL.write(1 << 5); // clear bit, output low (turn off led)
+        gpioa.BSRRL.write(1 << 5); // clear bit, output low (turn off led)
         wait(10_000);
     }
 }
@@ -157,8 +158,22 @@ fn idle(rcc: &mut RCC, gpioa: &mut GPIOA) {
 // provided by ST (and other companies). Actually, the file presesnted here is mostly a
 // cut/paste/replace of the stm32f40x.h, just Rustified.
 //
-// Here all peripheral access is unsafe, (as we are dereferencing raw pointers). In the code
-// we have fairly large unsafe blocks. Your task here is to
+// I this case we pass mutable pointer to the `idle`.
+//
+// Rewrite the accesses in the loop to use the data registerf directly (and make a read/modify/write).
+//
+// Run and see that the program behaves the same.
+//
+// commit your answers (bare5_1)
+//
+// 2.
+// Extend the read/write API with a modify, taking the address, field offsbet, field width, and value.
+//
+// Change the code into using your new API.
+//
+// Run and see that the program behaves the same.
+//
+// commit your answers (bare5_2)
 
 // As we are not using interrupts, we just register a dummy catch all handler
 #[link_section = ".vector_table.interrupts"]
diff --git a/examples/bare7.rs b/examples/bare7.rs
new file mode 100644
index 0000000000000000000000000000000000000000..101a29ea0ed6b89a27a91b01969f43cced223e28
--- /dev/null
+++ b/examples/bare7.rs
@@ -0,0 +1,119 @@
+//! Serial interface loopback
+#![deny(unsafe_code)]
+//#![deny(warnings)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate cortex_m_rtfm as rtfm;
+extern crate f4;
+extern crate heapless;
+
+#[macro_use(block)]
+extern crate nb;
+
+#[macro_use]
+extern crate cortex_m_debug;
+
+use f4::prelude::*;
+use f4::Serial;
+use f4::time::Hertz;
+use heapless::Vec;
+use rtfm::app;
+
+// CONFIGURATION
+const BAUD_RATE: Hertz = Hertz(115_200);
+
+// RTFM FRAMEWORK
+app! {
+    device: f4::stm32f40x,
+}
+
+// Init executes with interrupts disabled
+// Hence its safe to access all peripherals (no race-conditions)
+//
+// In this case init will never return
+// This is not the typical use-case as we will see later
+fn init(p: init::Peripherals) {
+    ipln!("init");
+    let serial = Serial(p.USART2);
+
+    serial.init(BAUD_RATE.invert(), None, p.GPIOA, p.RCC);
+
+    let mut vector: Vec<u8, [u8; 4]> = Vec::new();
+    loop {
+        match block!(serial.read()) {
+            Ok(byte) => {
+                let _ = vector.push(byte);
+                ipln!("Ok {:?}", vector);
+                let _ = serial.write(byte);
+            }
+            Err(err) => {
+                ipln!("Error {:?}", err);
+                p.USART2.dr.read(); // clear the error by reading the data register
+            }
+        }
+    }
+}
+
+// We will never reach `idle` since we burn the CPU arduino style :)
+fn idle() -> ! {
+    // Sleep
+    loop {
+        rtfm::wfi();
+    }
+}
+
+// 1. compile and run the project at 16MHz
+// make sure its running (not paused)
+// start a terminal program, e.g., `moserial`
+// connect to the port
+//
+// Device       /dev/ttyACM0
+// Baude Rate   115200
+// Data Bits    8
+// Stop Bits    1
+// Parity       None
+// Handshake    None
+//
+// (this is also known in short as 15200 8N1)
+//
+// you should now be able to send data and recive an echo from the MCU
+//
+// try sending: "abcd" as a single sequence (set the option No end in moserial)
+// (don't send the quation marks, just abcd)
+//
+// what did you receive, and what was the output of the ITM trace
+// ** your answer here **
+//
+// now try sending 'a', 'b', 'c', 'd' character by character
+// (just send the characters not the single quotes and commas)
+// what did you receive, and what was the output of the ITM trace
+// ** your answer here **
+//
+// why did the transmission fail? (hint, think about timing...)
+// ** your answer here **
+//
+// commit your answers (bare7_1)
+//
+// 2. now stress the buffer lengt sending a sequence
+// 'a', 'b', 'c', 'd', 'e' character by character
+// what did you receive, and what was the output of the ITM trace
+// ** your answer here **
+//
+// if done correctly you see an evedince of Rust's memory safety
+// the buffer will be saturated (all elements occupied)
+// but no buffer owerwrite will occur (outside the buffer)
+//
+// your job now is to check the API of `heapless`
+// https://docs.rs/heapless/0.2.1/heapless/
+//
+// and catch the case we are trying to write to a full buffer/vector
+// and write a suiteble error message
+//
+// commit your answers (bare7_2)
+//
+// !!!!! NOTICE !!!!!
+// here we are not solving the underlying problem
+// we are just mitigating the effects
+// in bare8 we will se how to use interrupts for reliable
+// high-speed communictation
diff --git a/examples/bare8.rs b/examples/bare8.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e3befba16e6a0ebb27341d111854b6392bdb6013
--- /dev/null
+++ b/examples/bare8.rs
@@ -0,0 +1,211 @@
+//! Serial interface loopback
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate cortex_m_rtfm as rtfm;
+extern crate f4;
+extern crate heapless;
+
+#[macro_use]
+extern crate cortex_m_debug;
+
+use f4::prelude::*;
+use f4::Serial;
+use f4::time::Hertz;
+use heapless::Vec;
+use rtfm::{app, Resource, Threshold};
+
+// CONFIGURATION
+const BAUD_RATE: Hertz = Hertz(115_200);
+
+// RTFM FRAMEWORK
+app! {
+    device: f4::stm32f40x,
+
+    resources: {
+        static VECTOR: Vec<u8, [u8; 4]> = Vec::new();
+    },
+
+    tasks: {
+        USART2: {
+            path: rx,
+            priority: 2,
+            resources: [VECTOR, USART2],
+        },
+        EXTI1: {
+            path: trace,
+            priority: 1,
+            resources: [VECTOR],
+        }
+    },
+}
+
+// `rx` task trigger on arrival of a USART2 interrupt
+fn rx(t: &mut Threshold, r: USART2::Resources) {
+    let serial = Serial(&**r.USART2);
+
+    // we don't need to block waiting for data to arrive
+    // (as we were triggered) by the data arrival (or error)
+    match serial.read() {
+        Ok(byte) => {
+            // received byte correct
+            r.VECTOR.claim_mut(t, |vector, _| {
+                // critical section for the shared vector
+                let _ = vector.push(byte);
+                // here you could put your error handling for vector full
+            });
+            let _ = serial.write(byte);
+        }
+        Err(err) => {
+            // some transmission error
+            ipln!("Error {:?}", err);
+            r.USART2.dr.read(); // clear the error by reading the data register
+        }
+    }
+
+    // trigger the `trace` task
+    rtfm::set_pending(f4::stm32f40x::Interrupt::EXTI1);
+}
+
+// `trace` task triggered by the hight priority `rx` task
+// a low priority task for the background processing (like tracing)
+fn trace(t: &mut Threshold, r: EXTI1::Resources) {
+    let mut b = [0; 4]; // local buffer
+    let mut l = 0; // length of the received vector
+
+    r.VECTOR.claim(t, |vector, _| {
+        // critical section for the shared vector
+        // here the task `rx` will be blocked from executing
+        l = vector.len();
+        b[..l].copy_from_slice(&***vector); // efficent copy vector to the local buffer
+    });
+    // since we do the actual tracing (relatively slow)
+    // OUTSIDE the claim (critical section), there will be no
+    // additional blocking of `rx`
+    ipln!("Vec {:?}", &b[..l]);
+}
+
+// Here we see the typical use of init INITIALIZING the system
+fn init(p: init::Peripherals, _r: init::Resources) {
+    ipln!("init");
+    let serial = Serial(p.USART2);
+
+    serial.init(BAUD_RATE.invert(), None, p.GPIOA, p.RCC);
+    // in effect telling the USART2 to trigger the `rx` task/interrupt
+    serial.listen(f4::serial::Event::Rxne);
+}
+
+// We will spend all time sleeping (unless we have work to do)
+// reactive programming in RTFM ftw!!!
+fn idle() -> ! {
+    // Sleep
+    loop {
+        rtfm::wfi();
+    }
+}
+
+// 1. compile and run the project at 16MHz
+// make sure its running (not paused)
+// start a terminal program, e.g., `moserial`
+// connect to the port
+//
+// Device       /dev/ttyACM0
+// Baude Rate   115200
+// Data Bits    8
+// Stop Bits    1
+// Parity       None
+// Handshake    None
+//
+// (this is also known in short as 15200 8N1)
+//
+// you should now be able to send data and recive an echo from the MCU
+//
+// try sending: "abcd" as a single sequence (set the option No end in moserial)
+// (don't send the quation marks, just abcd)
+//
+// what did you receive, and what was the output of the ITM trace
+// ** your answer here **
+//
+// did you experience any over-run errors?
+// ** your answer here **
+//
+// what is the key problem and its solution (try to follow the commented code)
+// ** your answer here **
+//
+// commit your answers (bare8_1)
+//
+// 2. now catch the case when we are trying to write to a full vector/buffer
+// and write a suiteble error message
+//
+// commit your answers (bare8_2)
+//
+// as a side note....
+//
+// The concurrency model behind RTFM offers
+// 1. Race-free resource access
+//
+// 2. Deadlock-free exection
+//
+// 3. Shared execution stack (no pre-allocated stack regions)
+//
+// 4. Bound priority inversion
+//
+// 5. Theoretical underpinning ->
+//    + proofs of soundness
+//    + schedulability analysis
+//    + response time analysis
+//    + stack memory analysis
+//    + ... leverages on 25 years of reseach in the real-time community
+//      based on the seminal work of Baker in the early 1990s
+//      (known as the Stack Resource Policy, SRP)
+//
+// Our implementation in Rust offers
+// 1. compile check and analysis of tasks and resources
+//    + the API implementation together with the Rust compiler will ensure that
+//      both RTFM (SRP) soundness and the Rust memory model invariants
+//      are upheld (under all circumpstances).
+//
+// 2. arguably the worlds fastest real time scheduler *
+//    + task invocation 0-cycle OH on top of HW interrupt handling
+//    + 2 cycle OH for locking a shared resource (on claim entry)
+//    + 1 cycle OH for releasineg a shared resoure (on claim exit)
+//
+// 3. arguably the worlds most memory efficient scheduler *
+//    + 1 byte stack memory OH for each (nested) claim
+//      (no additional book-keeping during run-time)
+//
+//    * applies to static task/resource models with single core
+//      pre-emptive, static priority scheduling
+//
+// in comparison "real-time" schedulers for threaded models like FreeRTOS
+//    - CPU and memory OH magnitudes larger (100s of cycles/kilobytes of memory)
+//    - ... and what's worse OH is typically unbound (no proofs of worst case)
+//    - potential race conditions (up to the user to verify)
+//    - potential dead-locks (up to the implementation)
+//    - potential unbound priority inversion (up to the implementation)
+//
+// Rust RTFM (currently) target ONLY STATIC SYSTEMS, there is no notion
+// of dynamically creating new executions contexts/threads
+// so a direct comparison is not completely fair.
+//
+// On the other hand, embedded applications are typically static by nature
+// so a STATIC model is to that end better suitable.
+//
+// RTFM is reactive by nature, a task execute to end, triggered
+// by an internal or external event, (where an interrupt is an external event
+// from the environment, like a HW peripheral such as the USART2).
+//
+// Threads on the other hand are concurrent and infinte by nature and
+// actively blocking/yeilding awaiting stimuli. Hence reactivity needs to be CODED.
+// This leads to an anomaly, the underlying HW is reactive (interrupts),
+// requiring an interrupt handler, that creates a signal to the scheduler.
+//
+// The scheduler then needs to keep track of all threads and at some point choose
+// to dispatch the awaiting thread. So reactivity is bottlenecked to the point
+// of scheduling by que management, context switching and other additional
+// book keeping.
+//
+// In essence, the thread scheduler tries to re-establish the reactivity that
+// were there (interrupts), a battle that cannot be won...
diff --git a/examples/bare9.rs b/examples/bare9.rs
new file mode 100644
index 0000000000000000000000000000000000000000..90a4ad80253814c695f6079a789233db068062bd
--- /dev/null
+++ b/examples/bare9.rs
@@ -0,0 +1,32 @@
+// now you are on your own.....
+//
+// look at the examples in the f4 crate
+// https://github.com/jsjolund/f4
+//
+// try out the examples/pwm-control.rs
+//
+// connect an oschillocope to the pwm output
+// check that you can control the pwm over the serial
+//
+//
+// your assingment is to improve the user interface
+// to take commands
+//
+// on          // turn on the pwm output
+// off         // turn off the pwm output
+// set p       // set the duty cycle to `p` %
+//
+// and optionally
+// freq f      // set pww frequency to `f` hz
+// ...         // your own commands
+//
+// I would suggest using the bare8 as a starting point
+// and adding code from the pwm-control example
+// you may look if `parse` can be of use to you here...
+// make the command parser work first, and then add the pwm code.
+//
+//
+// commit your solution (bare9)
+//
+// https://play.rust-lang.org/,
+// offers a good way to prototype and share code snippets