Skip to content

Commit 7daa9ed

Browse files
Merge #651
651: Use `critical_section` for `Peripherals::take`. r=therealprof a=reitermarkus - `cortex_m` rust-embedded/cortex-m#447 - `msp430` rust-embedded/msp430#13 - `riscv` rust-embedded/riscv#110 - `xtensa_lx` esp-rs/xtensa-lx#20, esp-rs/esp-hal#151 - `mips_mcu` kiffie/pic32-rs#5 Co-authored-by: Markus Reiter <me@reitermark.us>
2 parents a39a61d + 47b7679 commit 7daa9ed

File tree

4 files changed

+65
-67
lines changed

4 files changed

+65
-67
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

ci/svd2rust-regress/src/svd_test.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ use std::io::prelude::*;
55
use std::path::PathBuf;
66
use std::process::{Command, Output};
77

8-
const CRATES_ALL: &[&str] = &["bare-metal = \"0.2.0\"", "vcell = \"0.1.2\""];
8+
const CRATES_ALL: &[&str] = &["critical-section = \"1.0\"", "vcell = \"0.1.2\""];
99
const CRATES_MSP430: &[&str] = &["msp430 = \"0.2.2\"", "msp430-rt = \"0.2.0\""];
1010
const CRATES_MSP430_NIGHTLY: &[&str] = &["msp430-atomic = \"0.1.2\""];
11-
const CRATES_CORTEX_M: &[&str] = &["cortex-m = \"0.7.0\"", "cortex-m-rt = \"0.6.13\""];
12-
const CRATES_RISCV: &[&str] = &["riscv = \"0.5.0\"", "riscv-rt = \"0.6.0\""];
11+
const CRATES_CORTEX_M: &[&str] = &["cortex-m = \"0.7.6\"", "cortex-m-rt = \"0.6.13\""];
12+
const CRATES_RISCV: &[&str] = &["riscv = \"0.9.0\"", "riscv-rt = \"0.9.0\""];
1313
const CRATES_XTENSALX: &[&str] = &["xtensa-lx-rt = \"0.9.0\"", "xtensa-lx = \"0.6.0\""];
1414
const CRATES_MIPS: &[&str] = &["mips-mcu = \"0.1.0\""];
1515
const PROFILE_ALL: &[&str] = &["[profile.dev]", "incremental = false"];

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;

