Trait Clock

Source
pub trait Clock {
    type Instant: Instant;

    // Required method
    fn now(&self) -> Self::Instant;

    // Provided method
    fn elapsed(&self, instant: Self::Instant) -> Duration { ... }
}
Expand description

Clock trait for clocks which are expected to be always running and never fail

The trait has an associated type Instant which needs to implement the Instant trait. For most users of this trait, it should be fine to keep this type generic and not further restrict it. This will keep the code compatible with all clock implementations and improve platform-independence. If a specific type is required for whatever reason, the instant module defines some types which could be used by clock implementers. Keep in mind though, that even if the Instant type would support high-resolution clocks, this does not guarantee that the underlying clock actually supports that resolution. Therefore, clock resolution requirements need to be documented in a different way.

The design decision to define the clock trait as infallible has been made because handling clock errors is often extremely difficult. Experience has shown that clock users tend to unwrap on all clock interactions, if not directly then at least eventually after propagating errors as far as they could. Having an infallible clock trait is cleaner because it communicates that clock implementers need to make sure that the clock is always working, at least for the time it is available to the clock users. If, for some reason, working with a fallible clock is required, an approach might be to use a (properly synchronized) global Option<&impl Clock> which is set to None whenever the clock is not available. But this use case is explicitly not supported or advocated for by this crate.

Since the Instant trait could not contain the std::time::Instant::elapsed method which depends on a global clock, this method is moved here in addition to the now method.

All methods in this trait require shared & references so that a single clock reference can be shared and used for a whole application. This might be in contrast to many embedded approaches in which such hardware-related accesses are often done via an exclusive &mut reference. But in fact, this trait is not designed to describe exclusive access to a hardware clock (with the possibility to start, stop or reconfigure it), but to gain access to a virtually global shared clock. To allow this, clock implementers need to use an effective synchronization or locking mechanism to allow such accesses.

Required Associated Types§

Source

type Instant: Instant

Associated instant type which is returned from the now method

Required Methods§

Source

fn now(&self) -> Self::Instant

Returns the current time as an instant

Provided Methods§

Source

fn elapsed(&self, instant: Self::Instant) -> Duration

Returns the amount of time elapsed since the given instant.

§Panics

As in the current version of the Rust stdlib, this method saturates instead of panicking.

§Examples
use core::time::Duration;
use embedded_timers::instant::Instant;
use embedded_timers::clock::Clock;

let clock = MyClock;
let instant = clock.now();
let three_secs = Duration::from_secs(3);
sleep(three_secs);
assert!(clock.elapsed(instant) >= three_secs);

Implementors§