diff --git a/examples/lock2.rs b/examples/lock2.rs index ab41cf8a74..809d4dcc66 100644 --- a/examples/lock2.rs +++ b/examples/lock2.rs @@ -7,6 +7,7 @@ use cortex_m_semihosting::debug; use lm3s6965::Interrupt; +use panic_semihosting as _; #[rtic::app(device = lm3s6965)] const APP: () = { diff --git a/examples/lock3.rs b/examples/lock3.rs new file mode 100644 index 0000000000..ed37cfcd44 --- /dev/null +++ b/examples/lock3.rs @@ -0,0 +1,62 @@ +//! 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 _; + +#[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) { + // the higher priority task does *not* need a critical section + *c.resources.shared += 1; + + hprintln!("D - shared = {}", *c.resources.shared).unwrap(); + } + + #[task(binds = GPIOC, priority = 3)] + fn gpioc(_: gpioc::Context) { + hprintln!("C").unwrap(); + } +}; diff --git a/expand_lock.rs b/expand_lock.rs index 2490cbe79b..fe8c16eb18 100644 --- a/expand_lock.rs +++ b/expand_lock.rs @@ -1,5 +1,5 @@ #![feature(prelude_import)] -//! examples/lock2.rs +//! examples/lock.rs #![deny(unsafe_code)] #![deny(warnings)] #![no_main] @@ -10,8 +10,9 @@ use core::prelude::v1::*; extern crate core; #[macro_use] extern crate compiler_builtins; -use cortex_m_semihosting::debug; +use cortex_m_semihosting::{debug, hprintln}; use lm3s6965::Interrupt; +use panic_semihosting as _; #[allow(non_snake_case)] fn init(_: init::Context) { rtic::pend(Interrupt::GPIOA); @@ -19,16 +20,44 @@ fn init(_: init::Context) { #[allow(non_snake_case)] fn gpioa(mut c: gpioa::Context) { use rtic::Mutex as _; + ::cortex_m_semihosting::export::hstdout_str("A\n").unwrap(); c.resources.shared.lock(|shared| { *shared += 1; rtic::pend(Interrupt::GPIOB); + ::cortex_m_semihosting::export::hstdout_fmt(::core::fmt::Arguments::new_v1( + &["B - shared = ", "\n"], + &match (&*shared,) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + )) + .unwrap(); + rtic::pend(Interrupt::GPIOC); }); + ::cortex_m_semihosting::export::hstdout_str("E\n").unwrap(); debug::exit(debug::EXIT_SUCCESS); } #[allow(non_snake_case)] fn gpiob(c: gpiob::Context) { use rtic::Mutex as _; *c.resources.shared += 1; + ::cortex_m_semihosting::export::hstdout_fmt(::core::fmt::Arguments::new_v1( + &["D - shared = ", "\n"], + &match (&*c.resources.shared,) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + )) + .unwrap(); +} +#[allow(non_snake_case)] +fn gpioc(_: gpioc::Context) { + use rtic::Mutex as _; + ::cortex_m_semihosting::export::hstdout_str("C\n").unwrap(); } #[allow(non_snake_case)] ///Initialization function @@ -47,19 +76,31 @@ pub mod init { } mod resources { use rtic::export::Priority; + use core::cell::Cell; #[allow(non_camel_case_types)] pub struct shared<'a> { priority: &'a Priority, + locked: Cell, } impl<'a> shared<'a> { #[inline(always)] pub unsafe fn new(priority: &'a Priority) -> Self { - shared { priority } + shared { + priority, + locked: Cell::new(false), + } } #[inline(always)] pub unsafe fn priority(&self) -> &Priority { self.priority } + #[inline(always)] + pub unsafe fn get_locked(&self) -> bool { + self.locked.get() + } + pub unsafe fn set_locked(&self, b: bool) { + self.locked.set(b); + } } } #[allow(non_snake_case)] @@ -110,5 +151,17 @@ pub mod gpiob { } } } +#[allow(non_snake_case)] +///Hardware task +pub mod gpioc { + /// Execution context + pub struct Context {} + impl Context { + #[inline(always)] + pub unsafe fn new(priority: &rtic::export::Priority) -> Self { + Context {} + } + } +} /// Implementation details -const APP: () = { # [ doc = r" Always include the device crate which contains the vector table" ] use lm3s6965 as _ ; # [ allow ( non_upper_case_globals ) ] static mut shared : u32 = 0 ; impl < 'a > rtic :: Mutex for resources :: shared < 'a > { type T = u32 ; # [ inline ( always ) ] fn lock < R > ( & mut self , f : impl FnOnce ( & mut u32 ) -> R ) -> R { # [ doc = r" Priority ceiling" ] const CEILING : u8 = 2u8 ; unsafe { rtic :: export :: lock ( & mut shared , self . priority ( ) , CEILING , lm3s6965 :: NVIC_PRIO_BITS , f ) } } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOA ( ) { const PRIORITY : u8 = 1u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpioa ( gpioa :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } impl < 'a > gpioaResources < 'a > { # [ inline ( always ) ] unsafe fn new ( priority : & 'a rtic :: export :: Priority ) -> Self { gpioaResources { shared : resources :: shared :: new ( priority ) , } } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOB ( ) { const PRIORITY : u8 = 2u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpiob ( gpiob :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } impl < 'a > gpiobResources < 'a > { # [ inline ( always ) ] unsafe fn new ( priority : & 'a rtic :: export :: Priority ) -> Self { gpiobResources { shared : & mut shared , } } } # [ no_mangle ] unsafe extern "C" fn main ( ) -> ! { let _TODO : ( ) = ( ) ; rtic :: export :: interrupt :: disable ( ) ; let mut core : rtic :: export :: Peripherals = core :: mem :: transmute ( ( ) ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 1u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOA , rtic :: export :: logical2hw ( 1u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOA ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 2u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOB , rtic :: export :: logical2hw ( 2u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOB ) ; core . SCB . scr . modify ( | r | r | 1 << 1 ) ; let late = crate :: init ( init :: Context :: new ( core . into ( ) ) ) ; rtic :: export :: interrupt :: enable ( ) ; loop { rtic :: export :: wfi ( ) } } }; +const APP: () = { # [ doc = r" Always include the device crate which contains the vector table" ] use lm3s6965 as _ ; # [ allow ( non_upper_case_globals ) ] static mut shared : u32 = 0 ; impl < 'a > rtic :: Mutex for resources :: shared < 'a > { type T = u32 ; # [ inline ( always ) ] fn lock < R > ( & mut self , f : impl FnOnce ( & mut u32 ) -> R ) -> R { # [ doc = r" Priority ceiling" ] const CEILING : u8 = 2u8 ; if self . get_locked ( ) { :: core :: panicking :: panic ( "Resource locked in sequential context" ) ; } ; self . set_locked ( true ) ; let r = unsafe { rtic :: export :: lock ( & mut shared , self . priority ( ) , CEILING , lm3s6965 :: NVIC_PRIO_BITS , f ) } ; self . set_locked ( false ) ; r } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOA ( ) { const PRIORITY : u8 = 1u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpioa ( gpioa :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } impl < 'a > gpioaResources < 'a > { # [ inline ( always ) ] unsafe fn new ( priority : & 'a rtic :: export :: Priority ) -> Self { gpioaResources { shared : resources :: shared :: new ( priority ) , } } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOB ( ) { const PRIORITY : u8 = 2u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpiob ( gpiob :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } impl < 'a > gpiobResources < 'a > { # [ inline ( always ) ] unsafe fn new ( priority : & 'a rtic :: export :: Priority ) -> Self { gpiobResources { shared : & mut shared , } } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOC ( ) { const PRIORITY : u8 = 3u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpioc ( gpioc :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } # [ no_mangle ] unsafe extern "C" fn main ( ) -> ! { let _TODO : ( ) = ( ) ; rtic :: export :: interrupt :: disable ( ) ; let mut core : rtic :: export :: Peripherals = core :: mem :: transmute ( ( ) ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 1u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOA , rtic :: export :: logical2hw ( 1u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOA ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 2u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOB , rtic :: export :: logical2hw ( 2u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOB ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 3u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOC , rtic :: export :: logical2hw ( 3u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOC ) ; core . SCB . scr . modify ( | r | r | 1 << 1 ) ; let late = crate :: init ( init :: Context :: new ( core . into ( ) ) ) ; rtic :: export :: interrupt :: enable ( ) ; loop { rtic :: export :: wfi ( ) } } }; diff --git a/expand_lock2.rs b/expand_lock2.rs index 43052a2312..3189f9704a 100644 --- a/expand_lock2.rs +++ b/expand_lock2.rs @@ -1,5 +1,5 @@ #![feature(prelude_import)] -//! examples/lock2.rs +//! examples/lock.rs #![deny(unsafe_code)] #![deny(warnings)] #![no_main] @@ -10,8 +10,9 @@ use core::prelude::v1::*; extern crate core; #[macro_use] extern crate compiler_builtins; -use cortex_m_semihosting::debug; +use cortex_m_semihosting::{debug, hprintln}; use lm3s6965::Interrupt; +use panic_semihosting as _; #[allow(non_snake_case)] fn init(_: init::Context) { rtic::pend(Interrupt::GPIOA); @@ -19,16 +20,44 @@ fn init(_: init::Context) { #[allow(non_snake_case)] fn gpioa(mut c: gpioa::Context) { use rtic::Mutex as _; + ::cortex_m_semihosting::export::hstdout_str("A\n").unwrap(); c.resources.shared.lock(|shared| { *shared += 1; rtic::pend(Interrupt::GPIOB); + ::cortex_m_semihosting::export::hstdout_fmt(::core::fmt::Arguments::new_v1( + &["B - shared = ", "\n"], + &match (&*shared,) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + )) + .unwrap(); + rtic::pend(Interrupt::GPIOC); }); + ::cortex_m_semihosting::export::hstdout_str("E\n").unwrap(); debug::exit(debug::EXIT_SUCCESS); } #[allow(non_snake_case)] fn gpiob(c: gpiob::Context) { use rtic::Mutex as _; *c.resources.shared += 1; + ::cortex_m_semihosting::export::hstdout_fmt(::core::fmt::Arguments::new_v1( + &["D - shared = ", "\n"], + &match (&*c.resources.shared,) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + )) + .unwrap(); +} +#[allow(non_snake_case)] +fn gpioc(_: gpioc::Context) { + use rtic::Mutex as _; + ::cortex_m_semihosting::export::hstdout_str("C\n").unwrap(); } #[allow(non_snake_case)] ///Initialization function @@ -46,8 +75,8 @@ pub mod init { } } mod resources { - use rtic::export::Priority; use core::cell::Cell; + use rtic::export::Priority; #[allow(non_camel_case_types)] pub struct shared<'a> { priority: &'a Priority, @@ -73,37 +102,11 @@ mod resources { self.locked.set(true); } } - #[allow(non_camel_case_types)] - pub struct shared2<'a> { - priority: &'a Priority, - locked: Cell, - } - impl<'a> shared2<'a> { - #[inline(always)] - pub unsafe fn new(priority: &'a Priority) -> Self { - shared2 { - priority, - locked: Cell::new(false), - } - } - #[inline(always)] - pub unsafe fn priority(&self) -> &Priority { - self.priority - } - #[inline(always)] - pub unsafe fn is_locked(&self) -> bool { - self.locked.get() - } - pub unsafe fn lock(&self) { - self.locked.set(true); - } - } } #[allow(non_snake_case)] ///Resources `gpioa` has access to pub struct gpioaResources<'a> { pub shared: resources::shared<'a>, - pub shared2: resources::shared2<'a>, } #[allow(non_snake_case)] ///Hardware task @@ -128,7 +131,6 @@ pub mod gpioa { ///Resources `gpiob` has access to pub struct gpiobResources<'a> { pub shared: &'a mut u32, - pub shared2: &'a mut u32, } #[allow(non_snake_case)] ///Hardware task @@ -149,5 +151,109 @@ pub mod gpiob { } } } +#[allow(non_snake_case)] +///Hardware task +pub mod gpioc { + /// Execution context + pub struct Context {} + impl Context { + #[inline(always)] + pub unsafe fn new(priority: &rtic::export::Priority) -> Self { + Context {} + } + } +} /// Implementation details -const APP: () = { # [ doc = r" Always include the device crate which contains the vector table" ] use lm3s6965 as _ ; # [ allow ( non_upper_case_globals ) ] static mut shared : u32 = 0 ; impl < 'a > rtic :: Mutex for resources :: shared < 'a > { type T = u32 ; # [ inline ( always ) ] fn lock < R > ( & mut self , f : impl FnOnce ( & mut u32 ) -> R ) -> R { # [ doc = r" Priority ceiling" ] const CEILING : u8 = 2u8 ; unsafe { rtic :: export :: lock ( & mut shared , self . priority ( ) , CEILING , lm3s6965 :: NVIC_PRIO_BITS , f ) } } } # [ allow ( non_upper_case_globals ) ] static mut shared2 : u32 = 0 ; impl < 'a > rtic :: Mutex for resources :: shared2 < 'a > { type T = u32 ; # [ inline ( always ) ] fn lock < R > ( & mut self , f : impl FnOnce ( & mut u32 ) -> R ) -> R { # [ doc = r" Priority ceiling" ] const CEILING : u8 = 2u8 ; unsafe { rtic :: export :: lock ( & mut shared2 , self . priority ( ) , CEILING , lm3s6965 :: NVIC_PRIO_BITS , f ) } } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOA ( ) { const PRIORITY : u8 = 1u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpioa ( gpioa :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } impl < 'a > gpioaResources < 'a > { # [ inline ( always ) ] unsafe fn new ( priority : & 'a rtic :: export :: Priority ) -> Self { gpioaResources { shared : resources :: shared :: new ( priority ) , shared2 : resources :: shared2 :: new ( priority ) , } } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOB ( ) { const PRIORITY : u8 = 2u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpiob ( gpiob :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } impl < 'a > gpiobResources < 'a > { # [ inline ( always ) ] unsafe fn new ( priority : & 'a rtic :: export :: Priority ) -> Self { gpiobResources { shared : & mut shared , shared2 : & mut shared2 , } } } # [ no_mangle ] unsafe extern "C" fn main ( ) -> ! { let _TODO : ( ) = ( ) ; rtic :: export :: interrupt :: disable ( ) ; let mut core : rtic :: export :: Peripherals = core :: mem :: transmute ( ( ) ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 1u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOA , rtic :: export :: logical2hw ( 1u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOA ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 2u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOB , rtic :: export :: logical2hw ( 2u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOB ) ; core . SCB . scr . modify ( | r | r | 1 << 1 ) ; let late = crate :: init ( init :: Context :: new ( core . into ( ) ) ) ; rtic :: export :: interrupt :: enable ( ) ; loop { rtic :: export :: wfi ( ) } } }; +const APP: () = { + #[doc = r" Always include the device crate which contains the vector table"] + use lm3s6965 as _; + #[allow(non_upper_case_globals)] + static mut shared: u32 = 0; + impl<'a> rtic::Mutex for resources::shared<'a> { + type T = u32; + #[inline(always)] + fn lock(&mut self, f: impl FnOnce(&mut u32) -> R) -> R { + #[doc = r" Priority ceiling"] + const CEILING: u8 = 2u8; + unsafe { + rtic::export::lock( + &mut shared, + self.priority(), + CEILING, + lm3s6965::NVIC_PRIO_BITS, + f, + ) + } + } + } + #[allow(non_snake_case)] + #[no_mangle] + unsafe fn GPIOA() { + const PRIORITY: u8 = 1u8; + rtic::export::run(PRIORITY, || { + crate::gpioa(gpioa::Context::new(&rtic::export::Priority::new(PRIORITY))) + }); + } + impl<'a> gpioaResources<'a> { + #[inline(always)] + unsafe fn new(priority: &'a rtic::export::Priority) -> Self { + gpioaResources { + shared: resources::shared::new(priority), + } + } + } + #[allow(non_snake_case)] + #[no_mangle] + unsafe fn GPIOB() { + const PRIORITY: u8 = 2u8; + rtic::export::run(PRIORITY, || { + crate::gpiob(gpiob::Context::new(&rtic::export::Priority::new(PRIORITY))) + }); + } + impl<'a> gpiobResources<'a> { + #[inline(always)] + unsafe fn new(priority: &'a rtic::export::Priority) -> Self { + gpiobResources { + shared: &mut shared, + } + } + } + #[allow(non_snake_case)] + #[no_mangle] + unsafe fn GPIOC() { + const PRIORITY: u8 = 3u8; + rtic::export::run(PRIORITY, || { + crate::gpioc(gpioc::Context::new(&rtic::export::Priority::new(PRIORITY))) + }); + } + #[no_mangle] + unsafe extern "C" fn main() -> ! { + let _TODO: () = (); + rtic::export::interrupt::disable(); + let mut core: rtic::export::Peripherals = core::mem::transmute(()); + let _ = [(); ((1 << lm3s6965::NVIC_PRIO_BITS) - 1u8 as usize)]; + core.NVIC.set_priority( + lm3s6965::Interrupt::GPIOA, + rtic::export::logical2hw(1u8, lm3s6965::NVIC_PRIO_BITS), + ); + rtic::export::NVIC::unmask(lm3s6965::Interrupt::GPIOA); + let _ = [(); ((1 << lm3s6965::NVIC_PRIO_BITS) - 2u8 as usize)]; + core.NVIC.set_priority( + lm3s6965::Interrupt::GPIOB, + rtic::export::logical2hw(2u8, lm3s6965::NVIC_PRIO_BITS), + ); + rtic::export::NVIC::unmask(lm3s6965::Interrupt::GPIOB); + let _ = [(); ((1 << lm3s6965::NVIC_PRIO_BITS) - 3u8 as usize)]; + core.NVIC.set_priority( + lm3s6965::Interrupt::GPIOC, + rtic::export::logical2hw(3u8, lm3s6965::NVIC_PRIO_BITS), + ); + rtic::export::NVIC::unmask(lm3s6965::Interrupt::GPIOC); + core.SCB.scr.modify(|r| r | 1 << 1); + let late = crate::init(init::Context::new(core.into())); + rtic::export::interrupt::enable(); + loop { + rtic::export::wfi() + } + } +}; diff --git a/macros/src/codegen/resources.rs b/macros/src/codegen/resources.rs index 6788648b39..d2edaef736 100644 --- a/macros/src/codegen/resources.rs +++ b/macros/src/codegen/resources.rs @@ -103,12 +103,12 @@ pub fn codegen( } #[inline(always)] - pub unsafe fn is_locked(&self) -> bool { + pub unsafe fn get_locked(&self) -> bool { self.locked.get() } - pub unsafe fn lock(&self) { - self.locked.set(true); + pub unsafe fn set_locked(&self, b: bool) { + self.locked.set(b); } } )); diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index 68aca5d1f3..d8d05453fa 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -71,13 +71,17 @@ pub fn impl_mutex( #cfg_core impl<'a> rtic::Mutex for #path<'a> { type T = #ty; - #[inline(always)] fn lock(&mut self, f: impl FnOnce(&mut #ty) -> R) -> R { /// Priority ceiling const CEILING: u8 = #ceiling; - unsafe { + if unsafe { self.get_locked() } { + panic!("Resource locked in sequential context"); + }; + unsafe { self.set_locked(true); } + + let r = unsafe { rtic::export::lock( #ptr, #priority, @@ -85,7 +89,9 @@ pub fn impl_mutex( #device::NVIC_PRIO_BITS, f, ) - } + }; + unsafe { self.set_locked(false); } + r } } ) diff --git a/src/export.rs b/src/export.rs index e23b8f3a8b..0bfbd7039b 100644 --- a/src/export.rs +++ b/src/export.rs @@ -124,6 +124,7 @@ pub unsafe fn lock( nvic_prio_bits: u8, f: impl FnOnce(&mut T) -> R, ) -> R { + let current = priority.get(); if current < ceiling {