Skip to content

Commit bd33444

Browse files
committed
Use critical_section for Peripherals::take.
1 parent a39a61d commit bd33444

File tree

2 files changed

+24
-28
lines changed

2 files changed

+24
-28
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
- Use `critical_section::with` instead of `interrupt::free` for `Peripherals::take`.
11+
1012
## [v0.25.1] - 2022-08-22
1113

1214
- Fixed parentheses in RegisterBlock field accessors

src/generate/device.rs

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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(|_| {
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

Comments
 (0)