Merge branch 'main' of https://egit.irs.uni-stuttgart.de/rust/spacepackets
All checks were successful
Rust/spacepackets/pipeline/head This commit looks good

This commit is contained in:
Robin Müller 2023-01-22 16:58:05 +01:00
commit b55fe9f443
6 changed files with 65 additions and 16 deletions

View File

@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased] # [unreleased]
# [v0.5.1] 2023-01-22
## Added ## Added
- `time::cds::TimeProvider` - `time::cds::TimeProvider`
@ -20,6 +22,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Add `Ord` and `PartialOrd` implementations. - Add `Ord` and `PartialOrd` implementations.
- Add `Add<Duration>` and `AddAssign<Duration>` implementations. - Add `Add<Duration>` and `AddAssign<Duration>` implementations.
## Fixed
- `time::cds::TimeProvider`: Fixed a bug where subsecond milliseconds were not accounted for
when the provider has no submillisecond precision.
# [v0.5.0] 2023-01-20 # [v0.5.0] 2023-01-20
The timestamp of `PusTm` is now optional. See Added and Changed section for details. The timestamp of `PusTm` is now optional. See Added and Changed section for details.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "spacepackets" name = "spacepackets"
version = "0.5.0" version = "0.5.1"
edition = "2021" edition = "2021"
rust-version = "1.60" rust-version = "1.60"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"] authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]

18
release_checklist.md Normal file
View File

@ -0,0 +1,18 @@
Checklist for new releases
=======
# Pre-Release
1. Make sure any new modules are documented sufficiently enough and check docs with
`cargo doc --all-features --open`.
2. Bump version specifier in `Cargo.toml`.
3. Update `CHANGELOG.md`: Convert `unreleased` section into version section with date and add new
`unreleased` section.
4. Run `cargo test --all-features`.
5. Run `cargo fmt` and `cargo clippy`. Check `cargo msrv` against MSRV in `Cargo.toml`.
6. Wait for CI/CD results for EGit and Github. These also check cross-compilation for bare-metal
targets.
# Post-Release
1. Create a new release on `EGit` based on the release branch.

View File

