From 046d614b378017bcb9389a0ea9ca19b658716196 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <jorge@japaric.io>
Date: Fri, 28 Jul 2017 21:03:00 -0500
Subject: [PATCH] update examples

---
 .cargo/config                  |  10 +++
 .gdbinit                       |   6 ++
 .gitignore                     |   2 +
 .travis.yml                    |   2 +
 Xargo.toml                     |   6 ++
 ci/script.sh                   |  51 ++------------
 examples/blinky-await.rs       |  92 -------------------------
 examples/blinky-blocking.rs    |   4 +-
 examples/blinky-futures.rs     |  90 ------------------------
 examples/blinky.rs             |  24 +++----
 examples/capture1.rs           |   5 +-
 examples/capture2.rs           |   5 +-
 examples/capture3.rs           |   5 +-
 examples/capture4.rs           |   6 +-
 examples/claim.rs              |  76 +++++++++++++++++++++
 examples/concurrent-await.rs   | 120 --------------------------------
 examples/concurrent-futures.rs | 121 ---------------------------------
 examples/concurrent.rs         |  71 ++++++++-----------
 examples/cpu.rs                |  22 ++----
 examples/gpio.rs               |   1 -
 examples/hello-world.rs        |   6 +-
 examples/hello.rs              |   1 -
 examples/itm.rs                |   5 +-
 examples/loopback.rs           |  10 +--
 examples/preemption.rs         |  86 +++++++++++++++++++++++
 examples/pwm-control.rs        |   7 +-
 examples/qei1.rs               |  25 +++----
 examples/qei2.rs               |  24 +++----
 examples/qei3.rs               |  24 +++----
 examples/qei4.rs               |  24 +++----
 examples/raise.rs              |  62 +++++++++++++++++
 examples/sharing.rs            |  81 ++++++++++++++++++++++
 examples/spi1.rs               |   6 +-
 examples/spi2.rs               |   6 +-
 examples/usart1-rx-dma.rs      |   9 +--
 examples/usart1-tx-dma.rs      |   9 +--
 examples/usart1.rs             |   3 +-
 examples/usart2.rs             |   3 +-
 examples/usart3.rs             |   3 +-
 examples/wait1.rs              |   4 +-
 examples/wait2.rs              |   4 +-
 examples/wait3.rs              |   4 +-
 examples/wait4.rs              |   4 +-
 examples/ws2812.rs             |   5 +-
 src/dma.rs                     |   2 +-
 src/lib.rs                     |   1 -
 46 files changed, 461 insertions(+), 676 deletions(-)
 create mode 100644 .cargo/config
 create mode 100644 .gdbinit
 create mode 100644 Xargo.toml
 delete mode 100644 examples/blinky-await.rs
 delete mode 100644 examples/blinky-futures.rs
 create mode 100644 examples/claim.rs
 delete mode 100644 examples/concurrent-await.rs
 delete mode 100644 examples/concurrent-futures.rs
 create mode 100644 examples/preemption.rs
 create mode 100644 examples/raise.rs
 create mode 100644 examples/sharing.rs

