Skip to content

Commit 153f753

Browse files
committed
zephyr: Provide critical-section for Zephyr
Implement a general critical section handler, using spinlocks, for Rust users to be able to use the `critical-section` crate. This crate is used by other crates as well. Signed-off-by: David Brown <[email protected]>
1 parent c88376c commit 153f753

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

zephyr/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ zephyr-sys = { version = "3.7.0", path = "../zephyr-sys" }
1515
[dependencies.fugit]
1616
version = "0.3.7"
1717

18+
[dependencies.critical-section]
19+
version = "1.1.2"
20+
features = ["restore-state-u32"]
21+
1822
[dependencies.portable-atomic]
1923
version = "1.7.0"
2024
# We assume that the instances where portable atomic must provide its own implementation (target

zephyr/src/sys.rs

+32
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,35 @@ pub const K_FOREVER: k_timeout_t = k_timeout_t { ticks: -1 };
2626
/// Low-level Zephyr Constant. Calls using this value will not wait if the operation cannot be
2727
/// performed immediately.
2828
pub const K_NO_WAIT: k_timeout_t = k_timeout_t { ticks: 0 };
29+
30+
pub mod critical {
31+
//! Zephyr implementation of critical sections.
32+
//!
33+
//! Critical sections from Rust are handled with a single Zephyr spinlock. This doesn't allow
34+
//! any nesting, but neither does the `critical-section` crate.
35+
36+
use core::{ffi::c_int, ptr::addr_of_mut};
37+
38+
use critical_section::RawRestoreState;
39+
use zephyr_sys::{k_spinlock, k_spin_lock, k_spin_unlock, k_spinlock_key_t};
40+
41+
struct ZephyrCriticalSection;
42+
critical_section::set_impl!(ZephyrCriticalSection);
43+
44+
// The critical section shares a single spinlock.
45+
static mut LOCK: k_spinlock = unsafe { core::mem::zeroed() };
46+
47+
unsafe impl critical_section::Impl for ZephyrCriticalSection {
48+
unsafe fn acquire() -> RawRestoreState {
49+
let res = k_spin_lock(addr_of_mut!(LOCK));
50+
res.key as RawRestoreState
51+
}
52+
53+
unsafe fn release(token: RawRestoreState) {
54+
k_spin_unlock(addr_of_mut!(LOCK),
55+
k_spinlock_key_t {
56+
key: token as c_int,
57+
});
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)