diff options
| author | Finomnis <Finomnis@users.noreply.github.com> | 2024-04-11 00:00:38 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-10 22:00:38 +0000 |
| commit | 8c23e178f3838bcdd13662a2ffefd39ec144e869 (patch) | |
| tree | f2d2cefcd6bb2876e74ee6035b5489a4a2d9590f /rtic-time/src/monotonic.rs | |
| parent | e4cc5fd17b8a2df332af0ee25c8bd7092e66afb0 (diff) | |
Monotonic rewrite (#874)
* Rework timer_queue and monotonic architecture
Goals:
* make Monotonic purely internal
* make Monotonic purely tick passed, no fugit involved
* create a wrapper struct in the user's code via a macro that then
converts the "now" from the tick based monotonic to a fugit based
timestamp
We need to proxy the delay functions of the timer queue anyway,
so we could simply perform the conversion in those proxy functions.
* Update cargo.lock
* Update readme of rtic-time
* CI: ESP32: Redact esp_image: Too volatile
* Fixup: Changelog double entry rebase mistake
---------
Co-authored-by: Henrik Tjäder <henrik@tjaders.com>
Diffstat (limited to 'rtic-time/src/monotonic.rs')
| -rw-r--r-- | rtic-time/src/monotonic.rs | 240 |
1 files changed, 6 insertions, 234 deletions
diff --git a/rtic-time/src/monotonic.rs b/rtic-time/src/monotonic.rs index e6a160d..7c9d915 100644 --- a/rtic-time/src/monotonic.rs +++ b/rtic-time/src/monotonic.rs @@ -1,236 +1,8 @@ -//! A monotonic clock / counter definition. +//! Structs and traits surrounding the [`Monotonic`](crate::Monotonic) trait. -/// # A monotonic clock / counter definition. -/// -/// ## Correctness -/// -/// The trait enforces that proper time-math is implemented between `Instant` and `Duration`. This -/// is a requirement on the time library that the user chooses to use. -pub trait Monotonic { - /// The time at time zero. - const ZERO: Self::Instant; +pub use timer_queue_based_monotonic::{ + TimerQueueBasedDuration, TimerQueueBasedInstant, TimerQueueBasedMonotonic, +}; - /// The duration between two timer ticks. - const TICK_PERIOD: Self::Duration; - - /// The type for instant, defining an instant in time. - /// - /// **Note:** In all APIs in RTIC that use instants from this monotonic, this type will be used. - type Instant: Ord - + Copy - + core::ops::Add<Self::Duration, Output = Self::Instant> - + core::ops::Sub<Self::Duration, Output = Self::Instant> - + core::ops::Sub<Self::Instant, Output = Self::Duration>; - - /// The type for duration, defining an duration of time. - /// - /// **Note:** In all APIs in RTIC that use duration from this monotonic, this type will be used. - type Duration; - - /// Get the current time. - fn now() -> Self::Instant; - - /// Set the compare value of the timer interrupt. - /// - /// **Note:** This method does not need to handle race conditions of the monotonic, the timer - /// queue in RTIC checks this. - fn set_compare(instant: Self::Instant); - - /// This method used to be required by an errata workaround - /// for the nrf52 family, but it has been disabled as the - /// workaround was erroneous. - #[deprecated( - since = "1.2.0", - note = "this method is erroneous and has been disabled" - )] - fn should_dequeue_check(_: Self::Instant) -> bool { - panic!("This method should not be used as it is erroneous.") - } - - /// Clear the compare interrupt flag. - fn clear_compare_flag(); - - /// Pend the timer's interrupt. - fn pend_interrupt(); - - /// Optional. Runs on interrupt before any timer queue handling. - fn on_interrupt() {} - - /// Optional. This is used to save power, this is called when the timer queue is not empty. - /// - /// Enabling and disabling the monotonic needs to propagate to `now` so that an instant - /// based of `now()` is still valid. - /// - /// NOTE: This may be called more than once. - fn enable_timer() {} - - /// Optional. This is used to save power, this is called when the timer queue is empty. - /// - /// Enabling and disabling the monotonic needs to propagate to `now` so that an instant - /// based of `now()` is still valid. - /// - /// NOTE: This may be called more than once. - fn disable_timer() {} -} - -/// Creates impl blocks for [`embedded_hal::delay::DelayNs`][DelayNs], -/// based on [`fugit::ExtU64Ceil`][ExtU64Ceil]. -/// -/// [DelayNs]: https://docs.rs/embedded-hal/latest/embedded_hal/delay/trait.DelayNs.html -/// [ExtU64Ceil]: https://docs.rs/fugit/latest/fugit/trait.ExtU64Ceil.html -#[macro_export] -macro_rules! embedded_hal_delay_impl_fugit64 { - ($t:ty) => { - impl ::embedded_hal::delay::DelayNs for $t { - fn delay_ns(&mut self, ns: u32) { - use ::fugit::ExtU64Ceil; - - let now = Self::now(); - let mut done = now + u64::from(ns).nanos_at_least(); - if now != done { - // Compensate for sub-tick uncertainty - done += Self::TICK_PERIOD; - } - - while Self::now() < done {} - } - - fn delay_us(&mut self, us: u32) { - use ::fugit::ExtU64Ceil; - - let now = Self::now(); - let mut done = now + u64::from(us).micros_at_least(); - if now != done { - // Compensate for sub-tick uncertainty - done += Self::TICK_PERIOD; - } - - while Self::now() < done {} - } - - fn delay_ms(&mut self, ms: u32) { - use ::fugit::ExtU64Ceil; - - let now = Self::now(); - let mut done = now + u64::from(ms).millis_at_least(); - if now != done { - // Compensate for sub-tick uncertainty - done += Self::TICK_PERIOD; - } - - while Self::now() < done {} - } - } - }; -} - -/// Creates impl blocks for [`embedded_hal_async::delay::DelayNs`][DelayNs], -/// based on [`fugit::ExtU64Ceil`][ExtU64Ceil]. -/// -/// [DelayNs]: https://docs.rs/embedded-hal-async/latest/embedded_hal_async/delay/trait.DelayNs.html -/// [ExtU64Ceil]: https://docs.rs/fugit/latest/fugit/trait.ExtU64Ceil.html -#[macro_export] -macro_rules! embedded_hal_async_delay_impl_fugit64 { - ($t:ty) => { - impl ::embedded_hal_async::delay::DelayNs for $t { - #[inline] - async fn delay_ns(&mut self, ns: u32) { - use ::fugit::ExtU64Ceil; - Self::delay(u64::from(ns).nanos_at_least()).await; - } - - #[inline] - async fn delay_us(&mut self, us: u32) { - use ::fugit::ExtU64Ceil; - Self::delay(u64::from(us).micros_at_least()).await; - } - - #[inline] - async fn delay_ms(&mut self, ms: u32) { - use ::fugit::ExtU64Ceil; - Self::delay(u64::from(ms).millis_at_least()).await; - } - } - }; -} - -/// Creates impl blocks for [`embedded_hal::delay::DelayNs`][DelayNs], -/// based on [`fugit::ExtU32Ceil`][ExtU32Ceil]. -/// -/// [DelayNs]: https://docs.rs/embedded-hal/latest/embedded_hal/delay/trait.DelayNs.html -/// [ExtU32Ceil]: https://docs.rs/fugit/latest/fugit/trait.ExtU32Ceil.html -#[macro_export] -macro_rules! embedded_hal_delay_impl_fugit32 { - ($t:ty) => { - impl ::embedded_hal::delay::DelayNs for $t { - fn delay_ns(&mut self, ns: u32) { - use ::fugit::ExtU32Ceil; - - let now = Self::now(); - let mut done = now + ns.nanos_at_least(); - if now != done { - // Compensate for sub-tick uncertainty - done += Self::TICK_PERIOD; - } - - while Self::now() < done {} - } - - fn delay_us(&mut self, us: u32) { - use ::fugit::ExtU32Ceil; - - let now = Self::now(); - let mut done = now + us.micros_at_least(); - if now != done { - // Compensate for sub-tick uncertainty - done += Self::TICK_PERIOD; - } - - while Self::now() < done {} - } - - fn delay_ms(&mut self, ms: u32) { - use ::fugit::ExtU32Ceil; - - let now = Self::now(); - let mut done = now + ms.millis_at_least(); - if now != done { - // Compensate for sub-tick uncertainty - done += Self::TICK_PERIOD; - } - - while Self::now() < done {} - } - } - }; -} - -/// Creates impl blocks for [`embedded_hal_async::delay::DelayNs`][DelayNs], -/// based on [`fugit::ExtU32Ceil`][ExtU32Ceil]. -/// -/// [DelayNs]: https://docs.rs/embedded-hal-async/latest/embedded_hal_async/delay/trait.DelayNs.html -/// [ExtU32Ceil]: https://docs.rs/fugit/latest/fugit/trait.ExtU32Ceil.html -#[macro_export] -macro_rules! embedded_hal_async_delay_impl_fugit32 { - ($t:ty) => { - impl ::embedded_hal_async::delay::DelayNs for $t { - #[inline] - async fn delay_ns(&mut self, ns: u32) { - use ::fugit::ExtU32Ceil; - Self::delay(ns.nanos_at_least()).await; - } - - #[inline] - async fn delay_us(&mut self, us: u32) { - use ::fugit::ExtU32Ceil; - Self::delay(us.micros_at_least()).await; - } - - #[inline] - async fn delay_ms(&mut self, ms: u32) { - use ::fugit::ExtU32Ceil; - Self::delay(ms.millis_at_least()).await; - } - } - }; -} +mod embedded_hal_macros; +mod timer_queue_based_monotonic; |
