embassy-supervisor
A generic, HAL-agnostic task-lifecycle supervisor for the embassy
async embedded framework. no_std, no allocator, no board crates — it compiles for any embassy
target. The only third-party deps are pure-embassy crates (embassy-executor/-sync/-time/
-futures), heapless, and portable-atomic.
What it does
- Dependency-ordered lifecycle — declare each task as a
TaskNodewith itsdeps; the supervisor topologically sorts the graph, brings tasks up in dependency order, and tears dependents down before the things they depend on. - Lifecycle modes —
Terminate(started at boot, restartable),Pause(park/resume while keeping a held resource),OnDemand(started on demand to scale a pool). - Elastic pools (feature
pool) —ElasticPoolscales a set of single-instance worker nodes with load via a swappableScalingPolicy(e.g.DeferredShrink), within a fixed budget. - Runtime control (feature
control) — drive start/stop/pause/resume from anywhere (an HTTP endpoint, a button, …) through a decoupled mailbox (request_control/apply_control) that honors dependencies and pool membership.
The supervisor deliberately does not allocate, own a HAL, manage power states, or know what your tasks do — it orchestrates their lifecycle and leaves the rest to you.
Quickstart
use Spawner;
use ;
// Each subsystem is a `TaskNode` wrapping a spawn fn; `app` depends on `net`.
static NET: TaskNode = new;
static APP: TaskNode = new;
task_graph! // emits `ALL_NODES` + `NODE_COUNT`
async
Cargo features
| feature | default | what it adds |
|---|---|---|
control |
✓ | runtime control plane (ControlOp, request_control, apply_control) |
pool |
✓ | elastic worker pools (ElasticPool, with_pools, run_pools) |
defmt |
route the supervisor's logs through defmt (otherwise the log macros are no-ops) |
default-features = false gives a minimal core that only does dependency-ordered
bring-up/teardown — dropping the control plane and pools trims flash and a couple of statics.
no_std / MSRV
#![no_std] and #![forbid(unsafe_code)]. Requires Rust 1.85+ (edition 2024). The embassy
dependencies are pre-1.0 (embassy-executor 0.10, embassy-sync 0.8, embassy-time 0.5), so a
consuming application must use compatible embassy minor versions.
Full example
The firmware crate in the
repository is a complete working application on an RP2350 — USB-CDC-NCM networking, an HTTP control
plane, an elastic worker pool, and OTA firmware update — all driven by this supervisor.
License
Dual-licensed under either MIT or Apache-2.0, at your option.