edge-executor
This crate ships a minimal async executor suitable for microcontrollers and embedded systems in general.
A no_std drop-in replacement for smol's async-executor, with the implementation being a thin wrapper around smol's async-task as well.
Examples
// ESP-IDF example, local execution, local borrows.
// With STD enabled, you can also just use `edge_executor::block_on`
// instead of `esp_idf_svc::hal::task::block_on`.
use LocalExecutor;
use block_on;
// STD example, work-stealing execution.
use unbounded;
use Parallel;
use ;
// WASM example.
use ;
use LocalExecutor;
use StaticCell;
use spawn_local;
use TimeoutFuture;
static LOCAL_EX: = new;
Highlights
no_std(but does needalloc):- The executor uses allocations in a controlled way: only when a new task is being spawn, as well as during the construction of the executor itself;
- For a
no_stdand "no_alloc" executor, look at embassy-executor, which statically pre-allocates all tasks.
- Works on targets which have no
core::sync::atomicsupport, thanks to portable-atomic; - Does not assume an RTOS and can run completely bare-metal too;
- Lockless, atomic-based, bounded task queue by default, which works well for waking the executor directly from an ISR on e.g. FreeRTOS or ESP-IDF (unbounded also an option with feature
unbounded, yet that might mean potential allocations in an ISR context, which should be avoided).
Great features carried over from async-executor:
- Stack borrows: futures spawned on the executor need to live only as long as the executor itself. No
F: Future + 'staticconstraints; - Completely portable and async.
Executor::runsimply returns aFuture. Polling this future runs the executor, i.e.block_on(executor.run(core::future:pending::<()>())); const newconstructor function.
NOTE:
To compile on no_std targets that do not have atomics in Rust core (i.e. riscv32imc-unknown-none-elf and similar single-core MCUs),
enable features portable-atomic and critical-section. I.e.: