@@ -300,48 +300,42 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
300300 }
301301 }
302302
303- let span = Span :: call_site ( ) ;
304- let take = match config. target {
305- Target :: CortexM => Some ( Ident :: new ( "cortex_m" , span) ) ,
306- Target :: Msp430 => Some ( Ident :: new ( "msp430" , span) ) ,
307- Target :: RISCV => Some ( Ident :: new ( "riscv" , span) ) ,
308- Target :: XtensaLX => Some ( Ident :: new ( "xtensa_lx" , span) ) ,
309- Target :: Mips => Some ( Ident :: new ( "mips_mcu" , span) ) ,
310- Target :: None => None ,
311- }
312- . map ( |krate| {
313- quote ! {
314- ///Returns all the peripherals *once*
315- #[ inline]
316- pub fn take( ) -> Option <Self > {
317- #krate:: interrupt:: free( |_| {
318- if unsafe { DEVICE_PERIPHERALS } {
319- None
320- } else {
321- Some ( unsafe { Peripherals :: steal( ) } )
322- }
323- } )
324- }
325- }
326- } ) ;
327-
328303 out. extend ( quote ! {
329304 // NOTE `no_mangle` is used here to prevent linking different minor versions of the device
330305 // crate as that would let you `take` the device peripherals more than once (one per minor
331306 // version)
332307 #[ no_mangle]
333308 static mut DEVICE_PERIPHERALS : bool = false ;
334309
335- ///All the peripherals
310+ /// All the peripherals.
336311 #[ allow( non_snake_case) ]
337312 pub struct Peripherals {
338313 #fields
339314 }
340315
341316 impl Peripherals {
342- #take
317+ /// Returns all the peripherals *once*.
318+ #[ cfg( feature = "critical-section" ) ]
319+ #[ inline]
320+ pub fn take( ) -> Option <Self > {
321+ critical_section:: with( |_| unsafe {
322+ // SAFETY: We are in a critical section, so we have exclusive access
323+ // to `DEVICE_PERIPHERALS`.
324+ if unsafe { DEVICE_PERIPHERALS } {
325+ return None
326+ }
327+
328+ // SAFETY: `DEVICE_PERIPHERALS` is set to `true` by `Peripherals::steal`,
329+ // ensuring the peripherals can only be returned once.
330+ Some ( unsafe { Peripherals :: steal( ) } )
331+ } )
332+ }
343333
344- ///Unchecked version of `Peripherals::take`
334+ /// Unchecked version of `Peripherals::take`.
335+ ///
336+ /// # Safety
337+ ///
338+ /// Each of the returned peripherals must be used at most once.
345339 #[ inline]
346340 pub unsafe fn steal( ) -> Self {
347341 DEVICE_PERIPHERALS = true ;
0 commit comments