Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use critical_section for Peripherals::take. #651

Merged
merged 1 commit into from
Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

- Use `critical_section::with` instead of `interrupt::free` for `Peripherals::take`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A mention to take not being provided if critical-section is not enabled could probably be added here


## [v0.25.1] - 2022-08-22

- Fixed parentheses in RegisterBlock field accessors
Expand Down
6 changes: 3 additions & 3 deletions ci/svd2rust-regress/src/svd_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use std::io::prelude::*;
use std::path::PathBuf;
use std::process::{Command, Output};

const CRATES_ALL: &[&str] = &["bare-metal = \"0.2.0\"", "vcell = \"0.1.2\""];
const CRATES_ALL: &[&str] = &["critical-section = \"1.0\"", "vcell = \"0.1.2\""];
const CRATES_MSP430: &[&str] = &["msp430 = \"0.2.2\"", "msp430-rt = \"0.2.0\""];
const CRATES_MSP430_NIGHTLY: &[&str] = &["msp430-atomic = \"0.1.2\""];
const CRATES_CORTEX_M: &[&str] = &["cortex-m = \"0.7.0\"", "cortex-m-rt = \"0.6.13\""];
const CRATES_RISCV: &[&str] = &["riscv = \"0.5.0\"", "riscv-rt = \"0.6.0\""];
const CRATES_CORTEX_M: &[&str] = &["cortex-m = \"0.7.6\"", "cortex-m-rt = \"0.6.13\""];
const CRATES_RISCV: &[&str] = &["riscv = \"0.9.0\"", "riscv-rt = \"0.9.0\""];
const CRATES_XTENSALX: &[&str] = &["xtensa-lx-rt = \"0.9.0\"", "xtensa-lx = \"0.6.0\""];
const CRATES_MIPS: &[&str] = &["mips-mcu = \"0.1.0\""];
const PROFILE_ALL: &[&str] = &["[profile.dev]", "incremental = false"];
Expand Down
50 changes: 22 additions & 28 deletions src/generate/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,48 +300,42 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
}
}

let span = Span::call_site();
let take = match config.target {
Target::CortexM => Some(Ident::new("cortex_m", span)),
Target::Msp430 => Some(Ident::new("msp430", span)),
Target::RISCV => Some(Ident::new("riscv", span)),
Target::XtensaLX => Some(Ident::new("xtensa_lx", span)),
Target::Mips => Some(Ident::new("mips_mcu", span)),
Target::None => None,
}
.map(|krate| {
quote! {
///Returns all the peripherals *once*
#[inline]
pub fn take() -> Option<Self> {
#krate::interrupt::free(|_| {
if unsafe { DEVICE_PERIPHERALS } {
None
} else {
Some(unsafe { Peripherals::steal() })
}
})
}
}
});

