Skip to content

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;
}