diff --git a/src/lib.rs b/src/lib.rs index 3d08402d30..aeb29e0b41 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -436,7 +436,7 @@ extern crate typenum; use core::cell::UnsafeCell; use core::marker::PhantomData; -use core::{mem, ptr}; +use core::ptr; use cortex_m::ctxt::Context; use cortex_m::interrupt::Nr; @@ -612,7 +612,7 @@ where /// Disables a `task` /// /// The task won't run even if the underlying interrupt is raised -pub fn disable(_task: fn(T, P)) +pub fn disable(_task: fn(T, P, C)) where T: Context + Nr, { @@ -624,7 +624,7 @@ where } /// Enables a `task` -pub fn enable(_task: fn(T, P)) +pub fn enable(_task: fn(T, P, C)) where T: Context + Nr, { @@ -655,7 +655,7 @@ pub fn logical2hw(logical: u8) -> u8 { } /// Requests the execution of a `task` -pub fn request(_task: fn(T, P)) +pub fn request(_task: fn(T, P, C)) where T: Context + Nr, { @@ -719,15 +719,6 @@ pub struct P { _marker: PhantomData, } -impl P { - /// Turns this priority into a ceiling - pub fn as_ceiling(&self) -> &C { - unsafe { - mem::transmute(self) - } - } -} - impl P where T: Unsigned, @@ -885,11 +876,12 @@ macro_rules! tasks { enable_tasks(); }); - fn validate_signature(_: fn($crate::P0) -> !) {} + fn validate_signature(_: fn($crate::P0, $crate::C0) -> !) {} validate_signature(idle); let p0 = unsafe { ::core::mem::transmute::<_, P0>(()) }; - idle(p0); + let c0 = unsafe { ::core::mem::transmute::<_, C0>(()) }; + idle(p0, c0); fn set_priorities() { // NOTE(safe) this function runs in an interrupt free context @@ -931,11 +923,19 @@ macro_rules! tasks { extern "C" fn $task( task: ::$device::interrupt::$Interrupt ) { + fn validate_signature( + _: fn(::$device::interrupt::$Interrupt, + $crate::P, + $crate::C)) {} + validate_signature(::$task); let p = unsafe { ::core::mem::transmute::<_, $crate::$P>(()) }; + let c = unsafe { + ::core::mem::transmute(()) + }; $crate::_validate_priority(&p); - ::$task(task, p) + ::$task(task, p, c) } $task diff --git a/tests/cfail/access.rs b/tests/cfail/access.rs index db776025b0..7524b068fd 100644 --- a/tests/cfail/access.rs +++ b/tests/cfail/access.rs @@ -9,9 +9,7 @@ static R4: Resource = Resource::new(0); static R5: Resource = Resource::new(0); static R6: Resource = Resource::new(0); -fn j1(prio: P2) { - let ceil = prio.as_ceiling(); - +fn j1(prio: P2, ceil: C2) { ceil.raise( &R1, |ceil| { // NOTE SC = System Ceiling, P = task Priority diff --git a/tests/cfail/ceiling.rs b/tests/cfail/ceiling.rs index e29694b5a9..d1961c93c3 100644 --- a/tests/cfail/ceiling.rs +++ b/tests/cfail/ceiling.rs @@ -1,12 +1,10 @@ extern crate cortex_m_rtfm as rtfm; -use rtfm::{C3, P0, P2, Resource}; +use rtfm::{C2, C3, P0, P2, Resource}; static R1: Resource<(), C3> = Resource::new(()); -fn j1(prio: P2) { - let ceil = prio.as_ceiling(); - +fn j1(prio: P2, ceil: C2) { let c3 = ceil.raise( &R1, |ceil| { // forbidden: ceiling token can't outlive the critical section diff --git a/tests/cfail/lock.rs b/tests/cfail/lock.rs index 073e1dd9ca..62d3c6ef4e 100644 --- a/tests/cfail/lock.rs +++ b/tests/cfail/lock.rs @@ -1,34 +1,28 @@ extern crate cortex_m_rtfm as rtfm; -use rtfm::{C16, C2, P1, P16, P2, P3, Resource}; +use rtfm::{C16, C1, C2, C3, P1, P16, P2, P3, Resource}; static R1: Resource = Resource::new(0); // You CAN'T use `raise` to lower the system ceiling -fn j1(prio: P3) { - let ceil = prio.as_ceiling(); - +fn j1(prio: P3, ceil: C3) { ceil.raise(&R1, |ceil| {}); //~^ error } // You don't need to raise the ceiling to access a resource with ceiling equal // to the task priority. -fn j2(prio: P2) { - let ceil = prio.as_ceiling(); - +fn j2(prio: P2, ceil: C2) { ceil.raise(&R1, |_| {}); //~^ error // OK - let r1 = R1.access(&prio, ceil); + let r1 = R1.access(&prio, &ceil); } // You CAN access a resource with ceiling C from a task with priority P if C > P // and you raise the ceiling first -fn j3(prio: P1) { - let ceil = prio.as_ceiling(); - +fn j3(prio: P1, ceil: C1) { // OK ceil.raise(&R1, |ceil| { let r1 = R1.access(&prio, ceil); }) } @@ -36,15 +30,13 @@ fn j3(prio: P1) { static R2: Resource = Resource::new(0); // Tasks with priority less than P16 can't access a resource with ceiling C16 -fn j4(prio: P1) { - let ceil = prio.as_ceiling(); - +fn j4(prio: P1, ceil: C1) { ceil.raise(&R2, |ceil| {}); //~^ error } // Only tasks with priority P16 can access a resource with ceiling C16 -fn j5(prio: P16) { +fn j5(prio: P16, ceil: C16) { // OK - let r2 = R2.access(&prio, prio.as_ceiling()); + let r2 = R2.access(&prio, &ceil); } diff --git a/tests/cfail/peripherals-alias-2.rs b/tests/cfail/peripherals-alias-2.rs index e649459c63..555cd740a2 100644 --- a/tests/cfail/peripherals-alias-2.rs +++ b/tests/cfail/peripherals-alias-2.rs @@ -6,7 +6,7 @@ #[macro_use] extern crate cortex_m_rtfm as rtfm; -use rtfm::{C16, P0, P1}; +use rtfm::{C0, C16, P0, P1}; use device::interrupt::Exti0; peripherals!(device, { @@ -30,7 +30,7 @@ tasks!(device, {}); fn init(_: P0, _: &C16) {} -fn idle(_: P0) -> ! { +fn idle(_: P0, _: C0) -> ! { loop {} } diff --git a/tests/cfail/race-1.rs b/tests/cfail/race-1.rs index 9d08f42b05..167802d22b 100644 --- a/tests/cfail/race-1.rs +++ b/tests/cfail/race-1.rs @@ -1,12 +1,10 @@ extern crate cortex_m_rtfm as rtfm; -use rtfm::{C2, C4, P1, P3, Resource}; +use rtfm::{C1, C2, C3, C4, P1, P3, Resource}; static R1: Resource = Resource::new(0); -fn j1(prio: P1) { - let ceil = prio.as_ceiling(); - +fn j1(prio: P1, ceil: C1) { ceil.raise( &R1, |ceil| { let r1 = R1.access(&prio, ceil); @@ -17,7 +15,7 @@ fn j1(prio: P1) { ); } -fn j2(_task: Task, prio: P3) { +fn j2(_task: Task, prio: P3, ceil: C3) { rtfm::atomic( |ceil| { // OK C2 (R1's ceiling) <= C16 (system ceiling) diff --git a/tests/cfail/race-2.rs b/tests/cfail/race-2.rs index 71f44fb968..402a4835f6 100644 --- a/tests/cfail/race-2.rs +++ b/tests/cfail/race-2.rs @@ -1,13 +1,11 @@ extern crate cortex_m_rtfm as rtfm; -use rtfm::{C2, C4, P1, P3, Resource}; +use rtfm::{C1, C2, C3, C4, P1, P3, Resource}; static R1: Resource = Resource::new(0); static R2: Resource = Resource::new(0); -fn j1(prio: P1) { - let ceil = prio.as_ceiling(); - +fn j1(prio: P1, ceil: C1) { ceil.raise( &R1, |ceil| { let r1 = R1.access(&prio, ceil); @@ -18,9 +16,7 @@ fn j1(prio: P1) { ); } -fn j2(_task: Task, prio: P3) { - let ceil = prio.as_ceiling(); - +fn j2(_task: Task, prio: P3, ceil: C3) { ceil.raise( &R2, |ceil| { // OK C2 (R1's ceiling) <= C4 (system ceiling) diff --git a/tests/cfail/tasks-p0.rs b/tests/cfail/tasks-p0.rs index 521db54584..4034f62a44 100644 --- a/tests/cfail/tasks-p0.rs +++ b/tests/cfail/tasks-p0.rs @@ -1,11 +1,11 @@ -// error-pattern: type mismatch +// error-pattern: expected struct `typenum::Equal`, found struct `typenum::Greater` #![feature(used)] #[macro_use] extern crate cortex_m_rtfm as rtfm; -use rtfm::{C16, P0, P1}; +use rtfm::{C0, C1, C16, P0, P1}; use device::interrupt::Exti0; // WRONG: Tasks can't have a priority of 0. @@ -20,11 +20,11 @@ tasks!(device, { fn init(_: P0, _: &C16) {} -fn idle(_: P0) -> ! { +fn idle(_: P0, _: C0) -> ! { loop {} } -fn j1(_task: Exti0, _prio: P1) {} +fn j1(_task: Exti0, _prio: P1, _ceil: C1) {} // fake device crate extern crate core; @@ -32,6 +32,7 @@ extern crate cortex_m; mod device { pub mod interrupt { + use cortex_m::ctxt::Context; use cortex_m::interrupt::Nr; extern "C" fn default_handler(_: T) {} @@ -39,14 +40,17 @@ mod device { pub struct Handlers { pub Exti0: extern "C" fn(Exti0), pub Exti1: extern "C" fn(Exti1), + pub Exti2: extern "C" fn(Exti2), } pub struct Exti0; pub struct Exti1; + pub struct Exti2; pub enum Interrupt { Exti0, Exti1, + Exti2, } unsafe impl Nr for Interrupt { @@ -55,9 +59,34 @@ mod device { } } + unsafe impl Context for Exti0 {} + + unsafe impl Nr for Exti0 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti1 {} + + unsafe impl Nr for Exti1 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti2 {} + + unsafe impl Nr for Exti2 { + fn nr(&self) -> u8 { + 0 + } + } + pub const DEFAULT_HANDLERS: Handlers = Handlers { Exti0: default_handler, Exti1: default_handler, + Exti2: default_handler, }; } } diff --git a/tests/cfail/tasks-same-handler.rs b/tests/cfail/tasks-same-handler.rs index 457ff55e91..1d32d58185 100644 --- a/tests/cfail/tasks-same-handler.rs +++ b/tests/cfail/tasks-same-handler.rs @@ -1,12 +1,12 @@ -// error-pattern: specified more than once +// error-pattern: field `Exti0` specified more than once #![feature(used)] #[macro_use] extern crate cortex_m_rtfm as rtfm; -use rtfm::{C16, P0, P1, P2}; -use device::interrupt::Exti0; +use rtfm::{C0, C1, C16, C2, P0, P1, P2}; +use device::interrupt::{Exti0, Exti1}; // WRONG: Two tasks mapped to the same interrupt handler tasks!(device, { @@ -24,13 +24,13 @@ tasks!(device, { fn init(_: P0, _: &C16) {} -fn idle(_: P0) -> ! { +fn idle(_: P0, _: C0) -> ! { loop {} } -fn j1(_task: Exti0, _prio: P1) {} +fn j1(_task: Exti0, _prio: P1, _ceil: C1) {} -fn j2(_task: Exti0, _prio: P1) {} +fn j2(_task: Exti0, _prio: P2, _ceil: C2) {} // fake device crate extern crate core; @@ -38,6 +38,7 @@ extern crate cortex_m; mod device { pub mod interrupt { + use cortex_m::ctxt::Context; use cortex_m::interrupt::Nr; extern "C" fn default_handler(_: T) {} @@ -45,14 +46,17 @@ mod device { pub struct Handlers { pub Exti0: extern "C" fn(Exti0), pub Exti1: extern "C" fn(Exti1), + pub Exti2: extern "C" fn(Exti2), } pub struct Exti0; pub struct Exti1; + pub struct Exti2; pub enum Interrupt { Exti0, Exti1, + Exti2, } unsafe impl Nr for Interrupt { @@ -61,9 +65,34 @@ mod device { } } + unsafe impl Context for Exti0 {} + + unsafe impl Nr for Exti0 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti1 {} + + unsafe impl Nr for Exti1 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti2 {} + + unsafe impl Nr for Exti2 { + fn nr(&self) -> u8 { + 0 + } + } + pub const DEFAULT_HANDLERS: Handlers = Handlers { Exti0: default_handler, Exti1: default_handler, + Exti2: default_handler, }; } } diff --git a/tests/cfail/tasks-wrong-ceiling.rs b/tests/cfail/tasks-wrong-ceiling.rs new file mode 100644 index 0000000000..84dd133f8e --- /dev/null +++ b/tests/cfail/tasks-wrong-ceiling.rs @@ -0,0 +1,91 @@ +// error-pattern: mismatched types + +#![feature(used)] + +#[macro_use] +extern crate cortex_m_rtfm as rtfm; + +use rtfm::{C0, C1, C16, C2, P0, P1}; +use device::interrupt::Exti0; + +tasks!(device, { + j1: Task { + interrupt: Exti0, + priority: P1, + enabled: true, + }, +}); + +fn init(_: P0, _: &C16) {} + +fn idle(_: P0, _: C0) -> ! { + loop {} +} + +// Wrong ceiling token. `prio` and `ceil` must match in levels +fn j1(_task: Exti0, _prio: P1, _ceil: C2) {} + +// fake device crate +extern crate core; +extern crate cortex_m; + +mod device { + pub mod interrupt { + use cortex_m::ctxt::Context; + use cortex_m::interrupt::Nr; + + extern "C" fn default_handler(_: T) {} + + pub struct Handlers { + pub Exti0: extern "C" fn(Exti0), + pub Exti1: extern "C" fn(Exti1), + pub Exti2: extern "C" fn(Exti2), + } + + pub struct Exti0; + pub struct Exti1; + pub struct Exti2; + + pub enum Interrupt { + Exti0, + Exti1, + Exti2, + } + + unsafe impl Nr for Interrupt { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti0 {} + + unsafe impl Nr for Exti0 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti1 {} + + unsafe impl Nr for Exti1 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti2 {} + + unsafe impl Nr for Exti2 { + fn nr(&self) -> u8 { + 0 + } + } + + pub const DEFAULT_HANDLERS: Handlers = Handlers { + Exti0: default_handler, + Exti1: default_handler, + Exti2: default_handler, + }; + } +} diff --git a/tests/cfail/tasks-wrong-idle.rs b/tests/cfail/tasks-wrong-idle.rs index 9c247a94ad..954fd220b1 100644 --- a/tests/cfail/tasks-wrong-idle.rs +++ b/tests/cfail/tasks-wrong-idle.rs @@ -6,7 +6,7 @@ extern crate cortex_m_rtfm as rtfm; use device::interrupt::Exti0; -use rtfm::{C16, P0, P1}; +use rtfm::{C0, C1, C16, P0, P1}; tasks!(device, { j1: Task { @@ -18,12 +18,10 @@ tasks!(device, { fn init(_: P0, _: &C16) {} -// WRONG. `idle` must have signature `fn(P0) -> !` -fn idle(_: P1) -> ! { - loop {} -} +// WRONG. `idle` must have signature `fn(P0, C0) -> !` +fn idle(_: P0, _: C0) {} -fn j1(_task: Exti0, _prio: P1) {} +fn j1(_task: Exti0, _prio: P1, _ceil: C1) {} // fake device crate extern crate core; @@ -31,6 +29,7 @@ extern crate cortex_m; mod device { pub mod interrupt { + use cortex_m::ctxt::Context; use cortex_m::interrupt::Nr; extern "C" fn default_handler(_: T) {} @@ -38,14 +37,17 @@ mod device { pub struct Handlers { pub Exti0: extern "C" fn(Exti0), pub Exti1: extern "C" fn(Exti1), + pub Exti2: extern "C" fn(Exti2), } pub struct Exti0; pub struct Exti1; + pub struct Exti2; pub enum Interrupt { Exti0, Exti1, + Exti2, } unsafe impl Nr for Interrupt { @@ -54,9 +56,34 @@ mod device { } } + unsafe impl Context for Exti0 {} + + unsafe impl Nr for Exti0 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti1 {} + + unsafe impl Nr for Exti1 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti2 {} + + unsafe impl Nr for Exti2 { + fn nr(&self) -> u8 { + 0 + } + } + pub const DEFAULT_HANDLERS: Handlers = Handlers { Exti0: default_handler, Exti1: default_handler, + Exti2: default_handler, }; } } diff --git a/tests/cfail/tasks-wrong-init.rs b/tests/cfail/tasks-wrong-init.rs index ab82234dd7..e9ebc6183b 100644 --- a/tests/cfail/tasks-wrong-init.rs +++ b/tests/cfail/tasks-wrong-init.rs @@ -5,7 +5,7 @@ #[macro_use] extern crate cortex_m_rtfm as rtfm; -use rtfm::{C1, P0, P1}; +use rtfm::{C0, C1, C16, P0, P1}; use device::interrupt::Exti0; tasks!(device, { @@ -19,11 +19,11 @@ tasks!(device, { // WRONG. `init` must have signature `fn(P0, &C16)` fn init(_: P0, _: &C1) {} -fn idle(_: P0) -> ! { +fn idle(_: P0, _: C0) -> ! { loop {} } -fn j1(_task: Exti0, _prio: P1) {} +fn j1(_task: Exti0, _prio: P1, _ceil: C1) {} // fake device crate extern crate core; @@ -31,6 +31,7 @@ extern crate cortex_m; mod device { pub mod interrupt { + use cortex_m::ctxt::Context; use cortex_m::interrupt::Nr; extern "C" fn default_handler(_: T) {} @@ -38,14 +39,17 @@ mod device { pub struct Handlers { pub Exti0: extern "C" fn(Exti0), pub Exti1: extern "C" fn(Exti1), + pub Exti2: extern "C" fn(Exti2), } pub struct Exti0; pub struct Exti1; + pub struct Exti2; pub enum Interrupt { Exti0, Exti1, + Exti2, } unsafe impl Nr for Interrupt { @@ -54,9 +58,34 @@ mod device { } } + unsafe impl Context for Exti0 {} + + unsafe impl Nr for Exti0 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti1 {} + + unsafe impl Nr for Exti1 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti2 {} + + unsafe impl Nr for Exti2 { + fn nr(&self) -> u8 { + 0 + } + } + pub const DEFAULT_HANDLERS: Handlers = Handlers { Exti0: default_handler, Exti1: default_handler, + Exti2: default_handler, }; } } diff --git a/tests/cfail/tasks-wrong-priority.rs b/tests/cfail/tasks-wrong-priority.rs index 827acdde9e..01ff7df84b 100644 --- a/tests/cfail/tasks-wrong-priority.rs +++ b/tests/cfail/tasks-wrong-priority.rs @@ -5,8 +5,8 @@ #[macro_use] extern crate cortex_m_rtfm as rtfm; -use cortex_m_srp::{C16, P0, P1, P2}; -use device::interrupt::Exti1; +use device::interrupt::Exti0; +use rtfm::{C0, C1, C16, C2, P0, P1, P2}; tasks!(device, { j1: Task { @@ -18,12 +18,12 @@ tasks!(device, { fn init(_: P0, _: &C16) {} -fn idle(_: P0) -> ! { +fn idle(_: P0, _: C0) -> ! { loop {} } // Wrong priority token. Declared P1, got P2 -fn j1(_task: Exti1, _prio: P1) {} +fn j1(_task: Exti0, _prio: P2, _ceil: C2) {} // fake device crate extern crate core; @@ -31,6 +31,7 @@ extern crate cortex_m; mod device { pub mod interrupt { + use cortex_m::ctxt::Context; use cortex_m::interrupt::Nr; extern "C" fn default_handler(_: T) {} @@ -38,14 +39,17 @@ mod device { pub struct Handlers { pub Exti0: extern "C" fn(Exti0), pub Exti1: extern "C" fn(Exti1), + pub Exti2: extern "C" fn(Exti2), } pub struct Exti0; pub struct Exti1; + pub struct Exti2; pub enum Interrupt { Exti0, Exti1, + Exti2, } unsafe impl Nr for Interrupt { @@ -54,9 +58,34 @@ mod device { } } + unsafe impl Context for Exti0 {} + + unsafe impl Nr for Exti0 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti1 {} + + unsafe impl Nr for Exti1 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti2 {} + + unsafe impl Nr for Exti2 { + fn nr(&self) -> u8 { + 0 + } + } + pub const DEFAULT_HANDLERS: Handlers = Handlers { Exti0: default_handler, Exti1: default_handler, + Exti2: default_handler, }; } } diff --git a/tests/cfail/tasks-wrong-task.rs b/tests/cfail/tasks-wrong-task.rs index 479c223fcd..5fae160aa1 100644 --- a/tests/cfail/tasks-wrong-task.rs +++ b/tests/cfail/tasks-wrong-task.rs @@ -5,8 +5,8 @@ #[macro_use] extern crate cortex_m_rtfm as rtfm; -use cortex_mrtfm::{C16, P0, P1}; -use device::interrupt::Exti1; +use device::interrupt::{Exti0, Exti1}; +use rtfm::{C0, C1, C16, P0, P1}; tasks!(device, { j1: Task { @@ -18,12 +18,12 @@ tasks!(device, { fn init(_: P0, _: &C16) {} -fn idle(_: P0) -> ! { +fn idle(_: P0, _: C0) -> ! { loop {} } // Wrong task token. Declared Exti0, got Exti1 -fn j1(_task: Exti1, _prio: P1) {} +fn j1(_task: Exti1, _prio: P1, _ceil: C1) {} // fake device crate extern crate core; @@ -31,6 +31,7 @@ extern crate cortex_m; mod device { pub mod interrupt { + use cortex_m::ctxt::Context; use cortex_m::interrupt::Nr; extern "C" fn default_handler(_: T) {} @@ -38,14 +39,17 @@ mod device { pub struct Handlers { pub Exti0: extern "C" fn(Exti0), pub Exti1: extern "C" fn(Exti1), + pub Exti2: extern "C" fn(Exti2), } pub struct Exti0; pub struct Exti1; + pub struct Exti2; pub enum Interrupt { Exti0, Exti1, + Exti2, } unsafe impl Nr for Interrupt { @@ -54,9 +58,34 @@ mod device { } } + unsafe impl Context for Exti0 {} + + unsafe impl Nr for Exti0 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti1 {} + + unsafe impl Nr for Exti1 { + fn nr(&self) -> u8 { + 0 + } + } + + unsafe impl Context for Exti2 {} + + unsafe impl Nr for Exti2 { + fn nr(&self) -> u8 { + 0 + } + } + pub const DEFAULT_HANDLERS: Handlers = Handlers { Exti0: default_handler, Exti1: default_handler, + Exti2: default_handler, }; } }