From 9f80c9b916e93187e755750e8aff4b9c363ef507 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Mon, 15 Jun 2020 23:31:30 +0200 Subject: [PATCH] now with the very exclusive feature link_fail --- Cargo.toml | 6 ++- examples/lock5_mutex.rs | 85 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 examples/lock5_mutex.rs diff --git a/Cargo.toml b/Cargo.toml index 97d8d8700d..58b54feaf2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,11 +57,11 @@ version = '0.5.3' [lib] name = 'rtic' -# path = "../rtic-core" - +# path = '../rtic-core' [patch.crates-io.rtic-core] git = 'https://github.com/rtic-rs/rtic-core.git' branch = 'immutable_resource_proxies' + [dependencies] cortex-m = '0.6.2' @@ -99,6 +99,8 @@ heterogeneous = [ homogeneous = ['cortex-m-rtic-macros/homogeneous'] __v7 = [] __min_r1_43 = [] +link_fail = ['rtic-core/link_fail'] + [profile.release] codegen-units = 1 lto = true diff --git a/examples/lock5_mutex.rs b/examples/lock5_mutex.rs new file mode 100644 index 0000000000..f43f2ec6c9 --- /dev/null +++ b/examples/lock5_mutex.rs @@ -0,0 +1,85 @@ +//! examples/lock.rs + +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +use cortex_m_semihosting::{debug, hprintln}; +use lm3s6965::Interrupt; +use panic_semihosting as _; +use rtic::Mutex; +use rtic_core::Exclusive; + +#[rtic::app(device = lm3s6965)] +const APP: () = { + struct Resources { + #[init(0)] + shared: u32, + } + + #[init] + fn init(_: init::Context) { + rtic::pend(Interrupt::GPIOA); + } + + // when omitted priority is assumed to be `1` + #[task(binds = GPIOA, resources = [shared])] + fn gpioa(c: gpioa::Context) { + hprintln!("A").unwrap(); + + // 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 + rtic::pend(Interrupt::GPIOB); + + hprintln!("B - shared = {}", *shared).unwrap(); + + // GPIOC does not contend for `shared` so it's allowed to run now + rtic::pend(Interrupt::GPIOC); + }); + + // critical section is over: GPIOB can now start + + hprintln!("E").unwrap(); + + debug::exit(debug::EXIT_SUCCESS); + } + + #[task(binds = GPIOB, priority = 2, resources = [shared])] + fn gpiob(c: gpiob::Context) { + static mut STATE: u32 = 28; + c.resources.shared.lock(|shared| { + *shared += 1; + hprintln!("D - shared = {}", shared).unwrap(); + }); + advance(STATE, c.resources.shared); + } + + #[task(binds = GPIOC, priority = 3, resources = [shared])] + fn gpioc(c: gpioc::Context) { + static mut STATE: u32 = 0; + hprintln!("GPIOC(STATE = {})", *STATE).unwrap(); + *c.resources.shared += 2; + let ex_shared = Exclusive::new(c.resources.shared); + advance(STATE, ex_shared); // try swap order of (1) + *c.resources.shared += 3; // and (2), will fail + hprintln!("GPIOC(STATE = {})", *STATE).unwrap(); + } +}; + +// the second parameter is generic: it can be any type that implements the `Mutex` trait +fn advance(state: &mut u32, shared: impl Mutex) { + *state += 1; + + let (old, new) = shared.lock(|shared: &mut u32| { + let old = *shared; + *shared += *state; + (old, *shared) + }); + + hprintln!("shared: {} -> {}", old, new).unwrap(); +}