diff --git a/Cargo.toml b/Cargo.toml
index 4804d43af8c32a28c07808307b9d69c45b9425bd..bbdda9db60e6f40408d61ec230fb86e133a31dba 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,6 @@ edition = "2018"
 [dependencies]
 panic-halt              = "0.2"
 panic-semihosting       = "0.5"
-cortex-m-rtfm           = "0.5.1"
 cortex-m-semihosting    = "0.3.5"
 cortex-m                = "0.6.2"
 aligned                 = "0.3.2"
@@ -33,6 +32,13 @@ version         = "0.6.0"
 features        = ["stm32f401", "rt"]
 optional        = true
 
+[dependencies.cortex-m-rtfm]
+version         = "0.5.1"
+optional        = true
+
+[features]
+rtfm            = ["cortex-m-rtfm", "stm32f4xx-hal"]
+
 # this lets you use `cargo fix`!
 [[bin]]
 name            = "app"
@@ -48,6 +54,10 @@ required-features   = ["stm32f4"]
 name                = "serial"
 required-features   = ["stm32f4xx-hal"]
 
+[[example]]
+name                = "rtfm_blinky"
+required-features   = ["rtfm"]
+
 [profile.dev]
 opt-level       = 1
 codegen-units   = 16
diff --git a/examples/rtfm_itm.rs b/examples/rtfm_itm.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8b0721a5eb8f0d0c98a79338be2fb684fd1b0c95
--- /dev/null
+++ b/examples/rtfm_itm.rs
@@ -0,0 +1,43 @@
+#![no_main]
+#![no_std]
+
+use cortex_m::{iprint, iprintln};
+
+use pac::Interrupt;
+use panic_semihosting as _;
+use rtfm::app;
+use stm32f4xx_hal::stm32 as pac;
+
+#[app(device = stm32f4xx_hal::stm32, peripherals = true )]
+const APP: () = {
+    struct Resources {
+        itm: cortex_m::peripheral::ITM,
+    }
+    #[init]
+    fn init(cx: init::Context) -> init::LateResources {
+        let mut itm = cx.core.ITM;
+        let stim = &mut itm.stim[0];
+        iprintln!(stim, "in init");
+
+        rtfm::pend(Interrupt::EXTI0);
+        init::LateResources { itm }
+    }
+
+    #[idle (resources = [itm])]
+    fn idle(mut cx: idle::Context) -> ! {
+        cx.resources.itm.lock(|itm| {
+            let stim = &mut itm.stim[0];
+            iprintln!(stim, "idle");
+        });
+
+        loop {
+            continue;
+        }
+    }
+
+    #[task(binds = EXTI0, resources = [itm])]
+    fn exti0(cx: exti0::Context) {
+        let stim = &mut cx.resources.itm.stim[0];
+        iprintln!(stim, "exti0");
+    }
+};
diff --git a/examples/rtfm_itm_spawn.rs b/examples/rtfm_itm_spawn.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0c21588e23cf76860612c0d12930717827c1848c
--- /dev/null
+++ b/examples/rtfm_itm_spawn.rs
@@ -0,0 +1,50 @@
+#![no_main]
+#![no_std]
+
+use cortex_m::{iprint, iprintln};
+
+use pac::Interrupt;
+use panic_semihosting as _;
+use rtfm::app;
+use stm32f4xx_hal::stm32 as pac;
+
+#[app(device = stm32f4xx_hal::stm32, peripherals = true )]
+const APP: () = {
+    struct Resources {
+        itm: cortex_m::peripheral::ITM,
+    }
+    #[init(spawn = [task1])]
+    fn init(cx: init::Context) -> init::LateResources {
+        let mut itm = cx.core.ITM;
+        let stim = &mut itm.stim[0];
+        iprintln!(stim, "in init");
+
+        cx.spawn.task1("from init").unwrap();
+        init::LateResources { itm }
+    }
+
+    #[idle (resources = [itm], spawn = [task1])]
+    fn idle(mut cx: idle::Context) -> ! {
+        cx.resources.itm.lock(|itm| {
+            let stim = &mut itm.stim[0];
+            cx.spawn.task1("from idle, itm locked").unwrap();
+            iprintln!(stim, "idle");
+        });
+        cx.spawn.task1("from idle").unwrap();
+
+        loop {
+            continue;
+        }
+    }
+
+    #[task (resources = [itm])]
+    fn task1(cx: task1::Context, called_from: &'static str) {
+        let stim = &mut cx.resources.itm.stim[0];
+        iprintln!(stim, "task1 {}", called_from);
+    }
+
+    // Interrupt handlers used to dispatch software tasks
+    extern "C" {
+        fn EXTI0();
+    }
+};