diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-01-11 22:47:05 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-01-11 23:01:24 +0100 |
| commit | f0606da9adc8032cc92c06c0661b385742459fc8 (patch) | |
| tree | ccff465740429fa86f3455312ae02eab1170f8d4 | |
| parent | b3ab2d91f7ed48e6a377661e7e504cb0ae0091a3 (diff) | |
time: split queue driver too, don't reexport drivers.
| -rw-r--r-- | embassy-executor/Cargo.toml | 9 | ||||
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 27 | ||||
| -rw-r--r-- | embassy-executor/src/raw/timer_queue.rs | 12 | ||||
| -rw-r--r-- | embassy-time-driver/CHANGELOG.md | 51 | ||||
| -rw-r--r-- | embassy-time-queue-driver/Cargo.toml | 25 | ||||
| -rw-r--r-- | embassy-time-queue-driver/README.md | 8 | ||||
| -rw-r--r-- | embassy-time-queue-driver/build.rs | 1 | ||||
| -rw-r--r-- | embassy-time-queue-driver/src/lib.rs (renamed from embassy-time/src/queue.rs) | 42 | ||||
| -rw-r--r-- | embassy-time/Cargo.toml | 1 | ||||
| -rw-r--r-- | embassy-time/src/driver_mock.rs | 4 | ||||
| -rw-r--r-- | embassy-time/src/driver_std.rs | 5 | ||||
| -rw-r--r-- | embassy-time/src/driver_wasm.rs | 5 | ||||
| -rw-r--r-- | embassy-time/src/instant.rs | 6 | ||||
| -rw-r--r-- | embassy-time/src/lib.rs | 5 | ||||
| -rw-r--r-- | embassy-time/src/queue_generic.rs | 10 | ||||
| -rw-r--r-- | embassy-time/src/timer.rs | 16 | ||||
| -rw-r--r-- | examples/std/src/bin/serial.rs | 1 |
17 files changed, 100 insertions, 128 deletions
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index c71452398..da3c9a4fc 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml | |||
| @@ -33,7 +33,8 @@ log = { version = "0.4.14", optional = true } | |||
| 33 | rtos-trace = { version = "0.1.2", optional = true } | 33 | rtos-trace = { version = "0.1.2", optional = true } |
| 34 | 34 | ||
| 35 | embassy-executor-macros = { version = "0.4.0", path = "../embassy-executor-macros" } | 35 | embassy-executor-macros = { version = "0.4.0", path = "../embassy-executor-macros" } |
| 36 | embassy-time = { version = "0.2", path = "../embassy-time", optional = true} | 36 | embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver", optional = true } |
| 37 | embassy-time-queue-driver = { version = "0.1.0", path = "../embassy-time-queue-driver", optional = true } | ||
| 37 | critical-section = "1.1" | 38 | critical-section = "1.1" |
| 38 | 39 | ||
| 39 | document-features = "0.2.7" | 40 | document-features = "0.2.7" |
| @@ -63,8 +64,8 @@ nightly = ["embassy-executor-macros/nightly"] | |||
| 63 | # See: https://github.com/embassy-rs/embassy/pull/1263 | 64 | # See: https://github.com/embassy-rs/embassy/pull/1263 |
| 64 | turbowakers = [] | 65 | turbowakers = [] |
| 65 | 66 | ||
| 66 | ## Use timers from `embassy-time` | 67 | ## Use the executor-integrated `embassy-time` timer queue. |
| 67 | integrated-timers = ["dep:embassy-time"] | 68 | integrated-timers = ["dep:embassy-time-driver", "dep:embassy-time-queue-driver"] |
| 68 | 69 | ||
| 69 | #! ### Architecture | 70 | #! ### Architecture |
| 70 | _arch = [] # some arch was picked | 71 | _arch = [] # some arch was picked |
| @@ -177,4 +178,4 @@ task-arena-size-1048576 = [] | |||
| 177 | 178 | ||
| 178 | # END AUTOGENERATED CONFIG FEATURES | 179 | # END AUTOGENERATED CONFIG FEATURES |
| 179 | 180 | ||
| 180 | #! </details> \ No newline at end of file | 181 | #! </details> |
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index b16a1c7c3..3f00be4a8 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -30,9 +30,7 @@ use core::ptr::NonNull; | |||
| 30 | use core::task::{Context, Poll}; | 30 | use core::task::{Context, Poll}; |
| 31 | 31 | ||
| 32 | #[cfg(feature = "integrated-timers")] | 32 | #[cfg(feature = "integrated-timers")] |
| 33 | use embassy_time::driver::{self, AlarmHandle}; | 33 | use embassy_time_driver::{self, AlarmHandle}; |
| 34 | #[cfg(feature = "integrated-timers")] | ||
| 35 | use embassy_time::Instant; | ||
| 36 | #[cfg(feature = "rtos-trace")] | 34 | #[cfg(feature = "rtos-trace")] |
| 37 | use rtos_trace::trace; | 35 | use rtos_trace::trace; |
| 38 | 36 | ||
| @@ -50,7 +48,7 @@ pub(crate) struct TaskHeader { | |||
| 50 | poll_fn: SyncUnsafeCell<Option<unsafe fn(TaskRef)>>, | 48 | poll_fn: SyncUnsafeCell<Option<unsafe fn(TaskRef)>>, |
| 51 | 49 | ||
| 52 | #[cfg(feature = "integrated-timers")] | 50 | #[cfg(feature = "integrated-timers")] |
| 53 | pub(crate) expires_at: SyncUnsafeCell<Instant>, | 51 | pub(crate) expires_at: SyncUnsafeCell<u64>, |
| 54 | #[cfg(feature = "integrated-timers")] | 52 | #[cfg(feature = "integrated-timers")] |
| 55 | pub(crate) timer_queue_item: timer_queue::TimerQueueItem, | 53 | pub(crate) timer_queue_item: timer_queue::TimerQueueItem, |
| 56 | } | 54 | } |
| @@ -123,7 +121,7 @@ impl<F: Future + 'static> TaskStorage<F> { | |||
| 123 | poll_fn: SyncUnsafeCell::new(None), | 121 | poll_fn: SyncUnsafeCell::new(None), |
| 124 | 122 | ||
| 125 | #[cfg(feature = "integrated-timers")] | 123 | #[cfg(feature = "integrated-timers")] |
| 126 | expires_at: SyncUnsafeCell::new(Instant::from_ticks(0)), | 124 | expires_at: SyncUnsafeCell::new(0), |
| 127 | #[cfg(feature = "integrated-timers")] | 125 | #[cfg(feature = "integrated-timers")] |
| 128 | timer_queue_item: timer_queue::TimerQueueItem::new(), | 126 | timer_queue_item: timer_queue::TimerQueueItem::new(), |
| 129 | }, | 127 | }, |
| @@ -164,7 +162,7 @@ impl<F: Future + 'static> TaskStorage<F> { | |||
| 164 | this.raw.state.despawn(); | 162 | this.raw.state.despawn(); |
| 165 | 163 | ||
| 166 | #[cfg(feature = "integrated-timers")] | 164 | #[cfg(feature = "integrated-timers")] |
| 167 | this.raw.expires_at.set(Instant::MAX); | 165 | this.raw.expires_at.set(u64::MAX); |
| 168 | } | 166 | } |
| 169 | Poll::Pending => {} | 167 | Poll::Pending => {} |
| 170 | } | 168 | } |
| @@ -328,7 +326,7 @@ pub(crate) struct SyncExecutor { | |||
| 328 | impl SyncExecutor { | 326 | impl SyncExecutor { |
| 329 | pub(crate) fn new(pender: Pender) -> Self { | 327 | pub(crate) fn new(pender: Pender) -> Self { |
| 330 | #[cfg(feature = "integrated-timers")] | 328 | #[cfg(feature = "integrated-timers")] |
| 331 | let alarm = unsafe { unwrap!(driver::allocate_alarm()) }; | 329 | let alarm = unsafe { unwrap!(embassy_time_driver::allocate_alarm()) }; |
| 332 | 330 | ||
| 333 | Self { | 331 | Self { |
| 334 | run_queue: RunQueue::new(), | 332 | run_queue: RunQueue::new(), |
| @@ -377,18 +375,19 @@ impl SyncExecutor { | |||
| 377 | /// Same as [`Executor::poll`], plus you must only call this on the thread this executor was created. | 375 | /// Same as [`Executor::poll`], plus you must only call this on the thread this executor was created. |
| 378 | pub(crate) unsafe fn poll(&'static self) { | 376 | pub(crate) unsafe fn poll(&'static self) { |
| 379 | #[cfg(feature = "integrated-timers")] | 377 | #[cfg(feature = "integrated-timers")] |
| 380 | driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ()); | 378 | embassy_time_driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ()); |
| 381 | 379 | ||
| 382 | #[allow(clippy::never_loop)] | 380 | #[allow(clippy::never_loop)] |
| 383 | loop { | 381 | loop { |
| 384 | #[cfg(feature = "integrated-timers")] | 382 | #[cfg(feature = "integrated-timers")] |
| 385 | self.timer_queue.dequeue_expired(Instant::now(), wake_task_no_pend); | 383 | self.timer_queue |
| 384 | .dequeue_expired(embassy_time_driver::now(), wake_task_no_pend); | ||
| 386 | 385 | ||
| 387 | self.run_queue.dequeue_all(|p| { | 386 | self.run_queue.dequeue_all(|p| { |
| 388 | let task = p.header(); | 387 | let task = p.header(); |
| 389 | 388 | ||
| 390 | #[cfg(feature = "integrated-timers")] | 389 | #[cfg(feature = "integrated-timers")] |
| 391 | task.expires_at.set(Instant::MAX); | 390 | task.expires_at.set(u64::MAX); |
| 392 | 391 | ||
| 393 | if !task.state.run_dequeue() { | 392 | if !task.state.run_dequeue() { |
| 394 | // If task is not running, ignore it. This can happen in the following scenario: | 393 | // If task is not running, ignore it. This can happen in the following scenario: |
| @@ -418,7 +417,7 @@ impl SyncExecutor { | |||
| 418 | // If this is already in the past, set_alarm might return false | 417 | // If this is already in the past, set_alarm might return false |
| 419 | // In that case do another poll loop iteration. | 418 | // In that case do another poll loop iteration. |
| 420 | let next_expiration = self.timer_queue.next_expiration(); | 419 | let next_expiration = self.timer_queue.next_expiration(); |
| 421 | if driver::set_alarm(self.alarm, next_expiration.as_ticks()) { | 420 | if embassy_time_driver::set_alarm(self.alarm, next_expiration) { |
| 422 | break; | 421 | break; |
| 423 | } | 422 | } |
| 424 | } | 423 | } |
| @@ -568,8 +567,8 @@ pub fn wake_task_no_pend(task: TaskRef) { | |||
| 568 | struct TimerQueue; | 567 | struct TimerQueue; |
| 569 | 568 | ||
| 570 | #[cfg(feature = "integrated-timers")] | 569 | #[cfg(feature = "integrated-timers")] |
| 571 | impl embassy_time::queue::TimerQueue for TimerQueue { | 570 | impl embassy_time_queue_driver::TimerQueue for TimerQueue { |
| 572 | fn schedule_wake(&'static self, at: Instant, waker: &core::task::Waker) { | 571 | fn schedule_wake(&'static self, at: u64, waker: &core::task::Waker) { |
| 573 | let task = waker::task_from_waker(waker); | 572 | let task = waker::task_from_waker(waker); |
| 574 | let task = task.header(); | 573 | let task = task.header(); |
| 575 | unsafe { | 574 | unsafe { |
| @@ -580,7 +579,7 @@ impl embassy_time::queue::TimerQueue for TimerQueue { | |||
| 580 | } | 579 | } |
| 581 | 580 | ||
| 582 | #[cfg(feature = "integrated-timers")] | 581 | #[cfg(feature = "integrated-timers")] |
| 583 | embassy_time::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue); | 582 | embassy_time_queue_driver::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue); |
| 584 | 583 | ||
| 585 | #[cfg(feature = "rtos-trace")] | 584 | #[cfg(feature = "rtos-trace")] |
| 586 | impl rtos_trace::RtosTraceOSCallbacks for Executor { | 585 | impl rtos_trace::RtosTraceOSCallbacks for Executor { |
diff --git a/embassy-executor/src/raw/timer_queue.rs b/embassy-executor/src/raw/timer_queue.rs index 59a3b43f5..94a5f340b 100644 --- a/embassy-executor/src/raw/timer_queue.rs +++ b/embassy-executor/src/raw/timer_queue.rs | |||
| @@ -1,7 +1,5 @@ | |||
| 1 | use core::cmp::min; | 1 | use core::cmp::min; |
| 2 | 2 | ||
| 3 | use embassy_time::Instant; | ||
| 4 | |||
| 5 | use super::TaskRef; | 3 | use super::TaskRef; |
| 6 | use crate::raw::util::SyncUnsafeCell; | 4 | use crate::raw::util::SyncUnsafeCell; |
| 7 | 5 | ||
| @@ -30,7 +28,7 @@ impl TimerQueue { | |||
| 30 | 28 | ||
| 31 | pub(crate) unsafe fn update(&self, p: TaskRef) { | 29 | pub(crate) unsafe fn update(&self, p: TaskRef) { |
| 32 | let task = p.header(); | 30 | let task = p.header(); |
| 33 | if task.expires_at.get() != Instant::MAX { | 31 | if task.expires_at.get() != u64::MAX { |
| 34 | if task.state.timer_enqueue() { | 32 | if task.state.timer_enqueue() { |
| 35 | task.timer_queue_item.next.set(self.head.get()); | 33 | task.timer_queue_item.next.set(self.head.get()); |
| 36 | self.head.set(Some(p)); | 34 | self.head.set(Some(p)); |
| @@ -38,18 +36,18 @@ impl TimerQueue { | |||
| 38 | } | 36 | } |
| 39 | } | 37 | } |
| 40 | 38 | ||
| 41 | pub(crate) unsafe fn next_expiration(&self) -> Instant { | 39 | pub(crate) unsafe fn next_expiration(&self) -> u64 { |
| 42 | let mut res = Instant::MAX; | 40 | let mut res = u64::MAX; |
| 43 | self.retain(|p| { | 41 | self.retain(|p| { |
| 44 | let task = p.header(); | 42 | let task = p.header(); |
| 45 | let expires = task.expires_at.get(); | 43 | let expires = task.expires_at.get(); |
| 46 | res = min(res, expires); | 44 | res = min(res, expires); |
| 47 | expires != Instant::MAX | 45 | expires != u64::MAX |
| 48 | }); | 46 | }); |
| 49 | res | 47 | res |
| 50 | } | 48 | } |
| 51 | 49 | ||
| 52 | pub(crate) unsafe fn dequeue_expired(&self, now: Instant, on_task: impl Fn(TaskRef)) { | 50 | pub(crate) unsafe fn dequeue_expired(&self, now: u64, on_task: impl Fn(TaskRef)) { |
| 53 | self.retain(|p| { | 51 | self.retain(|p| { |
| 54 | let task = p.header(); | 52 | let task = p.header(); |
| 55 | if task.expires_at.get() <= now { | 53 | if task.expires_at.get() <= now { |
diff --git a/embassy-time-driver/CHANGELOG.md b/embassy-time-driver/CHANGELOG.md deleted file mode 100644 index d8c0c7d08..000000000 --- a/embassy-time-driver/CHANGELOG.md +++ /dev/null | |||
| @@ -1,51 +0,0 @@ | |||
| 1 | # Changelog | ||
| 2 | |||
| 3 | All notable changes to this project will be documented in this file. | ||
| 4 | |||
| 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
| 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
| 7 | |||
| 8 | ## 0.2.0 - 2023-12-04 | ||
| 9 | |||
| 10 | - Added tick rates in multiples of 10 kHz | ||
| 11 | - Remove nightly and unstable-traits features in preparation for 1.75. | ||
| 12 | - Update heapless to 0.8. | ||
| 13 | |||
| 14 | ## 0.1.5 - 2023-10-16 | ||
| 15 | |||
| 16 | - Added `links` key to Cargo.toml, to prevent multiple copies of this crate in the same binary. | ||
| 17 | Needed because different copies might get different tick rates, causing | ||
| 18 | wrong delays if the time driver is using one copy and user code is using another. | ||
| 19 | This is especially common when mixing crates from crates.io and git. | ||
| 20 | |||
| 21 | ## 0.1.4 - 2023-10-12 | ||
| 22 | |||
| 23 | - Added more tick rates | ||
| 24 | |||
| 25 | ## 0.1.3 - 2023-08-28 | ||
| 26 | |||
| 27 | - Update `embedded-hal-async` to `1.0.0-rc.2` | ||
| 28 | - Update `embedded-hal v1` to `1.0.0-rc.2` | ||
| 29 | |||
| 30 | ## 0.1.2 - 2023-07-05 | ||
| 31 | |||
| 32 | - Update `embedded-hal-async` to `0.2.0-alpha.2`. | ||
| 33 | - Update `embedded-hal v1` to `1.0.0-alpha.11`. (Note: v0.2 support is kept unchanged). | ||
| 34 | |||
| 35 | ## 0.1.1 - 2023-04-13 | ||
| 36 | |||
| 37 | - Update `embedded-hal-async` to `0.2.0-alpha.1` (uses `async fn` in traits). | ||
| 38 | - Update `embedded-hal v1` to `1.0.0-alpha.10`. (Note: v0.2 support is kept unchanged). | ||
| 39 | - Remove dep on `embassy-sync`. | ||
| 40 | - Fix reentrancy issues in the `std` time driver (#1177) | ||
| 41 | - Add `Duration::from_hz()`. | ||
| 42 | - impl `From` conversions to/from `core::time::Duration`. | ||
| 43 | - Add `#[must_use]` to all futures. | ||
| 44 | - Add inherent `async fn tick()` to `Ticker`, so you can use it directly without the `Stream` trait. | ||
| 45 | - Add more tick rates. | ||
| 46 | - impl `Default` for `Signal` | ||
| 47 | - Remove unnecessary uses of `atomic-polyfill` | ||
| 48 | |||
| 49 | ## 0.1.0 - 2022-08-26 | ||
| 50 | |||
| 51 | - First release | ||
diff --git a/embassy-time-queue-driver/Cargo.toml b/embassy-time-queue-driver/Cargo.toml new file mode 100644 index 000000000..85ee1da1b --- /dev/null +++ b/embassy-time-queue-driver/Cargo.toml | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | [package] | ||
| 2 | name = "embassy-time-queue-driver" | ||
| 3 | version = "0.1.0" | ||
| 4 | edition = "2021" | ||
| 5 | description = "Timer queue driver trait for embassy-time" | ||
| 6 | repository = "https://github.com/embassy-rs/embassy" | ||
| 7 | readme = "README.md" | ||
| 8 | license = "MIT OR Apache-2.0" | ||
| 9 | categories = [ | ||
| 10 | "embedded", | ||
| 11 | "no-std", | ||
| 12 | "concurrency", | ||
| 13 | "asynchronous", | ||
| 14 | ] | ||
| 15 | |||
| 16 | # Prevent multiple copies of this crate in the same binary. | ||
| 17 | # Needed because different copies might get different tick rates, causing | ||
| 18 | # wrong delays if the time driver is using one copy and user code is using another. | ||
| 19 | # This is especially common when mixing crates from crates.io and git. | ||
| 20 | links = "embassy-time-queue" | ||
| 21 | |||
| 22 | [package.metadata.embassy_docs] | ||
| 23 | src_base = "https://github.com/embassy-rs/embassy/blob/embassy-time-queue-driver-v$VERSION/embassy-time-queue-driver/src/" | ||
| 24 | src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-time-queue-driver/src/" | ||
| 25 | target = "x86_64-unknown-linux-gnu" | ||
diff --git a/embassy-time-queue-driver/README.md b/embassy-time-queue-driver/README.md new file mode 100644 index 000000000..8852b0358 --- /dev/null +++ b/embassy-time-queue-driver/README.md | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | # embassy-time-queue-driver | ||
| 2 | |||
| 3 | This crate contains the driver trait used by the [`embassy-time`](https://crates.io/crates/embassy-time) timer queue. | ||
| 4 | |||
| 5 | You should rarely need to use this crate directly. Only use it when implementing your own timer queue. | ||
| 6 | |||
| 7 | There is two timer queue implementations, one in `embassy-time` enabled by the `generic-queue` feature, and | ||
| 8 | another in `embassy-executor` enabled by the `integrated-timers` feature. | ||
diff --git a/embassy-time-queue-driver/build.rs b/embassy-time-queue-driver/build.rs new file mode 100644 index 000000000..f328e4d9d --- /dev/null +++ b/embassy-time-queue-driver/build.rs | |||
| @@ -0,0 +1 @@ | |||
| fn main() {} | |||
diff --git a/embassy-time/src/queue.rs b/embassy-time-queue-driver/src/lib.rs index d65197c54..50736e8c7 100644 --- a/embassy-time/src/queue.rs +++ b/embassy-time-queue-driver/src/lib.rs | |||
| @@ -1,20 +1,14 @@ | |||
| 1 | //! Timer queue implementation | 1 | #![no_std] |
| 2 | //! | 2 | #![doc = include_str!("../README.md")] |
| 3 | //! This module defines the interface a timer queue needs to implement to power the `embassy_time` module. | 3 | #![warn(missing_docs)] |
| 4 | //! | 4 | |
| 5 | //! # Implementing a timer queue | 5 | //! ## Implementing a timer queue |
| 6 | //! | 6 | //! |
| 7 | //! - Define a struct `MyTimerQueue` | 7 | //! - Define a struct `MyTimerQueue` |
| 8 | //! - Implement [`TimerQueue`] for it | 8 | //! - Implement [`TimerQueue`] for it |
| 9 | //! - Register it as the global timer queue with [`timer_queue_impl`](crate::timer_queue_impl). | 9 | //! - Register it as the global timer queue with [`timer_queue_impl`](crate::timer_queue_impl). |
| 10 | //! | 10 | //! |
| 11 | //! # Linkage details | 11 | //! ## Example |
| 12 | //! | ||
| 13 | //! Check the documentation of the [`driver`](crate::driver) module for more information. | ||
| 14 | //! | ||
| 15 | //! Similarly to driver, if there is none or multiple timer queues in the crate tree, linking will fail. | ||
| 16 | //! | ||
| 17 | //! # Example | ||
| 18 | //! | 12 | //! |
| 19 | //! ``` | 13 | //! ``` |
| 20 | //! use core::task::Waker; | 14 | //! use core::task::Waker; |
| @@ -25,23 +19,29 @@ | |||
| 25 | //! struct MyTimerQueue{}; // not public! | 19 | //! struct MyTimerQueue{}; // not public! |
| 26 | //! | 20 | //! |
| 27 | //! impl TimerQueue for MyTimerQueue { | 21 | //! impl TimerQueue for MyTimerQueue { |
| 28 | //! fn schedule_wake(&'static self, at: Instant, waker: &Waker) { | 22 | //! fn schedule_wake(&'static self, at: u64, waker: &Waker) { |
| 29 | //! todo!() | 23 | //! todo!() |
| 30 | //! } | 24 | //! } |
| 31 | //! } | 25 | //! } |
| 32 | //! ``` | 26 | //! |
| 33 | //! ```ignore | 27 | //! embassy_time_queue_driver::timer_queue_impl!(static QUEUE: MyTimerQueue = MyTimerQueue{}); |
| 34 | //! embassy_time::timer_queue_impl!(static QUEUE: MyTimerQueue = MyTimerQueue{}); | ||
| 35 | //! ``` | 28 | //! ``` |
| 36 | use core::task::Waker; | 29 | use core::task::Waker; |
| 37 | 30 | ||
| 38 | use crate::Instant; | ||
| 39 | |||
| 40 | /// Timer queue | 31 | /// Timer queue |
| 41 | pub trait TimerQueue { | 32 | pub trait TimerQueue { |
| 42 | /// Schedules a waker in the queue to be awoken at moment `at`. | 33 | /// Schedules a waker in the queue to be awoken at moment `at`. |
| 43 | /// If this moment is in the past, the waker might be awoken immediately. | 34 | /// If this moment is in the past, the waker might be awoken immediately. |
| 44 | fn schedule_wake(&'static self, at: Instant, waker: &Waker); | 35 | fn schedule_wake(&'static self, at: u64, waker: &Waker); |
| 36 | } | ||
| 37 | |||
| 38 | extern "Rust" { | ||
| 39 | fn _embassy_time_schedule_wake(at: u64, waker: &Waker); | ||
| 40 | } | ||
| 41 | |||
| 42 | /// Schedule the given waker to be woken at `at`. | ||
| 43 | pub fn schedule_wake(at: u64, waker: &Waker) { | ||
| 44 | unsafe { _embassy_time_schedule_wake(at, waker) } | ||
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | /// Set the TimerQueue implementation. | 47 | /// Set the TimerQueue implementation. |
| @@ -53,8 +53,8 @@ macro_rules! timer_queue_impl { | |||
| 53 | static $name: $t = $val; | 53 | static $name: $t = $val; |
| 54 | 54 | ||
| 55 | #[no_mangle] | 55 | #[no_mangle] |
| 56 | fn _embassy_time_schedule_wake(at: $crate::Instant, waker: &core::task::Waker) { | 56 | fn _embassy_time_schedule_wake(at: u64, waker: &core::task::Waker) { |
| 57 | <$t as $crate::queue::TimerQueue>::schedule_wake(&$name, at, waker); | 57 | <$t as $crate::TimerQueue>::schedule_wake(&$name, at, waker); |
| 58 | } | 58 | } |
| 59 | }; | 59 | }; |
| 60 | } | 60 | } |
diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index 729a2bd4f..f27de8ab4 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml | |||
| @@ -398,6 +398,7 @@ tick-hz-5_242_880_000 = ["embassy-time-driver/tick-hz-5_242_880_000"] | |||
| 398 | 398 | ||
| 399 | [dependencies] | 399 | [dependencies] |
| 400 | embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver" } | 400 | embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver" } |
| 401 | embassy-time-queue-driver = { version = "0.1.0", path = "../embassy-time-queue-driver" } | ||
| 401 | 402 | ||
| 402 | defmt = { version = "0.3", optional = true } | 403 | defmt = { version = "0.3", optional = true } |
| 403 | log = { version = "0.4.14", optional = true } | 404 | log = { version = "0.4.14", optional = true } |
diff --git a/embassy-time/src/driver_mock.rs b/embassy-time/src/driver_mock.rs index 7abc2bd70..8587f9172 100644 --- a/embassy-time/src/driver_mock.rs +++ b/embassy-time/src/driver_mock.rs | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | use core::cell::RefCell; | 1 | use core::cell::RefCell; |
| 2 | 2 | ||
| 3 | use critical_section::Mutex as CsMutex; | 3 | use critical_section::Mutex as CsMutex; |
| 4 | use embassy_time_driver::{AlarmHandle, Driver}; | ||
| 4 | 5 | ||
| 5 | use crate::driver::{AlarmHandle, Driver}; | ||
| 6 | use crate::{Duration, Instant}; | 6 | use crate::{Duration, Instant}; |
| 7 | 7 | ||
| 8 | /// A mock driver that can be manually advanced. | 8 | /// A mock driver that can be manually advanced. |
| @@ -28,7 +28,7 @@ use crate::{Duration, Instant}; | |||
| 28 | /// ``` | 28 | /// ``` |
| 29 | pub struct MockDriver(CsMutex<RefCell<InnerMockDriver>>); | 29 | pub struct MockDriver(CsMutex<RefCell<InnerMockDriver>>); |
| 30 | 30 | ||
| 31 | crate::driver::time_driver_impl!(static DRIVER: MockDriver = MockDriver::new()); | 31 | embassy_time_driver::time_driver_impl!(static DRIVER: MockDriver = MockDriver::new()); |
| 32 | 32 | ||
| 33 | impl MockDriver { | 33 | impl MockDriver { |
| 34 | /// Creates a new mock driver. | 34 | /// Creates a new mock driver. |
diff --git a/embassy-time/src/driver_std.rs b/embassy-time/src/driver_std.rs index 3b5524f9e..d182f8331 100644 --- a/embassy-time/src/driver_std.rs +++ b/embassy-time/src/driver_std.rs | |||
| @@ -6,8 +6,7 @@ use std::time::{Duration as StdDuration, Instant as StdInstant}; | |||
| 6 | use std::{mem, ptr, thread}; | 6 | use std::{mem, ptr, thread}; |
| 7 | 7 | ||
| 8 | use critical_section::Mutex as CsMutex; | 8 | use critical_section::Mutex as CsMutex; |
| 9 | 9 | use embassy_time_driver::{AlarmHandle, Driver}; | |
| 10 | use crate::driver::{AlarmHandle, Driver}; | ||
| 11 | 10 | ||
| 12 | const ALARM_COUNT: usize = 4; | 11 | const ALARM_COUNT: usize = 4; |
| 13 | 12 | ||
| @@ -45,7 +44,7 @@ struct TimeDriver { | |||
| 45 | } | 44 | } |
| 46 | 45 | ||
| 47 | const ALARM_NEW: AlarmState = AlarmState::new(); | 46 | const ALARM_NEW: AlarmState = AlarmState::new(); |
| 48 | crate::driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver { | 47 | embassy_time_driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver { |
| 49 | alarm_count: AtomicU8::new(0), | 48 | alarm_count: AtomicU8::new(0), |
| 50 | 49 | ||
| 51 | once: Once::new(), | 50 | once: Once::new(), |
diff --git a/embassy-time/src/driver_wasm.rs b/embassy-time/src/driver_wasm.rs index d75856c26..ad884f060 100644 --- a/embassy-time/src/driver_wasm.rs +++ b/embassy-time/src/driver_wasm.rs | |||
| @@ -4,11 +4,10 @@ use std::mem::MaybeUninit; | |||
| 4 | use std::ptr; | 4 | use std::ptr; |
| 5 | use std::sync::{Mutex, Once}; | 5 | use std::sync::{Mutex, Once}; |
| 6 | 6 | ||
| 7 | use embassy_time_driver::{AlarmHandle, Driver}; | ||
| 7 | use wasm_bindgen::prelude::*; | 8 | use wasm_bindgen::prelude::*; |
| 8 | use wasm_timer::Instant as StdInstant; | 9 | use wasm_timer::Instant as StdInstant; |
| 9 | 10 | ||
| 10 | use crate::driver::{AlarmHandle, Driver}; | ||
| 11 | |||
| 12 | const ALARM_COUNT: usize = 4; | 11 | const ALARM_COUNT: usize = 4; |
| 13 | 12 | ||
| 14 | struct AlarmState { | 13 | struct AlarmState { |
| @@ -42,7 +41,7 @@ struct TimeDriver { | |||
| 42 | } | 41 | } |
| 43 | 42 | ||
| 44 | const ALARM_NEW: AlarmState = AlarmState::new(); | 43 | const ALARM_NEW: AlarmState = AlarmState::new(); |
| 45 | crate::driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver { | 44 | embassy_time_driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver { |
| 46 | alarm_count: AtomicU8::new(0), | 45 | alarm_count: AtomicU8::new(0), |
| 47 | once: Once::new(), | 46 | once: Once::new(), |
| 48 | alarms: UninitCell::uninit(), | 47 | alarms: UninitCell::uninit(), |
diff --git a/embassy-time/src/instant.rs b/embassy-time/src/instant.rs index 5571cdd15..909f1b173 100644 --- a/embassy-time/src/instant.rs +++ b/embassy-time/src/instant.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use core::fmt; | 1 | use core::fmt; |
| 2 | use core::ops::{Add, AddAssign, Sub, SubAssign}; | 2 | use core::ops::{Add, AddAssign, Sub, SubAssign}; |
| 3 | 3 | ||
| 4 | use super::{driver, Duration, GCD_1K, GCD_1M, TICK_HZ}; | 4 | use super::{Duration, GCD_1K, GCD_1M, TICK_HZ}; |
| 5 | 5 | ||
| 6 | #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] | 6 | #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] |
| 7 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 7 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -18,7 +18,9 @@ impl Instant { | |||
| 18 | 18 | ||
| 19 | /// Returns an Instant representing the current time. | 19 | /// Returns an Instant representing the current time. |
| 20 | pub fn now() -> Instant { | 20 | pub fn now() -> Instant { |
| 21 | Instant { ticks: driver::now() } | 21 | Instant { |
| 22 | ticks: embassy_time_driver::now(), | ||
| 23 | } | ||
| 22 | } | 24 | } |
| 23 | 25 | ||
| 24 | /// Create an Instant from a tick count since system boot. | 26 | /// Create an Instant from a tick count since system boot. |
diff --git a/embassy-time/src/lib.rs b/embassy-time/src/lib.rs index 3f8c09f1a..d27eb92f6 100644 --- a/embassy-time/src/lib.rs +++ b/embassy-time/src/lib.rs | |||
| @@ -10,12 +10,9 @@ | |||
| 10 | // This mod MUST go first, so that the others see its macros. | 10 | // This mod MUST go first, so that the others see its macros. |
| 11 | pub(crate) mod fmt; | 11 | pub(crate) mod fmt; |
| 12 | 12 | ||
| 13 | pub use embassy_time_driver as driver; | ||
| 14 | |||
| 15 | mod delay; | 13 | mod delay; |
| 16 | mod duration; | 14 | mod duration; |
| 17 | mod instant; | 15 | mod instant; |
| 18 | pub mod queue; | ||
| 19 | mod timer; | 16 | mod timer; |
| 20 | 17 | ||
| 21 | #[cfg(feature = "mock-driver")] | 18 | #[cfg(feature = "mock-driver")] |
| @@ -32,8 +29,8 @@ mod driver_wasm; | |||
| 32 | mod queue_generic; | 29 | mod queue_generic; |
| 33 | 30 | ||
| 34 | pub use delay::{block_for, Delay}; | 31 | pub use delay::{block_for, Delay}; |
| 35 | pub use driver::TICK_HZ; | ||
| 36 | pub use duration::Duration; | 32 | pub use duration::Duration; |
| 33 | pub use embassy_time_driver::TICK_HZ; | ||
| 37 | pub use instant::Instant; | 34 | pub use instant::Instant; |
| 38 | pub use timer::{with_timeout, Ticker, TimeoutError, Timer}; | 35 | pub use timer::{with_timeout, Ticker, TimeoutError, Timer}; |
| 39 | 36 | ||
diff --git a/embassy-time/src/queue_generic.rs b/embassy-time/src/queue_generic.rs index 829368ffc..cf7a986d5 100644 --- a/embassy-time/src/queue_generic.rs +++ b/embassy-time/src/queue_generic.rs | |||
| @@ -3,10 +3,10 @@ use core::cmp::{min, Ordering}; | |||
| 3 | use core::task::Waker; | 3 | use core::task::Waker; |
| 4 | 4 | ||
| 5 | use critical_section::Mutex; | 5 | use critical_section::Mutex; |
| 6 | use embassy_time_driver::{allocate_alarm, set_alarm, set_alarm_callback, AlarmHandle}; | ||
| 7 | use embassy_time_queue_driver::TimerQueue; | ||
| 6 | use heapless::Vec; | 8 | use heapless::Vec; |
| 7 | 9 | ||
| 8 | use crate::driver::{allocate_alarm, set_alarm, set_alarm_callback, AlarmHandle}; | ||
| 9 | use crate::queue::TimerQueue; | ||
| 10 | use crate::Instant; | 10 | use crate::Instant; |
| 11 | 11 | ||
| 12 | #[cfg(feature = "generic-queue-8")] | 12 | #[cfg(feature = "generic-queue-8")] |
| @@ -167,12 +167,12 @@ impl Queue { | |||
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | impl TimerQueue for Queue { | 169 | impl TimerQueue for Queue { |
| 170 | fn schedule_wake(&'static self, at: Instant, waker: &Waker) { | 170 | fn schedule_wake(&'static self, at: u64, waker: &Waker) { |
| 171 | Queue::schedule_wake(self, at, waker); | 171 | Queue::schedule_wake(self, Instant::from_ticks(at), waker); |
| 172 | } | 172 | } |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | crate::timer_queue_impl!(static QUEUE: Queue = Queue::new()); | 175 | embassy_time_queue_driver::timer_queue_impl!(static QUEUE: Queue = Queue::new()); |
| 176 | 176 | ||
| 177 | #[cfg(test)] | 177 | #[cfg(test)] |
| 178 | #[cfg(feature = "mock-driver")] | 178 | #[cfg(feature = "mock-driver")] |
diff --git a/embassy-time/src/timer.rs b/embassy-time/src/timer.rs index 2705ba03f..565a65cb8 100644 --- a/embassy-time/src/timer.rs +++ b/embassy-time/src/timer.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::future::{poll_fn, Future}; | 1 | use core::future::{poll_fn, Future}; |
| 2 | use core::pin::Pin; | 2 | use core::pin::Pin; |
| 3 | use core::task::{Context, Poll, Waker}; | 3 | use core::task::{Context, Poll}; |
| 4 | 4 | ||
| 5 | use futures_util::future::{select, Either}; | 5 | use futures_util::future::{select, Either}; |
| 6 | use futures_util::stream::FusedStream; | 6 | use futures_util::stream::FusedStream; |
| @@ -116,7 +116,7 @@ impl Future for Timer { | |||
| 116 | if self.yielded_once && self.expires_at <= Instant::now() { | 116 | if self.yielded_once && self.expires_at <= Instant::now() { |
| 117 | Poll::Ready(()) | 117 | Poll::Ready(()) |
| 118 | } else { | 118 | } else { |
| 119 | schedule_wake(self.expires_at, cx.waker()); | 119 | embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker()); |
| 120 | self.yielded_once = true; | 120 | self.yielded_once = true; |
| 121 | Poll::Pending | 121 | Poll::Pending |
| 122 | } | 122 | } |
| @@ -185,7 +185,7 @@ impl Ticker { | |||
| 185 | self.expires_at += dur; | 185 | self.expires_at += dur; |
| 186 | Poll::Ready(()) | 186 | Poll::Ready(()) |
| 187 | } else { | 187 | } else { |
| 188 | schedule_wake(self.expires_at, cx.waker()); | 188 | embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker()); |
| 189 | Poll::Pending | 189 | Poll::Pending |
| 190 | } | 190 | } |
| 191 | }) | 191 | }) |
| @@ -202,7 +202,7 @@ impl Stream for Ticker { | |||
| 202 | self.expires_at += dur; | 202 | self.expires_at += dur; |
| 203 | Poll::Ready(Some(())) | 203 | Poll::Ready(Some(())) |
| 204 | } else { | 204 | } else { |
| 205 | schedule_wake(self.expires_at, cx.waker()); | 205 | embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker()); |
| 206 | Poll::Pending | 206 | Poll::Pending |
| 207 | } | 207 | } |
| 208 | } | 208 | } |
| @@ -214,11 +214,3 @@ impl FusedStream for Ticker { | |||
| 214 | false | 214 | false |
| 215 | } | 215 | } |
| 216 | } | 216 | } |
| 217 | |||
| 218 | extern "Rust" { | ||
| 219 | fn _embassy_time_schedule_wake(at: Instant, waker: &Waker); | ||
| 220 | } | ||
| 221 | |||
| 222 | fn schedule_wake(at: Instant, waker: &Waker) { | ||
| 223 | unsafe { _embassy_time_schedule_wake(at, waker) } | ||
| 224 | } | ||
diff --git a/examples/std/src/bin/serial.rs b/examples/std/src/bin/serial.rs index 435089aad..10c85511d 100644 --- a/examples/std/src/bin/serial.rs +++ b/examples/std/src/bin/serial.rs | |||
| @@ -3,6 +3,7 @@ mod serial_port; | |||
| 3 | 3 | ||
| 4 | use async_io::Async; | 4 | use async_io::Async; |
| 5 | use embassy_executor::Executor; | 5 | use embassy_executor::Executor; |
| 6 | use embassy_time as _; | ||
| 6 | use embedded_io_async::Read; | 7 | use embedded_io_async::Read; |
| 7 | use log::*; | 8 | use log::*; |
| 8 | use nix::sys::termios; | 9 | use nix::sys::termios; |
