watchdog_wdt.c

nRF52833-DK (boards.json id: nrf52833-dk) · File : watchdog_wdt.c · Language : C · Use case : Redémarrer automatiquement en cas de blocage

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

← Back to the board