diff --git a/Cargo.toml b/Cargo.toml index 096b24a..d28ed89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,5 +29,19 @@ default-features = false version = "0.8.11" features = ["const_mut_refs"] +[dependencies.critical-section] +version = "0.2.7" +optional = true + +[dependencies.embassy] +version = "0.1.0" +optional = true + +[features] +nrf-softdevice = ["dep:critical-section", "dep:embassy"] + [dev-dependencies] cortex-m-rt = "0.6.12" + +# [patch.crates-io] +# embassy = { git = "https://github.com/embassy-rs/embassy" } diff --git a/README.md b/README.md index 76b8225..ae60455 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ This project is developed and maintained by the [Cortex-M team][team]. ## [Documentation](https://docs.rs/alloc-cortex-m) +## Features + +The `nrf-softdevice` feature replaces `cortex_m::interrupt::free()` with +`critical_section::with()` when block interrupts. + ## [Change log](CHANGELOG.md) ## License diff --git a/src/lib.rs b/src/lib.rs index 66f425d..901009c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,9 +12,34 @@ use core::alloc::{GlobalAlloc, Layout}; use core::cell::RefCell; use core::ptr::{self, NonNull}; -use cortex_m::interrupt::Mutex; +#[cfg(not(feature = "nrf-softdevice"))] +use cortex_m::interrupt::{ + Mutex, + CriticalSection, +}; +#[cfg(feature = "nrf-softdevice")] +use { + critical_section::CriticalSection, + embassy::blocking_mutex::CriticalSectionMutex as Mutex, +}; use linked_list_allocator::Heap; +#[cfg(not(feature = "nrf-softdevice"))] +#[inline] +fn block_interrupts(f: F) -> R + where F: FnOnce(&CriticalSection) -> R +{ + cortex_m::interrupt::free(f) +} + +#[cfg(feature = "nrf-softdevice")] +#[inline] +fn block_interrupts(f: F) -> R + where F: FnOnce(CriticalSection) -> R +{ + critical_section::with(f) +} + pub struct CortexMHeap { heap: Mutex>, } @@ -24,12 +49,20 @@ impl CortexMHeap { /// /// You must initialize this heap using the /// [`init`](struct.CortexMHeap.html#method.init) method before using the allocator. + #[cfg(not(feature = "nrf-softdevice"))] pub const fn empty() -> CortexMHeap { CortexMHeap { heap: Mutex::new(RefCell::new(Heap::empty())), } } + #[cfg(feature = "nrf-softdevice")] + pub fn empty() -> CortexMHeap { + CortexMHeap { + heap: Mutex::new(RefCell::new(Heap::empty())), + } + } + /// Initializes the heap /// /// This function must be called BEFORE you run any code that makes use of the @@ -54,25 +87,25 @@ impl CortexMHeap { /// - This function must be called exactly ONCE. /// - `size > 0` pub unsafe fn init(&self, start_addr: usize, size: usize) { - cortex_m::interrupt::free(|cs| { + block_interrupts(|cs| { self.heap.borrow(cs).borrow_mut().init(start_addr, size); }); } /// Returns an estimate of the amount of bytes in use. pub fn used(&self) -> usize { - cortex_m::interrupt::free(|cs| self.heap.borrow(cs).borrow_mut().used()) + block_interrupts(|cs| self.heap.borrow(cs).borrow_mut().used()) } /// Returns an estimate of the amount of bytes available. pub fn free(&self) -> usize { - cortex_m::interrupt::free(|cs| self.heap.borrow(cs).borrow_mut().free()) + block_interrupts(|cs| self.heap.borrow(cs).borrow_mut().free()) } } unsafe impl GlobalAlloc for CortexMHeap { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - cortex_m::interrupt::free(|cs| { + block_interrupts(|cs| { self.heap .borrow(cs) .borrow_mut() @@ -83,7 +116,7 @@ unsafe impl GlobalAlloc for CortexMHeap { } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - cortex_m::interrupt::free(|cs| { + block_interrupts(|cs| { self.heap .borrow(cs) .borrow_mut()