@ -790,19 +790,19 @@ impl TimeProvider<DaysLen24Bits> {
/// ## Errors /// ## Errors
/// ///
/// This function will return [TimestampError::DateBeforeCcsdsEpoch] or /// This function will return [TimestampError::DateBeforeCcsdsEpoch] or
/// [TimestampError::CdsError] if the time is before the CCSDS epoch (01-01-1958 00:00:00) or /// [TimestampError::CdsError] if the time is before the CCSDS epoch (1958-01-01T00:00:00+00:00)
/// the CCSDS days value exceeds the allowed bit width (24 bits). /// or the CCSDS days value exceeds the allowed bit width (24 bits).
pub fn from_dt_with_u24_days(dt: &DateTime<Utc>) -> Result<Self, TimestampError> { pub fn from_dt_with_u24_days(dt: &DateTime<Utc>) -> Result<Self, TimestampError> {
Self::from_dt_generic(dt, LengthOfDaySegment::Long24Bits) Self::from_dt_generic(dt, LengthOfDaySegment::Long24Bits)
} }
/// Create a provider from a generic UNIX timestamp (seconds since 01-01-1970 00:00:00). /// Create a provider from a generic UNIX timestamp (seconds since 1970-01-01T00:00:00+00:00).
/// ///
/// ## Errors /// ## Errors
/// ///
/// This function will return [TimestampError::DateBeforeCcsdsEpoch] or /// This function will return [TimestampError::DateBeforeCcsdsEpoch] or
/// [TimestampError::CdsError] if the time is before the CCSDS epoch (01-01-1958 00:00:00) or /// [TimestampError::CdsError] if the time is before the CCSDS epoch (1958-01-01T00:00:00+00:00)
/// the CCSDS days value exceeds the allowed bit width (24 bits). /// or the CCSDS days value exceeds the allowed bit width (24 bits).
pub fn from_unix_secs_with_u24_days( pub fn from_unix_secs_with_u24_days(
unix_stamp: &UnixTimestamp, unix_stamp: &UnixTimestamp,
) -> Result<Self, TimestampError> { ) -> Result<Self, TimestampError> {
@ -879,13 +879,13 @@ impl TimeProvider<DaysLen16Bits> {
Self::from_now_generic(LengthOfDaySegment::Short16Bits) Self::from_now_generic(LengthOfDaySegment::Short16Bits)
} }
/// Create a provider from a generic UNIX timestamp (seconds since 01-01-1970 00:00:00). /// Create a provider from a generic UNIX timestamp (seconds since 1970-01-01T00:00:00+00:00).
/// ///
/// ## Errors /// ## Errors
/// ///
/// This function will return [TimestampError::DateBeforeCcsdsEpoch] or /// This function will return [TimestampError::DateBeforeCcsdsEpoch] or
/// [TimestampError::CdsError] if the time is before the CCSDS epoch (01-01-1958 00:00:00) or /// [TimestampError::CdsError] if the time is before the CCSDS epoch (1958-01-01T00:00:00+00:00)
/// the CCSDS days value exceeds the allowed bit width (24 bits). /// or the CCSDS days value exceeds the allowed bit width (24 bits).
pub fn from_unix_secs_with_u16_days( pub fn from_unix_secs_with_u16_days(
unix_stamp: &UnixTimestamp, unix_stamp: &UnixTimestamp,
) -> Result<Self, TimestampError> { ) -> Result<Self, TimestampError> {
@ -996,8 +996,14 @@ fn add_for_max_ccsds_days_val<T: ProvidesDaysLength>(
_ => None, _ => None,
} }
} else { } else {
increment_ms_of_day(
&mut next_ms_of_day,
duration.subsec_millis(),
&mut next_ccsds_days,
);
None None
}; };
// The subsecond millisecond were already handled.
let full_seconds = duration.as_secs(); let full_seconds = duration.as_secs();
let secs_of_day = (full_seconds % SECONDS_PER_DAY as u64) as u32; let secs_of_day = (full_seconds % SECONDS_PER_DAY as u64) as u32;
let ms_of_day = secs_of_day * 1000; let ms_of_day = secs_of_day * 1000;
@ -2102,6 +2108,16 @@ mod tests {
} }
} }
#[test]
fn test_addition_on_ref() {
// This test case also tests the case where there is no submillis precision but subsecond
// milliseconds.
let provider_ref = &TimeProvider::new_with_u16_days(2, 500);
let new_stamp = provider_ref + Duration::from_millis(2 * 24 * 60 * 60 * 1000 + 500);
assert_eq!(new_stamp.ccsds_days_as_u32(), 4);
assert_eq!(new_stamp.ms_of_day, 1000);
}
fn check_ps_and_carryover(prec: SubmillisPrecision, ms_of_day: u32, val: u32) { fn check_ps_and_carryover(prec: SubmillisPrecision, ms_of_day: u32, val: u32) {
if let SubmillisPrecision::Picoseconds(ps) = prec { if let SubmillisPrecision::Picoseconds(ps) = prec {
assert_eq!(ps, val); assert_eq!(ps, val);

View File

@ -134,8 +134,8 @@ pub struct FractionalPart(FractionalResolution, u32);
/// It has the capability to generate and read timestamps as specified in the CCSDS 301.0-B-4 /// It has the capability to generate and read timestamps as specified in the CCSDS 301.0-B-4
/// section 3.2 . The preamble field only has one byte, which allows a time code representation /// section 3.2 . The preamble field only has one byte, which allows a time code representation
/// through the year 2094. The time is represented as a simple binary counter starting from the /// through the year 2094. The time is represented as a simple binary counter starting from the
/// fixed CCSDS epoch (1958-01-01 00:00:00). It is possible to provide subsecond accuracy using the /// fixed CCSDS epoch (1958-01-01T00:00:00+00:00). It is possible to provide subsecond accuracy
/// fractional field with various available [resolutions][FractionalResolution]. /// using the fractional field with various available [resolutions][FractionalResolution].
/// ///
/// Having a preamble field of one byte limits the width of the counter /// Having a preamble field of one byte limits the width of the counter
/// type (generally seconds) to 4 bytes and the width of the fractions type to 3 bytes. This limits /// type (generally seconds) to 4 bytes and the width of the fractions type to 3 bytes. This limits

View File

@ -157,16 +157,16 @@ pub fn seconds_since_epoch() -> f64 {
/// Convert UNIX days to CCSDS days /// Convert UNIX days to CCSDS days
/// ///
/// - CCSDS epoch: 1958 January 1 /// - CCSDS epoch: 1958-01-01T00:00:00+00:00
/// - UNIX Epoch: 1970 January 1 /// - UNIX Epoch: 1970-01-01T00:00:00+00:00
pub const fn unix_to_ccsds_days(unix_days: i64) -> i64 { pub const fn unix_to_ccsds_days(unix_days: i64) -> i64 {
unix_days - DAYS_CCSDS_TO_UNIX as i64 unix_days - DAYS_CCSDS_TO_UNIX as i64
} }
/// Convert CCSDS days to UNIX days /// Convert CCSDS days to UNIX days
/// ///
/// - CCSDS epoch: 1958 January 1 /// - CCSDS epoch: 1958-01-01T00:00:00+00:00
/// - UNIX Epoch: 1970 January 1 /// - UNIX Epoch: 1970-01-01T00:00:00+00:00
pub const fn ccsds_to_unix_days(ccsds_days: i64) -> i64 { pub const fn ccsds_to_unix_days(ccsds_days: i64) -> i64 {
ccsds_days + DAYS_CCSDS_TO_UNIX as i64 ccsds_days + DAYS_CCSDS_TO_UNIX as i64
} }
@ -233,7 +233,7 @@ pub trait CcsdsTimeProvider {
fn date_time(&self) -> Option<DateTime<Utc>>; fn date_time(&self) -> Option<DateTime<Utc>>;
} }
/// UNIX timestamp: Elapsed seconds since 01-01-1970 00:00:00. /// UNIX timestamp: Elapsed seconds since 1970-01-01T00:00:00+00:00.
/// ///
/// Also can optionally include subsecond millisecond for greater accuracy. Please note that a /// Also can optionally include subsecond millisecond for greater accuracy. Please note that a
/// subsecond millisecond value of 0 gets converted to [None]. /// subsecond millisecond value of 0 gets converted to [None].
@ -539,6 +539,14 @@ mod tests {
assert_eq!(stamp1.subsecond_millis().unwrap(), 500); assert_eq!(stamp1.subsecond_millis().unwrap(), 500);
} }
#[test]
fn test_addition_on_ref() {
let stamp0 = &UnixTimestamp::new(20, 500).unwrap();
let stamp1 = stamp0 + Duration::from_millis(2500);
assert_eq!(stamp1.unix_seconds, 23);
assert!(stamp1.subsecond_millis().is_none());
}
#[test] #[test]
fn test_addition_spillover() { fn test_addition_spillover() {
let mut stamp0 = UnixTimestamp::new(1, 900).unwrap(); let mut stamp0 = UnixTimestamp::new(1, 900).unwrap();