Skip to content

Commit 9e8c8e7

Browse files
committed
Add implementation for critical-section 1.0.
1 parent e0bfe3a commit 9e8c8e7

File tree

7 files changed

+44
-4
lines changed

7 files changed

+44
-4
lines changed

.github/workflows/ci.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@ jobs:
1313
matrix:
1414
# All generated code should be running on stable now
1515
rust: [stable]
16+
features: ["", "critical-section-single-core"]
1617

1718
include:
1819
# Test MSRV
1920
- rust: 1.38.0
21+
features: ""
2022

2123
# Test nightly but don't fail
2224
- rust: nightly
25+
features: ""
26+
experimental: true
27+
- rust: nightly
28+
features: "critical-section-single-core"
2329
experimental: true
2430
steps:
2531
- uses: actions/checkout@v2
@@ -29,6 +35,6 @@ jobs:
2935
toolchain: ${{ matrix.rust }}
3036
override: true
3137
- name: Run tests
32-
run: cargo test --all
38+
run: cargo test --all --features "${{ matrix.features }}"
3339

3440
# FIXME: test on macOS and Windows

.github/workflows/clippy.yml

+1
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ jobs:
2323
- uses: actions-rs/clippy-check@v1
2424
with:
2525
token: ${{ secrets.GITHUB_TOKEN }}
26+
args: --features critical-section-single-core

CHANGELOG.md

+2
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+
- 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)
11+
1012
## [v0.7.5] - 2022-05-15
1113

1214
### Deprecated

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ links = "cortex-m" # prevent multiple versions of this crate to be linked toget
1717

1818
[dependencies]
1919
bare-metal = { version = "0.2.4", features = ["const-fn"] }
20+
critical-section = { version = "1.0.0", optional = true }
2021
volatile-register = "0.2.0"
2122
bitfield = "0.13.2"
2223
embedded-hal = "0.2.4"
@@ -32,6 +33,7 @@ cm7-r0p1 = ["cm7"]
3233
inline-asm = []
3334
linker-plugin-lto = []
3435
std = []
36+
critical-section-single-core = ["critical-section/restore-state-bool"]
3537

3638
[workspace]
3739
members = ["xtask", "cortex-m-semihosting", "panic-semihosting", "panic-itm"]

src/critical_section.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#[cfg(all(cortex_m, feature = "critical-section-single-core"))]
2+
mod single_core_critical_section {
3+
use critical_section::{set_impl, Impl, RawRestoreState};
4+
5+
use crate::interrupt;
6+
use crate::register::primask;
7+
8+
struct SingleCoreCriticalSection;
9+
set_impl!(SingleCoreCriticalSection);
10+
11+
unsafe impl Impl for SingleCoreCriticalSection {
12+
unsafe fn acquire() -> RawRestoreState {
13+
let was_active = primask::read().is_active();
14+
interrupt::disable();
15+
was_active
16+
}
17+
18+
unsafe fn release(was_active: RawRestoreState) {
19+
// Only re-enable interrupts if they were enabled before the critical section.
20+
if was_active {
21+
interrupt::enable()
22+
}
23+
}
24+
}
25+
}

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ mod macros;
9090
pub mod asm;
9191
#[cfg(armv8m)]
9292
pub mod cmse;
93+
mod critical_section;
9394
pub mod delay;
9495
pub mod interrupt;
9596
#[cfg(all(not(armv6m), not(armv8m_base)))]

xtask/tests/ci.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,22 @@ fn build(package: &str, target: &str, features: &[&str]) {
4444

4545
#[rustfmt::skip]
4646
static PACKAGE_FEATURES: &[(&str, &[&str], &[&str])] = &[
47-
("cortex-m", ALL_TARGETS, &["inline-asm", "cm7-r0p1"]), // no `linker-plugin-lto` since it's experimental
47+
("cortex-m", ALL_TARGETS, &["inline-asm", "cm7-r0p1", "critical-section-single-core"]), // no `linker-plugin-lto` since it's experimental
4848
("cortex-m-semihosting", ALL_TARGETS, &["inline-asm", "no-semihosting", "jlink-quirks"]),
4949
("panic-semihosting", ALL_TARGETS, &["inline-asm", "exit", "jlink-quirks"]),
5050
("panic-itm", NON_BASE_TARGETS, &[]),
5151
];
5252

53-
fn check_crates_build(is_nightly: bool) {
53+
fn check_crates_build(is_nightly: bool, is_msrv: bool) {
5454
// Build all crates for each supported target.
5555
for (package, targets, all_features) in PACKAGE_FEATURES {
5656
for target in *targets {
5757
// Filters crate features, keeping only those that are supported.
5858
// Relies on all crates in this repo to use the same convention.
5959
let should_use_feature = |feat: &str| {
6060
match feat {
61+
// critical-section doesn't build in 1.38 due to using `#[doc(include_str!(..))]`
62+
"critical-section-single-core" => !is_msrv,
6163
// This is nightly-only, so don't use it on stable.
6264
"inline-asm" => is_nightly,
6365
// This only affects thumbv7em targets.
@@ -103,8 +105,9 @@ fn main() {
103105

104106
let output = Command::new("rustc").arg("-V").output().unwrap();
105107
let is_nightly = str::from_utf8(&output.stdout).unwrap().contains("nightly");
108+
let is_msrv = str::from_utf8(&output.stdout).unwrap().contains("1.38");
106109

107-
check_crates_build(is_nightly);
110+
check_crates_build(is_nightly, is_msrv);
108111

109112
// Check host-side applications of the crate.
110113
check_host_side();

0 commit comments

Comments
 (0)