diff --git a/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock b/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock index 38152e6..aa4b9fb 100644 --- a/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock +++ b/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock @@ -631,6 +631,7 @@ dependencies = [ "satrs-shared", "smallvec", "spacepackets", + "static_cell", "thiserror", ] @@ -720,6 +721,15 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_cell" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" +dependencies = [ + "portable-atomic", +] + [[package]] name = "stm32h7" version = "0.15.1" diff --git a/satrs/Cargo.toml b/satrs/Cargo.toml index c333c71..13ee3b1 100644 --- a/satrs/Cargo.toml +++ b/satrs/Cargo.toml @@ -13,79 +13,29 @@ keywords = ["no-std", "space", "aerospace"] categories = ["aerospace", "aerospace::space-protocols", "no-std", "hardware-support", "embedded"] [dependencies] +satrs-shared = ">=0.1.3, <=0.2" delegate = ">0.7, <=0.13" paste = "1" derive-new = ">=0.6, <=0.7" smallvec = "1" crc = "3" +num_enum = { version = ">0.5, <=0.7", default-features = false } +spacepackets = { version = "0.13", default-features = false } +cobs = { version = "0.3", default-features = false } +num-traits = { version = "0.2", default-features = false } +thiserror = { version = "2", default-features = false } -[dependencies.satrs-shared] -version = ">=0.1.3, <=0.2" - -[dependencies.num_enum] -version = ">0.5, <=0.7" -default-features = false - -[dependencies.spacepackets] -version = "0.13" -default-features = false - -[dependencies.cobs] -version = "0.3" -default-features = false - -[dependencies.num-traits] -version = "0.2" -default-features = false - -[dependencies.dyn-clone] -version = "1" -optional = true - -[dependencies.hashbrown] -version = ">=0.14, <=0.15" -optional = true - -[dependencies.heapless] -version = "0.8" -optional = true - -[dependencies.downcast-rs] -version = "2" -default-features = false -optional = true - -[dependencies.bus] -version = "2.2" -optional = true - -[dependencies.crossbeam-channel] -version= "0.5" -default-features = false -optional = true - -[dependencies.thiserror] -version = "2" -default-features = false - -[dependencies.serde] -version = "1" -default-features = false -optional = true - -[dependencies.socket2] -version = "0.5.4" -features = ["all"] -optional = true - -[dependencies.mio] -version = "1" -features = ["os-poll", "net"] -optional = true - -[dependencies.defmt] -version = "0.3" -optional = true +hashbrown = { version = ">=0.14, <=0.15", optional = true } +static_cell = { version = "2", optional = true } +dyn-clone = { version = "1", optional = true } +heapless = { version = "0.8", optional = true } +downcast-rs = { version = "2", default-features = false, optional = true } +bus = { version = "2.2", optional = true } +crossbeam-channel = { version = "0.5", default-features = false, optional = true } +serde = { version = "1", default-features = false, optional = true } +socket2 = { version = "0.5", features = ["all"], optional = true } +mio = { version = "1", features = ["os-poll", "net"], optional = true } +defmt = { version = "0.3", optional = true } [dev-dependencies] serde = "1" @@ -121,7 +71,7 @@ alloc = [ ] serde = ["dep:serde", "spacepackets/serde", "satrs-shared/serde"] crossbeam = ["crossbeam-channel"] -heapless = ["dep:heapless"] +heapless = ["dep:heapless", "static_cell"] defmt = ["dep:defmt", "spacepackets/defmt"] test_util = [] diff --git a/satrs/src/pool.rs b/satrs/src/pool.rs index 86e4b75..1b40191 100644 --- a/satrs/src/pool.rs +++ b/satrs/src/pool.rs @@ -378,74 +378,27 @@ pub struct SubpoolConfig { #[cfg(feature = "heapless")] pub mod heapless_mod { use super::*; - use core::cell::UnsafeCell; - use core::sync::atomic::{AtomicBool, Ordering}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct PoolIsFull; - #[derive(Debug)] - pub struct UnsafeCellBufWrapper { - val: UnsafeCell, - once: AtomicBool, - } - // `Sync` is required because `UnsafeCell` is not `Sync` by default. - // This is safe as long as access is manually synchronized. - unsafe impl Sync for UnsafeCellBufWrapper {} - - impl UnsafeCellBufWrapper { - /// Creates a new wrapper around an arbitrary value which should be [Sync]. - pub const fn new(v: T) -> Self { - unsafe { Self::new_unchecked(v) } - } - } - - impl UnsafeCellBufWrapper { - /// Creates a new wrapper around a buffer. - /// - /// # Safety - /// - /// Currently, the [Sync] trait is implemented for all T and ignores the usual [Sync] bound - /// on T. This API should only be called for declaring byte buffers statically or if T is - /// known to be [Sync]. You can use [new] to let the compiler do the [Sync] check. - pub const unsafe fn new_unchecked(v: T) -> Self { - Self { - val: UnsafeCell::new(v), - once: AtomicBool::new(false), - } - } - - /// Retrieves a mutable reference to the internal value once. - /// - /// All subsequent calls return None. - pub fn get_mut(&self) -> Option<&mut T> { - if self.once.load(Ordering::Relaxed) { - return None; - } - // Safety: We ensure that this is only done once with an [AtomicBool]. - let mut_ref = unsafe { &mut *self.val.get() }; - self.once.store(true, Ordering::Relaxed); - Some(mut_ref) - } - } - /// Helper macro to generate static buffers for the [crate::pool::StaticHeaplessMemoryPool]. #[macro_export] macro_rules! static_subpool { ($pool_name: ident, $sizes_list_name: ident, $num_blocks: expr, $block_size: expr) => { - static $pool_name: $crate::pool::UnsafeCellBufWrapper<[u8; $num_blocks * $block_size]> = - $crate::pool::UnsafeCellBufWrapper::new([0; $num_blocks * $block_size]); - static $sizes_list_name: $crate::pool::UnsafeCellBufWrapper<[usize; $num_blocks]> = - $crate::pool::UnsafeCellBufWrapper::new([$crate::pool::STORE_FREE; $num_blocks]); + static $pool_name: static_cell::ConstStaticCell<[u8; $num_blocks * $block_size]> = + static_cell::ConstStaticCell::new([0; $num_blocks * $block_size]); + static $sizes_list_name: static_cell::ConstStaticCell<[usize; $num_blocks]> = + static_cell::ConstStaticCell::new([$crate::pool::STORE_FREE; $num_blocks]); }; ($pool_name: ident, $sizes_list_name: ident, $num_blocks: expr, $block_size: expr, $meta_data: meta) => { #[$meta_data] - static $pool_name: $crate::pool::UnsafeCellBufWrapper<[u8; $num_blocks * $block_size]> = - $crate::pool::UnsafeCellBufWrapper::new([0; $num_blocks * $block_size]); + static $pool_name: static_cell::ConstStaticCell<[u8; $num_blocks * $block_size]> = + static_cell::ConstStaticCell::new([0; $num_blocks * $block_size]); #[$meta_data] - static $sizes_list_name: $crate::pool::UnsafeCellBufWrapper<[usize; $num_blocks]> = - $crate::pool::UnsafeCellBufWrapper::new([$crate::pool::STORE_FREE; $num_blocks]); + static $sizes_list_name: static_cell::ConstStaticCell<[usize; $num_blocks]> = + static_cell::ConstStaticCell::new([$crate::pool::STORE_FREE; $num_blocks]); }; } @@ -482,14 +435,14 @@ pub mod heapless_mod { /// /// let mut mem_pool: StaticHeaplessMemoryPool<2> = StaticHeaplessMemoryPool::new(true); /// mem_pool.grow( - /// SUBPOOL_SMALL.get_mut().unwrap(), - /// SUBPOOL_SMALL_SIZES.get_mut().unwrap(), + /// SUBPOOL_SMALL.take(), + /// SUBPOOL_SMALL_SIZES.take(), /// SUBPOOL_SMALL_NUM_BLOCKS, /// false /// ).unwrap(); /// mem_pool.grow( - /// SUBPOOL_LARGE.get_mut().unwrap(), - /// SUBPOOL_LARGE_SIZES.get_mut().unwrap(), + /// SUBPOOL_LARGE.take(), + /// SUBPOOL_LARGE_SIZES.take(), /// SUBPOOL_LARGE_NUM_BLOCKS, /// false /// ).unwrap(); @@ -1639,9 +1592,11 @@ mod tests { const SUBPOOL_1_BLOCK_SIZE: usize = 4; const SUBPOOL_1_NUM_ELEMENTS: u16 = 4; - static SUBPOOL_1: UnsafeCellBufWrapper< + static SUBPOOL_1: static_cell::ConstStaticCell< [u8; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE], - > = UnsafeCellBufWrapper::new([0; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE]); + > = static_cell::ConstStaticCell::new( + [0; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE], + ); static SUBPOOL_1_SIZES: Mutex> = Mutex::new(UnsafeCell::new( @@ -1650,11 +1605,14 @@ mod tests { const SUBPOOL_2_NUM_ELEMENTS: u16 = 2; const SUBPOOL_2_BLOCK_SIZE: usize = 8; - static SUBPOOL_2: UnsafeCellBufWrapper< + static SUBPOOL_2: static_cell::ConstStaticCell< [u8; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE], - > = UnsafeCellBufWrapper::new([0; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE]); - static SUBPOOL_2_SIZES: UnsafeCellBufWrapper<[usize; SUBPOOL_2_NUM_ELEMENTS as usize]> = - UnsafeCellBufWrapper::new([STORE_FREE; SUBPOOL_2_NUM_ELEMENTS as usize]); + > = static_cell::ConstStaticCell::new( + [0; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE], + ); + static SUBPOOL_2_SIZES: static_cell::ConstStaticCell< + [usize; SUBPOOL_2_NUM_ELEMENTS as usize], + > = static_cell::ConstStaticCell::new([STORE_FREE; SUBPOOL_2_NUM_ELEMENTS as usize]); const SUBPOOL_3_NUM_ELEMENTS: u16 = 1; const SUBPOOL_3_BLOCK_SIZE: usize = 16; @@ -1697,7 +1655,7 @@ mod tests { StaticHeaplessMemoryPool::new(false); assert!(heapless_pool .grow( - SUBPOOL_1.get_mut().unwrap(), + SUBPOOL_1.take(), unsafe { &mut *SUBPOOL_1_SIZES.lock().unwrap().get() }, SUBPOOL_1_NUM_ELEMENTS, true @@ -1705,16 +1663,16 @@ mod tests { .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_2.get_mut().unwrap(), - SUBPOOL_2_SIZES.get_mut().unwrap(), + SUBPOOL_2.take(), + SUBPOOL_2_SIZES.take(), SUBPOOL_2_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_3.get_mut().unwrap(), - SUBPOOL_3_SIZES.get_mut().unwrap(), + SUBPOOL_3.take(), + SUBPOOL_3_SIZES.take(), SUBPOOL_3_NUM_ELEMENTS, true ) @@ -1836,16 +1794,16 @@ mod tests { StaticHeaplessMemoryPool::new(true); assert!(heapless_pool .grow( - SUBPOOL_2.get_mut().unwrap(), - SUBPOOL_2_SIZES.get_mut().unwrap(), + SUBPOOL_2.take(), + SUBPOOL_2_SIZES.take(), SUBPOOL_2_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_4.get_mut().unwrap(), - SUBPOOL_4_SIZES.get_mut().unwrap(), + SUBPOOL_4.take(), + SUBPOOL_4_SIZES.take(), SUBPOOL_4_NUM_ELEMENTS, true ) @@ -1859,16 +1817,16 @@ mod tests { StaticHeaplessMemoryPool::new(true); assert!(heapless_pool .grow( - SUBPOOL_5.get_mut().unwrap(), - SUBPOOL_5_SIZES.get_mut().unwrap(), + SUBPOOL_5.take(), + SUBPOOL_5_SIZES.take(), SUBPOOL_5_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_3.get_mut().unwrap(), - SUBPOOL_3_SIZES.get_mut().unwrap(), + SUBPOOL_3.take(), + SUBPOOL_3_SIZES.take(), SUBPOOL_3_NUM_ELEMENTS, true ) @@ -1882,24 +1840,24 @@ mod tests { StaticHeaplessMemoryPool::new(true); assert!(heapless_pool .grow( - SUBPOOL_5.get_mut().unwrap(), - SUBPOOL_5_SIZES.get_mut().unwrap(), + SUBPOOL_5.take(), + SUBPOOL_5_SIZES.take(), SUBPOOL_5_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_6.get_mut().unwrap(), - SUBPOOL_6_SIZES.get_mut().unwrap(), + SUBPOOL_6.take(), + SUBPOOL_6_SIZES.take(), SUBPOOL_6_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_3.get_mut().unwrap(), - SUBPOOL_3_SIZES.get_mut().unwrap(), + SUBPOOL_3.take(), + SUBPOOL_3_SIZES.take(), SUBPOOL_3_NUM_ELEMENTS, true ) @@ -1913,24 +1871,24 @@ mod tests { StaticHeaplessMemoryPool::new(true); assert!(heapless_pool .grow( - SUBPOOL_5.get_mut().unwrap(), - SUBPOOL_5_SIZES.get_mut().unwrap(), + SUBPOOL_5.take(), + SUBPOOL_5_SIZES.take(), SUBPOOL_5_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_6.get_mut().unwrap(), - SUBPOOL_6_SIZES.get_mut().unwrap(), + SUBPOOL_6.take(), + SUBPOOL_6_SIZES.take(), SUBPOOL_6_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_3.get_mut().unwrap(), - SUBPOOL_3_SIZES.get_mut().unwrap(), + SUBPOOL_3.take(), + SUBPOOL_3_SIZES.take(), SUBPOOL_3_NUM_ELEMENTS, true )