Enhance the timer interface. - Make Duration a generic type, supporting both isize and f64 representation. - Derive comparison traits for Duration. - Add a Timestamp type and arithmetic between Durations and Timestamps.
diff --git a/src/timer.rs b/src/timer.rs index 0a1dbfd..6634282 100644 --- a/src/timer.rs +++ b/src/timer.rs
@@ -6,6 +6,7 @@ use crate::syscalls; use core::cell::Cell; use core::isize; +use core::ops::{Add, AddAssign, Sub}; const DRIVER_NUMBER: usize = 0x00000; @@ -21,7 +22,7 @@ pub const SUBSCRIBE_CALLBACK: usize = 0; } -pub fn sleep(duration: Duration) { +pub fn sleep(duration: Duration<isize>) { let expired = Cell::new(false); let mut with_callback = with_callback(|_, _| expired.set(true)); @@ -140,7 +141,7 @@ } } - pub fn set_alarm(&mut self, duration: Duration) -> TockResult<Alarm, SetAlarmError> { + pub fn set_alarm(&mut self, duration: Duration<isize>) -> TockResult<Alarm, SetAlarmError> { let now = self.get_current_clock(); let alarm_instant = now.num_ticks() as usize + (duration.ms() as usize * self.clock_frequency.hz()) / 1000; @@ -187,6 +188,10 @@ 1000 * (self.num_ticks / self.clock_frequency.hz() as isize) } } + + pub fn ms_f64(&self) -> f64 { + 1000.0 * (self.num_ticks as f64) / (self.clock_frequency.hz() as f64) + } } pub struct Alarm { @@ -209,17 +214,100 @@ NoMemoryAvailable, } -#[derive(Copy, Clone, Debug)] -pub struct Duration { - ms: isize, +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct Duration<T> { + ms: T, } -impl Duration { - pub fn from_ms(ms: isize) -> Duration { +impl<T> Duration<T> { + pub const fn from_ms(ms: T) -> Duration<T> { Duration { ms } } +} - pub fn ms(&self) -> isize { +impl<T> Duration<T> +where + T: Copy, +{ + pub fn ms(&self) -> T { self.ms } } + +impl<T> Sub for Duration<T> +where + T: Sub<Output = T>, +{ + type Output = Duration<T>; + + fn sub(self, other: Duration<T>) -> Duration<T> { + Duration { + ms: self.ms - other.ms, + } + } +} + +#[derive(Copy, Clone, Debug)] +pub struct Timestamp<T> { + ms: T, +} + +impl<T> Timestamp<T> { + pub const fn from_ms(ms: T) -> Timestamp<T> { + Timestamp { ms } + } +} + +impl<T> Timestamp<T> +where + T: Copy, +{ + pub fn ms(&self) -> T { + self.ms + } +} + +impl Timestamp<isize> { + pub fn from_clock_value(value: ClockValue) -> Timestamp<isize> { + Timestamp { ms: value.ms() } + } +} + +impl Timestamp<f64> { + pub fn from_clock_value(value: ClockValue) -> Timestamp<f64> { + Timestamp { ms: value.ms_f64() } + } +} + +impl<T> Sub for Timestamp<T> +where + T: Sub<Output = T>, +{ + type Output = Duration<T>; + + fn sub(self, other: Timestamp<T>) -> Duration<T> { + Duration::from_ms(self.ms - other.ms) + } +} + +impl<T> Add<Duration<T>> for Timestamp<T> +where + T: Copy + Add<Output = T>, +{ + type Output = Timestamp<T>; + + fn add(self, duration: Duration<T>) -> Timestamp<T> { + Timestamp { + ms: self.ms + duration.ms(), + } + } +} + +impl<T> AddAssign<Duration<T>> for Timestamp<T> +where + T: Copy + AddAssign, +{ + fn add_assign(&mut self, duration: Duration<T>) { + self.ms += duration.ms(); + } +}