Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Replace interrupt::free with critical_section::with.
  • Loading branch information
reitermarkus committed May 8, 2022
commit cfba329ad299cb7e49a5b16c844ec758c835f368
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