rtic-rs / rtic

Real-Time Interrupt-driven Concurrency (RTIC) framework for ARM Cortex-M microcontrollers

Home Page:https://rtic.rs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implementing Monotonic using `embedded_time`.

nickclare opened this issue · comments

Hi. Not sure if this is the right place for this, but hopefully you can help. I'm working on an rp2040 project, and want to implement Monotonic using the embedded_time crate to avoid additional dependencies. (embedded_time is already used internally by the rp2040 HAL). I've found a very straightforward implementation using fugit (see https://github.com/korken89/rp2040-monotonic). Is there an easy way to do this with embedded time, without having to change the embedded_time crate.

Whatever types I try to use for Instant and Duration don't seem to line up with the trait bounds to make it work, but there's a good chance I'm misunderstanding one or both of these libraries.

So far I've defined Clock as follows:

pub struct Clock {
    pub(crate) timer: Timer,
}

impl embedded_time::Clock for Clock {
    type T = u64;

    const SCALING_FACTOR: embedded_time::rate::Fraction = Fraction::new(1, 1_000_000);

    fn try_now(&self) -> Result<embedded_time::Instant<Self>, embedded_time::clock::Error> {
        Ok(Instant::new(self.timer.get_counter()))
    }
}

and am using type Instant = embedded_time::instant::Instant<Clock> in my Monotonic impl. The issue is then no type seems to meet the requirements for Duration. If I use Microseconds<u64>, I get:

error[E0271]: type mismatch resolving `<Instant<monotonic::Clock> as Sub>::Output == Microseconds<u64>`
  --> src/monotonic.rs:31:20
   |
31 |     type Instant = Instant<Clock>;
   |                    ^^^^^^^^^^^^^^ expected struct `Microseconds`, found struct `embedded_time::duration::Generic`
   |
   = note: expected struct `Microseconds<u64>`
              found struct `embedded_time::duration::Generic<u64>`
note: required by a bound in `rtic::Monotonic::Instant`
  --> /home/nickclare/.cargo/registry/src/github.com-1ecc6299db9ec823/rtic-monotonic-1.0.0/src/lib.rs:39:30
   |
39 |         + Sub<Self::Instant, Output = Self::Duration>;
   |                              ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `rtic::Monotonic::Instant`

Alternatively, If i try type Duration = Generic<u64>, I get:

error[E0277]: the trait bound `embedded_time::duration::Generic<u64>: FixedPoint` is not satisfied
  --> src/monotonic.rs:31:20
   |
31 |     type Instant = Instant<Clock>;
   |                    ^^^^^^^^^^^^^^ the trait `FixedPoint` is not implemented for `embedded_time::duration::Generic<u64>`
   |
   = note: required because of the requirements on the impl of `Sub<embedded_time::duration::Generic<u64>>` for `Instant<monotonic::Clock>`
note: required by a bound in `rtic::Monotonic::Instant`
  --> /home/nickclare/.cargo/registry/src/github.com-1ecc6299db9ec823/rtic-monotonic-1.0.0/src/lib.rs:38:31
   |
38 |         + Sub<Self::Duration, Output = Self::Instant>
   |                               ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `rtic::Monotonic::Instant`

In the worst case I can just use the fugit dependency, but I'm just trying to understand if what I'm trying to do is supposed to be possible and I'm missing something, or if it would require changes in one or both of these libraries (rtic and/or embedded_time). The book suggests it should be possible, but I haven't found any examples of it being done.

Thanks
Nick

Hi!

Which version of embedded time are you using? 0.13 release branch I've heard is the recommended one, as discussed here: #578

I have not seen much happening regarding embedded_time, which is unfortunate. I have personally migrated over to fugit, so I might be biased :P

We close this for now, pleas re-open if fugit would not work for you.