mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +01:00
update the examples in the crate documentation
This commit is contained in:
parent
d2008e783d
commit
3713959b3d
1 changed files with 38 additions and 35 deletions
67
src/lib.rs
67
src/lib.rs
|
@ -96,10 +96,11 @@
|
||||||
//! IDLE
|
//! IDLE
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! The `tasks!` macro forces the following structure into your program:
|
//! The `tasks!` macro overrides the `main` function and imposes the following
|
||||||
|
//! structure into your program:
|
||||||
//!
|
//!
|
||||||
//! - `init`, the initialization phase, is run first. This function is executed
|
//! - `init`, the initialization phase, is run first. This function is executed
|
||||||
//! in a *global* critical section and can't be preempted.
|
//! inside a *global* critical section and can't be preempted.
|
||||||
//!
|
//!
|
||||||
//! - `idle`, a never ending function that runs after `init`.
|
//! - `idle`, a never ending function that runs after `init`.
|
||||||
//!
|
//!
|
||||||
|
@ -115,8 +116,6 @@
|
||||||
//! extern crate cortex_m_rtfm as rtfm;
|
//! extern crate cortex_m_rtfm as rtfm;
|
||||||
//! extern crate stm32f100xx;
|
//! extern crate stm32f100xx;
|
||||||
//!
|
//!
|
||||||
//! use core::cell::Cell;
|
|
||||||
//!
|
|
||||||
//! use stm32f100xx::interrupt::Tim7Irq;
|
//! use stm32f100xx::interrupt::Tim7Irq;
|
||||||
//! use rtfm::{C16, Local, P0, P1};
|
//! use rtfm::{C16, Local, P0, P1};
|
||||||
//!
|
//!
|
||||||
|
@ -134,20 +133,20 @@
|
||||||
//!
|
//!
|
||||||
//! // TASKS
|
//! // TASKS
|
||||||
//! tasks!(stm32f100xx, {
|
//! tasks!(stm32f100xx, {
|
||||||
//! periodic: (Tim7Irq, P1),
|
//! periodic: (Tim7Irq, P1, true),
|
||||||
//! });
|
//! });
|
||||||
//!
|
//!
|
||||||
//! fn periodic(task: Tim7Irq, _priority: P1) {
|
//! fn periodic(mut task: Tim7Irq, _priority: P1) {
|
||||||
//! // Task local data
|
//! // Task local data
|
||||||
//! static STATE: Local<Cell<bool>, Tim7Irq> = Local::new(Cell::new(false));
|
//! static STATE: Local<bool, Tim7Irq> = Local::new(false);
|
||||||
//!
|
//!
|
||||||
//! let state = STATE.borrow(&task);
|
//! let state = STATE.borrow_mut(&mut task);
|
||||||
//!
|
//!
|
||||||
//! // Toggle state
|
//! // Toggle state
|
||||||
//! state.set(!state.get());
|
//! *state = !*state;
|
||||||
//!
|
//!
|
||||||
//! // Blink an LED
|
//! // Blink an LED
|
||||||
//! if state.get() {
|
//! if *state {
|
||||||
//! LED.on();
|
//! LED.on();
|
||||||
//! } else {
|
//! } else {
|
||||||
//! LED.off();
|
//! LED.off();
|
||||||
|
@ -156,8 +155,8 @@
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Here we define a task named `periodic` and bind it to the `Tim7Irq`
|
//! Here we define a task named `periodic` and bind it to the `Tim7Irq`
|
||||||
//! interrupt handler. Every time the `Tim7Irq` interrupt is triggered, the
|
//! interrupt. The `periodic` task will run every time the `Tim7Irq` interrupt
|
||||||
//! `periodic` runs. We assign to this task a priority of 1, `P1`; this is the
|
//! is triggered. We assign to this task a priority of 1 (`P1`); this is the
|
||||||
//! lowest priority that a task can have.
|
//! lowest priority that a task can have.
|
||||||
//!
|
//!
|
||||||
//! We use the [`Local`](./struct.Local.html) abstraction to add state to the
|
//! We use the [`Local`](./struct.Local.html) abstraction to add state to the
|
||||||
|
@ -184,8 +183,8 @@
|
||||||
//! // omitted: `idle`, `init`
|
//! // omitted: `idle`, `init`
|
||||||
//!
|
//!
|
||||||
//! tasks!(stm32f100xx, {
|
//! tasks!(stm32f100xx, {
|
||||||
//! t1: (Tim6DacIrq, P1),
|
//! t1: (Tim6DacIrq, P1, true),
|
||||||
//! t2: (Tim7Irq, P1),
|
//! t2: (Tim7Irq, P1, true),
|
||||||
//! });
|
//! });
|
||||||
//!
|
//!
|
||||||
//! // Data shared between tasks `t1` and `t2`
|
//! // Data shared between tasks `t1` and `t2`
|
||||||
|
@ -194,7 +193,7 @@
|
||||||
//! fn t1(_task: Tim6DacIrq, priority: P1) {
|
//! fn t1(_task: Tim6DacIrq, priority: P1) {
|
||||||
//! let ceiling = priority.as_ceiling();
|
//! let ceiling = priority.as_ceiling();
|
||||||
//!
|
//!
|
||||||
//! let counter = COUNTER.borrow(&priority, &ceiling);
|
//! let counter = COUNTER.access(&priority, &ceiling);
|
||||||
//!
|
//!
|
||||||
//! counter.set(counter.get() + 1);
|
//! counter.set(counter.get() + 1);
|
||||||
//! }
|
//! }
|
||||||
|
@ -202,7 +201,7 @@
|
||||||
//! fn t2(_task: Tim7Irq, priority: P1) {
|
//! fn t2(_task: Tim7Irq, priority: P1) {
|
||||||
//! let ceiling = priority.as_ceiling();
|
//! let ceiling = priority.as_ceiling();
|
||||||
//!
|
//!
|
||||||
//! let counter = COUNTER.borrow(&priority, &ceiling);
|
//! let counter = COUNTER.access(&priority, &ceiling);
|
||||||
//!
|
//!
|
||||||
//! counter.set(counter.get() + 2);
|
//! counter.set(counter.get() + 2);
|
||||||
//! }
|
//! }
|
||||||
|
@ -216,7 +215,7 @@
|
||||||
//! To share data between these two tasks, we use the
|
//! To share data between these two tasks, we use the
|
||||||
//! [`Resource`](./struct.Resource.html) abstraction. As the tasks can't preempt
|
//! [`Resource`](./struct.Resource.html) abstraction. As the tasks can't preempt
|
||||||
//! each other, they can access the `COUNTER` resource using the zero cost
|
//! each other, they can access the `COUNTER` resource using the zero cost
|
||||||
//! [`borrow`](./struct.Resource.html#method.borrow) method -- no
|
//! [`access`](./struct.Resource.html#method.access) method -- no
|
||||||
//! synchronization needed.
|
//! synchronization needed.
|
||||||
//!
|
//!
|
||||||
//! `COUNTER` has an extra type parameter: `C1`. This is the *ceiling* of the
|
//! `COUNTER` has an extra type parameter: `C1`. This is the *ceiling* of the
|
||||||
|
@ -243,8 +242,8 @@
|
||||||
//! // omitted: `idle`, `init`
|
//! // omitted: `idle`, `init`
|
||||||
//!
|
//!
|
||||||
//! tasks!(stm32f100xx, {
|
//! tasks!(stm32f100xx, {
|
||||||
//! t1: (Tim6DacIrq, P1),
|
//! t1: (Tim6DacIrq, P1, true),
|
||||||
//! t2: (Tim7Irq, P2),
|
//! t2: (Tim7Irq, P2, true),
|
||||||
//! });
|
//! });
|
||||||
//!
|
//!
|
||||||
//! static COUNTER: Resource<Cell<u32>, C2> = Resource::new(Cell::new(0));
|
//! static COUNTER: Resource<Cell<u32>, C2> = Resource::new(Cell::new(0));
|
||||||
|
@ -252,8 +251,12 @@
|
||||||
//! fn t1(_task: Tim6DacIrq, priority: P1) {
|
//! fn t1(_task: Tim6DacIrq, priority: P1) {
|
||||||
//! // ..
|
//! // ..
|
||||||
//!
|
//!
|
||||||
//! COUNTER.lock(&priority, |r1, _| {
|
//! let ceiling: &C1 = priority.as_ceiling();
|
||||||
//! r1.set(r1.get() + 1);
|
//!
|
||||||
|
//! ceiling.raise(&COUNTER, |ceiling: &C2| {
|
||||||
|
//! let counter = COUNTER.access(&priority, &ceiling);
|
||||||
|
//!
|
||||||
|
//! counter.set(counter.get() + 1);
|
||||||
//! });
|
//! });
|
||||||
//!
|
//!
|
||||||
//! // ..
|
//! // ..
|
||||||
|
@ -262,7 +265,7 @@
|
||||||
//! fn t2(_task: Tim7Irq, priority: P2) {
|
//! fn t2(_task: Tim7Irq, priority: P2) {
|
||||||
//! let ceiling = priority.as_ceiling();
|
//! let ceiling = priority.as_ceiling();
|
||||||
//!
|
//!
|
||||||
//! let counter = COUNTER.borrow(&priority, &ceiling);
|
//! let counter = COUNTER.access(&priority, &ceiling);
|
||||||
//!
|
//!
|
||||||
//! counter.set(counter.get() + 2);
|
//! counter.set(counter.get() + 2);
|
||||||
//! }
|
//! }
|
||||||
|
@ -275,20 +278,20 @@
|
||||||
//!
|
//!
|
||||||
//! To avoid data races, `t1` must modify `COUNTER` in an atomic way; i.e. `t2`
|
//! To avoid data races, `t1` must modify `COUNTER` in an atomic way; i.e. `t2`
|
||||||
//! most not preempt `t1` while `COUNTER` is being modified. This is
|
//! most not preempt `t1` while `COUNTER` is being modified. This is
|
||||||
//! accomplished using the [`lock`](./struct.Resource.html#method.lock) method.
|
//! accomplished by [`raise`](./struct.C.html#method.raise)-ing the `ceiling`.
|
||||||
//! This method creates a critical section, denoted by a closure, for whose span
|
//! This creates a critical section, denoted by a closure, for whose span
|
||||||
//! `COUNTER` is accessible but `t2` is blocked from preempting `t1`.
|
//! `COUNTER` is accessible but `t2` is blocked from preempting `t1`.
|
||||||
//!
|
//!
|
||||||
//! How `t2` accesses `COUNTER` remains unchanged. Since `t1` can't preempt `t2`
|
//! How `t2` accesses `COUNTER` remains unchanged. Since `t1` can't preempt `t2`
|
||||||
//! due to the differences in priority, no critical section is needed in `t2`.
|
//! due to the differences in priority; no critical section is needed in `t2`.
|
||||||
//!
|
//!
|
||||||
//! Note that the ceiling of `COUNTER` also changed to `C2`. This is required
|
//! Note that the ceiling of `COUNTER` had to change to `C2`. This is required
|
||||||
//! because the ceiling must be the maximum between `P1` and `P2`.
|
//! because the ceiling must be the maximum between `P1` and `P2`.
|
||||||
//!
|
//!
|
||||||
//! Finally, it should be noted that `COUNTER.lock` will only block tasks with a
|
//! Finally, it should be noted that the critical section in `t1` will only
|
||||||
//! priority of 2 or lower. This is exactly what the ceiling represents: it's
|
//! block tasks with a priority of 2 or lower. This is exactly what the ceiling
|
||||||
//! the "bar" that a task priority must pass in order to be able to preempt the
|
//! represents: it's the "bar" that a task priority must pass in order to be
|
||||||
//! current task / critical section.
|
//! able to preempt the current task / critical section.
|
||||||
//!
|
//!
|
||||||
//! # Peripherals as resources
|
//! # Peripherals as resources
|
||||||
//!
|
//!
|
||||||
|
@ -311,8 +314,8 @@
|
||||||
//! tasks!(stm32f100xx, {});
|
//! tasks!(stm32f100xx, {});
|
||||||
//!
|
//!
|
||||||
//! fn init(priority: P0, ceiling: &C16) {
|
//! fn init(priority: P0, ceiling: &C16) {
|
||||||
//! let gpioa = GPIOA.borrow(&priority, &ceiling);
|
//! let gpioa = GPIOA.access(&priority, &ceiling);
|
||||||
//! let rcc = RCC.borrow(&priority, &ceiling);
|
//! let rcc = RCC.access(&priority, &ceiling);
|
||||||
//!
|
//!
|
||||||
//! // ..
|
//! // ..
|
||||||
//! }
|
//! }
|
||||||
|
|
Loading…
Reference in a new issue