diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-07-12 03:29:09 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-07-12 03:45:48 +0200 |
| commit | 35a76c364a90cae23a2a1e72e1d084c226048915 (patch) | |
| tree | 7d71bcbbb93d5887f47704f8f7e0d9471c0355b4 | |
| parent | 94bd4eb7d5713e4c6e679617a3e6e94671c8ff77 (diff) | |
embassy/time: make optional via Cargo feature
| -rw-r--r-- | embassy-nrf/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy-rp/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy-std/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy-stm32/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy/Cargo.toml | 10 | ||||
| -rw-r--r-- | embassy/src/executor/mod.rs | 8 | ||||
| -rw-r--r-- | embassy/src/executor/raw.rs | 44 | ||||
| -rw-r--r-- | embassy/src/lib.rs | 1 | ||||
| -rw-r--r-- | embassy/src/time/mod.rs | 14 |
9 files changed, 52 insertions, 33 deletions
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 7b8e36414..85ded1df4 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml | |||
| @@ -21,7 +21,7 @@ nrf52840 = ["nrf52840-pac"] | |||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | [dependencies] | 23 | [dependencies] |
| 24 | embassy = { version = "0.1.0", path = "../embassy" } | 24 | embassy = { version = "0.1.0", path = "../embassy", features = ["time-tick-32768hz"] } |
| 25 | embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["nrf"]} | 25 | embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["nrf"]} |
| 26 | embassy-extras = {version = "0.1.0", path = "../embassy-extras" } | 26 | embassy-extras = {version = "0.1.0", path = "../embassy-extras" } |
| 27 | 27 | ||
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 2313c6432..503d2c706 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml | |||
| @@ -12,7 +12,7 @@ defmt-warn = [ ] | |||
| 12 | defmt-error = [ ] | 12 | defmt-error = [ ] |
| 13 | 13 | ||
| 14 | [dependencies] | 14 | [dependencies] |
| 15 | embassy = { version = "0.1.0", path = "../embassy" } | 15 | embassy = { version = "0.1.0", path = "../embassy", features = [ "time-tick-1mhz" ] } |
| 16 | embassy-extras = {version = "0.1.0", path = "../embassy-extras" } | 16 | embassy-extras = {version = "0.1.0", path = "../embassy-extras" } |
| 17 | embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["rp"]} | 17 | embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["rp"]} |
| 18 | 18 | ||
diff --git a/embassy-std/Cargo.toml b/embassy-std/Cargo.toml index 2a95838e8..2633f1232 100644 --- a/embassy-std/Cargo.toml +++ b/embassy-std/Cargo.toml | |||
| @@ -5,6 +5,6 @@ authors = ["Dario Nieuwenhuis <[email protected]>"] | |||
| 5 | edition = "2018" | 5 | edition = "2018" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy = { version = "0.1.0", path = "../embassy", features = ["std"] } | 8 | embassy = { version = "0.1.0", path = "../embassy", features = ["std", "time-tick-32768hz"] } |
| 9 | embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["std"]} | 9 | embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["std"]} |
| 10 | lazy_static = "1.4.0" | 10 | lazy_static = "1.4.0" |
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 4e37c94fe..654bc98ef 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -6,7 +6,7 @@ edition = "2018" | |||
| 6 | resolver = "2" | 6 | resolver = "2" |
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy = { version = "0.1.0", path = "../embassy" } | 9 | embassy = { version = "0.1.0", path = "../embassy", features = ["time-tick-32768hz"] } |
| 10 | embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] } | 10 | embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] } |
| 11 | embassy-extras = {version = "0.1.0", path = "../embassy-extras" } | 11 | embassy-extras = {version = "0.1.0", path = "../embassy-extras" } |
| 12 | embassy-traits = {version = "0.1.0", path = "../embassy-traits" } | 12 | embassy-traits = {version = "0.1.0", path = "../embassy-traits" } |
diff --git a/embassy/Cargo.toml b/embassy/Cargo.toml index 87f54409a..b2ad80495 100644 --- a/embassy/Cargo.toml +++ b/embassy/Cargo.toml | |||
| @@ -5,11 +5,13 @@ authors = ["Dario Nieuwenhuis <[email protected]>"] | |||
| 5 | edition = "2018" | 5 | edition = "2018" |
| 6 | 6 | ||
| 7 | [features] | 7 | [features] |
| 8 | default = ["tick-32768hz"] | 8 | default = [] |
| 9 | std = ["futures/std", "embassy-traits/std"] | 9 | std = ["futures/std", "embassy-traits/std"] |
| 10 | tick-32768hz = [] | 10 | |
| 11 | tick-1000hz = [] | 11 | time = [] |
| 12 | tick-1mhz = [] | 12 | time-tick-32768hz = ["time"] |
| 13 | time-tick-1000hz = ["time"] | ||
| 14 | time-tick-1mhz = ["time"] | ||
| 13 | 15 | ||
| 14 | defmt-trace = [] | 16 | defmt-trace = [] |
| 15 | defmt-debug = [] | 17 | defmt-debug = [] |
diff --git a/embassy/src/executor/mod.rs b/embassy/src/executor/mod.rs index d9740d56d..771f75ee8 100644 --- a/embassy/src/executor/mod.rs +++ b/embassy/src/executor/mod.rs | |||
| @@ -4,12 +4,12 @@ use core::{mem, ptr}; | |||
| 4 | 4 | ||
| 5 | pub mod raw; | 5 | pub mod raw; |
| 6 | mod run_queue; | 6 | mod run_queue; |
| 7 | #[cfg(feature = "time")] | ||
| 7 | mod timer_queue; | 8 | mod timer_queue; |
| 8 | mod util; | 9 | mod util; |
| 9 | mod waker; | 10 | mod waker; |
| 10 | 11 | ||
| 11 | use crate::interrupt::{Interrupt, InterruptExt}; | 12 | use crate::interrupt::{Interrupt, InterruptExt}; |
| 12 | use crate::time::Alarm; | ||
| 13 | 13 | ||
| 14 | #[must_use = "Calling a task function does nothing on its own. You must pass the returned SpawnToken to Executor::spawn()"] | 14 | #[must_use = "Calling a task function does nothing on its own. You must pass the returned SpawnToken to Executor::spawn()"] |
| 15 | pub struct SpawnToken<F> { | 15 | pub struct SpawnToken<F> { |
| @@ -116,7 +116,8 @@ impl Executor { | |||
| 116 | } | 116 | } |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | pub fn set_alarm(&mut self, alarm: &'static dyn Alarm) { | 119 | #[cfg(feature = "time")] |
| 120 | pub fn set_alarm(&mut self, alarm: &'static dyn crate::time::Alarm) { | ||
| 120 | self.inner.set_alarm(alarm); | 121 | self.inner.set_alarm(alarm); |
| 121 | } | 122 | } |
| 122 | 123 | ||
| @@ -160,7 +161,8 @@ impl<I: Interrupt> InterruptExecutor<I> { | |||
| 160 | } | 161 | } |
| 161 | } | 162 | } |
| 162 | 163 | ||
| 163 | pub fn set_alarm(&mut self, alarm: &'static dyn Alarm) { | 164 | #[cfg(feature = "time")] |
| 165 | pub fn set_alarm(&mut self, alarm: &'static dyn crate::time::Alarm) { | ||
| 164 | self.inner.set_alarm(alarm); | 166 | self.inner.set_alarm(alarm); |
| 165 | } | 167 | } |
| 166 | 168 | ||
diff --git a/embassy/src/executor/raw.rs b/embassy/src/executor/raw.rs index 52512c533..cd2f0446d 100644 --- a/embassy/src/executor/raw.rs +++ b/embassy/src/executor/raw.rs | |||
| @@ -1,18 +1,20 @@ | |||
| 1 | use atomic_polyfill::{AtomicU32, Ordering}; | 1 | use atomic_polyfill::{AtomicU32, Ordering}; |
| 2 | use core::cell::Cell; | 2 | use core::cell::Cell; |
| 3 | use core::cmp::min; | ||
| 4 | use core::future::Future; | 3 | use core::future::Future; |
| 5 | use core::marker::PhantomData; | 4 | use core::marker::PhantomData; |
| 6 | use core::pin::Pin; | 5 | use core::pin::Pin; |
| 7 | use core::ptr::NonNull; | 6 | use core::ptr::NonNull; |
| 8 | use core::task::{Context, Poll, Waker}; | 7 | use core::task::{Context, Poll}; |
| 9 | use core::{mem, ptr}; | 8 | use core::{mem, ptr}; |
| 10 | 9 | ||
| 11 | use super::run_queue::{RunQueue, RunQueueItem}; | 10 | use super::run_queue::{RunQueue, RunQueueItem}; |
| 12 | use super::timer_queue::{TimerQueue, TimerQueueItem}; | ||
| 13 | use super::util::UninitCell; | 11 | use super::util::UninitCell; |
| 14 | use super::waker; | 12 | use super::waker; |
| 15 | use super::SpawnToken; | 13 | use super::SpawnToken; |
| 14 | |||
| 15 | #[cfg(feature = "time")] | ||
| 16 | use super::timer_queue::{TimerQueue, TimerQueueItem}; | ||
| 17 | #[cfg(feature = "time")] | ||
| 16 | use crate::time::{Alarm, Instant}; | 18 | use crate::time::{Alarm, Instant}; |
| 17 | 19 | ||
| 18 | /// Task is spawned (has a future) | 20 | /// Task is spawned (has a future) |
| @@ -20,26 +22,33 @@ pub(crate) const STATE_SPAWNED: u32 = 1 << 0; | |||
| 20 | /// Task is in the executor run queue | 22 | /// Task is in the executor run queue |
| 21 | pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; | 23 | pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; |
| 22 | /// Task is in the executor timer queue | 24 | /// Task is in the executor timer queue |
| 25 | #[cfg(feature = "time")] | ||
| 23 | pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2; | 26 | pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2; |
| 24 | 27 | ||
| 25 | pub struct TaskHeader { | 28 | pub struct TaskHeader { |
| 26 | pub(crate) state: AtomicU32, | 29 | pub(crate) state: AtomicU32, |
| 27 | pub(crate) run_queue_item: RunQueueItem, | 30 | pub(crate) run_queue_item: RunQueueItem, |
| 28 | pub(crate) expires_at: Cell<Instant>, | ||
| 29 | pub(crate) timer_queue_item: TimerQueueItem, | ||
| 30 | pub(crate) executor: Cell<*const Executor>, // Valid if state != 0 | 31 | pub(crate) executor: Cell<*const Executor>, // Valid if state != 0 |
| 31 | pub(crate) poll_fn: UninitCell<unsafe fn(NonNull<TaskHeader>)>, // Valid if STATE_SPAWNED | 32 | pub(crate) poll_fn: UninitCell<unsafe fn(NonNull<TaskHeader>)>, // Valid if STATE_SPAWNED |
| 33 | |||
| 34 | #[cfg(feature = "time")] | ||
| 35 | pub(crate) expires_at: Cell<Instant>, | ||
| 36 | #[cfg(feature = "time")] | ||
| 37 | pub(crate) timer_queue_item: TimerQueueItem, | ||
| 32 | } | 38 | } |
| 33 | 39 | ||
| 34 | impl TaskHeader { | 40 | impl TaskHeader { |
| 35 | pub(crate) const fn new() -> Self { | 41 | pub(crate) const fn new() -> Self { |
| 36 | Self { | 42 | Self { |
| 37 | state: AtomicU32::new(0), | 43 | state: AtomicU32::new(0), |
| 38 | expires_at: Cell::new(Instant::from_ticks(0)), | ||
| 39 | run_queue_item: RunQueueItem::new(), | 44 | run_queue_item: RunQueueItem::new(), |
| 40 | timer_queue_item: TimerQueueItem::new(), | ||
| 41 | executor: Cell::new(ptr::null()), | 45 | executor: Cell::new(ptr::null()), |
| 42 | poll_fn: UninitCell::uninit(), | 46 | poll_fn: UninitCell::uninit(), |
| 47 | |||
| 48 | #[cfg(feature = "time")] | ||
| 49 | expires_at: Cell::new(Instant::from_ticks(0)), | ||
| 50 | #[cfg(feature = "time")] | ||
| 51 | timer_queue_item: TimerQueueItem::new(), | ||
| 43 | } | 52 | } |
| 44 | } | 53 | } |
| 45 | 54 | ||
| @@ -154,9 +163,12 @@ unsafe impl<F: Future + 'static> Sync for Task<F> {} | |||
| 154 | 163 | ||
| 155 | pub struct Executor { | 164 | pub struct Executor { |
| 156 | run_queue: RunQueue, | 165 | run_queue: RunQueue, |
| 157 | timer_queue: TimerQueue, | ||
| 158 | signal_fn: fn(*mut ()), | 166 | signal_fn: fn(*mut ()), |
| 159 | signal_ctx: *mut (), | 167 | signal_ctx: *mut (), |
| 168 | |||
| 169 | #[cfg(feature = "time")] | ||
| 170 | timer_queue: TimerQueue, | ||
| 171 | #[cfg(feature = "time")] | ||
| 160 | alarm: Option<&'static dyn Alarm>, | 172 | alarm: Option<&'static dyn Alarm>, |
| 161 | } | 173 | } |
| 162 | 174 | ||
| @@ -164,13 +176,17 @@ impl Executor { | |||
| 164 | pub const fn new(signal_fn: fn(*mut ()), signal_ctx: *mut ()) -> Self { | 176 | pub const fn new(signal_fn: fn(*mut ()), signal_ctx: *mut ()) -> Self { |
| 165 | Self { | 177 | Self { |
| 166 | run_queue: RunQueue::new(), | 178 | run_queue: RunQueue::new(), |
| 167 | timer_queue: TimerQueue::new(), | ||
| 168 | signal_fn, | 179 | signal_fn, |
| 169 | signal_ctx, | 180 | signal_ctx, |
| 181 | |||
| 182 | #[cfg(feature = "time")] | ||
| 183 | timer_queue: TimerQueue::new(), | ||
| 184 | #[cfg(feature = "time")] | ||
| 170 | alarm: None, | 185 | alarm: None, |
| 171 | } | 186 | } |
| 172 | } | 187 | } |
| 173 | 188 | ||
| 189 | #[cfg(feature = "time")] | ||
| 174 | pub fn set_alarm(&mut self, alarm: &'static dyn Alarm) { | 190 | pub fn set_alarm(&mut self, alarm: &'static dyn Alarm) { |
| 175 | self.alarm = Some(alarm); | 191 | self.alarm = Some(alarm); |
| 176 | } | 192 | } |
| @@ -192,6 +208,7 @@ impl Executor { | |||
| 192 | } | 208 | } |
| 193 | 209 | ||
| 194 | pub unsafe fn run_queued(&'static self) { | 210 | pub unsafe fn run_queued(&'static self) { |
| 211 | #[cfg(feature = "time")] | ||
| 195 | if self.alarm.is_some() { | 212 | if self.alarm.is_some() { |
| 196 | self.timer_queue.dequeue_expired(Instant::now(), |p| { | 213 | self.timer_queue.dequeue_expired(Instant::now(), |p| { |
| 197 | p.as_ref().enqueue(); | 214 | p.as_ref().enqueue(); |
| @@ -200,6 +217,8 @@ impl Executor { | |||
| 200 | 217 | ||
| 201 | self.run_queue.dequeue_all(|p| { | 218 | self.run_queue.dequeue_all(|p| { |
| 202 | let task = p.as_ref(); | 219 | let task = p.as_ref(); |
| 220 | |||
| 221 | #[cfg(feature = "time")] | ||
| 203 | task.expires_at.set(Instant::MAX); | 222 | task.expires_at.set(Instant::MAX); |
| 204 | 223 | ||
| 205 | let state = task.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel); | 224 | let state = task.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel); |
| @@ -216,11 +235,13 @@ impl Executor { | |||
| 216 | task.poll_fn.read()(p as _); | 235 | task.poll_fn.read()(p as _); |
| 217 | 236 | ||
| 218 | // Enqueue or update into timer_queue | 237 | // Enqueue or update into timer_queue |
| 238 | #[cfg(feature = "time")] | ||
| 219 | self.timer_queue.update(p); | 239 | self.timer_queue.update(p); |
| 220 | }); | 240 | }); |
| 221 | 241 | ||
| 222 | // If this is in the past, set_alarm will immediately trigger the alarm, | 242 | // If this is in the past, set_alarm will immediately trigger the alarm, |
| 223 | // which will make the wfe immediately return so we do another loop iteration. | 243 | // which will make the wfe immediately return so we do another loop iteration. |
| 244 | #[cfg(feature = "time")] | ||
| 224 | if let Some(alarm) = self.alarm { | 245 | if let Some(alarm) = self.alarm { |
| 225 | let next_expiration = self.timer_queue.next_expiration(); | 246 | let next_expiration = self.timer_queue.next_expiration(); |
| 226 | alarm.set_callback(self.signal_fn, self.signal_ctx); | 247 | alarm.set_callback(self.signal_fn, self.signal_ctx); |
| @@ -242,9 +263,10 @@ pub unsafe fn wake_task(task: NonNull<TaskHeader>) { | |||
| 242 | task.as_ref().enqueue(); | 263 | task.as_ref().enqueue(); |
| 243 | } | 264 | } |
| 244 | 265 | ||
| 245 | pub(crate) unsafe fn register_timer(at: Instant, waker: &Waker) { | 266 | #[cfg(feature = "time")] |
| 267 | pub(crate) unsafe fn register_timer(at: Instant, waker: &core::task::Waker) { | ||
| 246 | let task = waker::task_from_waker(waker); | 268 | let task = waker::task_from_waker(waker); |
| 247 | let task = task.as_ref(); | 269 | let task = task.as_ref(); |
| 248 | let expires_at = task.expires_at.get(); | 270 | let expires_at = task.expires_at.get(); |
| 249 | task.expires_at.set(min(expires_at, at)); | 271 | task.expires_at.set(expires_at.min(at)); |
| 250 | } | 272 | } |
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs index 3a0701d38..41102a180 100644 --- a/embassy/src/lib.rs +++ b/embassy/src/lib.rs | |||
| @@ -14,6 +14,7 @@ pub(crate) mod fmt; | |||
| 14 | pub mod executor; | 14 | pub mod executor; |
| 15 | pub mod interrupt; | 15 | pub mod interrupt; |
| 16 | pub mod io; | 16 | pub mod io; |
| 17 | #[cfg(feature = "time")] | ||
| 17 | pub mod time; | 18 | pub mod time; |
| 18 | pub mod util; | 19 | pub mod util; |
| 19 | 20 | ||
diff --git a/embassy/src/time/mod.rs b/embassy/src/time/mod.rs index 9b7a4be18..d9777c45b 100644 --- a/embassy/src/time/mod.rs +++ b/embassy/src/time/mod.rs | |||
| @@ -13,21 +13,13 @@ pub use instant::Instant; | |||
| 13 | pub use timer::{with_timeout, Ticker, TimeoutError, Timer}; | 13 | pub use timer::{with_timeout, Ticker, TimeoutError, Timer}; |
| 14 | pub use traits::*; | 14 | pub use traits::*; |
| 15 | 15 | ||
| 16 | #[cfg(any( | 16 | #[cfg(feature = "time-tick-1000hz")] |
| 17 | all(feature = "tick-32768hz", feature = "tick-1000hz"), | ||
| 18 | all(feature = "tick-32768hz", feature = "tick-1mhz"), | ||
| 19 | ))] | ||
| 20 | compile_error!( | ||
| 21 | "Disable default-features to be able to use a tick rate other than the default (32768 Hz)" | ||
| 22 | ); | ||
| 23 | |||
| 24 | #[cfg(feature = "tick-1000hz")] | ||
| 25 | pub const TICKS_PER_SECOND: u64 = 1_000; | 17 | pub const TICKS_PER_SECOND: u64 = 1_000; |
| 26 | 18 | ||
| 27 | #[cfg(feature = "tick-32768hz")] | 19 | #[cfg(feature = "time-tick-32768hz")] |
| 28 | pub const TICKS_PER_SECOND: u64 = 32_768; | 20 | pub const TICKS_PER_SECOND: u64 = 32_768; |
| 29 | 21 | ||
| 30 | #[cfg(feature = "tick-1mhz")] | 22 | #[cfg(feature = "time-tick-1mhz")] |
| 31 | pub const TICKS_PER_SECOND: u64 = 1_000_000; | 23 | pub const TICKS_PER_SECOND: u64 = 1_000_000; |
| 32 | 24 | ||
| 33 | static mut CLOCK: Option<&'static dyn Clock> = None; | 25 | static mut CLOCK: Option<&'static dyn Clock> = None; |
