time: split queue driver too, don't reexport drivers.
This commit is contained in:
parent
b3ab2d91f7
commit
f0606da9ad
17 changed files with 100 additions and 128 deletions
|
@ -33,7 +33,8 @@ log = { version = "0.4.14", optional = true }
|
||||||
rtos-trace = { version = "0.1.2", optional = true }
|
rtos-trace = { version = "0.1.2", optional = true }
|
||||||
|
|
||||||
embassy-executor-macros = { version = "0.4.0", path = "../embassy-executor-macros" }
|
embassy-executor-macros = { version = "0.4.0", path = "../embassy-executor-macros" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time", optional = true}
|
embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver", optional = true }
|
||||||
|
embassy-time-queue-driver = { version = "0.1.0", path = "../embassy-time-queue-driver", optional = true }
|
||||||
critical-section = "1.1"
|
critical-section = "1.1"
|
||||||
|
|
||||||
document-features = "0.2.7"
|
document-features = "0.2.7"
|
||||||
|
@ -63,8 +64,8 @@ nightly = ["embassy-executor-macros/nightly"]
|
||||||
# See: https://github.com/embassy-rs/embassy/pull/1263
|
# See: https://github.com/embassy-rs/embassy/pull/1263
|
||||||
turbowakers = []
|
turbowakers = []
|
||||||
|
|
||||||
## Use timers from `embassy-time`
|
## Use the executor-integrated `embassy-time` timer queue.
|
||||||
integrated-timers = ["dep:embassy-time"]
|
integrated-timers = ["dep:embassy-time-driver", "dep:embassy-time-queue-driver"]
|
||||||
|
|
||||||
#! ### Architecture
|
#! ### Architecture
|
||||||
_arch = [] # some arch was picked
|
_arch = [] # some arch was picked
|
||||||
|
|
|
@ -30,9 +30,7 @@ use core::ptr::NonNull;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
use embassy_time::driver::{self, AlarmHandle};
|
use embassy_time_driver::{self, AlarmHandle};
|
||||||
#[cfg(feature = "integrated-timers")]
|
|
||||||
use embassy_time::Instant;
|
|
||||||
#[cfg(feature = "rtos-trace")]
|
#[cfg(feature = "rtos-trace")]
|
||||||
use rtos_trace::trace;
|
use rtos_trace::trace;
|
||||||
|
|
||||||
|
@ -50,7 +48,7 @@ pub(crate) struct TaskHeader {
|
||||||
poll_fn: SyncUnsafeCell<Option<unsafe fn(TaskRef)>>,
|
poll_fn: SyncUnsafeCell<Option<unsafe fn(TaskRef)>>,
|
||||||
|
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
pub(crate) expires_at: SyncUnsafeCell<Instant>,
|
pub(crate) expires_at: SyncUnsafeCell<u64>,
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
pub(crate) timer_queue_item: timer_queue::TimerQueueItem,
|
pub(crate) timer_queue_item: timer_queue::TimerQueueItem,
|
||||||
}
|
}
|
||||||
|
@ -123,7 +121,7 @@ impl<F: Future + 'static> TaskStorage<F> {
|
||||||
poll_fn: SyncUnsafeCell::new(None),
|
poll_fn: SyncUnsafeCell::new(None),
|
||||||
|
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
expires_at: SyncUnsafeCell::new(Instant::from_ticks(0)),
|
expires_at: SyncUnsafeCell::new(0),
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
timer_queue_item: timer_queue::TimerQueueItem::new(),
|
timer_queue_item: timer_queue::TimerQueueItem::new(),
|
||||||
},
|
},
|
||||||
|
@ -164,7 +162,7 @@ impl<F: Future + 'static> TaskStorage<F> {
|
||||||
this.raw.state.despawn();
|
this.raw.state.despawn();
|
||||||
|
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
this.raw.expires_at.set(Instant::MAX);
|
this.raw.expires_at.set(u64::MAX);
|
||||||
}
|
}
|
||||||
Poll::Pending => {}
|
Poll::Pending => {}
|
||||||
}
|
}
|
||||||
|
@ -328,7 +326,7 @@ pub(crate) struct SyncExecutor {
|
||||||
impl SyncExecutor {
|
impl SyncExecutor {
|
||||||
pub(crate) fn new(pender: Pender) -> Self {
|
pub(crate) fn new(pender: Pender) -> Self {
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
let alarm = unsafe { unwrap!(driver::allocate_alarm()) };
|
let alarm = unsafe { unwrap!(embassy_time_driver::allocate_alarm()) };
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
run_queue: RunQueue::new(),
|
run_queue: RunQueue::new(),
|
||||||
|
@ -377,18 +375,19 @@ impl SyncExecutor {
|
||||||
/// Same as [`Executor::poll`], plus you must only call this on the thread this executor was created.
|
/// Same as [`Executor::poll`], plus you must only call this on the thread this executor was created.
|
||||||
pub(crate) unsafe fn poll(&'static self) {
|
pub(crate) unsafe fn poll(&'static self) {
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ());
|
embassy_time_driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ());
|
||||||
|
|
||||||
#[allow(clippy::never_loop)]
|
#[allow(clippy::never_loop)]
|
||||||
loop {
|
loop {
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
self.timer_queue.dequeue_expired(Instant::now(), wake_task_no_pend);
|
self.timer_queue
|
||||||
|
.dequeue_expired(embassy_time_driver::now(), wake_task_no_pend);
|
||||||
|
|
||||||
self.run_queue.dequeue_all(|p| {
|
self.run_queue.dequeue_all(|p| {
|
||||||
let task = p.header();
|
let task = p.header();
|
||||||
|
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
task.expires_at.set(Instant::MAX);
|
task.expires_at.set(u64::MAX);
|
||||||
|
|
||||||
if !task.state.run_dequeue() {
|
if !task.state.run_dequeue() {
|
||||||
// If task is not running, ignore it. This can happen in the following scenario:
|
// If task is not running, ignore it. This can happen in the following scenario:
|
||||||
|
@ -418,7 +417,7 @@ impl SyncExecutor {
|
||||||
// If this is already in the past, set_alarm might return false
|
// If this is already in the past, set_alarm might return false
|
||||||
// In that case do another poll loop iteration.
|
// In that case do another poll loop iteration.
|
||||||
let next_expiration = self.timer_queue.next_expiration();
|
let next_expiration = self.timer_queue.next_expiration();
|
||||||
if driver::set_alarm(self.alarm, next_expiration.as_ticks()) {
|
if embassy_time_driver::set_alarm(self.alarm, next_expiration) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,8 +567,8 @@ pub fn wake_task_no_pend(task: TaskRef) {
|
||||||
struct TimerQueue;
|
struct TimerQueue;
|
||||||
|
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
impl embassy_time::queue::TimerQueue for TimerQueue {
|
impl embassy_time_queue_driver::TimerQueue for TimerQueue {
|
||||||
fn schedule_wake(&'static self, at: Instant, waker: &core::task::Waker) {
|
fn schedule_wake(&'static self, at: u64, waker: &core::task::Waker) {
|
||||||
let task = waker::task_from_waker(waker);
|
let task = waker::task_from_waker(waker);
|
||||||
let task = task.header();
|
let task = task.header();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -580,7 +579,7 @@ impl embassy_time::queue::TimerQueue for TimerQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
embassy_time::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue);
|
embassy_time_queue_driver::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue);
|
||||||
|
|
||||||
#[cfg(feature = "rtos-trace")]
|
#[cfg(feature = "rtos-trace")]
|
||||||
impl rtos_trace::RtosTraceOSCallbacks for Executor {
|
impl rtos_trace::RtosTraceOSCallbacks for Executor {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
|
|
||||||
use embassy_time::Instant;
|
|
||||||
|
|
||||||
use super::TaskRef;
|
use super::TaskRef;
|
||||||
use crate::raw::util::SyncUnsafeCell;
|
use crate::raw::util::SyncUnsafeCell;
|
||||||
|
|
||||||
|
@ -30,7 +28,7 @@ impl TimerQueue {
|
||||||
|
|
||||||
pub(crate) unsafe fn update(&self, p: TaskRef) {
|
pub(crate) unsafe fn update(&self, p: TaskRef) {
|
||||||
let task = p.header();
|
let task = p.header();
|
||||||
if task.expires_at.get() != Instant::MAX {
|
if task.expires_at.get() != u64::MAX {
|
||||||
if task.state.timer_enqueue() {
|
if task.state.timer_enqueue() {
|
||||||
task.timer_queue_item.next.set(self.head.get());
|
task.timer_queue_item.next.set(self.head.get());
|
||||||
self.head.set(Some(p));
|
self.head.set(Some(p));
|
||||||
|
@ -38,18 +36,18 @@ impl TimerQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn next_expiration(&self) -> Instant {
|
pub(crate) unsafe fn next_expiration(&self) -> u64 {
|
||||||
let mut res = Instant::MAX;
|
let mut res = u64::MAX;
|
||||||
self.retain(|p| {
|
self.retain(|p| {
|
||||||
let task = p.header();
|
let task = p.header();
|
||||||
let expires = task.expires_at.get();
|
let expires = task.expires_at.get();
|
||||||
res = min(res, expires);
|
res = min(res, expires);
|
||||||
expires != Instant::MAX
|
expires != u64::MAX
|
||||||
});
|
});
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn dequeue_expired(&self, now: Instant, on_task: impl Fn(TaskRef)) {
|
pub(crate) unsafe fn dequeue_expired(&self, now: u64, on_task: impl Fn(TaskRef)) {
|
||||||
self.retain(|p| {
|
self.retain(|p| {
|
||||||
let task = p.header();
|
let task = p.header();
|
||||||
if task.expires_at.get() <= now {
|
if task.expires_at.get() <= now {
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
# Changelog
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
||||||
|
|
||||||
## 0.2.0 - 2023-12-04
|
|
||||||
|
|
||||||
- Added tick rates in multiples of 10 kHz
|
|
||||||
- Remove nightly and unstable-traits features in preparation for 1.75.
|
|
||||||
- Update heapless to 0.8.
|
|
||||||
|
|
||||||
## 0.1.5 - 2023-10-16
|
|
||||||
|
|
||||||
- Added `links` key to Cargo.toml, to prevent multiple copies of this crate in the same binary.
|
|
||||||
Needed because different copies might get different tick rates, causing
|
|
||||||
wrong delays if the time driver is using one copy and user code is using another.
|
|
||||||
This is especially common when mixing crates from crates.io and git.
|
|
||||||
|
|
||||||
## 0.1.4 - 2023-10-12
|
|
||||||
|
|
||||||
- Added more tick rates
|
|
||||||
|
|
||||||
## 0.1.3 - 2023-08-28
|
|
||||||
|
|
||||||
- Update `embedded-hal-async` to `1.0.0-rc.2`
|
|
||||||
- Update `embedded-hal v1` to `1.0.0-rc.2`
|
|
||||||
|
|
||||||
## 0.1.2 - 2023-07-05
|
|
||||||
|
|
||||||
- Update `embedded-hal-async` to `0.2.0-alpha.2`.
|
|
||||||
- Update `embedded-hal v1` to `1.0.0-alpha.11`. (Note: v0.2 support is kept unchanged).
|
|
||||||
|
|
||||||
## 0.1.1 - 2023-04-13
|
|
||||||
|
|
||||||
- Update `embedded-hal-async` to `0.2.0-alpha.1` (uses `async fn` in traits).
|
|
||||||
- Update `embedded-hal v1` to `1.0.0-alpha.10`. (Note: v0.2 support is kept unchanged).
|
|
||||||
- Remove dep on `embassy-sync`.
|
|
||||||
- Fix reentrancy issues in the `std` time driver (#1177)
|
|
||||||
- Add `Duration::from_hz()`.
|
|
||||||
- impl `From` conversions to/from `core::time::Duration`.
|
|
||||||
- Add `#[must_use]` to all futures.
|
|
||||||
- Add inherent `async fn tick()` to `Ticker`, so you can use it directly without the `Stream` trait.
|
|
||||||
- Add more tick rates.
|
|
||||||
- impl `Default` for `Signal`
|
|
||||||
- Remove unnecessary uses of `atomic-polyfill`
|
|
||||||
|
|
||||||
## 0.1.0 - 2022-08-26
|
|
||||||
|
|
||||||
- First release
|
|
25
embassy-time-queue-driver/Cargo.toml
Normal file
25
embassy-time-queue-driver/Cargo.toml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
[package]
|
||||||
|
name = "embassy-time-queue-driver"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
description = "Timer queue driver trait for embassy-time"
|
||||||
|
repository = "https://github.com/embassy-rs/embassy"
|
||||||
|
readme = "README.md"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
categories = [
|
||||||
|
"embedded",
|
||||||
|
"no-std",
|
||||||
|
"concurrency",
|
||||||
|
"asynchronous",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Prevent multiple copies of this crate in the same binary.
|
||||||
|
# Needed because different copies might get different tick rates, causing
|
||||||
|
# wrong delays if the time driver is using one copy and user code is using another.
|
||||||
|
# This is especially common when mixing crates from crates.io and git.
|
||||||
|
links = "embassy-time-queue"
|
||||||
|
|
||||||
|
[package.metadata.embassy_docs]
|
||||||
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-time-queue-driver-v$VERSION/embassy-time-queue-driver/src/"
|
||||||
|
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-time-queue-driver/src/"
|
||||||
|
target = "x86_64-unknown-linux-gnu"
|
8
embassy-time-queue-driver/README.md
Normal file
8
embassy-time-queue-driver/README.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# embassy-time-queue-driver
|
||||||
|
|
||||||
|
This crate contains the driver trait used by the [`embassy-time`](https://crates.io/crates/embassy-time) timer queue.
|
||||||
|
|
||||||
|
You should rarely need to use this crate directly. Only use it when implementing your own timer queue.
|
||||||
|
|
||||||
|
There is two timer queue implementations, one in `embassy-time` enabled by the `generic-queue` feature, and
|
||||||
|
another in `embassy-executor` enabled by the `integrated-timers` feature.
|
1
embassy-time-queue-driver/build.rs
Normal file
1
embassy-time-queue-driver/build.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
fn main() {}
|
|
@ -1,20 +1,14 @@
|
||||||
//! Timer queue implementation
|
#![no_std]
|
||||||
//!
|
#![doc = include_str!("../README.md")]
|
||||||
//! This module defines the interface a timer queue needs to implement to power the `embassy_time` module.
|
#![warn(missing_docs)]
|
||||||
//!
|
|
||||||
//! # Implementing a timer queue
|
//! ## Implementing a timer queue
|
||||||
//!
|
//!
|
||||||
//! - Define a struct `MyTimerQueue`
|
//! - Define a struct `MyTimerQueue`
|
||||||
//! - Implement [`TimerQueue`] for it
|
//! - Implement [`TimerQueue`] for it
|
||||||
//! - Register it as the global timer queue with [`timer_queue_impl`](crate::timer_queue_impl).
|
//! - Register it as the global timer queue with [`timer_queue_impl`](crate::timer_queue_impl).
|
||||||
//!
|
//!
|
||||||
//! # Linkage details
|
//! ## Example
|
||||||
//!
|
|
||||||
//! Check the documentation of the [`driver`](crate::driver) module for more information.
|
|
||||||
//!
|
|
||||||
//! Similarly to driver, if there is none or multiple timer queues in the crate tree, linking will fail.
|
|
||||||
//!
|
|
||||||
//! # Example
|
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! use core::task::Waker;
|
//! use core::task::Waker;
|
||||||
|
@ -25,23 +19,29 @@
|
||||||
//! struct MyTimerQueue{}; // not public!
|
//! struct MyTimerQueue{}; // not public!
|
||||||
//!
|
//!
|
||||||
//! impl TimerQueue for MyTimerQueue {
|
//! impl TimerQueue for MyTimerQueue {
|
||||||
//! fn schedule_wake(&'static self, at: Instant, waker: &Waker) {
|
//! fn schedule_wake(&'static self, at: u64, waker: &Waker) {
|
||||||
//! todo!()
|
//! todo!()
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//!
|
||||||
//! ```ignore
|
//! embassy_time_queue_driver::timer_queue_impl!(static QUEUE: MyTimerQueue = MyTimerQueue{});
|
||||||
//! embassy_time::timer_queue_impl!(static QUEUE: MyTimerQueue = MyTimerQueue{});
|
|
||||||
//! ```
|
//! ```
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
|
|
||||||
use crate::Instant;
|
|
||||||
|
|
||||||
/// Timer queue
|
/// Timer queue
|
||||||
pub trait TimerQueue {
|
pub trait TimerQueue {
|
||||||
/// Schedules a waker in the queue to be awoken at moment `at`.
|
/// Schedules a waker in the queue to be awoken at moment `at`.
|
||||||
/// If this moment is in the past, the waker might be awoken immediately.
|
/// If this moment is in the past, the waker might be awoken immediately.
|
||||||
fn schedule_wake(&'static self, at: Instant, waker: &Waker);
|
fn schedule_wake(&'static self, at: u64, waker: &Waker);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "Rust" {
|
||||||
|
fn _embassy_time_schedule_wake(at: u64, waker: &Waker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Schedule the given waker to be woken at `at`.
|
||||||
|
pub fn schedule_wake(at: u64, waker: &Waker) {
|
||||||
|
unsafe { _embassy_time_schedule_wake(at, waker) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the TimerQueue implementation.
|
/// Set the TimerQueue implementation.
|
||||||
|
@ -53,8 +53,8 @@ macro_rules! timer_queue_impl {
|
||||||
static $name: $t = $val;
|
static $name: $t = $val;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
fn _embassy_time_schedule_wake(at: $crate::Instant, waker: &core::task::Waker) {
|
fn _embassy_time_schedule_wake(at: u64, waker: &core::task::Waker) {
|
||||||
<$t as $crate::queue::TimerQueue>::schedule_wake(&$name, at, waker);
|
<$t as $crate::TimerQueue>::schedule_wake(&$name, at, waker);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -398,6 +398,7 @@ tick-hz-5_242_880_000 = ["embassy-time-driver/tick-hz-5_242_880_000"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver" }
|
embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver" }
|
||||||
|
embassy-time-queue-driver = { version = "0.1.0", path = "../embassy-time-queue-driver" }
|
||||||
|
|
||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
log = { version = "0.4.14", optional = true }
|
log = { version = "0.4.14", optional = true }
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use critical_section::Mutex as CsMutex;
|
use critical_section::Mutex as CsMutex;
|
||||||
|
use embassy_time_driver::{AlarmHandle, Driver};
|
||||||
|
|
||||||
use crate::driver::{AlarmHandle, Driver};
|
|
||||||
use crate::{Duration, Instant};
|
use crate::{Duration, Instant};
|
||||||
|
|
||||||
/// A mock driver that can be manually advanced.
|
/// A mock driver that can be manually advanced.
|
||||||
|
@ -28,7 +28,7 @@ use crate::{Duration, Instant};
|
||||||
/// ```
|
/// ```
|
||||||
pub struct MockDriver(CsMutex<RefCell<InnerMockDriver>>);
|
pub struct MockDriver(CsMutex<RefCell<InnerMockDriver>>);
|
||||||
|
|
||||||
crate::driver::time_driver_impl!(static DRIVER: MockDriver = MockDriver::new());
|
embassy_time_driver::time_driver_impl!(static DRIVER: MockDriver = MockDriver::new());
|
||||||
|
|
||||||
impl MockDriver {
|
impl MockDriver {
|
||||||
/// Creates a new mock driver.
|
/// Creates a new mock driver.
|
||||||
|
|
|
@ -6,8 +6,7 @@ use std::time::{Duration as StdDuration, Instant as StdInstant};
|
||||||
use std::{mem, ptr, thread};
|
use std::{mem, ptr, thread};
|
||||||
|
|
||||||
use critical_section::Mutex as CsMutex;
|
use critical_section::Mutex as CsMutex;
|
||||||
|
use embassy_time_driver::{AlarmHandle, Driver};
|
||||||
use crate::driver::{AlarmHandle, Driver};
|
|
||||||
|
|
||||||
const ALARM_COUNT: usize = 4;
|
const ALARM_COUNT: usize = 4;
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ struct TimeDriver {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ALARM_NEW: AlarmState = AlarmState::new();
|
const ALARM_NEW: AlarmState = AlarmState::new();
|
||||||
crate::driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
|
embassy_time_driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
|
||||||
alarm_count: AtomicU8::new(0),
|
alarm_count: AtomicU8::new(0),
|
||||||
|
|
||||||
once: Once::new(),
|
once: Once::new(),
|
||||||
|
|
|
@ -4,11 +4,10 @@ use std::mem::MaybeUninit;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::{Mutex, Once};
|
use std::sync::{Mutex, Once};
|
||||||
|
|
||||||
|
use embassy_time_driver::{AlarmHandle, Driver};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_timer::Instant as StdInstant;
|
use wasm_timer::Instant as StdInstant;
|
||||||
|
|
||||||
use crate::driver::{AlarmHandle, Driver};
|
|
||||||
|
|
||||||
const ALARM_COUNT: usize = 4;
|
const ALARM_COUNT: usize = 4;
|
||||||
|
|
||||||
struct AlarmState {
|
struct AlarmState {
|
||||||
|
@ -42,7 +41,7 @@ struct TimeDriver {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ALARM_NEW: AlarmState = AlarmState::new();
|
const ALARM_NEW: AlarmState = AlarmState::new();
|
||||||
crate::driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
|
embassy_time_driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
|
||||||
alarm_count: AtomicU8::new(0),
|
alarm_count: AtomicU8::new(0),
|
||||||
once: Once::new(),
|
once: Once::new(),
|
||||||
alarms: UninitCell::uninit(),
|
alarms: UninitCell::uninit(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::ops::{Add, AddAssign, Sub, SubAssign};
|
use core::ops::{Add, AddAssign, Sub, SubAssign};
|
||||||
|
|
||||||
use super::{driver, Duration, GCD_1K, GCD_1M, TICK_HZ};
|
use super::{Duration, GCD_1K, GCD_1M, TICK_HZ};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
@ -18,7 +18,9 @@ impl Instant {
|
||||||
|
|
||||||
/// Returns an Instant representing the current time.
|
/// Returns an Instant representing the current time.
|
||||||
pub fn now() -> Instant {
|
pub fn now() -> Instant {
|
||||||
Instant { ticks: driver::now() }
|
Instant {
|
||||||
|
ticks: embassy_time_driver::now(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an Instant from a tick count since system boot.
|
/// Create an Instant from a tick count since system boot.
|
||||||
|
|
|
@ -10,12 +10,9 @@
|
||||||
// This mod MUST go first, so that the others see its macros.
|
// This mod MUST go first, so that the others see its macros.
|
||||||
pub(crate) mod fmt;
|
pub(crate) mod fmt;
|
||||||
|
|
||||||
pub use embassy_time_driver as driver;
|
|
||||||
|
|
||||||
mod delay;
|
mod delay;
|
||||||
mod duration;
|
mod duration;
|
||||||
mod instant;
|
mod instant;
|
||||||
pub mod queue;
|
|
||||||
mod timer;
|
mod timer;
|
||||||
|
|
||||||
#[cfg(feature = "mock-driver")]
|
#[cfg(feature = "mock-driver")]
|
||||||
|
@ -32,8 +29,8 @@ mod driver_wasm;
|
||||||
mod queue_generic;
|
mod queue_generic;
|
||||||
|
|
||||||
pub use delay::{block_for, Delay};
|
pub use delay::{block_for, Delay};
|
||||||
pub use driver::TICK_HZ;
|
|
||||||
pub use duration::Duration;
|
pub use duration::Duration;
|
||||||
|
pub use embassy_time_driver::TICK_HZ;
|
||||||
pub use instant::Instant;
|
pub use instant::Instant;
|
||||||
pub use timer::{with_timeout, Ticker, TimeoutError, Timer};
|
pub use timer::{with_timeout, Ticker, TimeoutError, Timer};
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ use core::cmp::{min, Ordering};
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
|
|
||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
|
use embassy_time_driver::{allocate_alarm, set_alarm, set_alarm_callback, AlarmHandle};
|
||||||
|
use embassy_time_queue_driver::TimerQueue;
|
||||||
use heapless::Vec;
|
use heapless::Vec;
|
||||||
|
|
||||||
use crate::driver::{allocate_alarm, set_alarm, set_alarm_callback, AlarmHandle};
|
|
||||||
use crate::queue::TimerQueue;
|
|
||||||
use crate::Instant;
|
use crate::Instant;
|
||||||
|
|
||||||
#[cfg(feature = "generic-queue-8")]
|
#[cfg(feature = "generic-queue-8")]
|
||||||
|
@ -167,12 +167,12 @@ impl Queue {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TimerQueue for Queue {
|
impl TimerQueue for Queue {
|
||||||
fn schedule_wake(&'static self, at: Instant, waker: &Waker) {
|
fn schedule_wake(&'static self, at: u64, waker: &Waker) {
|
||||||
Queue::schedule_wake(self, at, waker);
|
Queue::schedule_wake(self, Instant::from_ticks(at), waker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::timer_queue_impl!(static QUEUE: Queue = Queue::new());
|
embassy_time_queue_driver::timer_queue_impl!(static QUEUE: Queue = Queue::new());
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(feature = "mock-driver")]
|
#[cfg(feature = "mock-driver")]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use core::future::{poll_fn, Future};
|
use core::future::{poll_fn, Future};
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll, Waker};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
use futures_util::future::{select, Either};
|
use futures_util::future::{select, Either};
|
||||||
use futures_util::stream::FusedStream;
|
use futures_util::stream::FusedStream;
|
||||||
|
@ -116,7 +116,7 @@ impl Future for Timer {
|
||||||
if self.yielded_once && self.expires_at <= Instant::now() {
|
if self.yielded_once && self.expires_at <= Instant::now() {
|
||||||
Poll::Ready(())
|
Poll::Ready(())
|
||||||
} else {
|
} else {
|
||||||
schedule_wake(self.expires_at, cx.waker());
|
embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
|
||||||
self.yielded_once = true;
|
self.yielded_once = true;
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ impl Ticker {
|
||||||
self.expires_at += dur;
|
self.expires_at += dur;
|
||||||
Poll::Ready(())
|
Poll::Ready(())
|
||||||
} else {
|
} else {
|
||||||
schedule_wake(self.expires_at, cx.waker());
|
embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -202,7 +202,7 @@ impl Stream for Ticker {
|
||||||
self.expires_at += dur;
|
self.expires_at += dur;
|
||||||
Poll::Ready(Some(()))
|
Poll::Ready(Some(()))
|
||||||
} else {
|
} else {
|
||||||
schedule_wake(self.expires_at, cx.waker());
|
embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,11 +214,3 @@ impl FusedStream for Ticker {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "Rust" {
|
|
||||||
fn _embassy_time_schedule_wake(at: Instant, waker: &Waker);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn schedule_wake(at: Instant, waker: &Waker) {
|
|
||||||
unsafe { _embassy_time_schedule_wake(at, waker) }
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ mod serial_port;
|
||||||
|
|
||||||
use async_io::Async;
|
use async_io::Async;
|
||||||
use embassy_executor::Executor;
|
use embassy_executor::Executor;
|
||||||
|
use embassy_time as _;
|
||||||
use embedded_io_async::Read;
|
use embedded_io_async::Read;
|
||||||
use log::*;
|
use log::*;
|
||||||
use nix::sys::termios;
|
use nix::sys::termios;
|
||||||
|
|
Loading…
Reference in a new issue