src/lib.rs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! [CMSIS-SVD]: http://www.keil.com/pack/doc/CMSIS/SVD/html/index.html
44
//!
5-
//! A SVD file is an XML file that describes the hardware features of a
5+
//! An SVD file is an XML file that describes the hardware features of a
66
//! microcontroller. In particular, it lists all the peripherals available to the
77
//! device, where the registers associated to each device are located in memory,
88
//! and what's the function of each register.
@@ -56,20 +56,23 @@
5656
//! $ cargo fmt
5757
//! ```
5858
//!
59-
//! The resulting crate must provide an opt-in "rt" feature and depend on these crates:
60-
//! `cortex-m` v0.7, `cortex-m-rt` >=v0.6.13 and `vcell` >=v0.1.2. Furthermore
61-
//! the "device" feature of `cortex-m-rt` must be enabled when the "rt" feature is enabled. The
62-
//! `Cargo.toml` of the device crate will look like this:
59+
//! The resulting crate must provide an opt-in `rt` feature and depend on these crates:
60+
//!
61+
//! - [`critical-section`](https://crates.io/crates/critical-section) v1.x
62+
//! - [`cortex-m`](https://crates.io/crates/cortex-m) >=v0.7.6
63+
//! - [`cortex-m-rt`](https://crates.io/crates/cortex-m-rt) >=v0.6.13
64+
//! - [`vcell`](https://crates.io/crates/vcell) >=v0.1.2
65+
//!
66+
//! Furthermore, the "device" feature of `cortex-m-rt` must be enabled when the `rt` feature
67+
//! is enabled. The `Cargo.toml` of the device crate will look like this:
6368
//!
6469
//! ``` toml
6570
//! [dependencies]
66-
//! cortex-m = "0.7"
71+
//! critical-section = { version = "1.0", optional = true }
72+
//! cortex-m = "0.7.6"
73+
//! cortex-m-rt = { version = "0.6.13", optional = true }
6774
//! vcell = "0.1.2"
6875
//!
69-
//! [dependencies.cortex-m-rt]
70-
//! optional = true
71-
//! version = "0.6.13"
72-
//!
7376
//! [features]
7477
//! rt = ["cortex-m-rt/device"]
7578
//! ```
@@ -110,21 +113,24 @@
110113
//! $ cargo fmt
111114
//! ```
112115
//!
113-
//! The resulting crate must provide opt-in "rt" feature and depend on these crates: `msp430`
114-
//! v0.3.x, `msp430-rt` v0.3.x, and `vcell` v0.1.x. If the `--nightly` flag is provided to
115-
//! `svd2rust`, then `msp430-atomic` v0.1.4 is also needed. Furthermore the "device" feature of
116-
//! `msp430-rt` must be enabled when the "rt" feature is enabled. The `Cargo.toml` of the device
117-
//! crate will look like this:
116+
//! The resulting crate must provide opt-in `rt` feature and depend on these crates:
117+
//!
118+
//! - [`critical-section`](https://crates.io/crates/critical-section) v1.x
119+
//! - [`msp430`](https://crates.io/crates/msp430) v0.3.x
120+
//! - [`msp430-rt`](https://crates.io/crates/msp430-rt) v0.3.x
121+
//! - [`vcell`](https://crates.io/crates/vcell) v0.1.x
122+
//!
123+
//! If the `--nightly` flag is provided to `svd2rust`, then `msp430-atomic` v0.1.4 is also needed.
124+
//! Furthermore the "device" feature of `msp430-rt` must be enabled when the `rt` feature is
125+
//! enabled. The `Cargo.toml` of the device crate will look like this:
118126
//!
119127
//! ``` toml
120128
//! [dependencies]
129+
//! critical-section = { version = "1.0", optional = true }
121130
//! msp430 = "0.3.0"
122-
//! vcell = "0.1.0"
123131
//! msp430-atomic = "0.1.4" # Only when using the --nightly flag
124-
//!
125-
//! [dependencies.msp430-rt]
126-
//! optional = true
127-
//! version = "0.3.0"
132+
//! msp430-rt = { version = "0.3.0", optional = true }
133+
//! vcell = "0.1.0"
128134
//!
129135
//! [features]
130136
//! rt = ["msp430-rt/device"]
@@ -134,28 +140,25 @@
134140
//! ## Other targets
135141
//!
136142
//! When the target is riscv or none `svd2rust` will emit only the `lib.rs` file. Like in
137-
//! the cortex-m case we recommend you use `form` and `rustfmt` on the output.
143+
//! the `cortex-m` case, we recommend you use `form` and `rustfmt` on the output.
138144
//!
139-
//! The resulting crate must provide an opt-in "rt" feature and depend on these crates:
145+
//! The resulting crate must provide an opt-in `rt` feature and depend on these crates:
140146
//!
141-
//! - [`bare-metal`](https://crates.io/crates/bare-metal) v0.2.x
147+
//! - [`critical-section`](https://crates.io/crates/critical-section) v1.x
148+
//! - [`riscv`](https://crates.io/crates/riscv) v0.9.x (if target is RISC-V)
149+
//! - [`riscv-rt`](https://crates.io/crates/riscv-rt) v0.9.x (if target is RISC-V)
142150
//! - [`vcell`](https://crates.io/crates/vcell) v0.1.x
143-
//! - [`riscv`](https://crates.io/crates/riscv) v0.4.x if target = riscv.
144-
//! - [`riscv-rt`](https://crates.io/crates/riscv-rt) v0.4.x if target = riscv.
145151
//!
146-
//! The `*-rt` dependencies must be optional only enabled when the "rt" feature is enabled. The
147-
//! `Cargo.toml` of the device crate will look like this for a riscv target:
152+
//! The `*-rt` dependencies must be optional only enabled when the `rt` feature is enabled. The
153+
//! `Cargo.toml` of the device crate will look like this for a RISC-V target:
148154
//!
149155
//! ``` toml
150156
//! [dependencies]
151-
//! bare-metal = "0.2.0"
152-
//! riscv = "0.4.0"
157+
//! critical-section = { version = "1.0", optional = true }
158+
//! riscv = "0.9.0"
159+
//! riscv-rt = { version = "0.9.0", optional = true }
153160
//! vcell = "0.1.0"
154161
//!
155-
//! [dependencies.riscv-rt]
156-
//! optional = true
157-
//! version = "0.4.0"
158-
//!
159162
//! [features]
160163
//! rt = ["riscv-rt"]
161164
//! ```
@@ -458,7 +461,6 @@
458461
//! used with the `cortex-m` crate `NVIC` API.
459462
//!
460463
//! ```ignore
461-
//! use cortex_m::interrupt;
462464
//! use cortex_m::peripheral::Peripherals;
463465
//! use stm32f30x::Interrupt;
464466
//!
@@ -469,9 +471,9 @@
469471
//! nvic.enable(Interrupt::TIM3);
470472
//! ```
471473
//!
472-
//! ## the "rt" feature
474+
//! ## the `rt` feature
473475
//!
474-
//! If the "rt" Cargo feature of the svd2rust generated crate is enabled, the crate will populate the
476+
//! If the `rt` Cargo feature of the svd2rust generated crate is enabled, the crate will populate the
475477
//! part of the vector table that contains the interrupt vectors and provide an
476478
//! [`interrupt!`](macro.interrupt.html) macro (non Cortex-M/MSP430 targets) or [`interrupt`] attribute
477479
//! (Cortex-M or [MSP430](https://docs.rs/msp430-rt-macros/0.1/msp430_rt_macros/attr.interrupt.html))

0 commit comments

Comments
 (0)