Merge pull request 'sequence counter improvements' (#140) from seq-counter-improvements into main

Reviewed-on: #140
This commit was merged in pull request #140.
This commit is contained in:
2025-09-09 10:27:08 +02:00
2 changed files with 35 additions and 22 deletions

View File

@@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `pus_version` API now returns a `Result<PusVersion, u8>` instead of a `PusVersion` to allow
modelling invalid version numbers properly.
- Renamed `CcsdsPacket::total_len` to `CcsdsPacket::packet_len`
- Renamed `SequenceCountProvider` to `SequenceCounter`
- Renamed `SeqCountProviderSimple` to `SequenceCounterSimple`
- Renamed `CcsdsSimpleSeqCountProvider` to `SequenceCounterCcsdsSimple`
- Renamed `SeqCountProviderSync` to `SequenceCounterSync`
## Removed
@@ -25,6 +29,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Added
- Added PUS A legacy support for telecommands inside the `ecss.tc_pus_a` module
- Added `SequenceCounter::increment_mut` and `SequenceCounter::get_and_increment_mut`
# [v0.15.0] 2025-07-18

View File

@@ -9,7 +9,7 @@ pub use stdmod::*;
/// The core functions are not mutable on purpose to allow easier usage with
/// static structs when using the interior mutability pattern. This can be achieved by using
/// [Cell], [core::cell::RefCell] or atomic types.
pub trait SequenceCountProvider {
pub trait SequenceCounter {
type Raw: Into<u64>;
const MAX_BIT_WIDTH: usize;
@@ -17,16 +17,25 @@ pub trait SequenceCountProvider {
fn increment(&self);
fn increment_mut(&mut self) {
self.increment();
}
fn get_and_increment(&self) -> Self::Raw {
let val = self.get();
self.increment();
val
}
fn get_and_increment_mut(&mut self) -> Self::Raw {
self.get_and_increment()
}
}
#[derive(Clone)]
pub struct SeqCountProviderSimple<T: Copy> {
pub struct SequenceCounterSimple<T: Copy> {
seq_count: Cell<T>,
// The maximum value
max_val: T,
}
@@ -34,7 +43,7 @@ macro_rules! impl_for_primitives {
($($ty: ident,)+) => {
$(
paste! {
impl SeqCountProviderSimple<$ty> {
impl SequenceCounterSimple<$ty> {
pub fn [<new_custom_max_val_ $ty>](max_val: $ty) -> Self {
Self {
seq_count: Cell::new(0),
@@ -49,13 +58,13 @@ macro_rules! impl_for_primitives {
}
}
impl Default for SeqCountProviderSimple<$ty> {
impl Default for SequenceCounterSimple<$ty> {
fn default() -> Self {
Self::[<new_ $ty>]()
}
}
impl SequenceCountProvider for SeqCountProviderSimple<$ty> {
impl SequenceCounter for SequenceCounterSimple<$ty> {
type Raw = $ty;
const MAX_BIT_WIDTH: usize = core::mem::size_of::<Self::Raw>() * 8;
@@ -87,19 +96,19 @@ impl_for_primitives!(u8, u16, u32, u64,);
/// This is a sequence count provider which wraps around at [MAX_SEQ_COUNT].
#[derive(Clone)]
pub struct CcsdsSimpleSeqCountProvider {
provider: SeqCountProviderSimple<u16>,
pub struct SequenceCounterCcsdsSimple {
provider: SequenceCounterSimple<u16>,
}
impl Default for CcsdsSimpleSeqCountProvider {
impl Default for SequenceCounterCcsdsSimple {
fn default() -> Self {
Self {
provider: SeqCountProviderSimple::new_custom_max_val_u16(MAX_SEQ_COUNT),
provider: SequenceCounterSimple::new_custom_max_val_u16(MAX_SEQ_COUNT),
}
}
}
impl SequenceCountProvider for CcsdsSimpleSeqCountProvider {
impl SequenceCounter for SequenceCounterCcsdsSimple {
type Raw = u16;
const MAX_BIT_WIDTH: usize = core::mem::size_of::<Self::Raw>() * 8;
delegate::delegate! {
@@ -124,12 +133,12 @@ pub mod stdmod {
/// that the API provided by this class will not panic und [Mutex] lock errors,
/// but it will yield 0 for the getter functions.
#[derive(Clone, Default)]
pub struct [<SeqCountProviderSync $ty:upper>] {
pub struct [<SequenceCounterSync $ty:upper>] {
seq_count: Arc<Mutex<$ty>>,
max_val: $ty
}
impl [<SeqCountProviderSync $ty:upper>] {
impl [<SequenceCounterSync $ty:upper>] {
pub fn new() -> Self {
Self::new_with_max_val($ty::MAX)
}
@@ -141,7 +150,7 @@ pub mod stdmod {
}
}
}
impl SequenceCountProvider for [<SeqCountProviderSync $ty:upper>] {
impl SequenceCounter for [<SequenceCounterSync $ty:upper>] {
type Raw = $ty;
const MAX_BIT_WIDTH: usize = core::mem::size_of::<Self::Raw>() * 8;
@@ -180,14 +189,13 @@ pub mod stdmod {
#[cfg(test)]
mod tests {
use crate::seq_count::{
CcsdsSimpleSeqCountProvider, SeqCountProviderSimple, SeqCountProviderSyncU8,
SequenceCountProvider,
SequenceCounter, SequenceCounterCcsdsSimple, SequenceCounterSimple, SequenceCounterSyncU8,
};
use crate::MAX_SEQ_COUNT;
#[test]
fn test_u8_counter() {
let u8_counter = SeqCountProviderSimple::<u8>::default();
let u8_counter = SequenceCounterSimple::<u8>::default();
assert_eq!(u8_counter.get(), 0);
assert_eq!(u8_counter.get_and_increment(), 0);
assert_eq!(u8_counter.get_and_increment(), 1);
@@ -196,7 +204,7 @@ mod tests {
#[test]
fn test_u8_counter_overflow() {
let u8_counter = SeqCountProviderSimple::new_u8();
let u8_counter = SequenceCounterSimple::new_u8();
for _ in 0..256 {
u8_counter.increment();
}
@@ -205,7 +213,7 @@ mod tests {
#[test]
fn test_ccsds_counter() {
let ccsds_counter = CcsdsSimpleSeqCountProvider::default();
let ccsds_counter = SequenceCounterCcsdsSimple::default();
assert_eq!(ccsds_counter.get(), 0);
assert_eq!(ccsds_counter.get_and_increment(), 0);
assert_eq!(ccsds_counter.get_and_increment(), 1);
@@ -214,7 +222,7 @@ mod tests {
#[test]
fn test_ccsds_counter_overflow() {
let ccsds_counter = CcsdsSimpleSeqCountProvider::default();
let ccsds_counter = SequenceCounterCcsdsSimple::default();
for _ in 0..MAX_SEQ_COUNT + 1 {
ccsds_counter.increment();
}
@@ -223,7 +231,7 @@ mod tests {
#[test]
fn test_atomic_ref_counters() {
let sync_u8_counter = SeqCountProviderSyncU8::new();
let sync_u8_counter = SequenceCounterSyncU8::new();
assert_eq!(sync_u8_counter.get(), 0);
assert_eq!(sync_u8_counter.get_and_increment(), 0);
assert_eq!(sync_u8_counter.get_and_increment(), 1);
@@ -232,7 +240,7 @@ mod tests {
#[test]
fn test_atomic_ref_counters_overflow() {
let sync_u8_counter = SeqCountProviderSyncU8::new();
let sync_u8_counter = SequenceCounterSyncU8::new();
for _ in 0..u8::MAX as u16 + 1 {
sync_u8_counter.increment();
}
@@ -241,7 +249,7 @@ mod tests {
#[test]
fn test_atomic_ref_counters_overflow_custom_max_val() {
let sync_u8_counter = SeqCountProviderSyncU8::new_with_max_val(128);
let sync_u8_counter = SequenceCounterSyncU8::new_with_max_val(128);
for _ in 0..129 {
sync_u8_counter.increment();
}