From 94bd4eb7d5713e4c6e679617a3e6e94671c8ff77 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 12 Jul 2021 03:10:01 +0200 Subject: [PATCH] embassy/time: refactor module structure --- embassy/src/executor/mod.rs | 1 - embassy/src/time/delay.rs | 70 +++++++++++++++++++++++++ embassy/src/time/mod.rs | 58 ++------------------ embassy/src/{executor => time}/timer.rs | 27 +--------- 4 files changed, 75 insertions(+), 81 deletions(-) create mode 100644 embassy/src/time/delay.rs rename embassy/src/{executor => time}/timer.rs (87%) diff --git a/embassy/src/executor/mod.rs b/embassy/src/executor/mod.rs index 598d4e55..d9740d56 100644 --- a/embassy/src/executor/mod.rs +++ b/embassy/src/executor/mod.rs @@ -4,7 +4,6 @@ use core::{mem, ptr}; pub mod raw; mod run_queue; -pub(crate) mod timer; mod timer_queue; mod util; mod waker; diff --git a/embassy/src/time/delay.rs b/embassy/src/time/delay.rs new file mode 100644 index 00000000..f8b7f840 --- /dev/null +++ b/embassy/src/time/delay.rs @@ -0,0 +1,70 @@ +use core::future::Future; + +use super::{Duration, Instant, Timer}; + +/// Async or blocking delay. +pub struct Delay; + +impl crate::traits::delay::Delay for Delay { + type DelayFuture<'a> = impl Future + 'a; + + fn delay_ms<'a>(&'a mut self, millis: u64) -> Self::DelayFuture<'a> { + Timer::after(Duration::from_millis(millis)) + } + fn delay_us<'a>(&'a mut self, micros: u64) -> Self::DelayFuture<'a> { + Timer::after(Duration::from_micros(micros)) + } +} + +/// Type used for blocking delays through embedded-hal traits. +/// +/// For this interface to work, the Executor's clock must be correctly initialized before using it. +/// The delays are implemented in a "best-effort" way, meaning that the cpu will block for at least +/// the amount provided, but accuracy can be affected by many factors, including interrupt usage. +/// Make sure to use a suitable tick rate for your use case. The tick rate can be chosen through +/// features flags of this crate. +pub struct BlockingTimer; + +impl embedded_hal::blocking::delay::DelayMs for BlockingTimer { + fn delay_ms(&mut self, ms: u8) { + block_for(Duration::from_millis(ms as u64)) + } +} + +impl embedded_hal::blocking::delay::DelayMs for BlockingTimer { + fn delay_ms(&mut self, ms: u16) { + block_for(Duration::from_millis(ms as u64)) + } +} + +impl embedded_hal::blocking::delay::DelayMs for BlockingTimer { + fn delay_ms(&mut self, ms: u32) { + block_for(Duration::from_millis(ms as u64)) + } +} + +impl embedded_hal::blocking::delay::DelayUs for BlockingTimer { + fn delay_us(&mut self, us: u8) { + block_for(Duration::from_micros(us as u64)) + } +} + +impl embedded_hal::blocking::delay::DelayUs for BlockingTimer { + fn delay_us(&mut self, us: u16) { + block_for(Duration::from_micros(us as u64)) + } +} + +impl embedded_hal::blocking::delay::DelayUs for BlockingTimer { + fn delay_us(&mut self, us: u32) { + block_for(Duration::from_micros(us as u64)) + } +} + +/// Blocks the cpu for at least `duration`. +/// +/// For this interface to work, the Executor's clock must be correctly initialized before using it. +pub fn block_for(duration: Duration) { + let expires_at = Instant::now() + duration; + while Instant::now() < expires_at {} +} diff --git a/embassy/src/time/mod.rs b/embassy/src/time/mod.rs index d50d9ef0..9b7a4be1 100644 --- a/embassy/src/time/mod.rs +++ b/embassy/src/time/mod.rs @@ -1,13 +1,16 @@ //! Time abstractions //! To use these abstractions, first call `set_clock` with an instance of an [Clock](trait.Clock.html). //! +mod delay; mod duration; mod instant; +mod timer; mod traits; -pub use crate::executor::timer::{with_timeout, Delay, Ticker, TimeoutError, Timer}; +pub use delay::{block_for, Delay}; pub use duration::Duration; pub use instant::Instant; +pub use timer::{with_timeout, Ticker, TimeoutError, Timer}; pub use traits::*; #[cfg(any( @@ -42,56 +45,3 @@ pub unsafe fn set_clock(clock: &'static dyn Clock) { pub(crate) fn now() -> u64 { unsafe { unwrap!(CLOCK, "No clock set").now() } } - -/// Type used for blocking delays through embedded-hal traits. -/// -/// For this interface to work, the Executor's clock must be correctly initialized before using it. -/// The delays are implemented in a "best-effort" way, meaning that the cpu will block for at least -/// the amount provided, but accuracy can be affected by many factors, including interrupt usage. -/// Make sure to use a suitable tick rate for your use case. The tick rate can be chosen through -/// features flags of this crate. -pub struct BlockingTimer; - -impl embedded_hal::blocking::delay::DelayMs for BlockingTimer { - fn delay_ms(&mut self, ms: u8) { - block_for(Duration::from_millis(ms as u64)) - } -} - -impl embedded_hal::blocking::delay::DelayMs for BlockingTimer { - fn delay_ms(&mut self, ms: u16) { - block_for(Duration::from_millis(ms as u64)) - } -} - -impl embedded_hal::blocking::delay::DelayMs for BlockingTimer { - fn delay_ms(&mut self, ms: u32) { - block_for(Duration::from_millis(ms as u64)) - } -} - -impl embedded_hal::blocking::delay::DelayUs for BlockingTimer { - fn delay_us(&mut self, us: u8) { - block_for(Duration::from_micros(us as u64)) - } -} - -impl embedded_hal::blocking::delay::DelayUs for BlockingTimer { - fn delay_us(&mut self, us: u16) { - block_for(Duration::from_micros(us as u64)) - } -} - -impl embedded_hal::blocking::delay::DelayUs for BlockingTimer { - fn delay_us(&mut self, us: u32) { - block_for(Duration::from_micros(us as u64)) - } -} - -/// Blocks the cpu for at least `duration`. -/// -/// For this interface to work, the Executor's clock must be correctly initialized before using it. -pub fn block_for(duration: Duration) { - let expires_at = Instant::now() + duration; - while Instant::now() < expires_at {} -} diff --git a/embassy/src/executor/timer.rs b/embassy/src/time/timer.rs similarity index 87% rename from embassy/src/executor/timer.rs rename to embassy/src/time/timer.rs index 8ee33696..a2a37f70 100644 --- a/embassy/src/executor/timer.rs +++ b/embassy/src/time/timer.rs @@ -1,36 +1,11 @@ use core::future::Future; -use core::marker::PhantomData; use core::pin::Pin; use core::task::{Context, Poll}; use futures::{future::select, future::Either, pin_mut, Stream}; -use super::raw; +use crate::executor::raw; use crate::time::{Duration, Instant}; -/// Delay abstraction using embassy's clock. -pub struct Delay { - _data: PhantomData, -} - -impl Delay { - pub fn new() -> Self { - Delay { - _data: PhantomData {}, - } - } -} - -impl crate::traits::delay::Delay for Delay { - type DelayFuture<'a> = impl Future + 'a; - - fn delay_ms<'a>(&'a mut self, millis: u64) -> Self::DelayFuture<'a> { - Timer::after(Duration::from_millis(millis)) - } - fn delay_us<'a>(&'a mut self, micros: u64) -> Self::DelayFuture<'a> { - Timer::after(Duration::from_micros(micros)) - } -} - pub struct TimeoutError; pub async fn with_timeout(timeout: Duration, fut: F) -> Result { let timeout_fut = Timer::after(timeout);