Skip to content

Commit 65db20e

Browse files
committed
Add implementation for critical-section 1.0 for single-hart chips.
1 parent bb3945d commit 65db20e

File tree

5 files changed

+54
-1
lines changed

5 files changed

+54
-1
lines changed

.github/workflows/ci.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ jobs:
3838
run: cargo check --target riscv64imac-unknown-none-elf
3939
- name: Run CI script for riscv64gc-unknown-none-elf under ${{ matrix.rust }}
4040
run: cargo check --target riscv64gc-unknown-none-elf
41+
- name: Run CI script for x86_64-unknown-linux-gnu under ${{ matrix.rust }} with critical-section-single-hart
42+
run: cargo check --target x86_64-unknown-linux-gnu --features critical-section-single-hart
43+
- name: Run CI script for riscv32imac-unknown-none-elf under ${{ matrix.rust }} with critical-section-single-hart
44+
run: cargo check --target riscv32imac-unknown-none-elf --features critical-section-single-hart
45+
- name: Run CI script for riscv64imac-unknown-none-elf under ${{ matrix.rust }} with critical-section-single-hart
46+
run: cargo check --target riscv64imac-unknown-none-elf --features critical-section-single-hart
47+
- name: Run CI script for riscv64gc-unknown-none-elf under ${{ matrix.rust }} with critical-section-single-hart
48+
run: cargo check --target riscv64gc-unknown-none-elf --features critical-section-single-hart
4149

4250
# On macOS and Windows, we at least make sure that the crate builds and links.
4351
build-other:
@@ -56,4 +64,4 @@ jobs:
5664
toolchain: stable
5765
override: true
5866
- name: Build crate for host OS
59-
run: cargo build
67+
run: cargo build --features critical-section-single-hart

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Added `critical-section-single-hart` feature which provides an implementation for the `critical_section` crate for single-hart systems, based on disabling all interrupts.
13+
1014
## [v0.9.0] - 2022-10-06
1115

1216
### Fixed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ targets = [
1717
"riscv64imac-unknown-none-elf", "riscv64gc-unknown-none-elf",
1818
]
1919

20+
[features]
21+
critical-section-single-hart = ["critical-section/restore-state-bool"]
22+
2023
[dependencies]
2124
bare-metal = "1.0.0"
2225
bit_field = "0.10.0"
26+
critical-section = "1.1.0"
2327
embedded-hal = "0.2.6"

src/critical_section.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use critical_section::{set_impl, Impl, RawRestoreState};
2+
3+
use crate::interrupt;
4+
use crate::register::mstatus;
5+
6+
struct SingleHartCriticalSection;
7+
set_impl!(SingleHartCriticalSection);
8+
9+
unsafe impl Impl for SingleHartCriticalSection {
10+
unsafe fn acquire() -> RawRestoreState {
11+
let was_active = mstatus::read().mie();
12+
interrupt::disable();
13+
was_active
14+
}
15+
16+
unsafe fn release(was_active: RawRestoreState) {
17+
// Only re-enable interrupts if they were enabled before the critical section.
18+
if was_active {
19+
interrupt::enable()
20+
}
21+
}
22+
}

src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@
1212
//! - Access to core registers like `mstatus` or `mcause`.
1313
//! - Interrupt manipulation mechanisms.
1414
//! - Wrappers around assembly instructions like `WFI`.
15+
//!
16+
//! # Optional features
17+
//!
18+
//! ## `critical-section-single-hart`
19+
//!
20+
//! This feature enables a [`critical-section`](https://github.com/rust-embedded/critical-section)
21+
//! implementation suitable for single-hart targets, based on disabling interrupts globally.
22+
//!
23+
//! It is **unsound** to enable it on multi-hart targets,
24+
//! and may cause functional problems in systems where some interrupts must be not be disabled
25+
//! or critical sections are managed as part of an RTOS. In these cases, you should use
26+
//! a target-specific implementation instead, typically provided by a HAL or RTOS crate.
1527
1628
#![no_std]
1729

@@ -22,3 +34,6 @@ pub mod register;
2234

2335
#[macro_use]
2436
mod macros;
37+
38+
#[cfg(all(riscv, feature = "critical-section-single-hart"))]
39+
mod critical_section;

0 commit comments

Comments
 (0)