diff options
| author | Jorge Aparicio <jorge@japaric.io> | 2018-11-03 17:02:41 +0100 |
|---|---|---|
| committer | Jorge Aparicio <jorge@japaric.io> | 2018-11-03 17:16:55 +0100 |
| commit | c631049efcadca8b07940c794cce2be58fa48444 (patch) | |
| tree | f6bd73e5c396fc06072557ee965cc59e9c8e3e9f /src/examples | |
| parent | 653338e7997a0cdc5deaed98b1bb5f60006717ed (diff) | |
v0.4.0
closes #32
closes #33
Diffstat (limited to 'src/examples')
| -rw-r--r-- | src/examples/_0_zero_tasks.rs | 47 | ||||
| -rw-r--r-- | src/examples/_1_one_task.rs | 100 | ||||
| -rw-r--r-- | src/examples/_2_two_tasks.rs | 62 | ||||
| -rw-r--r-- | src/examples/_3_preemption.rs | 71 | ||||
| -rw-r--r-- | src/examples/_4_nested.rs | 132 | ||||
| -rw-r--r-- | src/examples/_5_late_resources.rs | 90 | ||||
| -rw-r--r-- | src/examples/_6_safe_static_mut_ref.rs | 35 | ||||
| -rw-r--r-- | src/examples/_7_generics.rs | 77 | ||||
| -rw-r--r-- | src/examples/_8_full_syntax.rs | 87 | ||||
| -rw-r--r-- | src/examples/mod.rs | 11 |
10 files changed, 0 insertions, 712 deletions
diff --git a/src/examples/_0_zero_tasks.rs b/src/examples/_0_zero_tasks.rs deleted file mode 100644 index 0484bb9..0000000 --- a/src/examples/_0_zero_tasks.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! Minimal example with zero tasks -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; // IMPORTANT always do this rename -//! extern crate stm32f103xx; // the device crate -//! -//! // import the procedural macro -//! use rtfm::app; -//! -//! // This macro call indicates that this is a RTFM application -//! // -//! // This macro will expand to a `main` function so you don't need to supply -//! // `main` yourself. -//! app! { -//! // this is the path to the device crate -//! device: stm32f103xx, -//! } -//! -//! // The initialization phase. -//! // -//! // This runs first and within a *global* critical section. Nothing can preempt -//! // this function. -//! fn init(p: init::Peripherals) { -//! // This function has access to all the peripherals of the device -//! p.core.SYST; -//! p.device.GPIOA; -//! p.device.RCC; -//! // .. -//! } -//! -//! // The idle loop. -//! // -//! // 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() -> ! { -//! loop { -//! // This puts the processor to sleep until there's a task to service -//! rtfm::wfi(); -//! } -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_1_one_task.rs b/src/examples/_1_one_task.rs deleted file mode 100644 index b9075a5..0000000 --- a/src/examples/_1_one_task.rs +++ /dev/null @@ -1,100 +0,0 @@ -//! An application with one task -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![no_std] -//! -//! extern crate cortex_m; -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! use cortex_m::peripheral::syst::SystClkSource; -//! use rtfm::{app, Threshold}; -//! use stm32f103xx::GPIOC; -//! -//! 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 -//! // interrupt or exception becomes *pending* the corresponding task handler -//! // will be executed. -//! 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, -//! -//! // These are the resources this task has access to. -//! // -//! // The resources listed here must also appear in `app.resources` -//! resources: [ON], -//! }, -//! } -//! } -//! -//! fn init(mut p: init::Peripherals, r: init::Resources) { -//! // `init` can modify all the `resources` declared in `app!` -//! r.ON; -//! -//! // power on GPIOC -//! p.device.RCC.apb2enr.modify(|_, w| w.iopcen().enabled()); -//! -//! // configure PC13 as output -//! p.device.GPIOC.bsrr.write(|w| w.bs13().set()); -//! p.device -//! .GPIOC -//! .crh -//! .modify(|_, w| w.mode13().output().cnf13().push()); -//! -//! // configure the system timer to generate one interrupt every second -//! p.core.SYST.set_clock_source(SystClkSource::Core); -//! p.core.SYST.set_reload(8_000_000); // 1s -//! p.core.SYST.enable_interrupt(); -//! p.core.SYST.enable_counter(); -//! } -//! -//! fn idle() -> ! { -//! loop { -//! rtfm::wfi(); -//! } -//! } -//! -//! // This is the task handler of the SYS_TICK exception -//! // -//! // `_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. `SYS_TICK::Resources` -//! // has one field per resource declared in `app!`. -//! #[allow(unsafe_code)] -//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) { -//! // toggle state -//! *r.ON = !*r.ON; -//! -//! if *r.ON { -//! // set the pin PC13 high -//! // NOTE(unsafe) atomic write to a stateless register -//! unsafe { -//! (*GPIOC::ptr()).bsrr.write(|w| w.bs13().set()); -//! } -//! } else { -//! // set the pin PC13 low -//! // NOTE(unsafe) atomic write to a stateless register -//! unsafe { -//! (*GPIOC::ptr()).bsrr.write(|w| w.br13().reset()); -//! } -//! } -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_2_two_tasks.rs b/src/examples/_2_two_tasks.rs deleted file mode 100644 index 516ff0c..0000000 --- a/src/examples/_2_two_tasks.rs +++ /dev/null @@ -1,62 +0,0 @@ -//! Two tasks running at the *same* priority with access to the same resource -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! use rtfm::{app, Threshold}; -//! -//! app! { -//! device: stm32f103xx, -//! -//! resources: { -//! static COUNTER: u64 = 0; -//! }, -//! -//! // Both SYS_TICK and TIM2 have access to the `COUNTER` data -//! tasks: { -//! SYS_TICK: { -//! path: sys_tick, -//! resources: [COUNTER], -//! }, -//! -//! TIM2: { -//! path: tim2, -//! resources: [COUNTER], -//! }, -//! }, -//! } -//! -//! fn init(_p: init::Peripherals, _r: init::Resources) { -//! // .. -//! } -//! -//! fn idle() -> ! { -//! loop { -//! rtfm::wfi(); -//! } -//! } -//! -//! // 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, mut r: SYS_TICK::Resources) { -//! // .. -//! -//! *r.COUNTER += 1; -//! -//! // .. -//! } -//! -//! fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) { -//! // .. -//! -//! *r.COUNTER += 1; -//! -//! // .. -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_3_preemption.rs b/src/examples/_3_preemption.rs deleted file mode 100644 index 14c9d92..0000000 --- a/src/examples/_3_preemption.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Two tasks running at *different* priorities with access to the same resource -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! use rtfm::{app, Resource, Threshold}; -//! -//! app! { -//! device: stm32f103xx, -//! -//! resources: { -//! static COUNTER: u64 = 0; -//! }, -//! -//! tasks: { -//! // The `SYS_TICK` task has higher priority than `TIM2` -//! SYS_TICK: { -//! path: sys_tick, -//! priority: 2, -//! resources: [COUNTER], -//! }, -//! -//! TIM2: { -//! path: tim2, -//! priority: 1, -//! resources: [COUNTER], -//! }, -//! }, -//! } -//! -//! fn init(_p: init::Peripherals, _r: init::Resources) { -//! // .. -//! } -//! -//! fn idle() -> ! { -//! loop { -//! rtfm::wfi(); -//! } -//! } -//! -//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) { -//! // .. -//! -//! // This task can't be preempted by `tim2` so it has direct access to the -//! // resource data -//! *r.COUNTER += 1; -//! -//! // .. -//! } -//! -//! fn tim2(t: &mut Threshold, mut r: TIM2::Resources) { -//! // .. -//! -//! // 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 undefined behavior. -//! r.COUNTER.claim_mut(t, |counter, _t| { -//! // `claim_mut` creates a critical section -//! *counter += 1; -//! }); -//! -//! // .. -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_4_nested.rs b/src/examples/_4_nested.rs deleted file mode 100644 index 26f8fd8..0000000 --- a/src/examples/_4_nested.rs +++ /dev/null @@ -1,132 +0,0 @@ -//! Nesting claims and how the preemption threshold works -//! -//! 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)] -//! #![deny(warnings)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! use rtfm::{app, Resource, Threshold}; -//! use stm32f103xx::Interrupt; -//! -//! app! { -//! device: stm32f103xx, -//! -//! resources: { -//! static LOW: u64 = 0; -//! static HIGH: u64 = 0; -//! }, -//! -//! tasks: { -//! EXTI0: { -//! path: exti0, -//! priority: 1, -//! resources: [LOW, HIGH], -//! }, -//! -//! EXTI1: { -//! path: exti1, -//! priority: 2, -//! resources: [LOW], -//! }, -//! -//! EXTI2: { -//! path: exti2, -//! priority: 3, -//! resources: [HIGH], -//! }, -//! }, -//! } -//! -//! fn init(_p: init::Peripherals, _r: init::Resources) {} -//! -//! fn idle() -> ! { -//! // A -//! rtfm::bkpt(); -//! -//! // Sets task `exti0` as pending -//! // -//! // Because `exti0` has higher priority than `idle` it will be executed -//! // immediately -//! rtfm::set_pending(Interrupt::EXTI0); // ~> exti0 -//! -//! loop { -//! rtfm::wfi(); -//! } -//! } -//! -//! #[allow(non_snake_case)] -//! fn exti0( -//! t: &mut Threshold, -//! EXTI0::Resources { -//! LOW: mut low, -//! HIGH: mut high, -//! }: EXTI0::Resources, -//! ) { -//! // Because this task has a priority of 1 the preemption threshold `t` also -//! // starts at 1 -//! -//! // B -//! rtfm::bkpt(); -//! -//! // Because `exti1` has higher priority than `exti0` it can preempt it -//! rtfm::set_pending(Interrupt::EXTI1); // ~> exti1 -//! -//! // A claim creates a critical section -//! low.claim_mut(t, |_low, t| { -//! // 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 -//! -//! // D -//! rtfm::bkpt(); -//! -//! // 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 -//! // preemption threshold -//! rtfm::set_pending(Interrupt::EXTI2); // ~> exti2 -//! -//! // F -//! rtfm::bkpt(); -//! -//! // Claims can be nested -//! high.claim_mut(t, |_high, _| { -//! // This claim increases the preemption threshold to 3 -//! -//! // Now `exti2` can't preempt this task -//! rtfm::set_pending(Interrupt::EXTI2); -//! -//! // G -//! rtfm::bkpt(); -//! }); -//! -//! // 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 but this time to 1. Now the -//! // pending `exti1` task can preempt this task -//! // ~> exti1 -//! } -//! -//! fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) { -//! // C, I -//! rtfm::bkpt(); -//! } -//! -//! fn exti2(_t: &mut Threshold, _r: EXTI2::Resources) { -//! // E, H -//! rtfm::bkpt(); -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_5_late_resources.rs b/src/examples/_5_late_resources.rs deleted file mode 100644 index 7ab90a4..0000000 --- a/src/examples/_5_late_resources.rs +++ /dev/null @@ -1,90 +0,0 @@ -//! Demonstrates initialization of resources in `init`. -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! use rtfm::{app, Threshold}; -//! -//! app! { -//! device: stm32f103xx, -//! -//! resources: { -//! // Usually, resources are initialized with a constant initializer: -//! static ON: bool = false; -//! -//! // However, there are cases where this is not possible or not desired. -//! // For example, there may not be a sensible value to use, or the type may -//! // not be constructible in a constant (like `Vec`). -//! // -//! // While it is possible to use an `Option` in some cases, that requires -//! // you to properly initialize it and `.unwrap()` it at every use. It -//! // also consumes more memory. -//! // -//! // To solve this, it is possible to defer initialization of resources to -//! // `init` by omitting the initializer. Doing that will require `init` to -//! // return the values of all "late" resources. -//! static IP_ADDRESS: u32; -//! -//! // PORT is used by 2 tasks, making it a shared resource. This just tests -//! // another internal code path and is not important for the example. -//! static PORT: u16; -//! }, -//! -//! idle: { -//! // Test that late resources can be used in idle -//! resources: [IP_ADDRESS], -//! }, -//! -//! tasks: { -//! SYS_TICK: { -//! priority: 1, -//! path: sys_tick, -//! resources: [IP_ADDRESS, PORT, ON], -//! }, -//! -//! EXTI0: { -//! priority: 2, -//! path: exti0, -//! resources: [PORT], -//! } -//! } -//! } -//! -//! // The signature of `init` is now required to have a specific return type. -//! fn init(_p: init::Peripherals, _r: init::Resources) -> init::LateResources { -//! // `init::Resources` does not contain `IP_ADDRESS`, since it is not yet -//! // initialized. -//! //_r.IP_ADDRESS; // doesn't compile -//! -//! // ...obtain value for IP_ADDRESS from EEPROM/DHCP... -//! let ip_address = 0x7f000001; -//! -//! init::LateResources { -//! // This struct will contain fields for all resources with omitted -//! // initializers. -//! IP_ADDRESS: ip_address, -//! PORT: 0, -//! } -//! } -//! -//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) { -//! // Other tasks can access late resources like any other, since they are -//! // guaranteed to be initialized when tasks are run. -//! -//! r.IP_ADDRESS; -//! } -//! -//! fn exti0(_t: &mut Threshold, _r: EXTI0::Resources) {} -//! -//! fn idle(_t: &mut Threshold, _r: idle::Resources) -> ! { -//! loop { -//! rtfm::wfi(); -//! } -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_6_safe_static_mut_ref.rs b/src/examples/_6_safe_static_mut_ref.rs deleted file mode 100644 index 8f7267f..0000000 --- a/src/examples/_6_safe_static_mut_ref.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Safe creation of `&'static mut` references -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! use rtfm::app; -//! -//! app! { -//! device: stm32f103xx, -//! -//! resources: { -//! static BUFFER: [u8; 16] = [0; 16]; -//! }, -//! -//! init: { -//! resources: [BUFFER], -//! }, -//! } -//! -//! fn init(_p: init::Peripherals, r: init::Resources) { -//! let _buf: &'static mut [u8; 16] = r.BUFFER; -//! } -//! -//! fn idle() -> ! { -//! loop { -//! rtfm::wfi(); -//! } -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_7_generics.rs b/src/examples/_7_generics.rs deleted file mode 100644 index 5dafdbf..0000000 --- a/src/examples/_7_generics.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! Working with resources in a generic fashion -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! use rtfm::{app, Resource, Threshold}; -//! use stm32f103xx::{GPIOA, SPI1}; -//! -//! app! { -//! device: stm32f103xx, -//! -//! resources: { -//! static GPIOA: GPIOA; -//! static SPI1: SPI1; -//! }, -//! -//! tasks: { -//! EXTI0: { -//! path: exti0, -//! priority: 1, -//! resources: [GPIOA, SPI1], -//! }, -//! -//! EXTI1: { -//! path: exti1, -//! priority: 2, -//! resources: [GPIOA, SPI1], -//! }, -//! }, -//! } -//! -//! fn init(p: init::Peripherals) -> init::LateResources { -//! init::LateResources { -//! GPIOA: p.device.GPIOA, -//! SPI1: p.device.SPI1, -//! } -//! } -//! -//! fn idle() -> ! { -//! loop { -//! rtfm::wfi(); -//! } -//! } -//! -//! // A generic function that uses some resources -//! fn work<G, S>(t: &mut Threshold, gpioa: &G, spi1: &S) -//! where -//! G: Resource<Data = GPIOA>, -//! S: Resource<Data = SPI1>, -//! { -//! gpioa.claim(t, |_gpioa, t| { -//! // drive NSS low -//! -//! spi1.claim(t, |_spi1, _| { -//! // transfer data -//! }); -//! -//! // drive NSS high -//! }); -//! } -//! -//! // 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 -//! fn exti1(t: &mut Threshold, r: EXTI1::Resources) { -//! work(t, &r.GPIOA, &r.SPI1); -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_8_full_syntax.rs b/src/examples/_8_full_syntax.rs deleted file mode 100644 index cc7fbc2..0000000 --- a/src/examples/_8_full_syntax.rs +++ /dev/null @@ -1,87 +0,0 @@ -//! A showcase of the `app!` macro syntax -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! 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: { -//! // 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: { -//! // 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, -//! // 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 -//! // can start disabled if `false` is specified here -//! enabled: false, -//! path: tim2, -//! priority: 1, -//! 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); -//! } -//! } -//! } -//! } -//! -//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) { -//! *r.ON = !*r.ON; -//! -//! *r.CO_OWNED += 1; -//! } -//! -//! fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) { -//! *r.CO_OWNED += 1; -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/mod.rs b/src/examples/mod.rs deleted file mode 100644 index 64d1e2e..0000000 --- a/src/examples/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Examples -// Auto-generated. Do not modify. -pub mod _0_zero_tasks; -pub mod _1_one_task; -pub mod _2_two_tasks; -pub mod _3_preemption; -pub mod _4_nested; -pub mod _5_late_resources; -pub mod _6_safe_static_mut_ref; -pub mod _7_generics; -pub mod _8_full_syntax; |
