Skip to main content

task

Attribute Macro task 

Source
#[task]
Expand description

Declare a static async task.

The annotated function must be async fn name() { ... } — no parameters (shared state goes through statics, matching the usual embedded pattern for peripherals/queues). The body may freely use .awaitSleep, Semaphore::acquire(), Channel::send()/recv() all work as real futures polled by the executor.

§Attributes

  • priority (required): Task priority (0 = lowest, 31 = highest).
  • stack (optional): bytes reserved for the future’s state machine (default 512). Increase this if you get a “task future exceeds reserved stack size” panic at boot.

§Example

#[rivet::task(priority = 1, stack = 256)]
async fn blinky() {
    loop {
        rivet::time::Sleep::<500_000>::new().await; // 500ms
        toggle_led();
    }
}

§How it works

F (the compiler-generated Future type of an async fn) is unnameable on stable Rust, so it can’t appear in a static’s type. Instead the macro declares static CELL: TaskCell<STACK_SIZE> (STACK_SIZE is just a usize, always nameable) and generates a thin non-generic wrapper function that calls the crate’s generic TaskCell::poll::<F>, letting the compiler monomorphize the actual future read/write per task without ever needing to write F down.