Watchdog¶
Task: Reset when endless loop / failure occurs
Zephyr Example: https://github.com/zephyrproject-rtos/zephyr/blob/main/samples/drivers/watchdog/src/main.c
Kconfig: https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/watchdog/Kconfig.stm32
Warning
Some Operations are blocking, triggering the Watchdog due to missing updates.
Most important: Flash write operations!
Example¶
#include <zephyr/drivers/watchdog.h>
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_window_watchdog)
#define WDG_FEED_INTERVAL 50U
#endif
static void wdt_callback(const struct device *wdt_dev, int channel_id)
{
static bool handled_event;
if (handled_event) {
return;
}
wdt_feed(wdt_dev, channel_id);
printk("Handled things..ready to reset\n");
handled_event = true;
}
int main(void)
{
const struct device *const wwdg = DEVICE_DT_GET(DT_ALIAS(watchdog0));
if (!device_is_ready(wwdg)) {
printk("%s: device not ready.\n", wwdg->name);
return 0;
}
struct wdt_timeout_cfg wwdg_config = {
/* Reset SoC when watchdog timer expires. */
.flags = WDT_FLAG_RESET_SOC,
/* Expire watchdog after max window */
.window.min = 0,
.window.max = 100,
/* Set up watchdog callback. */
.callback = wdt_callback,
};
int wwdg_channel_id = wdt_install_timeout(wwdg, &wwdg_config);
if (wwdg_channel_id < 0) {
printk("Watchdog WWDG install error\n");
return 0;
}
int err = wdt_setup(wwdg, WDT_OPT_PAUSE_HALTED_BY_DBG);
if (err < 0) {
printk("Watchdog setup error\n");
return 0;
}
/* IWDG driver for STM32 doesn't support callback */
const struct device *const iwdg = DEVICE_DT_GET(DT_ALIAS(watchdog1));
if (!device_is_ready(iwdg)) {
printk("%s: device not ready.\n", iwdg->name);
return 0;
}
struct wdt_timeout_cfg iwdg_config = {
/* Reset SoC when watchdog timer expires. */
.flags = WDT_FLAG_RESET_SOC,
/* Expire watchdog after max window */
.window.min = 0,
.window.max = 100,
};
int iwdg_channel_id = wdt_install_timeout(iwdg, &iwdg_config);
if (iwdg_channel_id < 0) {
printk("Watchdog IWDG install error\n");
return 0;
}
int err = wdt_setup(iwdg, WDT_OPT_PAUSE_HALTED_BY_DBG);
if (err < 0) {
printk("Watchdog setup error\n");
return 0;
}
/* Wait opening window / window.min. */
k_msleep(0);
/* Feeding watchdog. */
printk("Feeding watchdog %d times\n", 5);
for (int i = 0; i < 5; ++i) {
printk("Feeding watchdog...\n");
wdt_feed(wwdg, wwdg_channel_id);
k_sleep(K_MSEC(50)); // before window.max
}
// wdt_disable(wwdg)
/* Waiting for the SoC reset. */
printk("Waiting for reset...\n");
while (1) {
k_yield();
}
return 0;
}