#[task]Expand description
This decorator macro replaces embassy_executor::task
to create an async task that can be monitored by the task-watchdog.
§Arguments
timeout: The duration to wait for a feed before considering the task stalled (e.g.timeout = Duration::from_millis(2000))setup: Whether this task contains setup code before the main loop (defaults tofalse). Iftrue, the macro will split the function body into a setup part (before the first loop) and a consume part (from the first loop onward), and will only register the watchdog and apply the timeout to the consume part. This allows for longer-running setup code without triggering a false positive stall detection, while still monitoring the main loop of the task. A task withsetup = truemust contain at least one loop statement (e.g.loop { ... }) for the macro to split on, and the user is expected to feed the watchdog inside the loop(s) to indicate the task is still alive.keep: Whether to keep the task descriptor after the task finishes (defaults totrue). Ifkeepisfalse, the task will be deregistered upon completion. A task withkeep = trueshould not be fallible.fallible: Setting this totruewill remove the requirement for the task function to return!(never), and allow it to return normally. This is useful for tasks that may need to exit on their own after some condition is met, rather than running indefinitely. A fallible task will still be monitored by the watchdog until it finishes, and crash the program. Setkeep = falsefor a fallible task to deregister itself from the watchdog when it finishes.retries: The number of times to retry feeding the watchdog before considering the task stalled (defaults to0). This is useful for allowing some number of missed feeds before triggering a stall, which can help reduce false positives in cases where occasional delays are expected (e.g.retries = 3will allow 3 missed feeds before considering the task stalled). By default, the watchdog will consider the task stalled immediately upon a missed feed.
§Function Requirements
- The function must be
asyncand return!(never), unlessfallible = trueis set, in which case it can return normally. - The function must have at least one parameter of type
embassy_task_watchdog::TaskWatchdog, and the first parameter must be an identifier pattern (e.g.wd: TaskWatchdog). The macro will convert this into a per-task bound watchdog (embassy_task_watchdog::BoundWatchdog) that the user can feed to indicate the task is still alive. - If
setup = trueis set, the function must contain at least one loop statement (e.g.loop { ... }) for the macro to split the setup and consume parts. Any code before the first loop will be considered setup code that runs once. The setup code should not be in a block (surrounded by{}). - If
keep = falseis set, the function should not be fallible, since it will deregister itself from the watchdog when it finishes, and won’t be around to feed it anymore - which will lead to timing out the watchdog.
§Examples
§Simple Example
Example usage for a task is shown below, that feeds the watchdog every 1000ms and is considered stalled if it goes more than 2000ms without feeding:
#[task(timeout = Duration::from_secs(2))]
async fn my_task(watchdog: TaskWatchdog) {
loop {
watchdog.feed().await; // Feed the watchdog to indicate the task is still alive
// Do some work
Timer::after(Duration::from_secs(1)).await;
}
}§Setup Mode Example
#[task(timeout = Duration::from_secs(2), setup = true)]
async fn my_task_with_setup(watchdog: TaskWatchdog) {
// Some setup code that runs once
do_setup().await;
loop {
watchdog.feed().await; // Feed the watchdog to indicate the task is still alive
// Do some work
}
}§Fallible Task Example
#[task(timeout = Duration::from_secs(2), fallible = true, keep = false)]
async fn my_fallible_task(watchdog: TaskWatchdog) {
loop {
watchdog.feed().await; // Feed the watchdog to indicate the task is still alive
// Do some work
if some_condition() {
return; // Exit the task normally, which will deregister it from the watchdog since keep = false
}
}
// task is deregistered here, since keep = false, so the watchdog will stop monitoring it
// and won't trigger a system reset.
}§Caution
In release builds, the macro checks that the number of tasks does not exceed the configured limit
(defaults to 32, refer to
embassy_task_watchdog_numtasks::MAX_TASKS),
and will produce a compile error if more tasks are defined. In debug builds, this
check is skipped to allow for continuous integration testing without needing to adjust the limit.