diff --git a/examples/full-syntax.rs b/examples/full-syntax.rs index 184349bfe8..20e8dfbce7 100644 --- a/examples/full-syntax.rs +++ b/examples/full-syntax.rs @@ -1,5 +1,4 @@ //! A showcase of the `app!` macro syntax - #![deny(unsafe_code)] #![feature(const_fn)] #![feature(proc_macro)] @@ -8,7 +7,7 @@ extern crate cortex_m_rtfm as rtfm; extern crate stm32f103xx; -use rtfm::{app, Resource, Threshold}; +use rtfm::{app, Threshold}; app! { device: stm32f103xx, @@ -21,23 +20,30 @@ app! { }, init: { - path: init_, // this is a path to the "init" function + // This is the path to the `init` function + // + // `init` doesn't necessarily has to be in the root of the crate + path: main::init, }, idle: { - path: idle_, // this is a path to the "idle" function + // This is a path to the `idle` function + // + // `idle` doesn't necessarily has to be in the root of the crate + path: main::idle, resources: [OWNED, SHARED], }, tasks: { SYS_TICK: { path: sys_tick, - priority: 1, + // If omitted priority is assumed to be 1 + // priority: 1, resources: [CO_OWNED, ON, SHARED], }, TIM2: { - // tasks are enabled, between `init` and `idle`, by default but they + // Tasks are enabled, between `init` and `idle`, by default but they // can start disabled if `false` is specified here enabled: false, path: tim2, @@ -47,18 +53,22 @@ app! { }, } -fn init_(_p: init::Peripherals, _r: init::Resources) {} +mod main { + use rtfm::{self, Resource, Threshold}; -fn idle_(t: &mut Threshold, mut r: idle::Resources) -> ! { - loop { - *r.OWNED != *r.OWNED; + pub fn init(_p: ::init::Peripherals, _r: ::init::Resources) {} - if *r.OWNED { - if r.SHARED.claim(t, |shared, _| **shared) { - rtfm::wfi(); + pub fn idle(t: &mut Threshold, mut r: ::idle::Resources) -> ! { + loop { + *r.OWNED != *r.OWNED; + + if *r.OWNED { + if r.SHARED.claim(t, |shared, _| **shared) { + rtfm::wfi(); + } + } else { + r.SHARED.claim_mut(t, |shared, _| **shared = !**shared); } - } else { - r.SHARED.claim_mut(t, |shared, _| **shared = !**shared); } } } diff --git a/examples/generics.rs b/examples/generics.rs index 6c6e1d6e5d..57c9b8ebc6 100644 --- a/examples/generics.rs +++ b/examples/generics.rs @@ -1,5 +1,4 @@ //! Working with resources in a generic fashion - #![deny(unsafe_code)] #![feature(proc_macro)] #![no_std] @@ -36,7 +35,7 @@ fn idle() -> ! { } } -// a generic function to use resources in any task (regardless of its priority) +// A generic function that uses some resources fn work(t: &mut Threshold, gpioa: &G, spi1: &S) where G: Resource, @@ -53,12 +52,12 @@ where }); } -// this task needs critical sections to access the resources +// This task needs critical sections to access the resources fn exti0(t: &mut Threshold, r: EXTI0::Resources) { work(t, &r.GPIOA, &r.SPI1); } -// this task has direct access to the resources +// This task has direct access to the resources fn exti1(t: &mut Threshold, r: EXTI1::Resources) { work(t, r.GPIOA, r.SPI1); } diff --git a/examples/modules.rs b/examples/modules.rs deleted file mode 100644 index 6bdf8d9aea..0000000000 --- a/examples/modules.rs +++ /dev/null @@ -1,76 +0,0 @@ -//! Using paths and modules -#![deny(unsafe_code)] -#![feature(const_fn)] -#![feature(proc_macro)] -#![no_std] - -extern crate cortex_m_rtfm as rtfm; -extern crate stm32f103xx; - -use rtfm::app; - -app! { - device: stm32f103xx, - - resources: { - static CO_OWNED: u32 = 0; - static ON: bool = false; - static OWNED: bool = false; - static SHARED: bool = false; - }, - - init: { - path: main::init, - }, - - idle: { - path: main::idle, - resources: [OWNED, SHARED], - }, - - tasks: { - SYS_TICK: { - path: tasks::sys_tick, - resources: [CO_OWNED, ON, SHARED], - }, - - TIM2: { - path: tasks::tim2, - resources: [CO_OWNED], - }, - }, -} - -mod main { - use rtfm::{self, Resource, Threshold}; - - pub fn init(_p: ::init::Peripherals, _r: ::init::Resources) {} - - pub fn idle(t: &mut Threshold, mut r: ::idle::Resources) -> ! { - loop { - *r.OWNED != *r.OWNED; - - if *r.OWNED { - if r.SHARED.claim(t, |shared, _| **shared) { - rtfm::wfi(); - } - } else { - r.SHARED.claim_mut(t, |shared, _| **shared = !**shared); - } - } - } -} - -pub mod tasks { - use rtfm::Threshold; - - pub fn sys_tick(_t: &mut Threshold, r: ::SYS_TICK::Resources) { - **r.ON = !**r.ON; - - **r.CO_OWNED += 1; - } - - pub fn tim2(_t: &mut Threshold, r: ::TIM2::Resources) { - **r.CO_OWNED += 1; - } -} diff --git a/examples/nested.rs b/examples/nested.rs index 92f90cbf1f..7013170910 100644 --- a/examples/nested.rs +++ b/examples/nested.rs @@ -2,7 +2,6 @@ //! //! If you run this program you'll hit the breakpoints as indicated by the //! letters in the comments: A, then B, then C, etc. - #![deny(unsafe_code)] #![feature(const_fn)] #![feature(proc_macro)] @@ -46,9 +45,12 @@ app! { fn init(_p: init::Peripherals, _r: init::Resources) {} fn idle() -> ! { - // sets task `exti0` as pending + // A + rtfm::bkpt(); + + // Sets task `exti0` as pending // - // because `exti0` has higher priority than `idle` it will be executed + // Because `exti0` has higher priority than `idle` it will be executed // immediately rtfm::set_pending(Interrupt::EXTI0); // ~> exti0 @@ -58,64 +60,66 @@ fn idle() -> ! { } fn exti0(t: &mut Threshold, r: EXTI0::Resources) { - // because this task has a priority of 1 the preemption threshold is also 1 + // Because this task has a priority of 1 the preemption threshold `t` also + // starts at 1 let mut low = r.LOW; let mut high = r.HIGH; - // A + // B rtfm::bkpt(); - // because `exti1` has higher priority than `exti0` it can preempt it + // Because `exti1` has higher priority than `exti0` it can preempt it rtfm::set_pending(Interrupt::EXTI1); // ~> exti1 - // a claim creates a critical section + // A claim creates a critical section low.claim_mut(t, |_low, t| { - // this claim increases the preemption threshold to 2 - // just high enough to not race with task `exti1` for access to the + // This claim increases the preemption threshold to 2 + // + // 2 is just high enough to not race with task `exti1` for access to the // `LOW` resource - // C + // D rtfm::bkpt(); - // now `exti1` can't preempt this task because its priority is equal to + // Now `exti1` can't preempt this task because its priority is equal to // the current preemption threshold rtfm::set_pending(Interrupt::EXTI1); - // but `exti2` can, because its priority is higher than the current + // But `exti2` can, because its priority is higher than the current // preemption threshold rtfm::set_pending(Interrupt::EXTI2); // ~> exti2 - // E + // F rtfm::bkpt(); - // claims can be nested + // Claims can be nested high.claim_mut(t, |_high, _| { // This claim increases the preemption threshold to 3 - // now `exti2` can't preempt this task + // Now `exti2` can't preempt this task rtfm::set_pending(Interrupt::EXTI2); - // F + // G rtfm::bkpt(); }); - // upon leaving the critical section the preemption threshold drops to 2 - // and `exti2` immediately preempts this task + // Upon leaving the critical section the preemption threshold drops back + // to 2 and `exti2` immediately preempts this task // ~> exti2 }); - // once again the preemption threshold drops to 1 - // now the pending `exti1` can preempt this task + // Once again the preemption threshold drops but this time to 1. Now the + // pending `exti1` task can preempt this task // ~> exti1 } fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) { - // B, H + // C, I rtfm::bkpt(); } fn exti2(_t: &mut Threshold, _r: EXTI2::Resources) { - // D, G + // E, H rtfm::bkpt(); } diff --git a/examples/one-task.rs b/examples/one-task.rs index e1d598ddfc..556177d0f1 100644 --- a/examples/one-task.rs +++ b/examples/one-task.rs @@ -14,11 +14,11 @@ use rtfm::{app, Threshold}; app! { device: stm32f103xx, - // Here resources are declared + // Here data resources are declared // - // Resources are static variables that are safe to share across tasks + // Data resources are static variables that are safe to share across tasks resources: { - // declaration of resources looks exactly like declaration of static + // Declaration of resources looks exactly like declaration of static // variables static ON: bool = false; }, @@ -31,20 +31,24 @@ app! { tasks: { // Here we declare that we'll use the SYS_TICK exception as a task SYS_TICK: { - // Path to the task *handler* + // Path to the task handler path: sys_tick, // This is the priority of the task. // - // 1 is the lowest priority a task can have. - // The maximum priority is determined by the number of priority bits - // the device has. This device has 4 priority bits so 16 is the - // maximum value. + // 1 is the lowest priority a task can have, and the maximum + // priority is determined by the number of priority bits the device + // has. `stm32f103xx` has 4 priority bits so 16 is the maximum valid + // value. + // + // You can omit this field. If you do the priority is assumed to be + // 1. priority: 1, - // These are the *resources* associated with this task + // These are the resources this task has access to. // - // The peripherals that the task needs can be listed here + // A resource can be a peripheral like `GPIOC` or a static variable + // like `ON` resources: [GPIOC, ON], }, } @@ -75,8 +79,10 @@ fn idle() -> ! { // This is the task handler of the SYS_TICK exception // -// `r` is the resources this task has access to. `SYS_TICK::Resources` has one -// field per every resource declared in `app!`. +// `_t` is the preemption threshold token. We won't use it in this program. +// +// `r` is the set of resources this task has access to. `TIMER0_A1::Resources` +// has one field per resource declared in `app!`. fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) { // toggle state **r.ON = !**r.ON; diff --git a/examples/preemption.rs b/examples/preemption.rs index 057e4fd906..256b9bddfd 100644 --- a/examples/preemption.rs +++ b/examples/preemption.rs @@ -1,4 +1,4 @@ -//! Two tasks running at different priorities with access to the same resource +//! Two tasks running at *different* priorities with access to the same resource #![deny(unsafe_code)] #![feature(const_fn)] #![feature(proc_macro)] @@ -17,7 +17,7 @@ app! { }, tasks: { - // the task `SYS_TICK` has higher priority than `TIM2` + // The `SYS_TICK` task has higher priority than `TIM2` SYS_TICK: { path: sys_tick, priority: 2, @@ -45,7 +45,7 @@ fn idle() -> ! { fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) { // .. - // this task can't be preempted by `tim2` so it has direct access to the + // This task can't be preempted by `tim2` so it has direct access to the // resource data **r.COUNTER += 1; @@ -55,10 +55,10 @@ fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) { fn tim2(t: &mut Threshold, mut r: TIM2::Resources) { // .. - // as this task runs at lower priority it needs a critical section to + // As this task runs at lower priority it needs a critical section to // prevent `sys_tick` from preempting it while it modifies this resource // data. The critical section is required to prevent data races which can - // lead to data corruption or data loss + // lead to undefined behavior r.COUNTER.claim_mut(t, |counter, _t| { **counter += 1; }); // .. diff --git a/examples/two-tasks.rs b/examples/two-tasks.rs index 42b91e4a07..ea059a0248 100644 --- a/examples/two-tasks.rs +++ b/examples/two-tasks.rs @@ -1,4 +1,4 @@ -//! Two tasks running at the same priority with access to the same resource +//! Two tasks running at the *same* priority with access to the same resource #![deny(unsafe_code)] #![feature(const_fn)] @@ -13,34 +13,25 @@ use rtfm::{app, Threshold}; app! { device: stm32f103xx, - // Resources that are plain data, not peripherals resources: { - // Declaration of resources looks like the declaration of `static` - // variables static COUNTER: u64 = 0; }, + // Both SYS_TICK and TIM2 have access to the `COUNTER` data tasks: { SYS_TICK: { path: sys_tick, - priority: 1, - // Both this task and TIM2 have access to the `COUNTER` resource resources: [COUNTER], }, - // An interrupt as a task TIM2: { - // For interrupts the `enabled` field must be specified. It - // indicates if the interrupt will be enabled or disabled once - // `idle` starts path: tim2, - priority: 1, resources: [COUNTER], }, }, } -// when data resources are declared in the top `resources` field, `init` will +// When data resources are declared in the top `resources` field, `init` will // have full access to them fn init(_p: init::Peripherals, _r: init::Resources) { // .. diff --git a/examples/zero-tasks.rs b/examples/zero-tasks.rs index 132016773a..9176103d43 100644 --- a/examples/zero-tasks.rs +++ b/examples/zero-tasks.rs @@ -1,7 +1,7 @@ //! Minimal example with zero tasks - #![deny(unsafe_code)] -#![feature(proc_macro)] // IMPORTANT always include this feature gate +// IMPORTANT always include this feature gate +#![feature(proc_macro)] #![no_std] extern crate cortex_m_rtfm as rtfm; // IMPORTANT always do this rename @@ -15,7 +15,7 @@ use rtfm::app; // This macro will expand to a `main` function so you don't need to supply // `main` yourself. app! { - // this is a path to the device crate + // this is the path to the device crate device: stm32f103xx, } @@ -28,20 +28,14 @@ fn init(p: init::Peripherals) { p.GPIOA; p.RCC; // .. - - // You'll hit this breakpoint first - rtfm::bkpt(); } // The idle loop. // -// This runs afterwards and has a priority of 0. All tasks can preempt this +// This runs after `init` and has a priority of 0. All tasks can preempt this // function. This function can never return so it must contain some sort of // endless loop. fn idle() -> ! { - // And then this breakpoint - rtfm::bkpt(); - loop { // This puts the processor to sleep until there's a task to service rtfm::wfi(); diff --git a/src/examples/_0_zero_tasks.rs b/src/examples/_0_zero_tasks.rs index 15231818bd..7ea085979a 100644 --- a/src/examples/_0_zero_tasks.rs +++ b/src/examples/_0_zero_tasks.rs @@ -1,9 +1,9 @@ //! Minimal example with zero tasks //! //! ``` -//! //! #![deny(unsafe_code)] -//! #![feature(proc_macro)] // IMPORTANT always include this feature gate +//! // IMPORTANT always include this feature gate +//! #![feature(proc_macro)] //! #![no_std] //! //! extern crate cortex_m_rtfm as rtfm; // IMPORTANT always do this rename @@ -17,7 +17,7 @@ //! // This macro will expand to a `main` function so you don't need to supply //! // `main` yourself. //! app! { -//! // this is a path to the device crate +//! // this is the path to the device crate //! device: stm32f103xx, //! } //! @@ -30,20 +30,14 @@ //! p.GPIOA; //! p.RCC; //! // .. -//! -//! // You'll hit this breakpoint first -//! rtfm::bkpt(); //! } //! //! // The idle loop. //! // -//! // This runs afterwards and has a priority of 0. All tasks can preempt this +//! // This runs after `init` and has a priority of 0. All tasks can preempt this //! // function. This function can never return so it must contain some sort of //! // endless loop. //! fn idle() -> ! { -//! // And then this breakpoint -//! rtfm::bkpt(); -//! //! loop { //! // This puts the processor to sleep until there's a task to service //! rtfm::wfi(); diff --git a/src/examples/_1_one_task.rs b/src/examples/_1_one_task.rs index 33e8bf7f49..1bccc2199e 100644 --- a/src/examples/_1_one_task.rs +++ b/src/examples/_1_one_task.rs @@ -1,14 +1,12 @@ //! An application with one task //! //! ``` -//! //! #![deny(unsafe_code)] //! #![feature(const_fn)] //! #![feature(proc_macro)] //! #![no_std] //! //! extern crate cortex_m; -//! #[macro_use(task)] //! extern crate cortex_m_rtfm as rtfm; //! extern crate stm32f103xx; //! @@ -18,6 +16,15 @@ //! app! { //! device: stm32f103xx, //! +//! // Here data resources are declared +//! // +//! // Data resources are static variables that are safe to share across tasks +//! resources: { +//! // Declaration of resources looks exactly like declaration of static +//! // variables +//! static ON: bool = false; +//! }, +//! //! // Here tasks are declared //! // //! // Each task corresponds to an interrupt or an exception. Every time the @@ -26,22 +33,30 @@ //! tasks: { //! // Here we declare that we'll use the SYS_TICK exception as a task //! SYS_TICK: { +//! // Path to the task handler +//! path: sys_tick, +//! //! // This is the priority of the task. -//! // 1 is the lowest priority a task can have. -//! // The maximum priority is determined by the number of priority bits -//! // the device has. This device has 4 priority bits so 16 is the -//! // maximum value. +//! // +//! // 1 is the lowest priority a task can have, and the maximum +//! // priority is determined by the number of priority bits the device +//! // has. `stm32f103xx` has 4 priority bits so 16 is the maximum valid +//! // value. +//! // +//! // You can omit this field. If you do the priority is assumed to be +//! // 1. //! priority: 1, //! -//! // These are the *resources* associated with this task +//! // These are the resources this task has access to. //! // -//! // The peripherals that the task needs can be listed here -//! resources: [GPIOC], +//! // A resource can be a peripheral like `GPIOC` or a static variable +//! // like `ON` +//! resources: [GPIOC, ON], //! }, //! } //! } //! -//! fn init(p: init::Peripherals) { +//! fn init(p: init::Peripherals, _r: init::Resources) { //! // power on GPIOC //! p.RCC.apb2enr.modify(|_, w| w.iopcen().enabled()); //! @@ -64,26 +79,17 @@ //! } //! } //! -//! // This binds the `sys_tick` handler to the `SYS_TICK` task -//! // -//! // This particular handler has local state associated to it. The value of the -//! // `STATE` variable will be preserved across invocations of this handler -//! task!(SYS_TICK, sys_tick, Locals { -//! static STATE: bool = false; -//! }); -//! //! // This is the task handler of the SYS_TICK exception //! // -//! // `t` is the preemption threshold token. We won't use it this time. -//! // `l` is the data local to this task. The type here must match the one declared -//! // in `task!`. -//! // `r` is the resources this task has access to. `SYS_TICK::Resources` has one -//! // field per resource declared in `app!`. -//! fn sys_tick(_t: &mut Threshold, l: &mut Locals, r: SYS_TICK::Resources) { +//! // `_t` is the preemption threshold token. We won't use it in this program. +//! // +//! // `r` is the set of resources this task has access to. `TIMER0_A1::Resources` +//! // has one field per resource declared in `app!`. +//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) { //! // toggle state -//! *l.STATE = !*l.STATE; +//! **r.ON = !**r.ON; //! -//! if *l.STATE { +//! if **r.ON { //! // set the pin PC13 high //! r.GPIOC.bsrr.write(|w| w.bs13().set()); //! } else { diff --git a/src/examples/_2_two_tasks.rs b/src/examples/_2_two_tasks.rs index 9eb61b184f..451293cfe8 100644 --- a/src/examples/_2_two_tasks.rs +++ b/src/examples/_2_two_tasks.rs @@ -1,4 +1,4 @@ -//! Two tasks running at the same priority with access to the same resource +//! Two tasks running at the *same* priority with access to the same resource //! //! ``` //! @@ -7,7 +7,6 @@ //! #![feature(proc_macro)] //! #![no_std] //! -//! #[macro_use(task)] //! extern crate cortex_m_rtfm as rtfm; //! extern crate stm32f103xx; //! @@ -16,33 +15,25 @@ //! app! { //! device: stm32f103xx, //! -//! // Resources that are plain data, not peripherals //! resources: { -//! // Declaration of resources looks like the declaration of `static` -//! // variables //! static COUNTER: u64 = 0; //! }, //! +//! // Both SYS_TICK and TIM2 have access to the `COUNTER` data //! tasks: { //! SYS_TICK: { -//! priority: 1, -//! // Both this task and TIM2 have access to the `COUNTER` resource +//! path: sys_tick, //! resources: [COUNTER], //! }, //! -//! // An interrupt as a task //! TIM2: { -//! // For interrupts the `enabled` field must be specified. It -//! // indicates if the interrupt will be enabled or disabled once -//! // `idle` starts -//! enabled: true, -//! priority: 1, +//! path: tim2, //! resources: [COUNTER], //! }, //! }, //! } //! -//! // when data resources are declared in the top `resources` field, `init` will +//! // When data resources are declared in the top `resources` field, `init` will //! // have full access to them //! fn init(_p: init::Peripherals, _r: init::Resources) { //! // .. @@ -54,8 +45,6 @@ //! } //! } //! -//! task!(SYS_TICK, sys_tick); -//! //! // As both tasks are running at the same priority one can't preempt the other. //! // Thus both tasks have direct access to the resource //! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) { @@ -66,8 +55,6 @@ //! // .. //! } //! -//! task!(TIM2, tim2); -//! //! fn tim2(_t: &mut Threshold, r: TIM2::Resources) { //! // .. //! diff --git a/src/examples/_3_preemption.rs b/src/examples/_3_preemption.rs index b93ec0863c..1f6b244bcb 100644 --- a/src/examples/_3_preemption.rs +++ b/src/examples/_3_preemption.rs @@ -1,13 +1,11 @@ -//! Two tasks running at different priorities with access to the same resource +//! Two tasks running at *different* priorities with access to the same resource //! //! ``` -//! //! #![deny(unsafe_code)] //! #![feature(const_fn)] //! #![feature(proc_macro)] //! #![no_std] //! -//! #[macro_use(task)] //! extern crate cortex_m_rtfm as rtfm; //! extern crate stm32f103xx; //! @@ -21,14 +19,15 @@ //! }, //! //! tasks: { -//! // the task `SYS_TICK` has higher priority than `TIM2` +//! // The `SYS_TICK` task has higher priority than `TIM2` //! SYS_TICK: { +//! path: sys_tick, //! priority: 2, //! resources: [COUNTER], //! }, //! //! TIM2: { -//! enabled: true, +//! path: tim2, //! priority: 1, //! resources: [COUNTER], //! }, @@ -45,27 +44,23 @@ //! } //! } //! -//! task!(SYS_TICK, sys_tick); -//! //! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) { //! // .. //! -//! // this task can't be preempted by `tim2` so it has direct access to the +//! // This task can't be preempted by `tim2` so it has direct access to the //! // resource data //! **r.COUNTER += 1; //! //! // .. //! } //! -//! task!(TIM2, tim2); -//! //! fn tim2(t: &mut Threshold, mut r: TIM2::Resources) { //! // .. //! -//! // as this task runs at lower priority it needs a critical section to +//! // As this task runs at lower priority it needs a critical section to //! // prevent `sys_tick` from preempting it while it modifies this resource //! // data. The critical section is required to prevent data races which can -//! // lead to data corruption or data loss +//! // lead to undefined behavior //! r.COUNTER.claim_mut(t, |counter, _t| { **counter += 1; }); //! //! // .. diff --git a/src/examples/_4_nested.rs b/src/examples/_4_nested.rs index 6be68d8eec..d0306210d8 100644 --- a/src/examples/_4_nested.rs +++ b/src/examples/_4_nested.rs @@ -4,13 +4,11 @@ //! letters in the comments: A, then B, then C, etc. //! //! ``` -//! //! #![deny(unsafe_code)] //! #![feature(const_fn)] //! #![feature(proc_macro)] //! #![no_std] //! -//! #[macro_use(task)] //! extern crate cortex_m_rtfm as rtfm; //! extern crate stm32f103xx; //! @@ -27,19 +25,19 @@ //! //! tasks: { //! EXTI0: { -//! enabled: true, +//! path: exti0, //! priority: 1, //! resources: [LOW, HIGH], //! }, //! //! EXTI1: { -//! enabled: true, +//! path: exti1, //! priority: 2, //! resources: [LOW], //! }, //! //! EXTI2: { -//! enabled: true, +//! path: exti2, //! priority: 3, //! resources: [HIGH], //! }, @@ -49,9 +47,12 @@ //! fn init(_p: init::Peripherals, _r: init::Resources) {} //! //! fn idle() -> ! { -//! // sets task `exti0` as pending +//! // A +//! rtfm::bkpt(); +//! +//! // Sets task `exti0` as pending //! // -//! // because `exti0` has higher priority than `idle` it will be executed +//! // Because `exti0` has higher priority than `idle` it will be executed //! // immediately //! rtfm::set_pending(Interrupt::EXTI0); // ~> exti0 //! @@ -60,72 +61,68 @@ //! } //! } //! -//! task!(EXTI0, exti0); -//! //! fn exti0(t: &mut Threshold, r: EXTI0::Resources) { -//! // because this task has a priority of 1 the preemption threshold is also 1 +//! // Because this task has a priority of 1 the preemption threshold `t` also +//! // starts at 1 //! //! let mut low = r.LOW; //! let mut high = r.HIGH; //! -//! // A +//! // B //! rtfm::bkpt(); //! -//! // because `exti1` has higher priority than `exti0` it can preempt it +//! // Because `exti1` has higher priority than `exti0` it can preempt it //! rtfm::set_pending(Interrupt::EXTI1); // ~> exti1 //! -//! // a claim creates a critical section +//! // A claim creates a critical section //! low.claim_mut(t, |_low, t| { -//! // this claim increases the preemption threshold to 2 -//! // just high enough to not race with task `exti1` for access to the +//! // This claim increases the preemption threshold to 2 +//! // +//! // 2 is just high enough to not race with task `exti1` for access to the //! // `LOW` resource //! -//! // C +//! // D //! rtfm::bkpt(); //! -//! // now `exti1` can't preempt this task because its priority is equal to +//! // Now `exti1` can't preempt this task because its priority is equal to //! // the current preemption threshold //! rtfm::set_pending(Interrupt::EXTI1); //! -//! // but `exti2` can, because its priority is higher than the current +//! // But `exti2` can, because its priority is higher than the current //! // preemption threshold //! rtfm::set_pending(Interrupt::EXTI2); // ~> exti2 //! -//! // E +//! // F //! rtfm::bkpt(); //! -//! // claims can be nested +//! // Claims can be nested //! high.claim_mut(t, |_high, _| { //! // This claim increases the preemption threshold to 3 //! -//! // now `exti2` can't preempt this task +//! // Now `exti2` can't preempt this task //! rtfm::set_pending(Interrupt::EXTI2); //! -//! // F +//! // G //! rtfm::bkpt(); //! }); //! -//! // upon leaving the critical section the preemption threshold drops to 2 -//! // and `exti2` immediately preempts this task +//! // Upon leaving the critical section the preemption threshold drops back +//! // to 2 and `exti2` immediately preempts this task //! // ~> exti2 //! }); //! -//! // once again the preemption threshold drops to 1 -//! // now the pending `exti1` can preempt this task +//! // Once again the preemption threshold drops but this time to 1. Now the +//! // pending `exti1` task can preempt this task //! // ~> exti1 //! } //! -//! task!(EXTI1, exti1); -//! //! fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) { -//! // B, H +//! // C, I //! rtfm::bkpt(); //! } //! -//! task!(EXTI2, exti2); -//! //! fn exti2(_t: &mut Threshold, _r: EXTI2::Resources) { -//! // D, G +//! // E, H //! rtfm::bkpt(); //! } //! ``` diff --git a/src/examples/_5_generics.rs b/src/examples/_5_generics.rs index a8f42cdff2..82ecdf99c7 100644 --- a/src/examples/_5_generics.rs +++ b/src/examples/_5_generics.rs @@ -1,12 +1,10 @@ //! Working with resources in a generic fashion //! //! ``` -//! //! #![deny(unsafe_code)] //! #![feature(proc_macro)] //! #![no_std] //! -//! #[macro_use(task)] //! extern crate cortex_m_rtfm as rtfm; //! extern crate stm32f103xx; //! @@ -18,13 +16,13 @@ //! //! tasks: { //! EXTI0: { -//! enabled: true, +//! path: exti0, //! priority: 1, //! resources: [GPIOA, SPI1], //! }, //! //! EXTI1: { -//! enabled: true, +//! path: exti1, //! priority: 2, //! resources: [GPIOA, SPI1], //! }, @@ -39,7 +37,7 @@ //! } //! } //! -//! // a generic function to use resources in any task (regardless of its priority) +//! // A generic function that uses some resources //! fn work(t: &mut Threshold, gpioa: &G, spi1: &S) //! where //! G: Resource, @@ -56,16 +54,12 @@ //! }); //! } //! -//! task!(EXTI0, exti0); -//! -//! // this task needs critical sections to access the resources +//! // This task needs critical sections to access the resources //! fn exti0(t: &mut Threshold, r: EXTI0::Resources) { //! work(t, &r.GPIOA, &r.SPI1); //! } //! -//! task!(EXTI1, exti1); -//! -//! // this task has direct access to the resources +//! // This task has direct access to the resources //! fn exti1(t: &mut Threshold, r: EXTI1::Resources) { //! work(t, r.GPIOA, r.SPI1); //! } diff --git a/src/examples/_6_full_syntax.rs b/src/examples/_6_full_syntax.rs index 9e93243676..449bee6cdd 100644 --- a/src/examples/_6_full_syntax.rs +++ b/src/examples/_6_full_syntax.rs @@ -1,83 +1,86 @@ //! A showcase of the `app!` macro syntax //! //! ``` -//! //! #![deny(unsafe_code)] //! #![feature(const_fn)] //! #![feature(proc_macro)] //! #![no_std] //! -//! #[macro_use(task)] //! extern crate cortex_m_rtfm as rtfm; //! extern crate stm32f103xx; //! -//! use rtfm::{app, Resource, Threshold}; +//! use rtfm::{app, Threshold}; //! //! app! { //! device: stm32f103xx, //! //! resources: { //! static CO_OWNED: u32 = 0; +//! static ON: bool = false; //! static OWNED: bool = false; //! static SHARED: bool = false; //! }, //! //! init: { -//! path: init_, // this is a path to the "init" function +//! // This is the path to the `init` function +//! // +//! // `init` doesn't necessarily has to be in the root of the crate +//! path: main::init, //! }, //! //! idle: { -//! locals: { -//! static COUNTER: u32 = 0; -//! }, -//! path: idle_, // this is a path to the "idle" function +//! // This is a path to the `idle` function +//! // +//! // `idle` doesn't necessarily has to be in the root of the crate +//! path: main::idle, //! resources: [OWNED, SHARED], //! }, //! //! tasks: { //! SYS_TICK: { -//! priority: 1, -//! resources: [CO_OWNED, SHARED], +//! path: sys_tick, +//! // If omitted priority is assumed to be 1 +//! // priority: 1, +//! resources: [CO_OWNED, ON, SHARED], //! }, //! //! TIM2: { -//! enabled: true, +//! // Tasks are enabled, between `init` and `idle`, by default but they +//! // can start disabled if `false` is specified here +//! enabled: false, +//! path: tim2, //! priority: 1, //! resources: [CO_OWNED], //! }, //! }, //! } //! -//! fn init_(_p: init::Peripherals, _r: init::Resources) {} +//! mod main { +//! use rtfm::{self, Resource, Threshold}; //! -//! fn idle_(t: &mut Threshold, l: &mut idle::Locals, mut r: idle::Resources) -> ! { -//! loop { -//! *l.COUNTER += 1; +//! pub fn init(_p: ::init::Peripherals, _r: ::init::Resources) {} //! -//! **r.OWNED != **r.OWNED; +//! pub fn idle(t: &mut Threshold, mut r: ::idle::Resources) -> ! { +//! loop { +//! *r.OWNED != *r.OWNED; //! -//! if **r.OWNED { -//! if r.SHARED.claim(t, |shared, _| **shared) { -//! rtfm::wfi(); +//! if *r.OWNED { +//! if r.SHARED.claim(t, |shared, _| **shared) { +//! rtfm::wfi(); +//! } +//! } else { +//! r.SHARED.claim_mut(t, |shared, _| **shared = !**shared); //! } -//! } else { -//! r.SHARED.claim_mut(t, |shared, _| **shared = !**shared); //! } //! } //! } //! -//! task!(SYS_TICK, sys_tick, Local { -//! static STATE: bool = true; -//! }); -//! -//! fn sys_tick(_t: &mut Threshold, l: &mut Local, r: SYS_TICK::Resources) { -//! *l.STATE = !*l.STATE; +//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) { +//! **r.ON = !**r.ON; //! //! **r.CO_OWNED += 1; //! } //! -//! task!(TIM2, tim2); -//! //! fn tim2(_t: &mut Threshold, r: TIM2::Resources) { //! **r.CO_OWNED += 1; //! }