rtic-monotonics: Add 64-bit SysTick monotonic

Counting at 1 kHz, 32 bits for counting ticks is not enough to ensure
monotonicity for more than 50 days. Add a feature to change the backing
storage to 64 bits.
This commit is contained in:
Nils Fitinghoff 2023-08-24 16:29:20 +02:00 committed by Emil Fresk
parent 609f14b1e4
commit 4ea73021d6
4 changed files with 36 additions and 7 deletions

View file

@ -7,6 +7,10 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
## Unreleased
### Added
- Feature `systick-64bit` to get 64-bit backed `TimerInstantU64` instead of `TimerInstantU32` from the SysTick-based monotonic timer
## v1.0.1 - 2023-08-20
### Added

View file

@ -48,6 +48,8 @@ defmt = ["fugit/defmt"]
cortex-m-systick = ["dep:cortex-m"]
systick-100hz = []
systick-10khz = []
# Use 64-bit wide backing storage for the Instant
systick-64bit = []
# Timer peripheral on the RP2040
rp2040 = ["dep:cortex-m", "dep:rp2040-pac"]

View file

@ -34,10 +34,22 @@
use super::Monotonic;
pub use super::{TimeoutError, TimerQueue};
use atomic_polyfill::{AtomicU32, Ordering};
use atomic_polyfill::Ordering;
use core::future::Future;
use cortex_m::peripheral::SYST;
pub use fugit::{self, ExtU32};
pub use fugit;
cfg_if::cfg_if! {
if #[cfg(feature = "systick-64bit")] {
pub use fugit::ExtU64;
use atomic_polyfill::AtomicU64;
static SYSTICK_CNT: AtomicU64 = AtomicU64::new(0);
} else {
pub use fugit::ExtU32;
use atomic_polyfill::AtomicU32;
static SYSTICK_CNT: AtomicU32 = AtomicU32::new(0);
}
}
static SYSTICK_TIMER_QUEUE: TimerQueue<Systick> = TimerQueue::new();
// Features should be additive, here systick-100hz gets picked if both
// `systick-100hz` and `systick-10khz` are enabled.
@ -94,9 +106,6 @@ impl Systick {
}
}
static SYSTICK_CNT: AtomicU32 = AtomicU32::new(0);
static SYSTICK_TIMER_QUEUE: TimerQueue<Systick> = TimerQueue::new();
// Forward timerqueue interface
impl Systick {
/// Used to access the underlying timer queue
@ -136,8 +145,15 @@ impl Systick {
}
impl Monotonic for Systick {
type Instant = fugit::TimerInstantU32<TIMER_HZ>;
type Duration = fugit::TimerDurationU32<TIMER_HZ>;
cfg_if::cfg_if! {
if #[cfg(feature = "systick-64bit")] {
type Instant = fugit::TimerInstantU64<TIMER_HZ>;
type Duration = fugit::TimerDurationU64<TIMER_HZ>;
} else {
type Instant = fugit::TimerInstantU32<TIMER_HZ>;
type Duration = fugit::TimerDurationU32<TIMER_HZ>;
}
}
const ZERO: Self::Instant = Self::Instant::from_ticks(0);
@ -175,10 +191,14 @@ impl Monotonic for Systick {
#[cfg(feature = "embedded-hal-async")]
impl embedded_hal_async::delay::DelayUs for Systick {
async fn delay_us(&mut self, us: u32) {
#[cfg(feature = "systick-64bit")]
let us = u64::from(us);
Self::delay(us.micros()).await;
}
async fn delay_ms(&mut self, ms: u32) {
#[cfg(feature = "systick-64bit")]
let ms = u64::from(ms);
Self::delay(ms.millis()).await;
}
}

View file

@ -67,6 +67,9 @@ impl Package {
"cortex-m-systick,embedded-hal-async",
"cortex-m-systick,systick-100hz,embedded-hal-async",
"cortex-m-systick,systick-10khz,embedded-hal-async",
"cortex-m-systick,embedded-hal-async,systick-64bit",
"cortex-m-systick,systick-100hz,embedded-hal-async,systick-64bit",
"cortex-m-systick,systick-10khz,embedded-hal-async,systick-64bit",
"rp2040,embedded-hal-async",
"nrf52810,embedded-hal-async",
"nrf52811,embedded-hal-async",