diff options
Diffstat (limited to 'embassy-executor')
| -rw-r--r-- | embassy-executor/Cargo.toml | 9 | ||||
| -rw-r--r-- | embassy-executor/src/arch/cortex_m.rs | 2 | ||||
| -rw-r--r-- | embassy-executor/src/arch/riscv32.rs | 2 | ||||
| -rw-r--r-- | embassy-executor/src/arch/std.rs | 2 | ||||
| -rw-r--r-- | embassy-executor/src/arch/wasm.rs | 2 | ||||
| -rw-r--r-- | embassy-executor/src/arch/xtensa.rs | 2 | ||||
| -rw-r--r-- | embassy-executor/src/lib.rs | 31 | ||||
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 39 |
8 files changed, 80 insertions, 9 deletions
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 25c3f0abd..1a611720c 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml | |||
| @@ -30,9 +30,13 @@ nightly = [] | |||
| 30 | 30 | ||
| 31 | integrated-timers = ["dep:embassy-time"] | 31 | integrated-timers = ["dep:embassy-time"] |
| 32 | 32 | ||
| 33 | # Trace interrupt invocations with rtos-trace. | ||
| 34 | rtos-trace-interrupt = ["rtos-trace"] | ||
| 35 | |||
| 33 | [dependencies] | 36 | [dependencies] |
| 34 | defmt = { version = "0.3", optional = true } | 37 | defmt = { version = "0.3", optional = true } |
| 35 | log = { version = "0.4.14", optional = true } | 38 | log = { version = "0.4.14", optional = true } |
| 39 | rtos-trace = { version = "0.1.2", optional = true } | ||
| 36 | 40 | ||
| 37 | futures-util = { version = "0.3.17", default-features = false } | 41 | futures-util = { version = "0.3.17", default-features = false } |
| 38 | embassy-macros = { version = "0.1.0", path = "../embassy-macros"} | 42 | embassy-macros = { version = "0.1.0", path = "../embassy-macros"} |
| @@ -40,7 +44,8 @@ embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true} | |||
| 40 | atomic-polyfill = "1.0.1" | 44 | atomic-polyfill = "1.0.1" |
| 41 | critical-section = "1.1" | 45 | critical-section = "1.1" |
| 42 | cfg-if = "1.0.0" | 46 | cfg-if = "1.0.0" |
| 47 | static_cell = "1.0" | ||
| 43 | 48 | ||
| 44 | # WASM dependencies | 49 | # WASM dependencies |
| 45 | wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true } | 50 | wasm-bindgen = { version = "0.2.82", optional = true } |
| 46 | js-sys = { version = "0.3", optional = true } \ No newline at end of file | 51 | js-sys = { version = "0.3", optional = true } |
diff --git a/embassy-executor/src/arch/cortex_m.rs b/embassy-executor/src/arch/cortex_m.rs index d6e758dfb..4b27a264e 100644 --- a/embassy-executor/src/arch/cortex_m.rs +++ b/embassy-executor/src/arch/cortex_m.rs | |||
| @@ -41,7 +41,7 @@ impl Executor { | |||
| 41 | /// Executor instance in a place where it'll live forever and grants you mutable | 41 | /// Executor instance in a place where it'll live forever and grants you mutable |
| 42 | /// access. There's a few ways to do this: | 42 | /// access. There's a few ways to do this: |
| 43 | /// | 43 | /// |
| 44 | /// - a [Forever](crate::util::Forever) (safe) | 44 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) |
| 45 | /// - a `static mut` (unsafe) | 45 | /// - a `static mut` (unsafe) |
| 46 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | 46 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) |
| 47 | /// | 47 | /// |
diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs index 7a7d5698c..2a4b006da 100644 --- a/embassy-executor/src/arch/riscv32.rs +++ b/embassy-executor/src/arch/riscv32.rs | |||
| @@ -43,7 +43,7 @@ impl Executor { | |||
| 43 | /// Executor instance in a place where it'll live forever and grants you mutable | 43 | /// Executor instance in a place where it'll live forever and grants you mutable |
| 44 | /// access. There's a few ways to do this: | 44 | /// access. There's a few ways to do this: |
| 45 | /// | 45 | /// |
| 46 | /// - a [Forever](crate::util::Forever) (safe) | 46 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) |
| 47 | /// - a `static mut` (unsafe) | 47 | /// - a `static mut` (unsafe) |
| 48 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | 48 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) |
| 49 | /// | 49 | /// |
diff --git a/embassy-executor/src/arch/std.rs b/embassy-executor/src/arch/std.rs index b93ab8a79..701f0eb18 100644 --- a/embassy-executor/src/arch/std.rs +++ b/embassy-executor/src/arch/std.rs | |||
| @@ -40,7 +40,7 @@ impl Executor { | |||
| 40 | /// Executor instance in a place where it'll live forever and grants you mutable | 40 | /// Executor instance in a place where it'll live forever and grants you mutable |
| 41 | /// access. There's a few ways to do this: | 41 | /// access. There's a few ways to do this: |
| 42 | /// | 42 | /// |
| 43 | /// - a [Forever](crate::util::Forever) (safe) | 43 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) |
| 44 | /// - a `static mut` (unsafe) | 44 | /// - a `static mut` (unsafe) |
| 45 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | 45 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) |
| 46 | /// | 46 | /// |
diff --git a/embassy-executor/src/arch/wasm.rs b/embassy-executor/src/arch/wasm.rs index 9d5aa31ed..98091cfbb 100644 --- a/embassy-executor/src/arch/wasm.rs +++ b/embassy-executor/src/arch/wasm.rs | |||
| @@ -59,7 +59,7 @@ impl Executor { | |||
| 59 | /// Executor instance in a place where it'll live forever and grants you mutable | 59 | /// Executor instance in a place where it'll live forever and grants you mutable |
| 60 | /// access. There's a few ways to do this: | 60 | /// access. There's a few ways to do this: |
| 61 | /// | 61 | /// |
| 62 | /// - a [Forever](crate::util::Forever) (safe) | 62 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) |
| 63 | /// - a `static mut` (unsafe) | 63 | /// - a `static mut` (unsafe) |
| 64 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | 64 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) |
| 65 | pub fn start(&'static mut self, init: impl FnOnce(Spawner)) { | 65 | pub fn start(&'static mut self, init: impl FnOnce(Spawner)) { |
diff --git a/embassy-executor/src/arch/xtensa.rs b/embassy-executor/src/arch/xtensa.rs index 20bd7b8a5..f908aaa70 100644 --- a/embassy-executor/src/arch/xtensa.rs +++ b/embassy-executor/src/arch/xtensa.rs | |||
| @@ -43,7 +43,7 @@ impl Executor { | |||
| 43 | /// Executor instance in a place where it'll live forever and grants you mutable | 43 | /// Executor instance in a place where it'll live forever and grants you mutable |
| 44 | /// access. There's a few ways to do this: | 44 | /// access. There's a few ways to do this: |
| 45 | /// | 45 | /// |
| 46 | /// - a [Forever](crate::util::Forever) (safe) | 46 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) |
| 47 | /// - a `static mut` (unsafe) | 47 | /// - a `static mut` (unsafe) |
| 48 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | 48 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) |
| 49 | /// | 49 | /// |
diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index 9328a7378..e4cbd04b9 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs | |||
| @@ -38,7 +38,38 @@ cfg_if::cfg_if! { | |||
| 38 | } | 38 | } |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | #[doc(hidden)] | ||
| 42 | /// Implementation details for embassy macros. DO NOT USE. | ||
| 43 | pub mod export { | ||
| 44 | #[cfg(feature = "rtos-trace")] | ||
| 45 | pub use rtos_trace::trace; | ||
| 46 | |||
| 47 | /// Expands the given block of code when `embassy-executor` is compiled with | ||
| 48 | /// the `rtos-trace-interrupt` feature. | ||
| 49 | #[doc(hidden)] | ||
| 50 | #[macro_export] | ||
| 51 | #[cfg(feature = "rtos-trace-interrupt")] | ||
| 52 | macro_rules! rtos_trace_interrupt { | ||
| 53 | ($($tt:tt)*) => { $($tt)* }; | ||
| 54 | } | ||
| 55 | |||
| 56 | /// Does not expand the given block of code when `embassy-executor` is | ||
| 57 | /// compiled without the `rtos-trace-interrupt` feature. | ||
| 58 | #[doc(hidden)] | ||
| 59 | #[macro_export] | ||
| 60 | #[cfg(not(feature = "rtos-trace-interrupt"))] | ||
| 61 | macro_rules! rtos_trace_interrupt { | ||
| 62 | ($($tt:tt)*) => {}; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 41 | pub mod raw; | 66 | pub mod raw; |
| 42 | 67 | ||
| 43 | mod spawner; | 68 | mod spawner; |
| 44 | pub use spawner::*; | 69 | pub use spawner::*; |
| 70 | |||
| 71 | /// Do not use. Used for macros and HALs only. Not covered by semver guarantees. | ||
| 72 | #[doc(hidden)] | ||
| 73 | pub mod _export { | ||
| 74 | pub use static_cell::StaticCell; | ||
| 75 | } | ||
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index afe67decb..e1258ebb5 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | //! ## WARNING: here be dragons! | 5 | //! ## WARNING: here be dragons! |
| 6 | //! | 6 | //! |
| 7 | //! Using this module requires respecting subtle safety contracts. If you can, prefer using the safe | 7 | //! Using this module requires respecting subtle safety contracts. If you can, prefer using the safe |
| 8 | //! executor wrappers in [`executor`](crate::executor) and the [`embassy_executor::task`](embassy_macros::task) macro, which are fully safe. | 8 | //! [executor wrappers](crate::Executor) and the [`embassy_executor::task`](embassy_macros::task) macro, which are fully safe. |
| 9 | 9 | ||
| 10 | mod run_queue; | 10 | mod run_queue; |
| 11 | #[cfg(feature = "integrated-timers")] | 11 | #[cfg(feature = "integrated-timers")] |
| @@ -26,6 +26,8 @@ use critical_section::CriticalSection; | |||
| 26 | use embassy_time::driver::{self, AlarmHandle}; | 26 | use embassy_time::driver::{self, AlarmHandle}; |
| 27 | #[cfg(feature = "integrated-timers")] | 27 | #[cfg(feature = "integrated-timers")] |
| 28 | use embassy_time::Instant; | 28 | use embassy_time::Instant; |
| 29 | #[cfg(feature = "rtos-trace")] | ||
| 30 | use rtos_trace::trace; | ||
| 29 | 31 | ||
| 30 | use self::run_queue::{RunQueue, RunQueueItem}; | 32 | use self::run_queue::{RunQueue, RunQueueItem}; |
| 31 | use self::util::UninitCell; | 33 | use self::util::UninitCell; |
| @@ -247,7 +249,7 @@ impl<F: Future + 'static, const N: usize> TaskPool<F, N> { | |||
| 247 | /// | 249 | /// |
| 248 | /// This is the core of the Embassy executor. It is low-level, requiring manual | 250 | /// This is the core of the Embassy executor. It is low-level, requiring manual |
| 249 | /// handling of wakeups and task polling. If you can, prefer using one of the | 251 | /// handling of wakeups and task polling. If you can, prefer using one of the |
| 250 | /// higher level executors in [`crate::executor`]. | 252 | /// [higher level executors](crate::Executor). |
| 251 | /// | 253 | /// |
| 252 | /// The raw executor leaves it up to you to handle wakeups and scheduling: | 254 | /// The raw executor leaves it up to you to handle wakeups and scheduling: |
| 253 | /// | 255 | /// |
| @@ -306,6 +308,9 @@ impl Executor { | |||
| 306 | /// - `task` must NOT be already enqueued (in this executor or another one). | 308 | /// - `task` must NOT be already enqueued (in this executor or another one). |
| 307 | #[inline(always)] | 309 | #[inline(always)] |
| 308 | unsafe fn enqueue(&self, cs: CriticalSection, task: NonNull<TaskHeader>) { | 310 | unsafe fn enqueue(&self, cs: CriticalSection, task: NonNull<TaskHeader>) { |
| 311 | #[cfg(feature = "rtos-trace")] | ||
| 312 | trace::task_ready_begin(task.as_ptr() as u32); | ||
| 313 | |||
| 309 | if self.run_queue.enqueue(cs, task) { | 314 | if self.run_queue.enqueue(cs, task) { |
| 310 | (self.signal_fn)(self.signal_ctx) | 315 | (self.signal_fn)(self.signal_ctx) |
| 311 | } | 316 | } |
| @@ -323,6 +328,9 @@ impl Executor { | |||
| 323 | pub(super) unsafe fn spawn(&'static self, task: NonNull<TaskHeader>) { | 328 | pub(super) unsafe fn spawn(&'static self, task: NonNull<TaskHeader>) { |
| 324 | task.as_ref().executor.set(self); | 329 | task.as_ref().executor.set(self); |
| 325 | 330 | ||
| 331 | #[cfg(feature = "rtos-trace")] | ||
| 332 | trace::task_new(task.as_ptr() as u32); | ||
| 333 | |||
| 326 | critical_section::with(|cs| { | 334 | critical_section::with(|cs| { |
| 327 | self.enqueue(cs, task); | 335 | self.enqueue(cs, task); |
| 328 | }) | 336 | }) |
| @@ -365,9 +373,15 @@ impl Executor { | |||
| 365 | return; | 373 | return; |
| 366 | } | 374 | } |
| 367 | 375 | ||
| 376 | #[cfg(feature = "rtos-trace")] | ||
| 377 | trace::task_exec_begin(p.as_ptr() as u32); | ||
| 378 | |||
| 368 | // Run the task | 379 | // Run the task |
| 369 | task.poll_fn.read()(p as _); | 380 | task.poll_fn.read()(p as _); |
| 370 | 381 | ||
| 382 | #[cfg(feature = "rtos-trace")] | ||
| 383 | trace::task_exec_end(); | ||
| 384 | |||
| 371 | // Enqueue or update into timer_queue | 385 | // Enqueue or update into timer_queue |
| 372 | #[cfg(feature = "integrated-timers")] | 386 | #[cfg(feature = "integrated-timers")] |
| 373 | self.timer_queue.update(p); | 387 | self.timer_queue.update(p); |
| @@ -381,6 +395,9 @@ impl Executor { | |||
| 381 | let next_expiration = self.timer_queue.next_expiration(); | 395 | let next_expiration = self.timer_queue.next_expiration(); |
| 382 | driver::set_alarm(self.alarm, next_expiration.as_ticks()); | 396 | driver::set_alarm(self.alarm, next_expiration.as_ticks()); |
| 383 | } | 397 | } |
| 398 | |||
| 399 | #[cfg(feature = "rtos-trace")] | ||
| 400 | trace::system_idle(); | ||
| 384 | } | 401 | } |
| 385 | 402 | ||
| 386 | /// Get a spawner that spawns tasks in this executor. | 403 | /// Get a spawner that spawns tasks in this executor. |
| @@ -426,3 +443,21 @@ unsafe fn _embassy_time_schedule_wake(at: Instant, waker: &core::task::Waker) { | |||
| 426 | let expires_at = task.expires_at.get(); | 443 | let expires_at = task.expires_at.get(); |
| 427 | task.expires_at.set(expires_at.min(at)); | 444 | task.expires_at.set(expires_at.min(at)); |
| 428 | } | 445 | } |
| 446 | |||
| 447 | #[cfg(feature = "rtos-trace")] | ||
| 448 | impl rtos_trace::RtosTraceOSCallbacks for Executor { | ||
| 449 | fn task_list() { | ||
| 450 | // We don't know what tasks exist, so we can't send them. | ||
| 451 | } | ||
| 452 | #[cfg(feature = "integrated-timers")] | ||
| 453 | fn time() -> u64 { | ||
| 454 | Instant::now().as_micros() | ||
| 455 | } | ||
| 456 | #[cfg(not(feature = "integrated-timers"))] | ||
| 457 | fn time() -> u64 { | ||
| 458 | 0 | ||
| 459 | } | ||
| 460 | } | ||
| 461 | |||
| 462 | #[cfg(feature = "rtos-trace")] | ||
| 463 | rtos_trace::global_os_callbacks! {Executor} | ||
