diff --git a/examples/bare9.rs b/examples/bare9.rs
index ecb7aa9369ea5b6ff3b47f4b7553ea0a3f9476c6..cf8a2c4ad67689aea6d043a845fd5e05b4e05a9b 100644
--- a/examples/bare9.rs
+++ b/examples/bare9.rs
@@ -1,12 +1,12 @@
 //! bare9.rs
-//! 
-//! Heapless 
-//! 
+//!
+//! Heapless
+//!
 //! What it covers:
 //! - Heapless Ringbuffer
 //! - Heapless Producer/Consumer lockfree data access
 //! - Interrupt driven I/O
-//! 
+//!
 
 #![no_main]
 #![no_std]
@@ -26,24 +26,29 @@ use nb::block;
 
 use rtfm::app;
 
-#[app(device = hal::stm32)]
+#[app(device = hal::stm32, peripherals = true)]
 const APP: () = {
-    // Late resources
-    static mut TX: Tx<hal::stm32::USART2> = ();
-    static mut RX: Rx<hal::stm32::USART2> = ();
-    static mut PRODUCER: Producer<'static, u8, U3> = ();
-    static mut CONSUMER: Consumer<'static, u8, U3> = ();
-    static mut ITM: ITM = ();
-
+    struct Resources {
+        // Late resources
+        TX: Tx<hal::stm32::USART2>,
+        RX: Rx<hal::stm32::USART2>,
+        PRODUCER: Producer<'static, u8, U3>,
+        CONSUMER: Consumer<'static, u8, U3>,
+        ITM: ITM,
+        // An initialized resource
+        #[init(None)]
+        RB: Option<Queue<u8, U3>>,
+    }
     // init runs in an interrupt free section
-    #[init]
-    fn init() {
+    #[init(resources = [RB])]
+    fn init(cx: init::Context) -> init::LateResources {
+        let mut core = cx.core;
+        let device = cx.device;
         // A ring buffer for our data
-        static mut RB: Option<Queue<u8, U3>> = None;
-        *RB = Some(Queue::new());
+        *cx.resources.RB = Some(Queue::new());
 
         // Split into producer/consumer pair
-        let (producer, consumer) = RB.as_mut().unwrap().split();
+        let (producer, consumer) = cx.resources.RB.as_mut().unwrap().split();
 
         let stim = &mut core.ITM.stim[0];
         iprintln!(stim, "bare9");
@@ -56,7 +61,7 @@ const APP: () = {
         let gpioa = device.GPIOA.split();
 
         let tx = gpioa.pa2.into_alternate_af7();
-        let rx = gpioa.pa3.into_alternate_af7(); 
+        let rx = gpioa.pa3.into_alternate_af7();
 
         let mut serial = Serial::usart2(
             device.USART2,
@@ -72,26 +77,27 @@ const APP: () = {
         let (tx, rx) = serial.split();
 
         // Late resources
-        // Our split queue
-        PRODUCER = producer;
-        CONSUMER = consumer;
+        init::LateResources {
+            // Our split queue
+            PRODUCER: producer,
+            CONSUMER: consumer,
 
-        // Our split serial
-        TX = tx;
-        RX = rx;
+            // Our split serial
+            TX: tx,
+            RX: rx,
 
-        // For debugging
-        ITM = core.ITM;
+            // For debugging
+            ITM: core.ITM,
+        }
     }
 
     // idle may be interrupted by other interrupt/tasks in the system
-    // #[idle(resources = [RX, TX, ITM])]
     #[idle(resources = [ITM, CONSUMER])]
-    fn idle() -> ! {
-        let stim = &mut resources.ITM.stim[0];
+    fn idle(cx: idle::Context) -> ! {
+        let stim = &mut cx.resources.ITM.stim[0];
 
         loop {
-            while let Some(byte) = resources.CONSUMER.dequeue() {
+            while let Some(byte) = cx.resources.CONSUMER.dequeue() {
                 iprintln!(stim, "data {}", byte);
             }
 
@@ -102,16 +108,18 @@ const APP: () = {
         }
     }
 
-    #[interrupt(resources = [RX, TX, PRODUCER])]
-    fn USART2() {
-        let rx = resources.RX;
-        let tx = resources.TX;
+    // task run on USART2 interrupt (set to fire for each byte received)
+    #[task(binds = USART2, resources = [RX, TX, PRODUCER])]
+    fn usart2(cx: usart2::Context) {
+        let rx = cx.resources.RX;
+        let tx = cx.resources.TX;
 
+        // at this point we know there must be a byte to read
         match rx.read() {
             Ok(byte) => {
                 tx.write(byte).unwrap();
-                
-                match resources.PRODUCER.enqueue(byte) {
+
+                match cx.resources.PRODUCER.enqueue(byte) {
                     Ok(_) => {}
                     Err(_) => asm::bkpt(),
                 }
@@ -121,18 +129,19 @@ const APP: () = {
     }
 };
 
+// Optional
 // 0. Compile and run the project at 16MHz in release mode
 //    make sure its running (not paused).
 //
-//    > cargo build --example bare9 --features "hal rtfm" --release
+//    > cargo build --example bare9 --features "rtfm" --release
 //    (or use the vscode build task)
-// 
+//
 // 1. Start a terminal program, connect with 15200 8N1
 //
-//    You should now be able to send data and recive an echo from the MCU
+//    You should now be able to send data and receive 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.
+//    don't send the quotation marks, just abcd.
 //
 //    What did you receive, and what was the output of the ITM trace.
 //
@@ -152,9 +161,9 @@ const APP: () = {
 //
 //    > cargo build --example bare9 --features "hal rtfm"
 //    (or use the vscode build task)
-// 
+//
 //    Try sending: "abcd" as a single sequence (set the option No end in moserial),
-//    don't send the quation marks, just abcd.
+//    don't send the quotation marks, just abcd.
 //
 //    What did you receive, and what was the output of the ITM trace.
 //
@@ -176,18 +185,18 @@ const APP: () = {
 //    The concurrency model behind RTFM offers
 //    1. Race-free resource access
 //
-//    2. Deadlock-free exection
+//    2. Deadlock-free execution
 //
 //    3. Shared execution stack (no pre-allocated stack regions)
 //
 //    4. Bound priority inversion
 //
 //    5. Theoretical underpinning ->
-//       + proofs of soundness
+//       + (pen and paper) proofs of soundness
 //       + schedulability analysis
 //       + response time analysis
 //       + stack memory analysis
-//       + ... leverages on >25 years of reseach in the real-time community
+//       + ... leverages on >25 years of research in the real-time community
 //         based on the seminal work of Baker in the early 1990s
 //         (known as the Stack Resource Policy, SRP)
 //
@@ -195,47 +204,45 @@ const APP: () = {
 //    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).
-//   
+//          are upheld (under all circumstances).
+//
 //    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 lock/claim entry)
-//       + 1 cycle OH for releasineg a shared resoure (on lock/claim exit)
-//   
+//       + 1 cycle OH for releasing a shared resource (on lock/claim exit)
+//
 //    3. arguably the worlds most memory efficient scheduler *
 //       + 1 byte stack memory OH for each (nested) lock/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)
+//
+//    In comparison "real-time" schedulers for threaded models (like FreeRTOS)
+//       - CPU and memory OH magnitudes larger 
 //       - ... and what's worse OH is typically unbound (no proofs of worst case)
+//    And additionally threaded models typically imposes
 //       - 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
+//
+//    However, 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.
-//   
+//
+//    Threads on the other hand are concurrent and infinite by nature and
+//    actively blocking/yielding awaiting stischedulers
 //    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
+//    to dispatch the awaiting thread. So reactivity is bottle-necked to the point
 //    of scheduling by queue management, context switching and other additional
 //    book keeping.
-//   
+//
 //    In essence, the thread scheduler tries to re-establish the reactivity that
-//    were there from the beginning (interrupts), a battle that cannot be won...
\ No newline at end of file
+//    were there from the beginning (interrupts), a battle that cannot be won...