aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jorge Aparicio <jorge@japaric.io> 2017-07-27 22:40:47 -0500
committerGravatar Jorge Aparicio <jorge@japaric.io> 2017-07-27 22:40:47 -0500
commite85d6e53c89cd1ea1da8826778c5a74154fb651d (patch)
tree76fbc30063df22724b9b160c85055e1d294513b0 /src
parent271df39bdba0690ea7ba77a6ff5d8d7edb9b8036 (diff)
downloadrtic-e85d6e53c89cd1ea1da8826778c5a74154fb651d.tar.gz
rtic-e85d6e53c89cd1ea1da8826778c5a74154fb651d.tar.zst
rtic-e85d6e53c89cd1ea1da8826778c5a74154fb651d.zip
update examples
Diffstat (limited to 'src')
-rw-r--r--src/examples/_0_zero_tasks.rs14
-rw-r--r--src/examples/_1_one_task.rs58
-rw-r--r--src/examples/_2_two_tasks.rs23
-rw-r--r--src/examples/_3_preemption.rs19
-rw-r--r--src/examples/_4_nested.rs61
-rw-r--r--src/examples/_5_generics.rs16
-rw-r--r--src/examples/_6_full_syntax.rs61
7 files changed, 114 insertions, 138 deletions
diff --git a/src/examples/_0_zero_tasks.rs b/src/examples/_0_zero_tasks.rs
index 15231818..7ea08597 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 33e8bf7f..1bccc219 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 9eb61b18..451293cf 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 b93ec086..1f6b244b 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 6be68d8e..d0306210 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 a8f42cdf..82ecdf99 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<G, S>(t: &mut Threshold, gpioa: &G, spi1: &S)
//! where
//! G: Resource<Data = GPIOA>,
@@ -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 9e932436..449bee6c 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;
//! }