From 3b00a2bdb8cc78d1c6572dba1defbf1576ade878 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Wed, 10 Nov 2021 09:28:03 +0100 Subject: [PATCH] Updated the monotonic impl chapter --- book/en/src/by-example/tips_monotonic_impl.md | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/book/en/src/by-example/tips_monotonic_impl.md b/book/en/src/by-example/tips_monotonic_impl.md index ad04ef0a69..608281a5cf 100644 --- a/book/en/src/by-example/tips_monotonic_impl.md +++ b/book/en/src/by-example/tips_monotonic_impl.md @@ -6,36 +6,42 @@ implement the [`rtic_monotonic::Monotonic`] trait. Implementing time that supports a vast range is generally **very** difficult, and in RTIC 0.5 it was a common problem how to implement time handling and not get stuck in weird special cases. Moreover -it was difficult to understand the relation between time and the timers used for scheduling. From -RTIC 0.6 we have moved to use [`embedded_time`] as the basis for all time-based operation and -abstraction of clocks. This is why from RTIC 0.6 it is almost trivial to implement the `Monotonic` -trait and use any timer in a system for scheduling. +it was difficult to understand the relation between time and the timers used for scheduling. For +RTIC 0.6 we have moved to assume the user has a time library, e.g. [`fugit`] or [`embedded_time`], +as the basis for all time-based operations when implementing `Monotonic`. This is why in RTIC 0.6 +it is almost trivial to implement the `Monotonic` trait and use any timer in a system for scheduling. The trait documents the requirements for each method, however a small PoC implementation is provided below. [`rtic_monotonic::Monotonic`]: https://docs.rs/rtic-monotonic/ +[`fugit`]: https://docs.rs/fugit/ [`embedded_time`]: https://docs.rs/embedded_time/ ```rust -use rtic_monotonic::{embedded_time::clock::Error, Clock, Fraction, Instant, Monotonic}; +pub use fugit::{self, ExtU32}; +use rtic_monotonic::Monotonic; /// Example wrapper struct for a timer -pub struct Timer { +pub struct Timer { tim: TIM2, } -impl Clock for Timer { - const SCALING_FACTOR: Fraction = Fraction::new(1, FREQ); - type T = u32; +impl Monotonic for Timer { + type Instant = fugit::TimerInstantU32; + type Duration = fugit::TimerDurationU32; - #[inline(always)] - fn try_now(&self) -> Result, Error> { - Ok(Instant::new(Self::count())) + fn now(&mut self) -> Self::Instant { + // Read the timer count + Self::Instant::from_ticks(Self::count()) + } + + fn zero() -> Self::Instant { + // This is used while the app is in `#[init]`, if the system cannot + // support time in `#[init]` this can also be a `panic!(..)` + Self::Instant::from_ticks(0) } -} -impl Monotonic for Timer { unsafe fn reset(&mut self) { // Reset timer counter self.tim.cnt.write(|_, w| w.bits(0)); @@ -45,11 +51,11 @@ impl Monotonic for Timer { self.tim.dier.modify(|_, w| w.cc1ie().set_bit()); } - // Use Compare channel 1 for Monotonic - fn set_compare(&mut self, instant: &Instant) { + fn set_compare(&mut self, instant: Instant) { + // Use Compare channel 1 for Monotonic self.tim .ccr1 - .write(|w| w.ccr().bits(instant.duration_since_epoch().integer())); + .write(|w| w.ccr().bits(instant.ticks())); } fn clear_compare_flag(&mut self) {