diff --git a/.cargo/config b/.cargo/config
new file mode 100644
index 0000000..6f29034
--- /dev/null
+++ b/.cargo/config
@@ -0,0 +1,10 @@
+[target.thumbv7m-none-eabi]
+runner = 'arm-none-eabi-gdb'
+rustflags = [
+  "-C", "link-arg=-Tlink.x",
+  "-C", "linker=arm-none-eabi-ld",
+  "-Z", "linker-flavor=ld",
+]
+
+[build]
+target = "thumbv7m-none-eabi"
diff --git a/.gdbinit b/.gdbinit
new file mode 100644
index 0000000..7c72d4f
--- /dev/null
+++ b/.gdbinit
@@ -0,0 +1,6 @@
+target remote :3333
+
+monitor arm semihosting enable
+
+load
+step
diff --git a/.gitignore b/.gitignore
index 6dc3db1..8bc31d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
 **/*.rs.bk
+*.org
+.gdb_history
 Cargo.lock
 target/
diff --git a/.travis.yml b/.travis.yml
index c14b79d..568e7ab 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,8 @@ language: rust
 
 matrix:
   include:
+    - env: TARGET=x86_64-unknown-linux-gnu
+      rust: nightly
     - env: TARGET=thumbv7m-none-eabi
       rust: nightly
       addons:
diff --git a/Xargo.toml b/Xargo.toml
new file mode 100644
index 0000000..89ad4cd
--- /dev/null
+++ b/Xargo.toml
@@ -0,0 +1,6 @@
+[dependencies.core]
+stage = 0
+
+[dependencies.compiler_builtins]
+features = ["mem"]
+stage = 1
\ No newline at end of file
diff --git a/ci/script.sh b/ci/script.sh
index 08323b2..0c48f8d 100644
--- a/ci/script.sh
+++ b/ci/script.sh
@@ -1,52 +1,13 @@
 set -euxo pipefail
 
 main() {
-    local src=$(pwd)
-    local td=$(mktemp -d)
-    local version=0.1.8
-    local url=https://github.com/japaric/cortex-m-quickstart/archive/v$version.tar.gz
+    if [ $TARGET = x86_64-unknown-linux-gnu ]; then
+        cargo build --target $TARGET
+        return
+    fi
 
-    pushd $td
-
-    curl -L $url | tar --strip-components 1 -xz
-
-    rm -rf build.rs examples memory.x src
-    ln -s $src/examples .
-
-    cat >>Cargo.toml <<EOF
-[dependencies.blue-pill]
-path = "$src"
-
-[dependencies.embedded-hal]
-git = "https://github.com/japaric/embedded-hal"
-rev = "5295697669f5b48a900aa325b8ebb4d4e8d4b236"
-
-[dependencies.cortex-m-rtfm]
-version = "0.1.1"
-
-[dependencies.futures]
-default-features = false
-version = "0.1.14"
-
-[dependencies.nb]
-git = "https://github.com/japaric/nb"
-EOF
-
-    for path in $(ls examples/*); do
-        local ex=$(basename $path)
-        ex=${ex%.*}
-
-        case $ex in
-            *-await)
-                continue
-                ;;
-        esac
-
-        xargo check --example $ex --target $TARGET
-    done
-
-    popd
-    rm -rf $td
+    xargo build --target $TARGET
+    xargo test --target $TARGET --examples
 }
 
 main
diff --git a/examples/blinky-await.rs b/examples/blinky-await.rs
deleted file mode 100644
index 5ce6fbf..0000000
--- a/examples/blinky-await.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-//! Blinky using `await!`
-
-#![allow(unreachable_code)] // for the `await!` macro
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![feature(const_fn)]
-#![feature(used)]
-#![no_std]
-
-extern crate blue_pill;
-
-extern crate embedded_hal as hal;
-
-// version = "0.2.3"
-extern crate cortex_m_rt;
-
-// version = "0.1.0"
-#[macro_use]
-extern crate cortex_m_rtfm as rtfm;
-
-extern crate futures;
-
-#[macro_use]
-extern crate nb;
-
-use blue_pill::led::{self, Green};
-use blue_pill::time::Hertz;
-use blue_pill::{Timer, stm32f103xx};
-use futures::future::{self, Loop};
-use futures::{Async, Future};
-use hal::prelude::*;
-use rtfm::{P0, T0, TMax};
-
-// CONFIGURATION
-const FREQUENCY: Hertz = Hertz(1);
-
-// RESOURCES
-peripherals!(stm32f103xx, {
-    GPIOC: Peripheral {
-        ceiling: C0,
-    },
-    RCC: Peripheral {
-        ceiling: C0,
-    },
-    TIM3: Peripheral {
-        ceiling: C0,
-    },
-});
-
-// INITIALIZATION PHASE
-fn init(ref prio: P0, thr: &TMax) {
-    let gpioc = &GPIOC.access(prio, thr);
-    let rcc = &RCC.access(prio, thr);
-    let tim3 = TIM3.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-
-    led::init(gpioc, rcc);
-    timer.init(FREQUENCY.invert(), rcc);
-}
-
-// IDLE LOOP
-fn idle(ref prio: P0, ref thr: T0) -> ! {
-    let tim3 = TIM3.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-
-    // Tasks
-    let mut blinky = (|| {
-        let mut state = false;
-        loop {
-            await!(timer.wait()).unwrap(); // NOTE E = !
-
-            state != state;
-
-            if state {
-                Green.on();
-            } else {
-                Green.off();
-            }
-        }
-    })();
-
-    // Event loop
-    timer.resume();
-    loop {
-        blinky.resume();
-    }
-}
-
-// TASKS
-tasks!(stm32f103xx, {});
diff --git a/examples/blinky-blocking.rs b/examples/blinky-blocking.rs
index d0045e6..50dd312 100644
--- a/examples/blinky-blocking.rs
+++ b/examples/blinky-blocking.rs
@@ -17,7 +17,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -37,7 +37,7 @@ fn init(p: init::Peripherals) {
     timer.init(FREQUENCY.invert(), p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM3);
 
     timer.resume();
diff --git a/examples/blinky-futures.rs b/examples/blinky-futures.rs
deleted file mode 100644
index 3d9e235..0000000
--- a/examples/blinky-futures.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-//! Blinky using futures
-
-#![allow(unreachable_code)] // for the `try_nb!` macro
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![feature(const_fn)]
-#![feature(used)]
-#![no_std]
-
-extern crate blue_pill;
-
-extern crate embedded_hal as hal;
-
-// version = "0.2.3"
-extern crate cortex_m_rt;
-
-// version = "0.1.0"
-#[macro_use]
-extern crate cortex_m_rtfm as rtfm;
-
-extern crate futures;
-
-#[macro_use]
-extern crate nb;
-
-use blue_pill::led::{self, Green};
-use blue_pill::time::Hertz;
-use blue_pill::{Timer, stm32f103xx};
-use futures::future::{self, Loop};
-use futures::{Async, Future};
-use hal::prelude::*;
-use rtfm::{P0, T0, TMax};
-
-// CONFIGURATION
-const FREQUENCY: Hertz = Hertz(1);
-
-// RESOURCES
-peripherals!(stm32f103xx, {
-    GPIOC: Peripheral {
-        ceiling: C0,
-    },
-    RCC: Peripheral {
-        ceiling: C0,
-    },
-    TIM3: Peripheral {
-        ceiling: C0,
-    },
-});
-
-// INITIALIZATION PHASE
-fn init(ref prio: P0, thr: &TMax) {
-    let gpioc = &GPIOC.access(prio, thr);
-    let rcc = &RCC.access(prio, thr);
-    let tim3 = TIM3.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-
-    led::init(gpioc, rcc);
-    timer.init(FREQUENCY.invert(), rcc);
-}
-
-// IDLE LOOP
-fn idle(ref prio: P0, ref thr: T0) -> ! {
-    let tim3 = TIM3.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-
-    // Tasks
-    let mut blinky = future::loop_fn::<_, (), _, _>(true, |state| {
-        future::poll_fn(move || Ok(Async::Ready(try_nb!(timer.wait()))))
-            .map(move |_| {
-                if state {
-                    Green.on();
-                } else {
-                    Green.off();
-                }
-
-                Loop::Continue(!state)
-            })
-    });
-
-    // Event loop
-    timer.resume();
-    loop {
-        blinky.poll().unwrap(); // NOTE(unwrap) E = !
-    }
-}
-
-// TASKS
-tasks!(stm32f103xx, {});
diff --git a/examples/blinky.rs b/examples/blinky.rs
index ad3e749..4020fae 100644
--- a/examples/blinky.rs
+++ b/examples/blinky.rs
@@ -1,14 +1,11 @@
 //! Blinks the user LED
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::led::{self, Green};
@@ -18,15 +15,19 @@ use rtfm::{app, Threshold};
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static ON: bool = false;
+    },
+
     tasks: {
         SYS_TICK: {
-            priority: 1,
+            path: toggle,
+            resources: [ON],
         },
     },
 }
 
-// INITIALIZATION PHASE
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     led::init(p.GPIOC, p.RCC);
 
     p.SYST.set_clock_source(SystClkSource::Core);
@@ -35,7 +36,6 @@ fn init(p: init::Peripherals) {
     p.SYST.enable_counter();
 }
 
-// IDLE LOOP
 fn idle() -> ! {
     // Sleep
     loop {
@@ -44,14 +44,10 @@ fn idle() -> ! {
 }
 
 // TASKS
-task!(SYS_TICK, blink, Locals {
-    static STATE: bool = false;
-});
-
-fn blink(_t: &mut Threshold, l: &mut Locals, _r: SYS_TICK::Resources) {
-    *l.STATE = !*l.STATE;
+fn toggle(_t: &mut Threshold, r: SYS_TICK::Resources) {
+    **r.ON = !**r.ON;
 
-    if *l.STATE {
+    if **r.ON {
         Green.on();
     } else {
         Green.off();
diff --git a/examples/capture1.rs b/examples/capture1.rs
index f07ee8a..a413904 100644
--- a/examples/capture1.rs
+++ b/examples/capture1.rs
@@ -1,5 +1,4 @@
 //! Input capture using TIM1
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
@@ -14,7 +13,7 @@ extern crate nb;
 use blue_pill::prelude::*;
 use blue_pill::time::Milliseconds;
 use blue_pill::{Capture, Channel};
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 // CONFIGURATION
 const RESOLUTION: Milliseconds = Milliseconds(1);
@@ -33,7 +32,7 @@ fn init(p: init::Peripherals) {
     capture.init(RESOLUTION, p.AFIO, p.GPIOA, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     const CHANNELS: [Channel; 4] =
         [Channel::_1, Channel::_2, Channel::_3, Channel::_4];
 
diff --git a/examples/capture2.rs b/examples/capture2.rs
index 70b89ef..bb08c50 100644
--- a/examples/capture2.rs
+++ b/examples/capture2.rs
@@ -14,9 +14,8 @@ extern crate nb;
 use blue_pill::time::Milliseconds;
 use blue_pill::{Capture, Channel};
 use blue_pill::prelude::*;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
-// CONFIGURATION
 const RESOLUTION: Milliseconds = Milliseconds(1);
 
 app! {
@@ -33,7 +32,7 @@ fn init(p: init::Peripherals) {
     capture.init(RESOLUTION, p.AFIO, p.GPIOA, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     const CHANNELS: [Channel; 4] =
         [Channel::_1, Channel::_2, Channel::_3, Channel::_4];
 
diff --git a/examples/capture3.rs b/examples/capture3.rs
index f3bc006..fd46304 100644
--- a/examples/capture3.rs
+++ b/examples/capture3.rs
@@ -14,9 +14,8 @@ extern crate nb;
 use blue_pill::prelude::*;
 use blue_pill::time::Milliseconds;
 use blue_pill::{Capture, Channel};
-use rtfm::app;
+use rtfm::{app, Threshold};
 
-// CONFIGURATION
 const RESOLUTION: Milliseconds = Milliseconds(1);
 
 app! {
@@ -33,7 +32,7 @@ fn init(p: init::Peripherals) {
     capture.init(RESOLUTION, p.AFIO, p.GPIOA, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     const CHANNELS: [Channel; 2] = [Channel::_1, Channel::_2];
 
     let capture = Capture(&*r.TIM3);
diff --git a/examples/capture4.rs b/examples/capture4.rs
index 3ea4494..2073106 100644
--- a/examples/capture4.rs
+++ b/examples/capture4.rs
@@ -1,5 +1,4 @@
 //! Input capture using TIM4
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
@@ -14,9 +13,8 @@ extern crate nb;
 use blue_pill::time::Milliseconds;
 use blue_pill::{Capture, Channel};
 use blue_pill::prelude::*;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
-// CONFIGURATION
 const RESOLUTION: Milliseconds = Milliseconds(1);
 
 app! {
@@ -33,7 +31,7 @@ fn init(p: init::Peripherals) {
     capture.init(RESOLUTION, p.AFIO, p.GPIOB, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     const CHANNELS: [Channel; 4] =
         [Channel::_1, Channel::_2, Channel::_3, Channel::_4];
 
diff --git a/examples/claim.rs b/examples/claim.rs
new file mode 100644
index 0000000..82aeaaa
--- /dev/null
+++ b/examples/claim.rs
@@ -0,0 +1,76 @@
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate blue_pill;
+extern crate cortex_m;
+extern crate cortex_m_rtfm as rtfm;
+
+use blue_pill::stm32f103xx::Interrupt;
+use rtfm::{app, Resource, Threshold};
+
+app! {
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static R1: bool = false;
+    },
+
+    tasks: {
+        EXTI0: {
+            path: exti0,
+            priority: 1,
+            resources: [R1],
+        },
+
+        EXTI1: {
+            path: exti1,
+            priority: 2,
+            resources: [R1],
+        },
+
+        EXTI2: {
+            path: exti2,
+            priority: 3,
+        },
+    },
+}
+
+fn init(_p: init::Peripherals, _r: init::Resources) {}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn exti0(t: &mut Threshold, r: EXTI0::Resources) {
+    // Threshold == 1
+
+    rtfm::set_pending(Interrupt::EXTI1); // ~> exti1
+
+    r.R1.claim(t, |_r1, _t| {
+        // Threshold = 2
+        rtfm::set_pending(Interrupt::EXTI1);
+
+        rtfm::set_pending(Interrupt::EXTI2); // ~> exti2
+    }); // Threshold = 1
+
+    // ~> exti1
+
+    rtfm::atomic(t, |t| {
+        // Threshold = MAX
+        let _r1 = r.R1.borrow(t);
+
+        rtfm::set_pending(Interrupt::EXTI1);
+
+        rtfm::set_pending(Interrupt::EXTI2);
+    }); // Threshold = 1
+
+    // ~> exti2, exti1
+}
+
+fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {
+    // .. modify R1 ..
+}
+
+fn exti2() {}
diff --git a/examples/concurrent-await.rs b/examples/concurrent-await.rs
deleted file mode 100644
index 1bed021..0000000
--- a/examples/concurrent-await.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-//! Two concurrent tasks using `await!`
-
-#![allow(unreachable_code)] // for the `await!` macro
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![feature(const_fn)]
-#![feature(used)]
-#![no_std]
-
-extern crate blue_pill;
-
-extern crate embedded_hal as hal;
-
-// version = "0.2.3"
-extern crate cortex_m_rt;
-
-// version = "0.1.0"
-#[macro_use]
-extern crate cortex_m_rtfm as rtfm;
-
-extern crate futures;
-
-#[macro_use]
-extern crate nb;
-
-use blue_pill::led::{self, Green};
-use blue_pill::time::Hertz;
-use blue_pill::{Serial, Timer, stm32f103xx};
-use futures::future::{self, Loop};
-use futures::{Async, Future};
-use hal::prelude::*;
-use rtfm::{P0, T0, TMax};
-
-// CONFIGURATION
-const BAUD_RATE: Hertz = Hertz(115_200);
-const FREQUENCY: Hertz = Hertz(1);
-
-// RESOURCES
-peripherals!(stm32f103xx, {
-    AFIO: Peripheral {
-        ceiling: C0,
-    },
-    GPIOA: Peripheral {
-        ceiling: C0,
-    },
-    GPIOC: Peripheral {
-        ceiling: C0,
-    },
-    RCC: Peripheral {
-        ceiling: C0,
-    },
-    TIM3: Peripheral {
-        ceiling: C0,
-    },
-    USART1: Peripheral {
-        ceiling: C0,
-    },
-});
-
-// INITIALIZATION PHASE
-fn init(ref prio: P0, thr: &TMax) {
-    let afio = &AFIO.access(prio, thr);
-    let gpioa = &GPIOA.access(prio, thr);
-    let gpioc = &GPIOC.access(prio, thr);
-    let rcc = &RCC.access(prio, thr);
-    let tim3 = TIM3.access(prio, thr);
-    let usart1 = USART1.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-    let serial = Serial(&*usart1);
-
-    led::init(gpioc, rcc);
-
-    serial.init(BAUD_RATE.invert(), afio, None, gpioa, rcc);
-
-    timer.init(FREQUENCY.invert(), rcc);
-}
-
-// IDLE LOOP
-#[inline(never)]
-fn idle(ref prio: P0, ref thr: T0) -> ! {
-    let tim3 = TIM3.access(prio, thr);
-    let usart1 = USART1.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-    let serial = Serial(&*usart1);
-
-    // Tasks
-    let mut blinky = (|| {
-        let mut state = false;
-        loop {
-            await!(timer.wait()).unwrap(); // NOTE(unwrap) E = !
-
-            state != state;
-
-            if state {
-                Green.on();
-            } else {
-                Green.off();
-            }
-        }
-    })();
-
-    let mut loopback = (|| loop {
-                            let byte = await!(serial.read()).unwrap();
-                            await!(serial.write()).unwrap();
-                        })();
-
-    // Resume the timer count
-    timer.resume();
-
-    // Event loop
-    loop {
-        blinky.resume();
-        loopback.resume();
-    }
-}
-
-// TASKS
-tasks!(stm32f103xx, {});
diff --git a/examples/concurrent-futures.rs b/examples/concurrent-futures.rs
deleted file mode 100644
index f959608..0000000
--- a/examples/concurrent-futures.rs
+++ /dev/null
@@ -1,121 +0,0 @@
-//! Two concurrent tasks using futures
-
-#![allow(unreachable_code)] // for the `try_nb!` macro
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![feature(const_fn)]
-#![feature(used)]
-#![no_std]
-
-extern crate blue_pill;
-
-extern crate embedded_hal as hal;
-
-// version = "0.2.3"
-extern crate cortex_m_rt;
-
-// version = "0.1.0"
-#[macro_use]
-extern crate cortex_m_rtfm as rtfm;
-
-extern crate futures;
-
-#[macro_use]
-extern crate nb;
-
-use blue_pill::led::{self, Green};
-use blue_pill::time::Hertz;
-use blue_pill::{Serial, Timer, stm32f103xx};
-use futures::future::{self, Loop};
-use futures::{Async, Future};
-use hal::prelude::*;
-use rtfm::{P0, T0, TMax};
-
-// CONFIGURATION
-const BAUD_RATE: Hertz = Hertz(115_200);
-const FREQUENCY: Hertz = Hertz(1);
-
-// RESOURCES
-peripherals!(stm32f103xx, {
-    AFIO: Peripheral {
-        ceiling: C0,
-    },
-    GPIOA: Peripheral {
-        ceiling: C0,
-    },
-    GPIOC: Peripheral {
-        ceiling: C0,
-    },
-    RCC: Peripheral {
-        ceiling: C0,
-    },
-    TIM3: Peripheral {
-        ceiling: C0,
-    },
-    USART1: Peripheral {
-        ceiling: C0,
-    },
-});
-
-// INITIALIZATION PHASE
-fn init(ref prio: P0, thr: &TMax) {
-    let afio = &AFIO.access(prio, thr);
-    let gpioa = &GPIOA.access(prio, thr);
-    let gpioc = &GPIOC.access(prio, thr);
-    let rcc = &RCC.access(prio, thr);
-    let tim3 = TIM3.access(prio, thr);
-    let usart1 = USART1.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-    let serial = Serial(&*usart1);
-
-    led::init(gpioc, rcc);
-
-    serial.init(BAUD_RATE.invert(), afio, None, gpioa, rcc);
-
-    timer.init(FREQUENCY.invert(), rcc);
-}
-
-// IDLE LOOP
-#[inline(never)]
-fn idle(ref prio: P0, ref thr: T0) -> ! {
-    let tim3 = TIM3.access(prio, thr);
-    let usart1 = USART1.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-    let serial = Serial(&*usart1);
-
-    // Tasks
-    let mut blinky = future::loop_fn::<_, (), _, _>(true, |state| {
-        future::poll_fn(move || Ok(Async::Ready(try_nb!(timer.wait()))))
-            .map(move |_| {
-                if state {
-                    Green.on();
-                } else {
-                    Green.off();
-                }
-
-                Loop::Continue(!state)
-            })
-    });
-
-    let mut loopback = future::loop_fn::<_, (), _, _>((), |_| {
-        future::poll_fn(move || Ok(Async::Ready(try_nb!(serial.read()))))
-            .and_then(|byte| {
-                future::poll_fn(
-                    move || Ok(Async::Ready(try_nb!(serial.write(byte)))),
-                )
-            })
-            .map(|_| Loop::Continue(()))
-    });
-
-    // Event loop
-    timer.resume();
-    loop {
-        loopback.poll().unwrap(); // NOTE(unwrap) E = !
-        blinky.poll().unwrap();
-    }
-}
-
-// TASKS
-tasks!(stm32f103xx, {});
diff --git a/examples/concurrent.rs b/examples/concurrent.rs
index 28dffae..10abc90 100644
--- a/examples/concurrent.rs
+++ b/examples/concurrent.rs
@@ -1,91 +1,76 @@
-//! Serial loopback
-
+//! Running two tasks concurrently
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
-
-#[macro_use]
+extern crate cortex_m;
 extern crate cortex_m_rtfm as rtfm;
 
+use blue_pill::Serial;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::serial::Event;
 use blue_pill::time::Hertz;
-use blue_pill::{Serial, Timer, stm32f103xx};
+use cortex_m::peripheral::SystClkSource;
 use rtfm::{app, Threshold};
 
+const BAUD_RATE: Hertz = Hertz(115_200);
+
 app! {
-    device: stm32f103xx,
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static ON: bool = false;
+    },
 
     tasks: {
-        TIM2: {
-            priority: 1,
-            enabled: true,
-            resources: [TIM2],
+        SYS_TICK: {
+            path: toggle,
+            resources: [ON],
         },
 
         USART1: {
-            priority: 1,
-            enabled: true,
+            path: loopback,
             resources: [USART1],
         },
     },
 }
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
-pub const FREQUENCY: Hertz = Hertz(1);
-
-// INITIALIZATION PHASE
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let serial = Serial(p.USART1);
-    let timer = Timer(p.TIM2);
 
     led::init(p.GPIOC, p.RCC);
 
     serial.init(BAUD_RATE.invert(), p.AFIO, None, p.GPIOA, p.RCC);
     serial.listen(Event::Rxne);
 
-    timer.init(FREQUENCY.invert(), p.RCC);
-    timer.resume();
+    p.SYST.set_clock_source(SystClkSource::Core);
+    p.SYST.set_reload(8_000_000); // 1s
+    p.SYST.enable_interrupt();
+    p.SYST.enable_counter();
 }
 
-// IDLE LOOP
 fn idle() -> ! {
-    // Sleep
     loop {
         rtfm::wfi();
     }
 }
 
-// TASKS
-task!(TIM2, blinky, Local {
-    static STATE: bool = false;
-});
-
-fn blinky(_t: &mut Threshold, l: &mut Local, r: TIM2::Resources) {
-    let timer = Timer(&**r.TIM2);
+fn loopback(_t: &mut Threshold, r: USART1::Resources) {
+    let serial = Serial(&**r.USART1);
 
-    timer.wait().unwrap();
+    let byte = serial.read().unwrap();
+    serial.write(byte).unwrap();
+}
 
-    *l.STATE = !*l.STATE;
+fn toggle(_t: &mut Threshold, r: SYS_TICK::Resources) {
+    **r.ON = !**r.ON;
 
-    if *l.STATE {
+    if **r.ON {
         Green.on();
     } else {
         Green.off();
     }
 }
-
-task!(USART1, loopback);
-
-fn loopback(_t: &mut Threshold, r: USART1::Resources) {
-    let serial = Serial(&**r.USART1);
-
-    let byte = serial.read().unwrap();
-    serial.write(byte).unwrap();
-}
diff --git a/examples/cpu.rs b/examples/cpu.rs
index b81ef4e..d5bab7c 100644
--- a/examples/cpu.rs
+++ b/examples/cpu.rs
@@ -1,27 +1,21 @@
 //! CPU usage monitor
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
-
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-
-#[macro_use]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::Timer;
-use blue_pill::stm32f103xx;
 use blue_pill::time::Hertz;
 use blue_pill::prelude::*;
 use rtfm::{app, Resource, Threshold};
 
 app! {
-    device: stm32f103xx,
+    device: blue_pill::stm32f103xx,
 
     resources: {
         static SLEEP_TIME: u32 = 0;
@@ -33,17 +27,14 @@ app! {
 
     tasks: {
         TIM2: {
-            priority: 1,
-            enabled: true,
+            path: periodic,
             resources: [ITM, SLEEP_TIME, TIM2],
         },
     },
 }
 
-// CONFIGURATION
 const FREQUENCY: Hertz = Hertz(1);
 
-// INITIALIZATION PHASE
 fn init(p: init::Peripherals, _r: init::Resources) {
     let timer = Timer(p.TIM2);
 
@@ -53,13 +44,12 @@ fn init(p: init::Peripherals, _r: init::Resources) {
     timer.resume();
 }
 
-// IDLE LOOP
-fn idle(_t: &mut Threshold, mut r: idle::Resources) -> ! {
+fn idle(t: &mut Threshold, mut r: idle::Resources) -> ! {
     loop {
         // For the span of this critical section the processor will not service
         // interrupts (tasks)
-        rtfm::atomic(|cs| {
-            let sleep_time = r.SLEEP_TIME.borrow_mut(cs);
+        rtfm::atomic(t, |t| {
+            let sleep_time = r.SLEEP_TIME.borrow_mut(t);
 
             // Sleep
             let before = r.DWT.cyccnt.read();
@@ -76,8 +66,6 @@ fn idle(_t: &mut Threshold, mut r: idle::Resources) -> ! {
     }
 }
 
-task!(TIM2, periodic);
-
 fn periodic(_t: &mut Threshold, r: TIM2::Resources) {
     let timer = Timer(&**r.TIM2);
 
diff --git a/examples/gpio.rs b/examples/gpio.rs
index 0b5a5b3..192656b 100644
--- a/examples/gpio.rs
+++ b/examples/gpio.rs
@@ -1,5 +1,4 @@
 //! Sets PB12 high
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
diff --git a/examples/hello-world.rs b/examples/hello-world.rs
index e053bdb..1d22e08 100644
--- a/examples/hello-world.rs
+++ b/examples/hello-world.rs
@@ -1,8 +1,6 @@
 //! Prints "Hello" and then "World" in the OpenOCD console
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
@@ -12,7 +10,7 @@ extern crate cortex_m_semihosting as semihosting;
 
 use core::fmt::Write;
 
-use rtfm::app;
+use rtfm::{app, Threshold};
 use semihosting::hio::{self, HStdout};
 
 app! {
@@ -35,7 +33,7 @@ fn init(_p: init::Peripherals, r: init::Resources) {
     **r.HSTDOUT = Some(hstdout);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     writeln!(r.HSTDOUT.as_mut().unwrap(), "World").unwrap();
 
     loop {
diff --git a/examples/hello.rs b/examples/hello.rs
index 63833fc..85afeb3 100644
--- a/examples/hello.rs
+++ b/examples/hello.rs
@@ -1,5 +1,4 @@
 //! Prints "Hello, World" in the OpenOCD console
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
diff --git a/examples/itm.rs b/examples/itm.rs
index 9c31f71..ab913ec 100644
--- a/examples/itm.rs
+++ b/examples/itm.rs
@@ -18,7 +18,6 @@
 //! Hello
 //! World
 //! ```
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
@@ -29,7 +28,7 @@ extern crate blue_pill;
 extern crate cortex_m;
 extern crate cortex_m_rtfm as rtfm;
 
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -43,7 +42,7 @@ fn init(p: init::Peripherals) {
     iprintln!(&p.ITM.stim[0], "Hello");
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     iprintln!(&r.ITM.stim[0], "World");
 
     // Sleep
diff --git a/examples/loopback.rs b/examples/loopback.rs
index 6e19cf2..cb91fa5 100644
--- a/examples/loopback.rs
+++ b/examples/loopback.rs
@@ -1,12 +1,10 @@
 //! Serial loopback via USART1
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::Serial;
@@ -15,16 +13,14 @@ use blue_pill::serial::Event;
 use blue_pill::time::Hertz;
 use rtfm::{app, Threshold};
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
 
     tasks: {
         USART1: {
-            enabled: true,
-            priority: 1,
+            path: loopback,
             resources: [USART1],
         },
     },
@@ -43,8 +39,6 @@ fn idle() -> ! {
     }
 }
 
-task!(USART1, loopback);
-
 fn loopback(_t: &mut Threshold, r: USART1::Resources) {
     let serial = Serial(&**r.USART1);
 
diff --git a/examples/preemption.rs b/examples/preemption.rs
new file mode 100644
index 0000000..4423ecd
--- /dev/null
+++ b/examples/preemption.rs
@@ -0,0 +1,86 @@
+//! Running two tasks that share data concurrently
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate blue_pill;
+extern crate cortex_m;
+extern crate cortex_m_rtfm as rtfm;
+
+use blue_pill::Serial;
+use blue_pill::led::{self, Green};
+use blue_pill::prelude::*;
+use blue_pill::serial::Event;
+use blue_pill::time::Hertz;
+use cortex_m::peripheral::SystClkSource;
+use rtfm::{app, Resource, Threshold};
+
+const BAUD_RATE: Hertz = Hertz(115_200);
+
+app! {
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static CONTEXT_SWITCHES: u32 = 0;
+        static ON: bool = false;
+    },
+
+    tasks: {
+        SYS_TICK: {
+            path: toggle,
+            priority: 1,
+            resources: [CONTEXT_SWITCHES, ON],
+        },
+
+        USART1: {
+            path: loopback,
+            priority: 2,
+            resources: [CONTEXT_SWITCHES, USART1],
+        },
+    },
+}
+
+fn init(p: init::Peripherals, _r: init::Resources) {
+    let serial = Serial(p.USART1);
+
+    led::init(p.GPIOC, p.RCC);
+
+    serial.init(BAUD_RATE.invert(), p.AFIO, None, p.GPIOA, p.RCC);
+    serial.listen(Event::Rxne);
+
+    p.SYST.set_clock_source(SystClkSource::Core);
+    p.SYST.set_reload(8_000_000); // 1s
+    p.SYST.enable_interrupt();
+    p.SYST.enable_counter();
+}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn loopback(_t: &mut Threshold, r: USART1::Resources) {
+    **r.CONTEXT_SWITCHES += 1;
+
+    let serial = Serial(&**r.USART1);
+
+    let byte = serial.read().unwrap();
+    serial.write(byte).unwrap();
+}
+
+fn toggle(t: &mut Threshold, mut r: SYS_TICK::Resources) {
+    r.CONTEXT_SWITCHES.claim_mut(t, |context_switches, _t| {
+        // inside a critical section
+        **context_switches += 1;
+    });
+
+    **r.ON = !**r.ON;
+
+    if **r.ON {
+        Green.on();
+    } else {
+        Green.off();
+    }
+}
diff --git a/examples/pwm-control.rs b/examples/pwm-control.rs
index 70ba754..a72977f 100644
--- a/examples/pwm-control.rs
+++ b/examples/pwm-control.rs
@@ -4,14 +4,12 @@
 //! - '+' increase duty by 1
 //! - '-' decrease duty by 1
 //! - '/' decrease duty by a factor of 2
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use core::u16;
@@ -29,8 +27,7 @@ app! {
 
     tasks: {
         USART1: {
-            enabled: true,
-            priority: 1,
+            path: rx,
             resources: [TIM2, USART1],
         },
     },
@@ -54,8 +51,6 @@ fn idle() -> ! {
     }
 }
 
-task!(USART1, rx);
-
 fn rx(_t: &mut Threshold, r: USART1::Resources) {
     let pwm = Pwm(&**r.TIM2);
     let serial = Serial(&**r.USART1);
diff --git a/examples/qei1.rs b/examples/qei1.rs
index ba49f09..0760b68 100644
--- a/examples/qei1.rs
+++ b/examples/qei1.rs
@@ -1,17 +1,14 @@
 //! Quadrature Encoder Interface using TIM1
 //!
 //! Periodically reports the readings of the QEI
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::prelude::*;
@@ -19,22 +16,24 @@ use blue_pill::time::Hertz;
 use blue_pill::{Qei, Timer};
 use rtfm::{app, Threshold};
 
-// CONFIGURATION
 const FREQUENCY: Hertz = Hertz(1);
 
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static PREVIOUS: Option<u16> = None;
+    },
+
     tasks: {
         TIM4: {
-            enabled: true,
-            priority: 1,
-            resources: [ITM, TIM1, TIM4],
+            path: periodic,
+            resources: [ITM, PREVIOUS, TIM1, TIM4],
         },
     },
 }
 
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let qei = Qei(p.TIM1);
     let timer = Timer(p.TIM4);
 
@@ -50,11 +49,7 @@ fn idle() -> ! {
     }
 }
 
-task!(TIM4, periodic, Locals {
-    static PREVIOUS: Option<u16> = None;
-});
-
-fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
+fn periodic(_t: &mut Threshold, r: TIM4::Resources) {
     let qei = Qei(&**r.TIM1);
     let timer = Timer(&**r.TIM4);
 
@@ -63,11 +58,11 @@ fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
     let curr = qei.count();
     let dir = qei.direction();
 
-    if let Some(prev) = l.PREVIOUS.take() {
+    if let Some(prev) = r.PREVIOUS.take() {
         let speed = (curr as i16).wrapping_sub(prev as i16);
 
         iprintln!(&r.ITM.stim[0], "{} - {} - {:?}", curr, speed, dir);
     }
 
-    *l.PREVIOUS = Some(curr);
+    **r.PREVIOUS = Some(curr);
 }
diff --git a/examples/qei2.rs b/examples/qei2.rs
index edba974..32b1feb 100644
--- a/examples/qei2.rs
+++ b/examples/qei2.rs
@@ -1,17 +1,14 @@
 //! Quadrature Encoder Interface using TIM2
 //!
 //! Periodically reports the readings of the QEI
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::prelude::*;
@@ -24,16 +21,19 @@ const FREQUENCY: Hertz = Hertz(1);
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static PREVIOUS: Option<u16> = None;
+    },
+
     tasks: {
         TIM4: {
-            enabled: true,
-            priority: 1,
-            resources: [ITM, TIM2, TIM4],
+            path: periodic,
+            resources: [ITM, PREVIOUS, TIM2, TIM4],
         },
     },
 }
 
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let qei = Qei(p.TIM2);
     let timer = Timer(p.TIM4);
 
@@ -49,11 +49,7 @@ fn idle() -> ! {
     }
 }
 
-task!(TIM4, periodic, Locals {
-    static PREVIOUS: Option<u16> = None;
-});
-
-fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
+fn periodic(_t: &mut Threshold, r: TIM4::Resources) {
     let qei = Qei(&**r.TIM2);
     let timer = Timer(&**r.TIM4);
 
@@ -63,11 +59,11 @@ fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
     let curr = qei.count();
     let dir = qei.direction();
 
-    if let Some(prev) = l.PREVIOUS.take() {
+    if let Some(prev) = r.PREVIOUS.take() {
         let speed = (curr as i16).wrapping_sub(prev as i16);
 
         iprintln!(&r.ITM.stim[0], "{} - {} - {:?}", curr, speed, dir);
     }
 
-    *l.PREVIOUS = Some(curr);
+    **r.PREVIOUS = Some(curr);
 }
diff --git a/examples/qei3.rs b/examples/qei3.rs
index e0ed7de..7342aff 100644
--- a/examples/qei3.rs
+++ b/examples/qei3.rs
@@ -1,17 +1,14 @@
 //! Quadrature Encoder Interface using TIM3
 //!
 //! Periodically reports the readings of the QEI
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::time::Hertz;
@@ -24,16 +21,19 @@ const FREQUENCY: Hertz = Hertz(1);
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static PREVIOUS: Option<u16> = None;
+    },
+
     tasks: {
         TIM4: {
-            enabled: true,
-            priority: 1,
-            resources: [ITM, TIM3, TIM4],
+            path: periodic,
+            resources: [ITM, PREVIOUS, TIM3, TIM4],
         },
     },
 }
 
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let qei = Qei(p.TIM3);
     let timer = Timer(p.TIM4);
 
@@ -49,11 +49,7 @@ fn idle() -> ! {
     }
 }
 
-task!(TIM4, periodic, Locals {
-    static PREVIOUS: Option<u16> = None;
-});
-
-fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
+fn periodic(_t: &mut Threshold, r: TIM4::Resources) {
     let qei = Qei(&**r.TIM3);
     let timer = Timer(&**r.TIM4);
 
@@ -62,11 +58,11 @@ fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
     let curr = qei.count();
     let dir = qei.direction();
 
-    if let Some(prev) = l.PREVIOUS.take() {
+    if let Some(prev) = r.PREVIOUS.take() {
         let speed = (curr as i16).wrapping_sub(prev as i16);
 
         iprintln!(&r.ITM.stim[0], "{} - {} - {:?}", curr, speed, dir);
     }
 
-    *l.PREVIOUS = Some(curr);
+    **r.PREVIOUS = Some(curr);
 }
diff --git a/examples/qei4.rs b/examples/qei4.rs
index b04c7ea..b62a3b6 100644
--- a/examples/qei4.rs
+++ b/examples/qei4.rs
@@ -1,17 +1,14 @@
 //! Quadrature Encoder Interface using TIM4
 //!
 //! Periodically reports the readings of the QEI
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::time::Hertz;
@@ -24,16 +21,19 @@ const FREQUENCY: Hertz = Hertz(1);
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static PREVIOUS: Option<u16> = None;
+    },
+
     tasks: {
         TIM1_UP_TIM10: {
-            enabled: true,
-            priority: 1,
-            resources: [ITM, TIM1, TIM4],
+            path: periodic,
+            resources: [ITM, PREVIOUS, TIM1, TIM4],
         },
     },
 }
 
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let qei = Qei(p.TIM4);
     let timer = Timer(p.TIM1);
 
@@ -49,11 +49,7 @@ fn idle() -> ! {
     }
 }
 
-task!(TIM1_UP_TIM10, periodic, Locals {
-    static PREVIOUS: Option<u16> = None;
-});
-
-fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM1_UP_TIM10::Resources) {
+fn periodic(_t: &mut Threshold, r: TIM1_UP_TIM10::Resources) {
     let qei = Qei(&**r.TIM4);
     let timer = Timer(&**r.TIM1);
 
@@ -62,11 +58,11 @@ fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM1_UP_TIM10::Resources) {
     let curr = qei.count();
     let dir = qei.direction();
 
-    if let Some(prev) = l.PREVIOUS.take() {
+    if let Some(prev) = r.PREVIOUS.take() {
         let speed = (curr as i16).wrapping_sub(prev as i16);
 
         iprintln!(&r.ITM.stim[0], "{} - {} - {:?}", curr, speed, dir);
     }
 
-    *l.PREVIOUS = Some(curr);
+    **r.PREVIOUS = Some(curr);
 }
diff --git a/examples/raise.rs b/examples/raise.rs
new file mode 100644
index 0000000..351eaf1
--- /dev/null
+++ b/examples/raise.rs
@@ -0,0 +1,62 @@
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate blue_pill;
+extern crate cortex_m;
+extern crate cortex_m_rtfm as rtfm;
+
+use cortex_m::asm;
+use rtfm::{app, Resource, Threshold};
+
+app! {
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static R1: bool = false;
+        static R2: bool = false;
+    },
+
+    tasks: {
+        EXTI0: {
+            path: exti0,
+            priority: 1,
+            resources: [R1, R2],
+        },
+
+        EXTI1: {
+            path: exti1,
+            priority: 2,
+            resources: [R1],
+        },
+
+        EXTI2: {
+            path: exti2,
+            priority: 3,
+            resources: [R2],
+        },
+    },
+}
+
+fn init(_p: init::Peripherals, _r: init::Resources) {}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn exti0(t: &mut Threshold, r: EXTI0::Resources) {
+    r.R1.claim(t, |_r1, t| {
+        asm::nop();
+
+        r.R2.claim(t, |_r2, _t| {
+            asm::nop();
+        });
+
+        asm::nop();
+    });
+}
+
+fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {}
+
+fn exti2(_t: &mut Threshold, _r: EXTI2::Resources) {}
diff --git a/examples/sharing.rs b/examples/sharing.rs
new file mode 100644
index 0000000..d499c57
--- /dev/null
+++ b/examples/sharing.rs
@@ -0,0 +1,81 @@
+//! Running two tasks, that share data, concurrently
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate blue_pill;
+extern crate cortex_m;
+extern crate cortex_m_rtfm as rtfm;
+
+use blue_pill::Serial;
+use blue_pill::led::{self, Green};
+use blue_pill::prelude::*;
+use blue_pill::serial::Event;
+use blue_pill::time::Hertz;
+use cortex_m::peripheral::SystClkSource;
+use rtfm::{app, Threshold};
+
+const BAUD_RATE: Hertz = Hertz(115_200);
+
+app! {
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static CONTEXT_SWITCHES: u32 = 0;
+        static ON: bool = false;
+    },
+
+    tasks: {
+        SYS_TICK: {
+            path: toggle,
+            resources: [CONTEXT_SWITCHES, ON],
+        },
+
+        USART1: {
+            path: loopback,
+            resources: [CONTEXT_SWITCHES, USART1],
+        },
+    },
+}
+
+fn init(p: init::Peripherals, _r: init::Resources) {
+    let serial = Serial(p.USART1);
+
+    led::init(p.GPIOC, p.RCC);
+
+    serial.init(BAUD_RATE.invert(), p.AFIO, None, p.GPIOA, p.RCC);
+    serial.listen(Event::Rxne);
+
+    p.SYST.set_clock_source(SystClkSource::Core);
+    p.SYST.set_reload(8_000_000); // 1s
+    p.SYST.enable_interrupt();
+    p.SYST.enable_counter();
+}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn loopback(_t: &mut Threshold, r: USART1::Resources) {
+    **r.CONTEXT_SWITCHES += 1;
+
+    let serial = Serial(&**r.USART1);
+
+    let byte = serial.read().unwrap();
+    serial.write(byte).unwrap();
+}
+
+fn toggle(_t: &mut Threshold, r: SYS_TICK::Resources) {
+    **r.CONTEXT_SWITCHES += 1;
+
+    **r.ON = !**r.ON;
+
+    if **r.ON {
+        Green.on();
+    } else {
+        Green.off();
+    }
+}
diff --git a/examples/spi1.rs b/examples/spi1.rs
index cbcd231..f0ccf03 100644
--- a/examples/spi1.rs
+++ b/examples/spi1.rs
@@ -12,7 +12,7 @@ extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::Spi;
 use blue_pill::prelude::*;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -28,7 +28,7 @@ fn init(p: init::Peripherals) {
     spi.init(p.AFIO, p.GPIOA, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     // Register to read
     const WHO_AM_I: u8 = 117;
 
@@ -39,7 +39,7 @@ fn idle(r: idle::Resources) -> ! {
     const ANS: u8 = 0x73;
 
     // Read mode
-    pub const R: u8 = 1 << 7;
+    const R: u8 = 1 << 7;
 
     let spi = Spi(&*r.SPI1);
 
diff --git a/examples/spi2.rs b/examples/spi2.rs
index 7436e24..caac90e 100644
--- a/examples/spi2.rs
+++ b/examples/spi2.rs
@@ -12,7 +12,7 @@ extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::Spi;
 use blue_pill::prelude::*;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -28,7 +28,7 @@ fn init(p: init::Peripherals) {
     spi.init(p.AFIO, p.GPIOB, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     // Register to read
     const WHO_AM_I: u8 = 117;
 
@@ -39,7 +39,7 @@ fn idle(r: idle::Resources) -> ! {
     const ANS: u8 = 0x73;
 
     // Read mode
-    pub const R: u8 = 1 << 7;
+    const R: u8 = 1 << 7;
 
     let spi = Spi(&*r.SPI2);
 
diff --git a/examples/usart1-rx-dma.rs b/examples/usart1-rx-dma.rs
index 7f3c0b3..dee5fea 100644
--- a/examples/usart1-rx-dma.rs
+++ b/examples/usart1-rx-dma.rs
@@ -1,5 +1,4 @@
 //! Test receiving serial data using the DMA
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(const_fn)]
@@ -7,7 +6,6 @@
 #![no_std]
 
 extern crate blue_pill;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 extern crate nb;
 
@@ -16,7 +14,7 @@ use blue_pill::dma::{Buffer, Dma1Channel5};
 use blue_pill::time::Hertz;
 use rtfm::{app, Threshold};
 
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -27,8 +25,7 @@ app! {
 
     tasks: {
         DMA1_CHANNEL5: {
-            enabled: true,
-            priority: 1,
+            path: transfer_done,
             resources: [BUFFER, DMA1],
         },
     },
@@ -48,8 +45,6 @@ fn idle() -> ! {
     }
 }
 
-task!(DMA1_CHANNEL5, transfer_done);
-
 fn transfer_done(_t: &mut Threshold, r: DMA1_CHANNEL5::Resources) {
     r.BUFFER.release(r.DMA1).unwrap();
 
diff --git a/examples/usart1-tx-dma.rs b/examples/usart1-tx-dma.rs
index 06f209e..c689851 100644
--- a/examples/usart1-tx-dma.rs
+++ b/examples/usart1-tx-dma.rs
@@ -1,5 +1,4 @@
 //! Test sending serial data using the DMA
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(const_fn)]
@@ -7,7 +6,6 @@
 #![no_std]
 
 extern crate blue_pill;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 extern crate nb;
 
@@ -16,7 +14,7 @@ use blue_pill::dma::{Buffer, Dma1Channel4};
 use blue_pill::time::Hertz;
 use rtfm::{app, Threshold};
 
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -27,8 +25,7 @@ app! {
 
     tasks: {
         DMA1_CHANNEL4: {
-            enabled: true,
-            priority: 1,
+            path: transfer_done,
             resources: [BUFFER, DMA1],
         },
     },
@@ -49,8 +46,6 @@ fn idle() -> ! {
     }
 }
 
-task!(DMA1_CHANNEL4, transfer_done);
-
 fn transfer_done(_t: &mut Threshold, r: DMA1_CHANNEL4::Resources) {
     r.BUFFER.release(r.DMA1).unwrap();
 
diff --git a/examples/usart1.rs b/examples/usart1.rs
index 9abd07d..ca0d23b 100644
--- a/examples/usart1.rs
+++ b/examples/usart1.rs
@@ -16,8 +16,7 @@ use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
 use rtfm::app;
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
diff --git a/examples/usart2.rs b/examples/usart2.rs
index 2af3b2e..0eb55a1 100644
--- a/examples/usart2.rs
+++ b/examples/usart2.rs
@@ -17,8 +17,7 @@ use blue_pill::prelude::*;
 use nb::Error;
 use rtfm::app;
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
diff --git a/examples/usart3.rs b/examples/usart3.rs
index 5d5815f..6dd8e96 100644
--- a/examples/usart3.rs
+++ b/examples/usart3.rs
@@ -17,8 +17,7 @@ use blue_pill::time::Hertz;
 use nb::Error;
 use rtfm::app;
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
diff --git a/examples/wait1.rs b/examples/wait1.rs
index bfe353c..21f51c9 100644
--- a/examples/wait1.rs
+++ b/examples/wait1.rs
@@ -12,7 +12,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -33,7 +33,7 @@ fn init(p: init::Peripherals) {
     timer.resume();
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM1);
 
     let mut state = false;
diff --git a/examples/wait2.rs b/examples/wait2.rs
index daad69e..3b23c27 100644
--- a/examples/wait2.rs
+++ b/examples/wait2.rs
@@ -12,7 +12,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -32,7 +32,7 @@ fn init(p: init::Peripherals) {
     timer.resume();
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM2);
 
     let mut state = false;
diff --git a/examples/wait3.rs b/examples/wait3.rs
index 6023c5d..b5d5c3e 100644
--- a/examples/wait3.rs
+++ b/examples/wait3.rs
@@ -12,7 +12,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -33,7 +33,7 @@ fn init(p: init::Peripherals) {
     timer.resume();
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM3);
 
     let mut state = false;
diff --git a/examples/wait4.rs b/examples/wait4.rs
index fe14a34..393f454 100644
--- a/examples/wait4.rs
+++ b/examples/wait4.rs
@@ -12,7 +12,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -33,7 +33,7 @@ fn init(p: init::Peripherals) {
     timer.resume();
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM4);
 
     let mut state = false;
diff --git a/examples/ws2812.rs b/examples/ws2812.rs
index 5f61faa..da623f8 100644
--- a/examples/ws2812.rs
+++ b/examples/ws2812.rs
@@ -1,7 +1,6 @@
 //! Drive a ring of 24 WS2812 LEDs
 //!
 //! To test this demo connect the data-in pin of the LED ring to pin PA0
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(const_fn)]
@@ -17,7 +16,7 @@ use blue_pill::dma::{Buffer, Dma1Channel2};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
 use blue_pill::{Channel, Pwm};
-use rtfm::{app, Static};
+use rtfm::{app, Static, Threshold};
 
 // CONFIGURATION
 const FREQUENCY: Hertz = Hertz(200_000);
@@ -51,7 +50,7 @@ fn init(p: init::Peripherals, r: init::Resources) {
     }
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let pwm = Pwm(&*r.TIM2);
     let buffer = Static::wrap_mut(r.BUFFER);
 
diff --git a/src/dma.rs b/src/dma.rs
index 0019657..fd581fe 100644
--- a/src/dma.rs
+++ b/src/dma.rs
@@ -43,10 +43,10 @@ pub struct Dma1Channel5 {
 // NOTE(packed) workaround for rust-lang/rust#41315
 #[repr(packed)]
 pub struct Buffer<T, CHANNEL> {
-    _marker: PhantomData<CHANNEL>,
     data: UnsafeCell<T>,
     flag: Cell<BorrowFlag>,
     state: Cell<State>,
+    _marker: PhantomData<CHANNEL>,
 }
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
diff --git a/src/lib.rs b/src/lib.rs
index 3e15a7f..515bbcb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -22,7 +22,6 @@ extern crate cast;
 extern crate embedded_hal as hal;
 extern crate nb;
 extern crate static_ref;
-extern crate volatile_register;
 
 pub extern crate stm32f103xx;
 
-- 
GitLab