simple_clock/lib.rs
1//! This library provides a very simple system clock interface with microsecond precision.
2//! Unlike the [`embedded-time`](https://crates.io/crates/embedded-time),
3//! the interface provided by this library is as simple as possible which is better suited
4//! for writing prototypes.
5
6#![cfg_attr(not(test), no_std)]
7
8#[cfg(test)]
9mod tests;
10
11/// Provides an abstraction for hardware-specific clocks with the microsecond precision.
12pub trait SimpleClock {
13 /// Returns an instant time in the microseconds.
14 fn now_us(&self) -> u64;
15}
16
17/// Provides an easy way to calculate elapsed times.
18///
19/// This timer is usually used to compute how much time is elapsed between two events
20/// or to determine the event's deadline in case of polling.
21pub struct ElapsedTimer<'a, T> {
22 clock: &'a T,
23 now: u64,
24}
25
26impl<'a, T: SimpleClock> ElapsedTimer<'a, T> {
27 /// Creates a new elapsed timer instance backed by the specified clock implementation.
28 pub fn new(clock: &'a T) -> Self {
29 Self {
30 clock,
31 now: clock.now_us(),
32 }
33 }
34
35 /// Restarts the timer and returns the number of microseconds
36 /// elapsed since this timer was started.
37 pub fn restart(&mut self) -> u64 {
38 let elapsed = self.elapsed();
39 self.now = self.clock.now_us();
40 elapsed
41 }
42
43 /// Returns the number of microseconds elapsed since this timer was started.
44 pub fn elapsed(&self) -> u64 {
45 self.clock.now_us().saturating_sub(self.now)
46 }
47}
48
49/// The deadline has been reached.
50#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51pub struct DeadlineReached(());
52
53/// Provides an easy way to specify operation deadline
54///
55/// This timer is usually used to limit polling operation by a certain period of time.
56#[derive(Debug)]
57pub struct Deadline<'a, C: SimpleClock> {
58 clock: &'a C,
59 deadline: u64,
60}
61
62impl<'a, C: SimpleClock> Deadline<'a, C> {
63 /// Creates a new deadline timer instance backed by the specified clock implementation
64 pub fn new(clock: &'a C, timeout: u64) -> Self {
65 Self {
66 clock,
67 deadline: clock.now_us() + timeout,
68 }
69 }
70
71 /// Returns error if the deadline has been reached.
72 pub fn reached(&self) -> Result<(), DeadlineReached> {
73 if self.clock.now_us() > self.deadline {
74 Err(DeadlineReached(()))
75 } else {
76 Ok(())
77 }
78 }
79}