aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-executor')
-rw-r--r--embassy-executor/Cargo.toml9
-rw-r--r--embassy-executor/src/arch/cortex_m.rs2
-rw-r--r--embassy-executor/src/arch/riscv32.rs2
-rw-r--r--embassy-executor/src/arch/std.rs2
-rw-r--r--embassy-executor/src/arch/wasm.rs2
-rw-r--r--embassy-executor/src/arch/xtensa.rs2
-rw-r--r--embassy-executor/src/lib.rs31
-rw-r--r--embassy-executor/src/raw/mod.rs39
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
31integrated-timers = ["dep:embassy-time"] 31integrated-timers = ["dep:embassy-time"]
32 32
33# Trace interrupt invocations with rtos-trace.
34rtos-trace-interrupt = ["rtos-trace"]
35
33[dependencies] 36[dependencies]
34defmt = { version = "0.3", optional = true } 37defmt = { version = "0.3", optional = true }
35log = { version = "0.4.14", optional = true } 38log = { version = "0.4.14", optional = true }
39rtos-trace = { version = "0.1.2", optional = true }
36 40
37futures-util = { version = "0.3.17", default-features = false } 41futures-util = { version = "0.3.17", default-features = false }
38embassy-macros = { version = "0.1.0", path = "../embassy-macros"} 42embassy-macros = { version = "0.1.0", path = "../embassy-macros"}
@@ -40,7 +44,8 @@ embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true}
40atomic-polyfill = "1.0.1" 44atomic-polyfill = "1.0.1"
41critical-section = "1.1" 45critical-section = "1.1"
42cfg-if = "1.0.0" 46cfg-if = "1.0.0"
47static_cell = "1.0"
43 48
44# WASM dependencies 49# WASM dependencies
45wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true } 50wasm-bindgen = { version = "0.2.82", optional = true }
46js-sys = { version = "0.3", optional = true } \ No newline at end of file 51js-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.
43pub 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
41pub mod raw; 66pub mod raw;
42 67
43mod spawner; 68mod spawner;
44pub use spawner::*; 69pub use spawner::*;
70
71/// Do not use. Used for macros and HALs only. Not covered by semver guarantees.
72#[doc(hidden)]
73pub 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
10mod run_queue; 10mod run_queue;
11#[cfg(feature = "integrated-timers")] 11#[cfg(feature = "integrated-timers")]
@@ -26,6 +26,8 @@ use critical_section::CriticalSection;
26use embassy_time::driver::{self, AlarmHandle}; 26use embassy_time::driver::{self, AlarmHandle};
27#[cfg(feature = "integrated-timers")] 27#[cfg(feature = "integrated-timers")]
28use embassy_time::Instant; 28use embassy_time::Instant;
29#[cfg(feature = "rtos-trace")]
30use rtos_trace::trace;
29 31
30use self::run_queue::{RunQueue, RunQueueItem}; 32use self::run_queue::{RunQueue, RunQueueItem};
31use self::util::UninitCell; 33use 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")]
448impl 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")]
463rtos_trace::global_os_callbacks! {Executor}