diff options
Diffstat (limited to '')
-rw-r--r-- | examples/lockopt.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/examples/lockopt.rs b/examples/lockopt.rs new file mode 100644 index 00000000..d01186ad --- /dev/null +++ b/examples/lockopt.rs @@ -0,0 +1,67 @@ +//! examples/optlock.rs + +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +use cortex_m_semihosting::debug; +use lm3s6965::Interrupt; +use panic_semihosting as _; +use rtfm::Exclusive; + +#[rtfm::app(device = lm3s6965)] +const APP: () = { + struct Resources { + #[init(0)] + shared: u32, + } + + #[init] + fn init(_: init::Context) { + rtfm::pend(Interrupt::GPIOA); + } + + // when omitted priority is assumed to be `1` + #[task(binds = GPIOA, resources = [shared])] + fn gpioa(mut c: gpioa::Context) { + // the lower priority task requires a critical section to access the data + c.resources.shared.lock(|shared| { + // data can only be modified within this critical section (closure) + *shared += 1; + + // GPIOB will *not* run right now due to the critical section + rtfm::pend(Interrupt::GPIOB); + + // hprintln!("B - shared = {}", *shared).unwrap(); + + // GPIOC does not contend for `shared` so it's allowed to run now + rtfm::pend(Interrupt::GPIOC); + }); + + // critical section is over: GPIOB can now start + + debug::exit(debug::EXIT_SUCCESS); + } + + #[task(binds = GPIOB, priority = 2, resources = [shared])] + fn gpiob(mut c: gpiob::Context) { + // higher priority task, with critical section + c.resources.shared.lock(|shared| { + *shared += 1; + }); + } + + #[task(binds = GPIOC, priority = 3, resources = [shared])] + fn gpioc(c: gpioc::Context) { + // highest priority task with critical section + // we wrap resource.shared into an Exclusive + let mut exclusive = Exclusive(c.resources.shared); + // we can access through both lock ... + exclusive.lock(|shared| { + *shared += 1; + }); + // and deref, i.e., non-orthogonal design + *exclusive += 1; + } +}; |