aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-07-12 03:29:09 +0200
committerDario Nieuwenhuis <[email protected]>2021-07-12 03:45:48 +0200
commit35a76c364a90cae23a2a1e72e1d084c226048915 (patch)
tree7d71bcbbb93d5887f47704f8f7e0d9471c0355b4
parent94bd4eb7d5713e4c6e679617a3e6e94671c8ff77 (diff)
embassy/time: make optional via Cargo feature
-rw-r--r--embassy-nrf/Cargo.toml2
-rw-r--r--embassy-rp/Cargo.toml2
-rw-r--r--embassy-std/Cargo.toml2
-rw-r--r--embassy-stm32/Cargo.toml2
-rw-r--r--embassy/Cargo.toml10
-rw-r--r--embassy/src/executor/mod.rs8
-rw-r--r--embassy/src/executor/raw.rs44
-rw-r--r--embassy/src/lib.rs1
-rw-r--r--embassy/src/time/mod.rs14
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]
24embassy = { version = "0.1.0", path = "../embassy" } 24embassy = { version = "0.1.0", path = "../embassy", features = ["time-tick-32768hz"] }
25embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["nrf"]} 25embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["nrf"]}
26embassy-extras = {version = "0.1.0", path = "../embassy-extras" } 26embassy-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 = [ ]
12defmt-error = [ ] 12defmt-error = [ ]
13 13
14[dependencies] 14[dependencies]
15embassy = { version = "0.1.0", path = "../embassy" } 15embassy = { version = "0.1.0", path = "../embassy", features = [ "time-tick-1mhz" ] }
16embassy-extras = {version = "0.1.0", path = "../embassy-extras" } 16embassy-extras = {version = "0.1.0", path = "../embassy-extras" }
17embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["rp"]} 17embassy-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]>"]
5edition = "2018" 5edition = "2018"
6 6
7[dependencies] 7[dependencies]
8embassy = { version = "0.1.0", path = "../embassy", features = ["std"] } 8embassy = { version = "0.1.0", path = "../embassy", features = ["std", "time-tick-32768hz"] }
9embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["std"]} 9embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["std"]}
10lazy_static = "1.4.0" 10lazy_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"
6resolver = "2" 6resolver = "2"
7 7
8[dependencies] 8[dependencies]
9embassy = { version = "0.1.0", path = "../embassy" } 9embassy = { version = "0.1.0", path = "../embassy", features = ["time-tick-32768hz"] }
10embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] } 10embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] }
11embassy-extras = {version = "0.1.0", path = "../embassy-extras" } 11embassy-extras = {version = "0.1.0", path = "../embassy-extras" }
12embassy-traits = {version = "0.1.0", path = "../embassy-traits" } 12embassy-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]>"]
5edition = "2018" 5edition = "2018"
6 6
7[features] 7[features]
8default = ["tick-32768hz"] 8default = []
9std = ["futures/std", "embassy-traits/std"] 9std = ["futures/std", "embassy-traits/std"]
10tick-32768hz = [] 10
11tick-1000hz = [] 11time = []
12tick-1mhz = [] 12time-tick-32768hz = ["time"]
13time-tick-1000hz = ["time"]
14time-tick-1mhz = ["time"]
13 15
14defmt-trace = [] 16defmt-trace = []
15defmt-debug = [] 17defmt-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
5pub mod raw; 5pub mod raw;
6mod run_queue; 6mod run_queue;
7#[cfg(feature = "time")]
7mod timer_queue; 8mod timer_queue;
8mod util; 9mod util;
9mod waker; 10mod waker;
10 11
11use crate::interrupt::{Interrupt, InterruptExt}; 12use crate::interrupt::{Interrupt, InterruptExt};
12use 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()"]
15pub struct SpawnToken<F> { 15pub 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 @@
1use atomic_polyfill::{AtomicU32, Ordering}; 1use atomic_polyfill::{AtomicU32, Ordering};
2use core::cell::Cell; 2use core::cell::Cell;
3use core::cmp::min;
4use core::future::Future; 3use core::future::Future;
5use core::marker::PhantomData; 4use core::marker::PhantomData;
6use core::pin::Pin; 5use core::pin::Pin;
7use core::ptr::NonNull; 6use core::ptr::NonNull;
8use core::task::{Context, Poll, Waker}; 7use core::task::{Context, Poll};
9use core::{mem, ptr}; 8use core::{mem, ptr};
10 9
11use super::run_queue::{RunQueue, RunQueueItem}; 10use super::run_queue::{RunQueue, RunQueueItem};
12use super::timer_queue::{TimerQueue, TimerQueueItem};
13use super::util::UninitCell; 11use super::util::UninitCell;
14use super::waker; 12use super::waker;
15use super::SpawnToken; 13use super::SpawnToken;
14
15#[cfg(feature = "time")]
16use super::timer_queue::{TimerQueue, TimerQueueItem};
17#[cfg(feature = "time")]
16use crate::time::{Alarm, Instant}; 18use 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
21pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; 23pub(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")]
23pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2; 26pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2;
24 27
25pub struct TaskHeader { 28pub 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
34impl TaskHeader { 40impl 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
155pub struct Executor { 164pub 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
245pub(crate) unsafe fn register_timer(at: Instant, waker: &Waker) { 266#[cfg(feature = "time")]
267pub(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;
14pub mod executor; 14pub mod executor;
15pub mod interrupt; 15pub mod interrupt;
16pub mod io; 16pub mod io;
17#[cfg(feature = "time")]
17pub mod time; 18pub mod time;
18pub mod util; 19pub 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;
13pub use timer::{with_timeout, Ticker, TimeoutError, Timer}; 13pub use timer::{with_timeout, Ticker, TimeoutError, Timer};
14pub use traits::*; 14pub 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))]
20compile_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")]
25pub const TICKS_PER_SECOND: u64 = 1_000; 17pub const TICKS_PER_SECOND: u64 = 1_000;
26 18
27#[cfg(feature = "tick-32768hz")] 19#[cfg(feature = "time-tick-32768hz")]
28pub const TICKS_PER_SECOND: u64 = 32_768; 20pub const TICKS_PER_SECOND: u64 = 32_768;
29 21
30#[cfg(feature = "tick-1mhz")] 22#[cfg(feature = "time-tick-1mhz")]
31pub const TICKS_PER_SECOND: u64 = 1_000_000; 23pub const TICKS_PER_SECOND: u64 = 1_000_000;
32 24
33static mut CLOCK: Option<&'static dyn Clock> = None; 25static mut CLOCK: Option<&'static dyn Clock> = None;