watchdog_wdt.c
Anti-hang insurance: the nRF hardware watchdog reboots the chip if the firmware stops feeding within 2 seconds. Essential for a remote wireless sensor where nobody will ever press the reset button.
Hardware
An nRF52833-DK board (Nordic, nRF52833 Cortex-M4F SoC, BLE 5) powered over USB: 4 LEDs on P0.13-P0.16 (active-low) and 4 buttons on P0.11, P0.12, P0.24, P0.25 (active-low, internal pull-up must be enabled). The board alone. To test, comment out wdt_feed(): the board reboots after 2 s (reset trace on the console).
Wiring
No wiring. The watchdog is an internal peripheral (wdt0 in both boards’ devicetree).
How it works
wdt_install_timeout declares a 2 s window with callback then CPU-core reset; wdt_setup arms the counter; wdt_feed reloads it. A while(1) that stops feeding = guaranteed reset.
Running it
Zephyr project: west build -b nrf52833dk/nrf52833 then west flash (on-board J-Link); 115200 serial console on the USB UART connector.
Variants
Use the callback to save state before reset (with WDT_FLAG_RESET_NONE), chain several windows, or gate external clocks before sleeping again.
watchdog_wdt.c
/* Watchdog matériel nRF : si wdt_feed n'est plus appelé sous
* 2 s, la puce réinitialise le CPU. Callback NULL = reset sec ;
* ici un callback printk avant reset (mode window non utilisé). */
#include <zephyr/kernel.h>
#include <zephyr/drivers/watchdog.h>
static const struct device *wdt = DEVICE_DT_GET(DT_NODELABEL(wdt0));
static void sur_timeout(const struct device *d, uint8_t chan)
{
ARG_UNUSED(d); ARG_UNUSED(chan);
printk("Watchdog : blocage détectée, reset imminent\n");
}
int main(void)
{
if (!device_is_ready(wdt)) {
return 1;
}
struct wdt_timeout_cfg cfg = {
.window.min = 0,
.window.max = 2000, /* 2 s */
.callback = sur_timeout,
.flags = WDT_FLAG_RESET_CPU_CORE,
};
int chan = wdt_install_timeout(wdt, &cfg);
if (chan < 0) {
return chan;
}
wdt_setup(wdt, 0);
while (1) {
/* Toute la logique applicative doit boucler ici.
Simuler un blocage : commenter le feed ci-dessous. */
wdt_feed(wdt, chan);
k_msleep(500);
}
return 0;
}