Expand description
§embassy-executor
An async/await executor designed for embedded usage.
- No
alloc, no heap needed. - Tasks are statically allocated. Each task gets its own
static, with the exact size to hold the task (or multiple instances of it, if usingpool_size) calculated automatically at compile time. If tasks don’t fit in RAM, this is detected at compile time by the linker. Runtime panics due to running out of memory are not possible. - No “fixed capacity” data structures, executor works with 1 or 1000 tasks without needing config/tuning.
- Integrated timer queue: sleeping is easy, just do
Timer::after_secs(1).await;. - No busy-loop polling: CPU sleeps when there’s no work to do, using interrupts or
WFE/SEV. - Efficient polling: a wake will only poll the woken task, not all of them.
- Fair: a task can’t monopolize CPU time even if it’s constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time.
- Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks.
§Platforms
The executor requires a “platform” to be defined to work. A platform defines the following things:
- The main loop, which typically consists of an infinite loop of polling the executor then sleeping the current thread/core in a platform-specific way.
- A “pender” callback, which must cause the executor’s thread/core to exit sleep so the executor gets polled again. This is called when a task running in the executor is woken.
The embassy-executor crate ships with support for some commonly used platforms, see the crate’s feature documentation.
Chip-specific executor platform implementations are maintained in their respective HALs:
embassy-rp: multicore support. Enabled with theexecutor-interruptorexecutor-threadfeatures.embassy-stm32: automatic low-power sleep support. Enabled with thelow-powerfeature.embassy-mcxa: automatic low-power sleep support. Enabled with theexecutor-platformfeature.esp-rtos: ESP32 RTOS support, multicore support. Enabled with theembassyfeature.
To use the executor, you must provide exactly one platform implementation, either from this crate, a HAL crate, or a custom one.
§Implementing a custom platform
To implement your own custom platform, e.g. on top of an RTOS, do the following:
- define the
__pendercallback.
#[unsafe(export_name = "__pender")]
fn __pender(context: *mut ()) {
// `context` is the argument passed to `raw::Executor::new`. Here we're using it
// to pass a handle to the RTOS task but you can use it for anything.
my_rtos::notify_task(context as _);
}- Wrap the
raw::Executorinto your ownExecutorstruct that defines the main loop.
pub struct Executor {
inner: raw::Executor,
not_send: PhantomData<*mut ()>,
}
impl Executor {
pub fn new() -> Self {
Self {
inner: raw::Executor::new(my_rtos::task_get_current() as _),
not_send: PhantomData,
}
}
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
init(self.inner.spawner());
loop {
unsafe { self.inner.poll() }
my_rtos::task_wait_for_notification();
}
}
}§Feature flags
nightly— Enable nightly-only featuresdefmt— Enable defmt logginglog— Enable log logging
§Platform
-
platform-std— STD platform. Enables running the executor on top ofstdthreading primitives. -
platform-cortex-m— Cortex-M platform. UsesWFE/SEVfor the thread executor, NVIC interrupts for the interrupt executor.- Only usable on single-core chips. (Exception: the thread executor might work if your chip has wired the “event” signal between the cores, so
SEVon one core can break aWFEin the other) - Only usable on bare-metal. Do not use this if you want to run the executor inside an RTOS thread, you must use RTOS primitives to sleep/notify the thread instead.
- Only usable on privileged mode.
- Only usable on single-core chips. (Exception: the thread executor might work if your chip has wired the “event” signal between the cores, so
-
platform-cortex-ar— Cortex-A/R platform. UsesWFE/SEVfor the thread executor. Interrupt executor is not supported.- Only usable on single-core chips. (Exception: the thread executor might work if your chip has wired the “event” signal between the cores, so
SEVon one core can break aWFEin the other) - Only usable on bare-metal. Do not use this if you want to run the executor inside an RTOS thread, you must use RTOS primitives to sleep/notify the thread instead.
- Only usable on privileged mode.
- Only usable on single-core chips. (Exception: the thread executor might work if your chip has wired the “event” signal between the cores, so
-
platform-riscv32— RISC-V 32-bit platform. Uses WFI for the thread executor. Interrupt executor is not supported.- Only usable on single-core chips.
- Only usable on bare-metal. Do not use this if you want to run the executor inside an RTOS thread, you must use RTOS primitives to sleep/notify the thread instead.
- Only usable on privileged mode.
-
platform-wasm— WASM platform. -
platform-avr— AVR platform. Uses WFI for the thread executor. Interrupt executor is not supported. -
platform-spin— Spin-loop platform.This “platform” implementation is architecture/platform/chip agnostic. The main loop polls the executor constantly without sleeping, and the pender callback simply does nothing. Using this is not recommended, you probably want to use a platform-specific implementation that can sleep instead.
§Metadata
metadata-name— Enable thenamefield in task metadata.
§Executor
executor-thread— Enable the thread-mode executor (using WFE/SEV in Cortex-M, WFI in other embedded platforms)executor-interrupt— Enable the interrupt-mode executor (available in Cortex-M only)trace— Enable tracing hooksrtos-trace— Enable support for rtos-trace frameworkscheduler-deadline— Enable “Earliest Deadline First” Scheduler, using soft-realtime “deadlines” to prioritize tasks based on the remaining time before their deadline. Adds some overhead.scheduler-priority— Enable “Highest Priority First” Scheduler. Adds some overhead.embassy-time-driver— Enable the embassy_time_driver dependency. This can unlock extra APIs, for example for thescheduler-deadline
Modules§
- raw
- Raw executor.
Structs§
- Executor
- Thread mode executor, using WFE/SEV.
- Interrupt
Executor - Interrupt mode executor.
- Metadata
- Metadata associated with a task.
- Send
Spawner - Handle to spawn tasks into an executor from any thread.
- Spawn
Token - Token to spawn a newly-created task in an executor.
- Spawner
- Handle to spawn tasks into an executor.
Enums§
- Spawn
Error - Error returned when spawning a task.
Attribute Macros§
- main
- Creates a new
executorinstance and declares an application entry point for Cortex-M spawning the corresponding function body as an async task. - task
- Declares an async task that can be run by
embassy-executor. The optionalpool_sizeparameter can be used to specify how many concurrent tasks can be spawned (default is 1) for the function.