| Crates.io | task-watchdog |
| lib.rs | task-watchdog |
| version | 0.1.2 |
| created_at | 2025-03-20 17:12:02.738637+00 |
| updated_at | 2025-03-30 14:25:09.382239+00 |
| description | 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 |
| homepage | |
| repository | https://github.com/piersfinlayson/task-watchdog |
| max_upload_size | |
| id | 1599487 |
| size | 181,442 |
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.
alloc and no_alloc modes for environments with or without heap availabilityno_std Compatible: Designed for resource-constrained embedded environments without an operating systemExamples are provided for async (using embassy-rs) and sync operation of task-watchdog. The async/embassy example supports the Pico, Pico 2 and STM32F103C8 (blue pill). The sync example supports the Pico and Pico 2.
First, install Rust
Add the approriate 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/STM321F103C8 device to a connected debug probe, and run one of:
builds/flash-async-pico.sh
builds/flash-async-pico2.sh
builds/flash-async-stm32f103c8.sh
builds/flash-async-nrf52840.sh
To understand how to use task-watchdog yourself, check out one of the examples:
intro.rs - A very basic Pico/Pico 2/STM32/nRF/ESP32 async exampleembassy.rs - Pico/Pico 2/STM32rp-sync.rs - Pico/Pico 2For ESP32 support see scripts/README.md.
The library supports both synchronous and asynchronous APIs with a consistent pattern across both styles.
For platforms using Embassy, tasks feed the watchdog asynchronously:
// Setup
let watchdog = WatchdogRunner::new(hw_watchdog, config, EmbassyClock);
// Register tasks with individual timeouts
watchdog.register_task(&MainTask, Duration::from_millis(2000)).await;
watchdog.register_task(&SensorTask, Duration::from_millis(5000)).await;
// Spawn the watchdog task itself
spawner.spawn(watchdog_task(watchdog)).unwrap();
// In your application tasks
async fn main_task(watchdog: &'static WatchdogRunnerType) -> ! {
loop {
// Do work...
watchdog.feed(&MainTask).await;
Timer::after(Duration::from_millis(1000)).await;
}
}
// Implement other tasks
See complete example at examples/src/embasy.rs
For platforms without an async runtime, manually manage the watchdog in your main loop:
// Setup
let mut watchdog = Watchdog::<TaskId, NUM_TASK_IDS, RpHalTaskWatchdog, RpHalClock>::new(
hw_watchdog, config, RpHalClock::new(timer)
);
// Register tasks with individual timeouts
watchdog.register_task(&TaskId::Main, RpHalDuration::millis(2000));
watchdog.register_task(&TaskId::Sensors, RpHalDuration::millis(3000));
// Start the watchdog
watchdog.start();
// In your main loop
loop {
// Feed watchdogs for active tasks
watchdog.feed(&TaskId::Main);
// Check for starved tasks
let _ = watchdog.check();
}
See complete example at examples/src/rp-sync.rs
The crate is designed to be platform-agnostic via trait implementations, but includes first-class support for:
rp2040/rp2350 features (embassy) and rp2040-hal/rp2350-hal (rp2040-hal/rp235x-hal respectively)embassy featureThere are many other features - see scripts/build-lib.sh for the valid combinations. The most common are:
embassy,rp2040,defmt - Async, Pico with defmt supportembassy,rp2350,defmt - Async, Pico 2 with defmt supportembassy,stm32,defmt - Async, STM32 with defmt support - you will also need embassy-stm32/your_stm32_board_typeembassy,nrf,defmt - Async, nRF with defmt support - you will also need embassy-nrf/your_nrf_board_typeLicensed under either of the following, at your option: