Skip to content

Commit

Permalink
Replace interrupt::free with critical_section::with.
Browse files Browse the repository at this point in the history
  • Loading branch information
reitermarkus committed May 5, 2022
1 parent 0d94e3b commit a3c5b41
Show file tree
Hide file tree
Showing 12 changed files with 71 additions and 61 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ jobs:
toolchain: ${{ matrix.rust }}
override: true
- name: Run tests
run: cargo test --all --exclude cortex-m-rt --exclude testsuite
run: cargo test --all --exclude cortex-m-rt --exclude testsuite --features cortex-m/single-core-critical-section

# FIXME: test on macOS and Windows
9 changes: 2 additions & 7 deletions .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
on:
push:
branches: [ staging, trying, master ]
pull_request_target:
pull_request:

name: Clippy check
jobs:
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
if: github.event_name == 'pull_request_target'
with:
ref: refs/pull/${{ github.event.number }}/head
- uses: actions/checkout@v3
if: github.event_name != 'pull_request_target'
- uses: actions-rs/toolchain@v1
with:
profile: minimal
Expand All @@ -23,4 +18,4 @@ jobs:
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all
args: --all --features cortex-m/single-core-critical-section
14 changes: 7 additions & 7 deletions .github/workflows/rt-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@ jobs:
- name: Install all Rust targets
run: rustup target install thumbv6m-none-eabi thumbv7m-none-eabi thumbv7em-none-eabi thumbv7em-none-eabihf thumbv8m.base-none-eabi thumbv8m.main-none-eabi thumbv8m.main-none-eabihf
- name: Build examples for thumbv6m-none-eabi
run: cargo build --target=thumbv6m-none-eabi --examples
run: cargo build --target=thumbv6m-none-eabi --features cortex-m/single-core-critical-section --examples
- name: Build examples for thumbv7m-none-eabi
run: cargo build --target=thumbv7m-none-eabi --examples
run: cargo build --target=thumbv7m-none-eabi --features cortex-m/single-core-critical-section --examples
- name: Build examples for thumbv7em-none-eabi
run: cargo build --target=thumbv7em-none-eabi --examples
run: cargo build --target=thumbv7em-none-eabi --features cortex-m/single-core-critical-section --examples
- name: Build examples for thumbv7em-none-eabihf
run: cargo build --target=thumbv7em-none-eabihf --examples
run: cargo build --target=thumbv7em-none-eabihf --features cortex-m/single-core-critical-section --examples
- name: Build examples for thumbv8m.base-none-eabi
run: cargo build --target=thumbv8m.base-none-eabi --examples
run: cargo build --target=thumbv8m.base-none-eabi --features cortex-m/single-core-critical-section --examples
- name: Build examples for thumbv8m.main-none-eabi
run: cargo build --target=thumbv8m.main-none-eabi --examples
run: cargo build --target=thumbv8m.main-none-eabi --features cortex-m/single-core-critical-section --examples
- name: Build examples for thumbv8m.main-none-eabihf
run: cargo build --target=thumbv8m.main-none-eabihf --examples
run: cargo build --target=thumbv8m.main-none-eabihf --features cortex-m/single-core-critical-section --examples
- name: Build crate for host OS
run: cargo build
31 changes: 17 additions & 14 deletions cortex-m-rt/ci/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ main() {

cargo check --target "$TARGET" --features device

# A `critical_section` implementation is always needed.
needed_features=cortex-m/single-core-critical-section

if [ "$TARGET" = x86_64-unknown-linux-gnu ] && [ "$TRAVIS_RUST_VERSION" = stable ]; then
( cd macros && cargo check && cargo test )

cargo test --features device --test compiletest
cargo test --features "device,${needed_features}" --test compiletest
fi

local examples=(
Expand Down Expand Up @@ -43,35 +46,35 @@ main() {
if [ "$TARGET" != x86_64-unknown-linux-gnu ]; then
# Only test on stable and nightly, not MSRV.
if [ "$TRAVIS_RUST_VERSION" = stable ] || [ "$TRAVIS_RUST_VERSION" = nightly ]; then
RUSTDOCFLAGS="-Cpanic=abort" cargo test --doc
RUSTDOCFLAGS="-Cpanic=abort" cargo test --features "${needed_features}" --doc
fi

for linker in "${linkers[@]}"; do
for ex in "${examples[@]}"; do
cargo rustc --target "$TARGET" --example "$ex" -- $linker
cargo rustc --target "$TARGET" --example "$ex" --release -- $linker
cargo rustc --target "$TARGET" --example "$ex" --features "${needed_features}" -- $linker
cargo rustc --target "$TARGET" --example "$ex" --features "${needed_features}" --release -- $linker
done
for ex in "${fail_examples[@]}"; do
! cargo rustc --target "$TARGET" --example "$ex" -- $linker
! cargo rustc --target "$TARGET" --example "$ex" --release -- $linker
! cargo rustc --target "$TARGET" --example "$ex" --features "${needed_features}" -- $linker
! cargo rustc --target "$TARGET" --example "$ex" --features "${needed_features}" --release -- $linker
done
cargo rustc --target "$TARGET" --example device --features device -- $linker
cargo rustc --target "$TARGET" --example device --features device --release -- $linker
cargo rustc --target "$TARGET" --example device --features "device,${needed_features}" -- $linker
cargo rustc --target "$TARGET" --example device --features "device,${needed_features}" --release -- $linker

cargo rustc --target "$TARGET" --example minimal --features set-sp -- $linker
cargo rustc --target "$TARGET" --example minimal --features set-sp --release -- $linker
cargo rustc --target "$TARGET" --example minimal --features set-vtor -- $linker
cargo rustc --target "$TARGET" --example minimal --features set-vtor --release -- $linker
cargo rustc --target "$TARGET" --example minimal --features "set-sp,${needed_features}" -- $linker
cargo rustc --target "$TARGET" --example minimal --features "set-sp,${needed_features}" --release -- $linker
cargo rustc --target "$TARGET" --example minimal --features "set-vtor,${needed_features}" -- $linker
cargo rustc --target "$TARGET" --example minimal --features "set-vtor,${needed_features}" --release -- $linker
done
fi

case $TARGET in
thumbv6m-none-eabi|thumbv7m-none-eabi)
for linker in "${linkers[@]}"; do
env RUSTFLAGS="$linker -C link-arg=-Tlink.x" cargo run \
--target "$TARGET" --example qemu | grep "x = 42"
--target "$TARGET" --features "${needed_features}" --example qemu | grep "x = 42"
env RUSTFLAGS="$linker -C link-arg=-Tlink.x" cargo run \
--target "$TARGET" --example qemu --release | grep "x = 42"
--target "$TARGET" --features "${needed_features}" --example qemu --release | grep "x = 42"
done

;;
Expand Down
1 change: 1 addition & 0 deletions cortex-m-semihosting/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ no-semihosting = []

[dependencies]
cortex-m = { path = "..", version = ">= 0.5.8, < 0.8" }
critical-section = "0.2"
10 changes: 4 additions & 6 deletions cortex-m-semihosting/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
use core::fmt::{self, Write};

use cortex_m::interrupt;

use crate::hio::{self, HostStream};

static mut HSTDOUT: Option<HostStream> = None;

pub fn hstdout_str(s: &str) {
let _result = interrupt::free(|| unsafe {
let _result = critical_section::with(|_| unsafe {
if HSTDOUT.is_none() {
HSTDOUT = Some(hio::hstdout()?);
}
Expand All @@ -19,7 +17,7 @@ pub fn hstdout_str(s: &str) {
}

pub fn hstdout_fmt(args: fmt::Arguments) {
let _result = interrupt::free(|| unsafe {
let _result = critical_section::with(|_| unsafe {
if HSTDOUT.is_none() {
HSTDOUT = Some(hio::hstdout()?);
}
Expand All @@ -31,7 +29,7 @@ pub fn hstdout_fmt(args: fmt::Arguments) {
static mut HSTDERR: Option<HostStream> = None;

pub fn hstderr_str(s: &str) {
let _result = interrupt::free(|| unsafe {
let _result = critical_section::with(|_| unsafe {
if HSTDERR.is_none() {
HSTDERR = Some(hio::hstderr()?);
}
Expand All @@ -41,7 +39,7 @@ pub fn hstderr_str(s: &str) {
}

pub fn hstderr_fmt(args: fmt::Arguments) {
let _result = interrupt::free(|| unsafe {
let _result = critical_section::with(|_| unsafe {
if HSTDERR.is_none() {
HSTDERR = Some(hio::hstderr()?);
}
Expand Down
41 changes: 23 additions & 18 deletions src/critical_section.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
use crate::interrupt;
use crate::register::primask::{self, Primask};
#[cfg(all(cortex_m, feature = "single-core-critical-section"))]
mod single_core_critical_section {
use crate::interrupt;
use crate::register::primask::{self, Primask};

struct CriticalSection;
critical_section::custom_impl!(CriticalSection);
struct CriticalSection;
critical_section::custom_impl!(CriticalSection);

const TOKEN_IGNORE: u8 = 0;
const TOKEN_REENABLE: u8 = 1;
const TOKEN_IGNORE: u8 = 0;
const TOKEN_REENABLE: u8 = 1;

unsafe impl critical_section::Impl for CriticalSection {
unsafe fn acquire() -> u8 {
match primask::read() {
Primask::Active => {
interrupt::disable();
TOKEN_REENABLE
unsafe impl critical_section::Impl for CriticalSection {
unsafe fn acquire() -> u8 {
match primask::read() {
Primask::Active => {
interrupt::disable();
TOKEN_REENABLE
}
Primask::Inactive => TOKEN_IGNORE,
}
Primask::Inactive => TOKEN_IGNORE,
}
}

unsafe fn release(token: u8) {
// Only re-enable interrupts if they were enabled before the critical section.
if token == TOKEN_REENABLE {
interrupt::enable()
unsafe fn release(token: u8) {
// Only re-enable interrupts if they were enabled before the critical section.
if token == TOKEN_REENABLE {
interrupt::enable()
}
}
}
}

pub use critical_section::with;
7 changes: 5 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ mod macros;
pub mod asm;
#[cfg(armv8m)]
pub mod cmse;
#[cfg(all(cortex_m, feature = "single-core-critical-section"))]
mod critical_section;
// This is only public so the `singleton` macro does not require depending on
// the `critical-section` crate separately.
#[doc(hidden)]
#[cfg(feature = "critical-section")]
pub mod critical_section;
pub mod delay;
pub mod interrupt;
#[cfg(all(not(armv6m), not(armv8m_base)))]
Expand Down
2 changes: 1 addition & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ macro_rules! iprintln {
#[macro_export]
macro_rules! singleton {
($name:ident: $ty:ty = $expr:expr) => {
$crate::interrupt::free(|| {
$crate::critical_section::with(|_| {
// this is a tuple of a MaybeUninit and a bool because using an Option here is
// problematic: Due to niche-optimization, an Option could end up producing a non-zero
// initializer value which would move the entire static from `.bss` into `.data`...
Expand Down
3 changes: 1 addition & 2 deletions src/peripheral/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
//!
//! - ARMv7-M Architecture Reference Manual (Issue E.b) - Chapter B3
use crate::interrupt;
use core::marker::PhantomData;
use core::ops;

Expand Down Expand Up @@ -164,7 +163,7 @@ impl Peripherals {
/// Returns all the core peripherals *once*
#[inline]
pub fn take() -> Option<Self> {
interrupt::free(|| {
critical_section::with(|_| {
if unsafe { TAKEN } {
None
} else {
Expand Down
5 changes: 2 additions & 3 deletions src/peripheral/sau.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//!
//! For reference please check the section B8.3 of the Armv8-M Architecture Reference Manual.
use crate::interrupt;
use crate::peripheral::SAU;
use bitfield::bitfield;
use volatile_register::{RO, RW};
Expand Down Expand Up @@ -162,7 +161,7 @@ impl SAU {
/// This function is executed under a critical section to prevent having inconsistent results.
#[inline]
pub fn set_region(&mut self, region_number: u8, region: SauRegion) -> Result<(), SauError> {
interrupt::free(|| {
critical_section::with(|_| {
let base_address = region.base_address;
let limit_address = region.limit_address;
let attribute = region.attribute;
Expand Down Expand Up @@ -215,7 +214,7 @@ impl SAU {
/// This function is executed under a critical section to prevent having inconsistent results.
#[inline]
pub fn get_region(&mut self, region_number: u8) -> Result<SauRegion, SauError> {
interrupt::free(|| {
critical_section::with(|_| {
if region_number >= self.region_numbers() {
Err(SauError::RegionNumberTooBig)
} else {
Expand Down
7 changes: 7 additions & 0 deletions xtask/tests/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ fn build(package: &str, target: &str, features: &[&str]) {
cargo.args(&["--features", *feat]);
}

// A `critical_section` implementation is always needed.
if package == "cortex-m" {
cargo.args(&["--features", "single-core-critical-section"]);
} else {
cargo.args(&["--features", "cortex-m/single-core-critical-section"]);
}

// Cargo features don't work right when invoked from the workspace root, so change to the
// package's directory when necessary.
if package != "cortex-m" {
Expand Down

0 comments on commit a3c5b41

Please sign in to comment.