diff --git a/Cargo.toml b/Cargo.toml
index 392538b452695726a5d60e1e9a7112641e79077f..8ce7bdb23d1c88c8122418cea38ed3f86c3f4357 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,6 +15,7 @@ version = "0.2.0"
 [dependencies]
 cortex-m = "0.3.1"
 static-ref = "0.2.1"
+rtfm-core = { git = "https://github.com/japaric/rtfm-core" }
 
 [dependencies.cortex-m-rtfm-macros]
 path = "macros"
diff --git a/macros/src/trans.rs b/macros/src/trans.rs
index a137e0ec7cb5eedf141d4af24ab12f9d5405f08f..4f389d3028e9fe9c3eaf1e25aa872ee04fa607fb 100644
--- a/macros/src/trans.rs
+++ b/macros/src/trans.rs
@@ -238,7 +238,7 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
             // Interrupt. These can be enabled / disabled through the NVIC
             if interrupts.is_empty() {
                 interrupts.push(quote! {
-                    let nvic = #device::NVIC.borrow(_cs);
+                    let nvic = &*#device::NVIC.get();
                 });
             }
 
@@ -262,7 +262,7 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
             // Exception
             if exceptions.is_empty() {
                 exceptions.push(quote! {
-                    let scb = #device::SCB.borrow(_cs);
+                    let scb = &*#device::SCB.get();
                 });
             }
 
