embassy-task-watchdog 0.0.5

A robust, flexible watchdog management library for embedded systems that multiplexes multiple task watchdogs into a single hardware watchdog timer, preventing system lockups when tasks fail to respond
Documentation

🐼🐻 embassy-task-watchdog πŸ›‘οΈ

A robust, flexible watchdog management library for embedded systems that multiplexes multiple task watchdogs into a single hardware watchdog timer, preventing system lockups when tasks fail to respond.

✨ Key Features

  • πŸ”„ Hardware Agnostic API: Implements a consistent, asynchronous interface across different embedded microcontrollers by leveraging embassy.
  • πŸ”€ Task Multiplexing: Consolidates multiple independent task watchdogs into a single hardware watchdog, triggering if any task fails to check in.
  • πŸ”Œ Compile-time Task Management: The embassy_task_watchdog::task macro replaces embassy_executor::task, and automatically registers the task with the Watchdog.
  • πŸ“¦ No-alloc Mode: All memory allocations are performed during compilation.
  • ⏱️ Configurable Timeouts: Individual timeout durations for each registered task.
  • πŸ§ͺ no_std Compatible: Designed for resource-constrained embedded environments without an operating system.
  • πŸ¦€ Compile-time Total Tasks Check: By default, the library supports 32 watchdog tasks. The limit can be changed by setting the EMBASSY_TASK_WATCHDOG_MAX_TASKS variable either in your .cargo/config.toml, or by passing it as an environment variable to cargo, e.g. EMBASSY_TASK_WATCHDOG_MAX_TASKS=8 cargo build. The check is disabled in debug builds to prevent errors in IDEs, but exceeding the number of tasks will trigger a compiler error in the release build.

πŸš€ Quick Start

Examples are provided for Raspberry Pi series of microcontrollers, as well as the STM32 microcontrollers using embassy. The examples support the Pico, Pico 2 and STM32F103C8 (blue pill).

First, install Rust

Add the appropriate target(s):

rustup target add thumbv6m-none-eabi         # RP2040/Pico
rustup target add thumbv8m.main-none-eabihf  # RP235x/Pico 2
rustup target add thumbv7m-none-eabi         # STM32
rustup target add thumbv7em-none-eabi        # NRF

Next, install probe-rs

Now connect your Pico/Pico 2/STM32F103C8 device to a connected debug probe, and go into one of:

Then execute

cargo run --release

To understand how to use embassy-task-watchdog yourself, check out one of the examples:

  • task-pico - A very basic Pi Pico async example
  • task-pico2 - A very basic Pi Pico 2 async example
  • task-stm32 - A very basic Blue Pill async example

πŸ“ Usage

The library supports the embassy-executor asynchronous API.

To use in your project, add the following line to your Cargo.toml file:

embassy-task-watchdog = { version = "0.0.2", features = ["rp"] } # additionally, supports defmt for logging, stm32 for STM32 devices...

πŸ› οΈ Features

  • rp: For Raspberry Pi Pico (RP2040) / Pico 2 (RP235xA) or RP235xB based devices. Set up for the correct chip in your Cargo.toml by selecting the correct feature in the embassy-rp dependency.
    • defmt-embassy-rp: defmt debugging for the Embassy executors.
  • stm32: For STM32 series of devices. Set up for the correct chip in your Cargo.toml by selecting the correct feature in the embassy-stm32 dependency.
    • defmt-embassy-stm32: defmt debugging for Embassy executors.
  • defmt: Enable defmt::Format for the embassy-task-watchdog crate.
  • defmg-messages: Enable log messages from the embassy-task-watchdog crate.

🧠 Core Concepts

  • Task Registration: Each monitored task is registered with its own timeout period. The registration is automatic.
  • Feeding: Tasks must feed, or pet, the watchdog within their timeout period to prevent a reset.
  • Task Multiplexing: The library efficiently manages multiple task timeouts through a single hardware watchdog, triggering if any individual task fails to check in.

Task Watchdog Multiplexing

⚑Asynchronous API using Embassy

Tasks feed the watchdog asynchronously, powered by Embassy:

// Imports
use embassy_task_watchdog::{
  WatchdogConfig, create_watchdog, 
  embassy_rp::{
    TaskWatchdog, WatchdogRunner, watchdog_run
  }
};
// Setup
let (watchdog, watchdogrunner) = create_watchdog!(hw_watchdog, config);

// Spawn the task and pass the watchdog
spawner.must_spawn(main_task(watchdog));
// Spawn the hardware watchdog runner and pass the watchdogrunner
spawner.must_spawn(watchdog_task(watchdogrunner));

// Define the hardware watchdog runner task
#[embassy_executor::task]
async fn watchdog_task(wdtrunner: WatchdogRunner) -> ! {
  wdtrunner.run().await
}

// In your application tasks
#[embassy_task_watchdog::task(timeout = Duration::from_millis(2000))]
async fn main_task(watchdog: TaskWatchdog) -> ! {
    loop {
        // Do work...
        watchdog.feed().await;
        Timer::after(Duration::from_millis(1000)).await;
    }
}

// Implement other tasks

πŸ—οΈ Platform Support

The crate includes first-class support for:

  • RP2040 and RP2350 (Raspberry Pi Pico and Pico 2) via the rp feature.
  • STM32 family via the stm32 feature.
  • defmt for defmt based logging.

πŸ“œ License

Licensed under either of the following, at your option:

πŸ”₯ Inspiration

This work is inspired heavily by the task-watchdog crate by Piers Finlayson, which provides a task multiplexing watchdog for embedded systems. It has not been maintained in almost a year (last commit was on April 10, 2025). This crate is a fork of that work, with the following goals:

  • Update the codebase to be compatible with the latest versions of Rust and Embassy, and to use modern Rust features and idioms.
  • Automate the task registration process with a procedural macro, to reduce boilerplate and make it easier to use.
  • Get rid of custom task identifier types through the Id trait that had to be manually managed.
  • Allow compile-time flexibility without allocations, with as many checks as possible.

To achieve these goals, the codebase has been refactored to limit its scope to embassy-based async applications, which is the primary use case for this crate. The API has been redesigned to be more ergonomic and easier to use, while still providing the same core functionality of multiplexing multiple task watchdogs into a single hardware watchdog timer.