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

Add implementation for critical-section 1.0, for cortex-m v0.7.x #448

Merged
merged 1 commit into from Aug 11, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/ci.yml
Expand Up @@ -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
Expand All @@ -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
1 change: 1 addition & 0 deletions .github/workflows/clippy.yml
Expand Up @@ -23,3 +23,4 @@ jobs:
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --features critical-section-single-core
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Expand Up @@ -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"
Expand All @@ -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"]
Expand Down
25 changes: 25 additions & 0 deletions 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()
}
}
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Expand Up @@ -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)))]
Expand Down
9 changes: 6 additions & 3 deletions xtask/tests/ci.rs
Expand Up @@ -44,20 +44,22 @@ 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 {
// Filters crate features, keeping only those that are supported.
// 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.
Expand Down Expand Up @@ -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();
Expand Down