Compare commits

..

1 Commits

Author SHA1 Message Date
e238b5d377 Mode Tree Feature Update 2025-02-07 15:16:43 +01:00
4 changed files with 163 additions and 78 deletions

View File

@ -631,7 +631,6 @@ dependencies = [
"satrs-shared",
"smallvec",
"spacepackets",
"static_cell",
"thiserror",
]
@ -721,15 +720,6 @@ 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"

View File

@ -3,6 +3,7 @@
extern crate alloc;
use rtic::app;
use rtic_monotonics::fugit::TimerInstantU32;
use rtic_monotonics::systick::prelude::*;
use satrs::pool::{PoolAddr, PoolProvider, StaticHeaplessMemoryPool};
use satrs::static_subpool;
@ -73,7 +74,9 @@ impl Net {
let mut iface = Interface::new(
config,
&mut ethdev,
smoltcp::time::Instant::from_millis(Mono::now().duration_since_epoch().to_millis()),
smoltcp::time::Instant::from_millis(
(Mono::now() - TimerInstantU32::<1000>::from_ticks(0)).to_millis(),
),
);
// Create sockets
let dhcp_socket = dhcpv4::Socket::new();
@ -92,7 +95,7 @@ impl Net {
/// Polls on the ethernet interface. You should refer to the smoltcp
/// documentation for poll() to understand how to call poll efficiently
pub fn poll<'a>(&mut self, sockets: &'a mut SocketSet) -> bool {
let uptime = Mono::now().duration_since_epoch();
let uptime = Mono::now() - TimerInstantU32::<1000>::from_ticks(0);
let timestamp = smoltcp::time::Instant::from_millis(uptime.to_millis());
self.iface.poll(timestamp, &mut self.ethdev, sockets)

View File

@ -13,29 +13,79 @@ 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 }
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 }
[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
[dev-dependencies]
serde = "1"
@ -71,7 +121,7 @@ alloc = [
]
serde = ["dep:serde", "spacepackets/serde", "satrs-shared/serde"]
crossbeam = ["crossbeam-channel"]
heapless = ["dep:heapless", "static_cell"]
heapless = ["dep:heapless"]
defmt = ["dep:defmt", "spacepackets/defmt"]
test_util = []

View File

@ -378,27 +378,74 @@ 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<T> {
val: UnsafeCell<T>,
once: AtomicBool,
}
// `Sync` is required because `UnsafeCell` is not `Sync` by default.
// This is safe as long as access is manually synchronized.
unsafe impl<T> Sync for UnsafeCellBufWrapper<T> {}
impl<T: Sync> UnsafeCellBufWrapper<T> {
/// 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<T> UnsafeCellBufWrapper<T> {
/// 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: 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]);
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]);
};
($pool_name: ident, $sizes_list_name: ident, $num_blocks: expr, $block_size: expr, $meta_data: meta) => {
#[$meta_data]
static $pool_name: static_cell::ConstStaticCell<[u8; $num_blocks * $block_size]> =
static_cell::ConstStaticCell::new([0; $num_blocks * $block_size]);
static $pool_name: $crate::pool::UnsafeCellBufWrapper<[u8; $num_blocks * $block_size]> =
$crate::pool::UnsafeCellBufWrapper::new([0; $num_blocks * $block_size]);
#[$meta_data]
static $sizes_list_name: static_cell::ConstStaticCell<[usize; $num_blocks]> =
static_cell::ConstStaticCell::new([$crate::pool::STORE_FREE; $num_blocks]);
static $sizes_list_name: $crate::pool::UnsafeCellBufWrapper<[usize; $num_blocks]> =
$crate::pool::UnsafeCellBufWrapper::new([$crate::pool::STORE_FREE; $num_blocks]);
};
}
@ -435,14 +482,14 @@ pub mod heapless_mod {
///
/// let mut mem_pool: StaticHeaplessMemoryPool<2> = StaticHeaplessMemoryPool::new(true);
/// mem_pool.grow(
/// SUBPOOL_SMALL.take(),
/// SUBPOOL_SMALL_SIZES.take(),
/// SUBPOOL_SMALL.get_mut().unwrap(),
/// SUBPOOL_SMALL_SIZES.get_mut().unwrap(),
/// SUBPOOL_SMALL_NUM_BLOCKS,
/// false
/// ).unwrap();
/// mem_pool.grow(
/// SUBPOOL_LARGE.take(),
/// SUBPOOL_LARGE_SIZES.take(),
/// SUBPOOL_LARGE.get_mut().unwrap(),
/// SUBPOOL_LARGE_SIZES.get_mut().unwrap(),
/// SUBPOOL_LARGE_NUM_BLOCKS,
/// false
/// ).unwrap();
@ -1593,11 +1640,9 @@ mod tests {
const SUBPOOL_1_BLOCK_SIZE: usize = 4;
const SUBPOOL_1_NUM_ELEMENTS: u16 = 4;
static SUBPOOL_1: static_cell::ConstStaticCell<
static SUBPOOL_1: UnsafeCellBufWrapper<
[u8; 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],
);
> = UnsafeCellBufWrapper::new([0; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE]);
static SUBPOOL_1_SIZES: Mutex<UnsafeCell<[usize; SUBPOOL_1_NUM_ELEMENTS as usize]>> =
Mutex::new(UnsafeCell::new(
@ -1606,14 +1651,11 @@ mod tests {
const SUBPOOL_2_NUM_ELEMENTS: u16 = 2;
const SUBPOOL_2_BLOCK_SIZE: usize = 8;
static SUBPOOL_2: static_cell::ConstStaticCell<
static SUBPOOL_2: UnsafeCellBufWrapper<
[u8; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE],
> = 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]);
> = 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]);
const SUBPOOL_3_NUM_ELEMENTS: u16 = 1;
const SUBPOOL_3_BLOCK_SIZE: usize = 16;
@ -1656,7 +1698,7 @@ mod tests {
StaticHeaplessMemoryPool::new(false);
assert!(heapless_pool
.grow(
SUBPOOL_1.take(),
SUBPOOL_1.get_mut().unwrap(),
unsafe { &mut *SUBPOOL_1_SIZES.lock().unwrap().get() },
SUBPOOL_1_NUM_ELEMENTS,
true
@ -1664,16 +1706,16 @@ mod tests {
.is_ok());
assert!(heapless_pool
.grow(
SUBPOOL_2.take(),
SUBPOOL_2_SIZES.take(),
SUBPOOL_2.get_mut().unwrap(),
SUBPOOL_2_SIZES.get_mut().unwrap(),
SUBPOOL_2_NUM_ELEMENTS,
true
)
.is_ok());
assert!(heapless_pool
.grow(
SUBPOOL_3.take(),
SUBPOOL_3_SIZES.take(),
SUBPOOL_3.get_mut().unwrap(),
SUBPOOL_3_SIZES.get_mut().unwrap(),
SUBPOOL_3_NUM_ELEMENTS,
true
)
@ -1795,16 +1837,16 @@ mod tests {
StaticHeaplessMemoryPool::new(true);
assert!(heapless_pool
.grow(
SUBPOOL_2.take(),
SUBPOOL_2_SIZES.take(),
SUBPOOL_2.get_mut().unwrap(),
SUBPOOL_2_SIZES.get_mut().unwrap(),
SUBPOOL_2_NUM_ELEMENTS,
true
)
.is_ok());
assert!(heapless_pool
.grow(
SUBPOOL_4.take(),
SUBPOOL_4_SIZES.take(),
SUBPOOL_4.get_mut().unwrap(),
SUBPOOL_4_SIZES.get_mut().unwrap(),
SUBPOOL_4_NUM_ELEMENTS,
true
)
@ -1818,16 +1860,16 @@ mod tests {
StaticHeaplessMemoryPool::new(true);
assert!(heapless_pool
.grow(
SUBPOOL_5.take(),
SUBPOOL_5_SIZES.take(),
SUBPOOL_5.get_mut().unwrap(),
SUBPOOL_5_SIZES.get_mut().unwrap(),
SUBPOOL_5_NUM_ELEMENTS,
true
)
.is_ok());
assert!(heapless_pool
.grow(
SUBPOOL_3.take(),
SUBPOOL_3_SIZES.take(),
SUBPOOL_3.get_mut().unwrap(),
SUBPOOL_3_SIZES.get_mut().unwrap(),
SUBPOOL_3_NUM_ELEMENTS,
true
)
@ -1841,24 +1883,24 @@ mod tests {
StaticHeaplessMemoryPool::new(true);
assert!(heapless_pool
.grow(
SUBPOOL_5.take(),
SUBPOOL_5_SIZES.take(),
SUBPOOL_5.get_mut().unwrap(),
SUBPOOL_5_SIZES.get_mut().unwrap(),
SUBPOOL_5_NUM_ELEMENTS,
true
)
.is_ok());
assert!(heapless_pool
.grow(
SUBPOOL_6.take(),
SUBPOOL_6_SIZES.take(),
SUBPOOL_6.get_mut().unwrap(),
SUBPOOL_6_SIZES.get_mut().unwrap(),
SUBPOOL_6_NUM_ELEMENTS,
true
)
.is_ok());
assert!(heapless_pool
.grow(
SUBPOOL_3.take(),
SUBPOOL_3_SIZES.take(),
SUBPOOL_3.get_mut().unwrap(),
SUBPOOL_3_SIZES.get_mut().unwrap(),
SUBPOOL_3_NUM_ELEMENTS,
true
)
@ -1872,24 +1914,24 @@ mod tests {
StaticHeaplessMemoryPool::new(true);
assert!(heapless_pool
.grow(
SUBPOOL_5.take(),
SUBPOOL_5_SIZES.take(),
SUBPOOL_5.get_mut().unwrap(),
SUBPOOL_5_SIZES.get_mut().unwrap(),
SUBPOOL_5_NUM_ELEMENTS,
true
)
.is_ok());
assert!(heapless_pool
.grow(
SUBPOOL_6.take(),
SUBPOOL_6_SIZES.take(),
SUBPOOL_6.get_mut().unwrap(),
SUBPOOL_6_SIZES.get_mut().unwrap(),
SUBPOOL_6_NUM_ELEMENTS,
true
)
.is_ok());
assert!(heapless_pool
.grow(
SUBPOOL_3.take(),
SUBPOOL_3_SIZES.take(),
SUBPOOL_3.get_mut().unwrap(),
SUBPOOL_3_SIZES.get_mut().unwrap(),
SUBPOOL_3_NUM_ELEMENTS,
true
)