out.extend(quote! {
// NOTE `no_mangle` is used here to prevent linking different minor versions of the device
// crate as that would let you `take` the device peripherals more than once (one per minor
// version)
#[no_mangle]
static mut DEVICE_PERIPHERALS: bool = false;

///All the peripherals
/// All the peripherals.
#[allow(non_snake_case)]
pub struct Peripherals {
#fields
}

impl Peripherals {
#take
/// Returns all the peripherals *once*.
#[cfg(feature = "critical-section")]
Emilgardis marked this conversation as resolved.
Show resolved Hide resolved
#[inline]
pub fn take() -> Option<Self> {
critical_section::with(|_| {
// SAFETY: We are in a critical section, so we have exclusive access
// to `DEVICE_PERIPHERALS`.
if unsafe { DEVICE_PERIPHERALS } {
return None
}

// SAFETY: `DEVICE_PERIPHERALS` is set to `true` by `Peripherals::steal`,
// ensuring the peripherals can only be returned once.
Some(unsafe { Peripherals::steal() })
})
}

///Unchecked version of `Peripherals::take`
/// Unchecked version of `Peripherals::take`.
///
/// # Safety
///
/// Each of the returned peripherals must be used at most once.
#[inline]
pub unsafe fn steal() -> Self {
DEVICE_PERIPHERALS = true;
Expand Down
74 changes: 38 additions & 36 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! [CMSIS-SVD]: http://www.keil.com/pack/doc/CMSIS/SVD/html/index.html
//!
//! A SVD file is an XML file that describes the hardware features of a
//! An SVD file is an XML file that describes the hardware features of a
//! microcontroller. In particular, it lists all the peripherals available to the
//! device, where the registers associated to each device are located in memory,
//! and what's the function of each register.
Expand Down Expand Up @@ -56,20 +56,23 @@
//! $ cargo fmt
//! ```
//!
//! The resulting crate must provide an opt-in "rt" feature and depend on these crates:
//! `cortex-m` v0.7, `cortex-m-rt` >=v0.6.13 and `vcell` >=v0.1.2. Furthermore
//! the "device" feature of `cortex-m-rt` must be enabled when the "rt" feature is enabled. The
//! `Cargo.toml` of the device crate will look like this:
//! The resulting crate must provide an opt-in `rt` feature and depend on these crates:
//!
//! - [`critical-section`](https://crates.io/crates/critical-section) v1.x
//! - [`cortex-m`](https://crates.io/crates/cortex-m) >=v0.7.6
//! - [`cortex-m-rt`](https://crates.io/crates/cortex-m-rt) >=v0.6.13
//! - [`vcell`](https://crates.io/crates/vcell) >=v0.1.2
//!
//! Furthermore, the "device" feature of `cortex-m-rt` must be enabled when the `rt` feature
//! is enabled. The `Cargo.toml` of the device crate will look like this:
//!
//! ``` toml
//! [dependencies]
//! cortex-m = "0.7"
//! critical-section = { version = "1.0", optional = true }
//! cortex-m = "0.7.6"
//! cortex-m-rt = { version = "0.6.13", optional = true }
//! vcell = "0.1.2"
//!
//! [dependencies.cortex-m-rt]
//! optional = true
//! version = "0.6.13"
//!
//! [features]
//! rt = ["cortex-m-rt/device"]
//! ```
Expand Down Expand Up @@ -110,21 +113,24 @@
//! $ cargo fmt
//! ```
//!
//! The resulting crate must provide opt-in "rt" feature and depend on these crates: `msp430`
//! v0.3.x, `msp430-rt` v0.3.x, and `vcell` v0.1.x. If the `--nightly` flag is provided to
//! `svd2rust`, then `msp430-atomic` v0.1.4 is also needed. Furthermore the "device" feature of
//! `msp430-rt` must be enabled when the "rt" feature is enabled. The `Cargo.toml` of the device
//! crate will look like this:
//! The resulting crate must provide opt-in `rt` feature and depend on these crates:
//!
//! - [`critical-section`](https://crates.io/crates/critical-section) v1.x
//! - [`msp430`](https://crates.io/crates/msp430) v0.3.x
//! - [`msp430-rt`](https://crates.io/crates/msp430-rt) v0.3.x
//! - [`vcell`](https://crates.io/crates/vcell) v0.1.x
//!
//! If the `--nightly` flag is provided to `svd2rust`, then `msp430-atomic` v0.1.4 is also needed.
//! Furthermore the "device" feature of `msp430-rt` must be enabled when the `rt` feature is
//! enabled. The `Cargo.toml` of the device crate will look like this:
//!
//! ``` toml
//! [dependencies]
//! critical-section = { version = "1.0", optional = true }
//! msp430 = "0.3.0"
//! vcell = "0.1.0"
//! msp430-atomic = "0.1.4" # Only when using the --nightly flag
//!
//! [dependencies.msp430-rt]
//! optional = true
//! version = "0.3.0"
//! msp430-rt = { version = "0.3.0", optional = true }
//! vcell = "0.1.0"
//!
//! [features]
//! rt = ["msp430-rt/device"]
Expand All @@ -134,28 +140,25 @@
//! ## Other targets
//!
//! When the target is riscv or none `svd2rust` will emit only the `lib.rs` file. Like in
//! the cortex-m case we recommend you use `form` and `rustfmt` on the output.
//! the `cortex-m` case, we recommend you use `form` and `rustfmt` on the output.
//!
//! The resulting crate must provide an opt-in "rt" feature and depend on these crates:
//! The resulting crate must provide an opt-in `rt` feature and depend on these crates:
//!
//! - [`bare-metal`](https://crates.io/crates/bare-metal) v0.2.x
//! - [`critical-section`](https://crates.io/crates/critical-section) v1.x
//! - [`riscv`](https://crates.io/crates/riscv) v0.9.x (if target is RISC-V)
//! - [`riscv-rt`](https://crates.io/crates/riscv-rt) v0.9.x (if target is RISC-V)
//! - [`vcell`](https://crates.io/crates/vcell) v0.1.x
//! - [`riscv`](https://crates.io/crates/riscv) v0.4.x if target = riscv.
//! - [`riscv-rt`](https://crates.io/crates/riscv-rt) v0.4.x if target = riscv.
//!
//! The `*-rt` dependencies must be optional only enabled when the "rt" feature is enabled. The
//! `Cargo.toml` of the device crate will look like this for a riscv target:
//! The `*-rt` dependencies must be optional only enabled when the `rt` feature is enabled. The
//! `Cargo.toml` of the device crate will look like this for a RISC-V target:
//!
//! ``` toml
//! [dependencies]
//! bare-metal = "0.2.0"
//! riscv = "0.4.0"
//! critical-section = { version = "1.0", optional = true }
//! riscv = "0.9.0"
//! riscv-rt = { version = "0.9.0", optional = true }
//! vcell = "0.1.0"
//!
//! [dependencies.riscv-rt]
//! optional = true
//! version = "0.4.0"
//!
//! [features]
//! rt = ["riscv-rt"]
//! ```
Expand Down Expand Up @@ -458,7 +461,6 @@
//! used with the `cortex-m` crate `NVIC` API.
//!
//! ```ignore
//! use cortex_m::interrupt;
//! use cortex_m::peripheral::Peripherals;
//! use stm32f30x::Interrupt;
//!
Expand All @@ -469,9 +471,9 @@
//! nvic.enable(Interrupt::TIM3);
//! ```
//!
//! ## the "rt" feature
//! ## the `rt` feature
//!
//! If the "rt" Cargo feature of the svd2rust generated crate is enabled, the crate will populate the
//! If the `rt` Cargo feature of the svd2rust generated crate is enabled, the crate will populate the
//! part of the vector table that contains the interrupt vectors and provide an
//! [`interrupt!`](macro.interrupt.html) macro (non Cortex-M/MSP430 targets) or [`interrupt`] attribute
//! (Cortex-M or [MSP430](https://docs.rs/msp430-rt-macros/0.1/msp430_rt_macros/attr.interrupt.html))
Expand Down