@@ -280,7 +280,7 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
         // type check
         let init: fn(#(#tys,)*) = #init;
 
-        #krate::atomic(|_cs| unsafe {
+        #krate::atomic(unsafe { &mut #krate::Threshold::new(0) }, |_t| unsafe {
             init(#(#exprs,)*);
 
             #(#exceptions)*
@@ -328,15 +328,19 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
 
                         fn borrow<'cs>(
                             &'cs self,
-                            _cs: &'cs #krate::CriticalSection,
+                            t: &'cs #krate::Threshold,
                         ) -> &'cs #krate::Static<#ty> {
+                            assert!(t.value() >= #ceiling);
+
                             unsafe { #krate::Static::ref_(&#_name) }
                         }
 
                         fn borrow_mut<'cs>(
                             &'cs mut self,
-                            _cs: &'cs #krate::CriticalSection,
+                            t: &'cs #krate::Threshold,
                         ) -> &'cs mut #krate::Static<#ty> {
+                            assert!(t.value() >= #ceiling);
+
                             unsafe {
                                 #krate::Static::ref_mut(&mut #_name)
                             }
@@ -390,8 +394,10 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
 
                         fn borrow<'cs>(
                             &'cs self,
-                            _cs: &'cs #krate::CriticalSection,
+                            t: &'cs #krate::Threshold,
                         ) -> &'cs #krate::Static<#device::#name> {
+                            assert!(t.value() >= #ceiling);
+
                             unsafe {
                                 #krate::Static::ref_(&*#device::#name.get())
                             }
@@ -399,8 +405,10 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
 
                         fn borrow_mut<'cs>(
                             &'cs mut self,
-                            _cs: &'cs #krate::CriticalSection,
+                            t: &'cs #krate::Threshold,
                         ) -> &'cs mut #krate::Static<#device::#name> {
+                            assert!(t.value() >= #ceiling);
+
                             unsafe {
                                 #krate::Static::ref_mut(
                                     &mut *#device::#name.get(),
@@ -458,7 +466,7 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
 
                 impls.push(quote! {
                     #[allow(unsafe_code)]
-                    impl #krate::Resource for _resource::#name {
+                    unsafe impl #krate::Resource for _resource::#name {
                         #(#impl_items)*
                     }
                 });
@@ -594,7 +602,13 @@ fn tasks(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
             let priority = task.priority;
             if needs_threshold {
                 tys.push(quote!(&mut #krate::Threshold));
-                exprs.push(quote!(&mut #krate::Threshold::new(#priority)));
+                exprs.push(quote! {
+                    &mut if #priority == 1 << #device::NVIC_PRIO_BITS {
+                        #krate::Threshold::new(::core::u8::MAX)
+                    } else {
+                        #krate::Threshold::new(#priority)
+                    }
+                });
             }
 
             if has_resources {
diff --git a/src/lib.rs b/src/lib.rs
index 43079c17575a89f3361ddf28cfab045ad6218fc0..ba9676234182886b712231f6d90eadc9b7b4040e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -50,7 +50,6 @@
 //!
 //! In increasing grade of complexity, see the [examples](./examples/index.html)
 //! module.
-
 #![deny(missing_docs)]
 #![deny(warnings)]
 #![feature(asm)]
@@ -61,76 +60,32 @@
 
 extern crate cortex_m;
 extern crate cortex_m_rtfm_macros;
+extern crate rtfm_core;
 extern crate static_ref;
 
+use core::u8;
+
+pub use rtfm_core::{Resource, Static, Threshold};
 pub use cortex_m::asm::{bkpt, wfi};
-pub use cortex_m::interrupt::CriticalSection;
-pub use cortex_m::interrupt::free as atomic;
 pub use cortex_m_rtfm_macros::app;
-pub use static_ref::Static;
-use cortex_m::interrupt::Nr;
+use cortex_m::interrupt::{self, Nr};
 #[cfg(not(armv6m))]
-use cortex_m::register::{basepri, basepri_max};
+use cortex_m::register::basepri;
 
 pub mod examples;
 
-/// A resource, a means to share data between tasks
-pub trait Resource {
-    /// The data protected by the resource
-    type Data;
-
-    /// Borrows the resource data for the duration of a *global* critical
-    /// section
-    fn borrow<'cs>(
-        &'cs self,
-        cs: &'cs CriticalSection,
-    ) -> &'cs Static<Self::Data>;
-
-    /// Mutable variant of `borrow`
-    fn borrow_mut<'cs>(
-        &'cs mut self,
-        cs: &'cs CriticalSection,
-    ) -> &'cs mut Static<Self::Data>;
-
-    /// Claims the resource data for the span of the closure `f`. For the
-    /// duration of the closure other tasks that may access the resource data
-    /// are prevented from preempting the current task.
-    fn claim<R, F>(&self, t: &mut Threshold, f: F) -> R
-    where
-        F: FnOnce(&Static<Self::Data>, &mut Threshold) -> R;
-
-    /// Mutable variant of `claim`
-    fn claim_mut<R, F>(&mut self, t: &mut Threshold, f: F) -> R
-    where
-        F: FnOnce(&mut Static<Self::Data>, &mut Threshold) -> R;
-}
-
-impl<T> Resource for Static<T> {
-    type Data = T;
-
-    fn borrow<'cs>(&'cs self, _cs: &'cs CriticalSection) -> &'cs Static<T> {
-        self
-    }
-
-    fn borrow_mut<'cs>(
-        &'cs mut self,
-        _cs: &'cs CriticalSection,
-    ) -> &'cs mut Static<T> {
-        self
-    }
-
-    fn claim<R, F>(&self, t: &mut Threshold, f: F) -> R
-    where
-        F: FnOnce(&Static<Self::Data>, &mut Threshold) -> R,
-    {
-        f(self, t)
-    }
-
-    fn claim_mut<R, F>(&mut self, t: &mut Threshold, f: F) -> R
-    where
-        F: FnOnce(&mut Static<Self::Data>, &mut Threshold) -> R,
-    {
-        f(self, t)
+/// Executes the closure `f` in an interrupt free context
+pub fn atomic<R, F>(t: &mut Threshold, f: F) -> R
+where
+    F: FnOnce(&mut Threshold) -> R,
+{
+    if t.value() == u8::MAX {
+        f(t)
+    } else {
+        interrupt::disable();
+        let r = f(&mut unsafe { Threshold::max() });
+        unsafe { interrupt::enable() };
+        r
     }
 }
 
@@ -147,20 +102,19 @@ where
     F: FnOnce(T, &mut Threshold) -> R,
 {
     let max_priority = 1 << nvic_prio_bits;
-    if ceiling > t.value {
+    if ceiling > t.value() {
         match () {
             #[cfg(armv6m)]
-            () => {
-                atomic(|_| f(data, &mut Threshold::new(max_priority)))
-            }
+            () => atomic(t, |t| f(data, t)),
+
             #[cfg(not(armv6m))]
             () => {
                 if ceiling == max_priority {
-                    atomic(|_| f(data, &mut Threshold::new(max_priority)))
+                    atomic(t, |t| f(data, t))
                 } else {
                     let old = basepri::read();
                     let hw = (max_priority - ceiling) << (8 - nvic_prio_bits);
-                    basepri_max::write(hw);
+                    basepri::write(hw);
                     let ret = f(data, &mut Threshold::new(ceiling));
                     basepri::write(old);
                     ret
@@ -172,25 +126,6 @@ where
     }
 }
 
-/// Preemption threshold token
-///
-/// The preemption threshold indicates the priority a task must have to preempt
-/// the current context. For example a threshold of 2 indicates that only
-/// interrupts / exceptions with a priority of 3 or greater can preempt the
-/// current context
-pub struct Threshold {
-    value: u8,
-}
-
-impl Threshold {
-    #[doc(hidden)]
-    pub unsafe fn new(value: u8) -> Self {
-        Threshold { value }
-    }
-}
-
-impl !Send for Threshold {}
-
 /// Sets an interrupt as pending
 ///
 /// If the interrupt priority is high enough the interrupt will be serviced
@@ -205,63 +140,6 @@ where
     nvic.set_pending(interrupt);
 }
 
-/// Binds a task `$handler` to the interrupt / exception `$NAME`
-///
-/// This macro takes two arguments: the name of an exception / interrupt and the
-/// path to the function that will be used as the task handler. That function
-/// must have signature `fn(&mut Threshold, $NAME::Resources)`.
-///
-/// Optionally, a third argument may be used to declare task local data.
-/// The handler will have exclusive access to these *local* variables on each
-/// invocation. If the third argument is used then the signature of the handler
-/// function must be `fn(&mut Threshold, &mut $locals, $NAME::Resources)`.
-#[macro_export]
-macro_rules! task {
-    ($NAME:ident, $handler:path) => {
-        #[allow(non_snake_case)]
-        #[allow(unsafe_code)]
-        #[no_mangle]
-        pub unsafe extern "C" fn $NAME() {
-            let f: fn(&mut $crate::Threshold, ::$NAME::Resources) = $handler;
-
-            f(
-                &mut $crate::Threshold::new(::$NAME::$NAME),
-                ::$NAME::Resources::new(),
-            );
-        }
-    };
-
-    ($NAME:ident, $handler:path, $locals:ident {
-        $(static $var:ident: $ty:ty = $expr:expr;)+
-    }) => {
-        #[allow(non_snake_case)]
-        struct $locals {
-            $($var: $crate::Static<$ty>,)+
-        }
-
-        #[allow(non_snake_case)]
-        #[allow(unsafe_code)]
-        #[no_mangle]
-        pub unsafe extern "C" fn $NAME() {
-            let f: fn(
-                &mut $crate::Threshold,
-                &mut $locals,
-                ::$NAME::Resources,
-            ) = $handler;
-
-            static mut LOCALS: $locals = $locals {
-                $($var: unsafe { $crate::Static::new($expr) },)+
-            };
-
-            f(
-                &mut $crate::Threshold::new(::$NAME::$NAME),
-                &mut LOCALS,
-                ::$NAME::Resources::new(),
-            );
-        }
-    };
-}
-
 #[allow(non_camel_case_types)]
 #[doc(hidden)]
 pub enum Exception {