From 2cbd48331ce1a38c5f09c3049d7b619202e71e6e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 9 Sep 2025 10:24:20 +0200 Subject: [PATCH] sequence counter improvements --- CHANGELOG.md | 5 +++++ src/seq_count.rs | 52 ++++++++++++++++++++++++++++-------------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9915792..64a2021 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `pus_version` API now returns a `Result` 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 diff --git a/src/seq_count.rs b/src/seq_count.rs index 7194c0d..ffe8e06 100644 --- a/src/seq_count.rs +++ b/src/seq_count.rs @@ -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; 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 { +pub struct SequenceCounterSimple { seq_count: Cell, + // 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 [](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::[]() } } - impl SequenceCountProvider for SeqCountProviderSimple<$ty> { + impl SequenceCounter for SequenceCounterSimple<$ty> { type Raw = $ty; const MAX_BIT_WIDTH: usize = core::mem::size_of::() * 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, +pub struct SequenceCounterCcsdsSimple { + provider: SequenceCounterSimple, } -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::() * 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 [] { + pub struct [] { seq_count: Arc>, max_val: $ty } - impl [] { + impl [] { pub fn new() -> Self { Self::new_with_max_val($ty::MAX) } @@ -141,7 +150,7 @@ pub mod stdmod { } } } - impl SequenceCountProvider for [] { + impl SequenceCounter for [] { type Raw = $ty; const MAX_BIT_WIDTH: usize = core::mem::size_of::() * 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::::default(); + let u8_counter = SequenceCounterSimple::::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(); }