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:
@@ -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
|
- `pus_version` API now returns a `Result<PusVersion, u8>` instead of a `PusVersion` to allow
|
||||||
modelling invalid version numbers properly.
|
modelling invalid version numbers properly.
|
||||||
- Renamed `CcsdsPacket::total_len` to `CcsdsPacket::packet_len`
|
- 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
|
## Removed
|
||||||
|
|
||||||
@@ -25,6 +29,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
## Added
|
## Added
|
||||||
|
|
||||||
- Added PUS A legacy support for telecommands inside the `ecss.tc_pus_a` module
|
- 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
|
# [v0.15.0] 2025-07-18
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pub use stdmod::*;
|
|||||||
/// The core functions are not mutable on purpose to allow easier usage with
|
/// 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
|
/// static structs when using the interior mutability pattern. This can be achieved by using
|
||||||
/// [Cell], [core::cell::RefCell] or atomic types.
|
/// [Cell], [core::cell::RefCell] or atomic types.
|
||||||
pub trait SequenceCountProvider {
|
pub trait SequenceCounter {
|
||||||
type Raw: Into<u64>;
|
type Raw: Into<u64>;
|
||||||
const MAX_BIT_WIDTH: usize;
|
const MAX_BIT_WIDTH: usize;
|
||||||
|
|
||||||
@@ -17,16 +17,25 @@ pub trait SequenceCountProvider {
|
|||||||
|
|
||||||
fn increment(&self);
|
fn increment(&self);
|
||||||
|
|
||||||
|
fn increment_mut(&mut self) {
|
||||||
|
self.increment();
|
||||||
|
}
|
||||||
|
|
||||||
fn get_and_increment(&self) -> Self::Raw {
|
fn get_and_increment(&self) -> Self::Raw {
|
||||||
let val = self.get();
|
let val = self.get();
|
||||||
self.increment();
|
self.increment();
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_and_increment_mut(&mut self) -> Self::Raw {
|
||||||
|
self.get_and_increment()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SeqCountProviderSimple<T: Copy> {
|
pub struct SequenceCounterSimple<T: Copy> {
|
||||||
seq_count: Cell<T>,
|
seq_count: Cell<T>,
|
||||||
|
// The maximum value
|
||||||
max_val: T,
|
max_val: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +43,7 @@ macro_rules! impl_for_primitives {
|
|||||||
($($ty: ident,)+) => {
|
($($ty: ident,)+) => {
|
||||||
$(
|
$(
|
||||||
paste! {
|
paste! {
|
||||||
impl SeqCountProviderSimple<$ty> {
|
impl SequenceCounterSimple<$ty> {
|
||||||
pub fn [<new_custom_max_val_ $ty>](max_val: $ty) -> Self {
|
pub fn [<new_custom_max_val_ $ty>](max_val: $ty) -> Self {
|
||||||
Self {
|
Self {
|
||||||
seq_count: Cell::new(0),
|
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 {
|
fn default() -> Self {
|
||||||
Self::[<new_ $ty>]()
|
Self::[<new_ $ty>]()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SequenceCountProvider for SeqCountProviderSimple<$ty> {
|
impl SequenceCounter for SequenceCounterSimple<$ty> {
|
||||||
type Raw = $ty;
|
type Raw = $ty;
|
||||||
const MAX_BIT_WIDTH: usize = core::mem::size_of::<Self::Raw>() * 8;
|
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].
|
/// This is a sequence count provider which wraps around at [MAX_SEQ_COUNT].
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CcsdsSimpleSeqCountProvider {
|
pub struct SequenceCounterCcsdsSimple {
|
||||||
provider: SeqCountProviderSimple<u16>,
|
provider: SequenceCounterSimple<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CcsdsSimpleSeqCountProvider {
|
impl Default for SequenceCounterCcsdsSimple {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
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;
|
type Raw = u16;
|
||||||
const MAX_BIT_WIDTH: usize = core::mem::size_of::<Self::Raw>() * 8;
|
const MAX_BIT_WIDTH: usize = core::mem::size_of::<Self::Raw>() * 8;
|
||||||
delegate::delegate! {
|
delegate::delegate! {
|
||||||
@@ -124,12 +133,12 @@ pub mod stdmod {
|
|||||||
/// that the API provided by this class will not panic und [Mutex] lock errors,
|
/// that the API provided by this class will not panic und [Mutex] lock errors,
|
||||||
/// but it will yield 0 for the getter functions.
|
/// but it will yield 0 for the getter functions.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct [<SeqCountProviderSync $ty:upper>] {
|
pub struct [<SequenceCounterSync $ty:upper>] {
|
||||||
seq_count: Arc<Mutex<$ty>>,
|
seq_count: Arc<Mutex<$ty>>,
|
||||||
max_val: $ty
|
max_val: $ty
|
||||||
}
|
}
|
||||||
|
|
||||||
impl [<SeqCountProviderSync $ty:upper>] {
|
impl [<SequenceCounterSync $ty:upper>] {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::new_with_max_val($ty::MAX)
|
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;
|
type Raw = $ty;
|
||||||
const MAX_BIT_WIDTH: usize = core::mem::size_of::<Self::Raw>() * 8;
|
const MAX_BIT_WIDTH: usize = core::mem::size_of::<Self::Raw>() * 8;
|
||||||
|
|
||||||
@@ -180,14 +189,13 @@ pub mod stdmod {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::seq_count::{
|
use crate::seq_count::{
|
||||||
CcsdsSimpleSeqCountProvider, SeqCountProviderSimple, SeqCountProviderSyncU8,
|
SequenceCounter, SequenceCounterCcsdsSimple, SequenceCounterSimple, SequenceCounterSyncU8,
|
||||||
SequenceCountProvider,
|
|
||||||
};
|
};
|
||||||
use crate::MAX_SEQ_COUNT;
|
use crate::MAX_SEQ_COUNT;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_u8_counter() {
|
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(), 0);
|
||||||
assert_eq!(u8_counter.get_and_increment(), 0);
|
assert_eq!(u8_counter.get_and_increment(), 0);
|
||||||
assert_eq!(u8_counter.get_and_increment(), 1);
|
assert_eq!(u8_counter.get_and_increment(), 1);
|
||||||
@@ -196,7 +204,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_u8_counter_overflow() {
|
fn test_u8_counter_overflow() {
|
||||||
let u8_counter = SeqCountProviderSimple::new_u8();
|
let u8_counter = SequenceCounterSimple::new_u8();
|
||||||
for _ in 0..256 {
|
for _ in 0..256 {
|
||||||
u8_counter.increment();
|
u8_counter.increment();
|
||||||
}
|
}
|
||||||
@@ -205,7 +213,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ccsds_counter() {
|
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(), 0);
|
||||||
assert_eq!(ccsds_counter.get_and_increment(), 0);
|
assert_eq!(ccsds_counter.get_and_increment(), 0);
|
||||||
assert_eq!(ccsds_counter.get_and_increment(), 1);
|
assert_eq!(ccsds_counter.get_and_increment(), 1);
|
||||||
@@ -214,7 +222,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ccsds_counter_overflow() {
|
fn test_ccsds_counter_overflow() {
|
||||||
let ccsds_counter = CcsdsSimpleSeqCountProvider::default();
|
let ccsds_counter = SequenceCounterCcsdsSimple::default();
|
||||||
for _ in 0..MAX_SEQ_COUNT + 1 {
|
for _ in 0..MAX_SEQ_COUNT + 1 {
|
||||||
ccsds_counter.increment();
|
ccsds_counter.increment();
|
||||||
}
|
}
|
||||||
@@ -223,7 +231,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_atomic_ref_counters() {
|
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(), 0);
|
||||||
assert_eq!(sync_u8_counter.get_and_increment(), 0);
|
assert_eq!(sync_u8_counter.get_and_increment(), 0);
|
||||||
assert_eq!(sync_u8_counter.get_and_increment(), 1);
|
assert_eq!(sync_u8_counter.get_and_increment(), 1);
|
||||||
@@ -232,7 +240,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_atomic_ref_counters_overflow() {
|
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 {
|
for _ in 0..u8::MAX as u16 + 1 {
|
||||||
sync_u8_counter.increment();
|
sync_u8_counter.increment();
|
||||||
}
|
}
|
||||||
@@ -241,7 +249,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_atomic_ref_counters_overflow_custom_max_val() {
|
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 {
|
for _ in 0..129 {
|
||||||
sync_u8_counter.increment();
|
sync_u8_counter.increment();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user