update examples

This commit is contained in:
Jorge Aparicio 2017-04-25 09:23:27 -05:00
parent 3713959b3d
commit 62356da0be

View file

@ -1,22 +1,23 @@
//! RTFM: Real Time For the Masses (ARM Cortex-M edition) //! RTFM: Real Time For the Masses (ARM Cortex-M edition)
//! //!
//! RTFM is a framework for building embedded event-driven / real-time //! RTFM is a framework for building event-driven applications for ARM Cortex-M
//! applications. //! microcontrollers.
//! //!
//! This crate is based on the RTFM framework created by [prof. Per //! This crate is based on the RTFM framework created by [prof. Per
//! Lindgren][per] and uses a simplified version of the Stack Resource Policy as //! Lindgren][per] and uses a simplified version of the Stack Resource Policy as
//! scheduling policy. (Check the [references] for details) //! scheduling policy. Check the [references] for details.
//! //!
//! [per]: https://www.ltu.se/staff/p/pln-1.11258?l=en //! [per]: https://www.ltu.se/staff/p/pln-1.11258?l=en
//! [references]: ./index.html#references //! [references]: ./index.html#references
//! //!
//! # Features //! # Features
//! //!
//! - Event triggered tasks as the unit of concurrency. //! - **Event triggered tasks** as the unit of concurrency.
//! - Supports prioritizing tasks and, thus, preemptive multitasking. //! - Supports prioritization of tasks and, thus, **preemptive multitasking**.
//! - Data sharing through fine grained, *partial* critical sections. //! - **Data race free memory sharing** through fine grained *partial* critical
//! - Deadlock free execution guaranteed at compile time. //! sections.
//! - Minimal overhead as the scheduler has no software component / runtime; the //! - **Deadlock free execution** guaranteed at compile time.
//! - **Minimal overhead** as the scheduler has no software component / runtime; the
//! hardware does all the scheduling. //! hardware does all the scheduling.
//! - Full support for all Cortex M3, M4 and M7 devices. M0(+) is also supported //! - Full support for all Cortex M3, M4 and M7 devices. M0(+) is also supported
//! but the whole API is not available (due to missing hardware features). //! but the whole API is not available (due to missing hardware features).
@ -26,11 +27,11 @@
//! crate defaults to 16 as that's the most common scenario. //! crate defaults to 16 as that's the most common scenario.
//! - This task model is amenable to known WCET (Worst Case Execution Time) //! - This task model is amenable to known WCET (Worst Case Execution Time)
//! analysis and scheduling analysis techniques. (Though we haven't yet //! analysis and scheduling analysis techniques. (Though we haven't yet
//! developed tooling for that.) //! developed Rust friendly tooling for that.)
//! //!
//! # Limitations //! # Limitations
//! //!
//! - Task priority must remain constant at runtime. //! - Task priorities must remain constant at runtime.
//! //!
//! # Dependencies //! # Dependencies
//! //!
@ -66,12 +67,12 @@
//! extern crate cortex_m_rtfm as rtfm; //! extern crate cortex_m_rtfm as rtfm;
//! //!
//! // device crate generated using svd2rust //! // device crate generated using svd2rust
//! extern crate stm32f100xx; //! extern crate stm32f30x;
//! //!
//! use rtfm::{C16, P0}; //! use rtfm::{C16, P0};
//! //!
//! // Declare tasks. None in this example //! // TASKS (None in this example)
//! tasks!(stm32f100xx, {}); //! tasks!(stm32f30x, {});
//! //!
//! // INITIALIZATION PHASE //! // INITIALIZATION PHASE
//! fn init(_priority: P0, _ceiling: &C16) { //! fn init(_priority: P0, _ceiling: &C16) {
@ -99,7 +100,7 @@
//! The `tasks!` macro overrides the `main` function and imposes the following //! The `tasks!` macro overrides the `main` function and imposes the following
//! structure into your program: //! structure into your program:
//! //!
//! - `init`, the initialization phase, is run first. This function is executed //! - `init`, the initialization phase, runs first. This function is executed
//! inside 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`.
@ -114,9 +115,9 @@
//! extern crate cortex_m_rt; //! extern crate cortex_m_rt;
//! #[macro_use] //! #[macro_use]
//! extern crate cortex_m_rtfm as rtfm; //! extern crate cortex_m_rtfm as rtfm;
//! extern crate stm32f100xx; //! extern crate stm32f30x;
//! //!
//! use stm32f100xx::interrupt::Tim7Irq; //! use stm32f30x::interrupt::Tim7;
//! use rtfm::{C16, Local, P0, P1}; //! use rtfm::{C16, Local, P0, P1};
//! //!
//! // INITIALIZATION PHASE //! // INITIALIZATION PHASE
@ -132,13 +133,13 @@
//! } //! }
//! //!
//! // TASKS //! // TASKS
//! tasks!(stm32f100xx, { //! tasks!(stm32f30x, {
//! periodic: (Tim7Irq, P1, true), //! periodic: (Tim7, P1, true),
//! }); //! });
//! //!
//! fn periodic(mut task: Tim7Irq, _priority: P1) { //! fn periodic(mut task: Tim7, _priority: P1) {
//! // Task local data //! // Task local data
//! static STATE: Local<bool, Tim7Irq> = Local::new(false); //! static STATE: Local<bool, Tim7> = Local::new(false);
//! //!
//! let state = STATE.borrow_mut(&mut task); //! let state = STATE.borrow_mut(&mut task);
//! //!
@ -154,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 `Tim7`
//! interrupt. The `periodic` task will run every time the `Tim7Irq` interrupt //! interrupt. The `periodic` task will run every time the `Tim7` interrupt
//! is triggered. 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.
//! //!
@ -163,7 +164,7 @@
//! task; this task local data will be preserved across runs of the `periodic` //! task; this task local data will be preserved across runs of the `periodic`
//! task. Note that `STATE` is owned by the `periodic` task, in the sense that //! task. Note that `STATE` is owned by the `periodic` task, in the sense that
//! no other task can access it; this is reflected in its type signature (the //! no other task can access it; this is reflected in its type signature (the
//! `Tim7Irq` type parameter). //! `Tim7` type parameter).
//! //!
//! # Two "serial" tasks //! # Two "serial" tasks
//! //!
@ -173,35 +174,35 @@
//! extern crate cortex_m_rt; //! extern crate cortex_m_rt;
//! #[macro_use] //! #[macro_use]
//! extern crate cortex_m_rtfm as rtfm; //! extern crate cortex_m_rtfm as rtfm;
//! extern crate stm32f100xx; //! extern crate stm32f30x;
//! //!
//! use core::cell::Cell; //! use core::cell::Cell;
//! //!
//! use stm32f100xx::interrupt::{Tim6DacIrq, Tim7Irq}; //! use stm32f30x::interrupt::{Tim6Dacunder, Tim7};
//! use rtfm::{C1, C16, P0, P1, Resource}; //! use rtfm::{C1, C16, P0, P1, Resource};
//! //!
//! // omitted: `idle`, `init` //! // omitted: `idle`, `init`
//! //!
//! tasks!(stm32f100xx, { //! tasks!(stm32f30x, {
//! t1: (Tim6DacIrq, P1, true), //! t1: (Tim6Dacunder, P1, true),
//! t2: (Tim7Irq, P1, true), //! t2: (Tim7, P1, true),
//! }); //! });
//! //!
//! // Data shared between tasks `t1` and `t2` //! // Data shared between tasks `t1` and `t2`
//! static COUNTER: Resource<Cell<u32>, C1> = Resource::new(Cell::new(0)); //! static COUNTER: Resource<Cell<u32>, C1> = Resource::new(Cell::new(0));
//! //!
//! fn t1(_task: Tim6DacIrq, priority: P1) { //! fn t1(_task: Tim6Dacunder, priority: P1) {
//! let ceiling = priority.as_ceiling(); //! let ceiling = priority.as_ceiling();
//! //!
//! let counter = COUNTER.access(&priority, &ceiling); //! let counter = COUNTER.access(&priority, ceiling);
//! //!
//! counter.set(counter.get() + 1); //! counter.set(counter.get() + 1);
//! } //! }
//! //!
//! fn t2(_task: Tim7Irq, priority: P1) { //! fn t2(_task: Tim7, priority: P1) {
//! let ceiling = priority.as_ceiling(); //! let ceiling = priority.as_ceiling();
//! //!
//! let counter = COUNTER.access(&priority, &ceiling); //! let counter = COUNTER.access(&priority, ceiling);
//! //!
//! counter.set(counter.get() + 2); //! counter.set(counter.get() + 2);
//! } //! }
@ -232,29 +233,29 @@
//! extern crate cortex_m_rt; //! extern crate cortex_m_rt;
//! #[macro_use] //! #[macro_use]
//! extern crate cortex_m_rtfm as rtfm; //! extern crate cortex_m_rtfm as rtfm;
//! extern crate stm32f100xx; //! extern crate stm32f30x;
//! //!
//! use core::cell::Cell; //! use core::cell::Cell;
//! //!
//! use stm32f100xx::interrupt::{Tim6DacIrq, Tim7Irq}; //! use stm32f30x::interrupt::{Tim6Dacunder, Tim7};
//! use rtfm::{C2, C16, P0, P1, P2, Resource}; //! use rtfm::{C2, C16, P0, P1, P2, Resource};
//! //!
//! // omitted: `idle`, `init` //! // omitted: `idle`, `init`
//! //!
//! tasks!(stm32f100xx, { //! tasks!(stm32f30x, {
//! t1: (Tim6DacIrq, P1, true), //! t1: (Tim6Dacunder, P1, true),
//! t2: (Tim7Irq, P2, true), //! t2: (Tim7, P2, true),
//! }); //! });
//! //!
//! static COUNTER: Resource<Cell<u32>, C2> = Resource::new(Cell::new(0)); //! static COUNTER: Resource<Cell<u32>, C2> = Resource::new(Cell::new(0));
//! //!
//! fn t1(_task: Tim6DacIrq, priority: P1) { //! fn t1(_task: Tim6Dacunder, priority: P1) {
//! // .. //! // ..
//! //!
//! let ceiling: &C1 = priority.as_ceiling(); //! let ceiling: &C1 = priority.as_ceiling();
//! //!
//! ceiling.raise(&COUNTER, |ceiling: &C2| { //! ceiling.raise(&COUNTER, |ceiling: &C2| {
//! let counter = COUNTER.access(&priority, &ceiling); //! let counter = COUNTER.access(&priority, ceiling);
//! //!
//! counter.set(counter.get() + 1); //! counter.set(counter.get() + 1);
//! }); //! });
@ -262,10 +263,10 @@
//! // .. //! // ..
//! } //! }
//! //!
//! fn t2(_task: Tim7Irq, priority: P2) { //! fn t2(_task: Tim7, priority: P2) {
//! let ceiling = priority.as_ceiling(); //! let ceiling = priority.as_ceiling();
//! //!
//! let counter = COUNTER.access(&priority, &ceiling); //! let counter = COUNTER.access(&priority, ceiling);
//! //!
//! counter.set(counter.get() + 2); //! counter.set(counter.get() + 2);
//! } //! }
@ -273,7 +274,7 @@
//! //!
//! Now we have a variation of the previous example. Like before, `t1` has a //! Now we have a variation of the previous example. Like before, `t1` has a
//! priority of 1 (`P1`) but `t2` now has a priority of 2 (`P2`). This means //! priority of 1 (`P1`) but `t2` now has a priority of 2 (`P2`). This means
//! that `t2` can preempt `t1` if a `Tim7Irq` interrupt occurs while `t1` is //! that `t2` can preempt `t1` if a `Tim7` interrupt occurs while `t1` is
//! being executed. //! being executed.
//! //!
//! 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`