aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Dario Nieuwenhuis <dirbaio@dirbaio.net> 2022-08-10 18:17:31 +0200
committerGravatar Dario Nieuwenhuis <dirbaio@dirbaio.net> 2022-08-11 23:32:41 +0200
commit9e8c8e794d378ce51198fbb9ba27094b430e6d52 (patch)
treee26456eb8c4313661385ed86e142b7e337d2811a
parente0bfe3ae21903e9dbd80e903e726f7341662e12b (diff)
downloadcortex-m-9e8c8e794d378ce51198fbb9ba27094b430e6d52.tar.gz
cortex-m-9e8c8e794d378ce51198fbb9ba27094b430e6d52.tar.zst
cortex-m-9e8c8e794d378ce51198fbb9ba27094b430e6d52.zip
Add implementation for critical-section 1.0.
-rw-r--r--.github/workflows/ci.yml8
-rw-r--r--.github/workflows/clippy.yml1
-rw-r--r--CHANGELOG.md2
-rw-r--r--Cargo.toml2
-rw-r--r--src/critical_section.rs25
-rw-r--r--src/lib.rs1
-rw-r--r--xtask/tests/ci.rs9
7 files changed, 44 insertions, 4 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7289085..e792872 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,13 +13,19 @@ jobs:
matrix:
# All generated code should be running on stable now
rust: [stable]
+ features: ["", "critical-section-single-core"]
include:
# Test MSRV
- rust: 1.38.0
+ features: ""
# Test nightly but don't fail
- rust: nightly
+ features: ""
+ experimental: true
+ - rust: nightly
+ features: "critical-section-single-core"
experimental: true
steps:
- uses: actions/checkout@v2
@@ -29,6 +35,6 @@ jobs:
toolchain: ${{ matrix.rust }}
override: true
- name: Run tests
- run: cargo test --all
+ run: cargo test --all --features "${{ matrix.features }}"
# FIXME: test on macOS and Windows
diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml
index d55d697..7a83695 100644
--- a/.github/workflows/clippy.yml
+++ b/.github/workflows/clippy.yml
@@ -23,3 +23,4 @@ jobs:
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
+ args: --features critical-section-single-core
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 95ed203..4beab90 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
+- Added `critical-section-single-core` feature which provides an implementation for the `critical_section` crate for single-core systems, based on disabling all interrupts. (#448)
+
## [v0.7.5] - 2022-05-15
### Deprecated
diff --git a/Cargo.toml b/Cargo.toml
index dc0678e..f107cb4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,7 @@ links = "cortex-m" # prevent multiple versions of this crate to be linked toget
[dependencies]
bare-metal = { version = "0.2.4", features = ["const-fn"] }
+critical-section = { version = "1.0.0", optional = true }
volatile-register = "0.2.0"
bitfield = "0.13.2"
embedded-hal = "0.2.4"
@@ -32,6 +33,7 @@ cm7-r0p1 = ["cm7"]
inline-asm = []
linker-plugin-lto = []
std = []
+critical-section-single-core = ["critical-section/restore-state-bool"]
[workspace]
members = ["xtask", "cortex-m-semihosting", "panic-semihosting", "panic-itm"]
diff --git a/src/critical_section.rs b/src/critical_section.rs
new file mode 100644
index 0000000..d33e90f
--- /dev/null
+++ b/src/critical_section.rs
@@ -0,0 +1,25 @@
+#[cfg(all(cortex_m, feature = "critical-section-single-core"))]
+mod single_core_critical_section {
+ use critical_section::{set_impl, Impl, RawRestoreState};
+
+ use crate::interrupt;
+ use crate::register::primask;
+
+ struct SingleCoreCriticalSection;
+ set_impl!(SingleCoreCriticalSection);
+
+ unsafe impl Impl for SingleCoreCriticalSection {
+ unsafe fn acquire() -> RawRestoreState {
+ let was_active = primask::read().is_active();
+ interrupt::disable();
+ was_active
+ }
+
+ unsafe fn release(was_active: RawRestoreState) {
+ // Only re-enable interrupts if they were enabled before the critical section.
+ if was_active {
+ interrupt::enable()
+ }
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 4790f98..1796b78 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -90,6 +90,7 @@ mod macros;
pub mod asm;
#[cfg(armv8m)]
pub mod cmse;
+mod critical_section;
pub mod delay;
pub mod interrupt;
#[cfg(all(not(armv6m), not(armv8m_base)))]
diff --git a/xtask/tests/ci.rs b/xtask/tests/ci.rs
index 37466e9..ded7555 100644
--- a/xtask/tests/ci.rs
+++ b/xtask/tests/ci.rs
@@ -44,13 +44,13 @@ fn build(package: &str, target: &str, features: &[&str]) {
#[rustfmt::skip]
static PACKAGE_FEATURES: &[(&str, &[&str], &[&str])] = &[
- ("cortex-m", ALL_TARGETS, &["inline-asm", "cm7-r0p1"]), // no `linker-plugin-lto` since it's experimental
+ ("cortex-m", ALL_TARGETS, &["inline-asm", "cm7-r0p1", "critical-section-single-core"]), // no `linker-plugin-lto` since it's experimental
("cortex-m-semihosting", ALL_TARGETS, &["inline-asm", "no-semihosting", "jlink-quirks"]),
("panic-semihosting", ALL_TARGETS, &["inline-asm", "exit", "jlink-quirks"]),
("panic-itm", NON_BASE_TARGETS, &[]),
];
-fn check_crates_build(is_nightly: bool) {
+fn check_crates_build(is_nightly: bool, is_msrv: bool) {
// Build all crates for each supported target.
for (package, targets, all_features) in PACKAGE_FEATURES {
for target in *targets {
@@ -58,6 +58,8 @@ fn check_crates_build(is_nightly: bool) {
// Relies on all crates in this repo to use the same convention.
let should_use_feature = |feat: &str| {
match feat {
+ // critical-section doesn't build in 1.38 due to using `#[doc(include_str!(..))]`
+ "critical-section-single-core" => !is_msrv,
// This is nightly-only, so don't use it on stable.
"inline-asm" => is_nightly,
// This only affects thumbv7em targets.
@@ -103,8 +105,9 @@ fn main() {
let output = Command::new("rustc").arg("-V").output().unwrap();
let is_nightly = str::from_utf8(&output.stdout).unwrap().contains("nightly");
+ let is_msrv = str::from_utf8(&output.stdout).unwrap().contains("1.38");
- check_crates_build(is_nightly);
+ check_crates_build(is_nightly, is_msrv);
// Check host-side applications of the crate.
check_host_side();