watchdog_wdt.c

nRF52833-DK (id boards.json : nrf52833-dk) · Fichier : watchdog_wdt.c · Langage : C · Usage : Redémarrer automatiquement en cas de blocage

Assurance anti-blocage : le watchdog matériel du nRF redémarre la puce si le firmware oublie de pointer sous 2 secondes. Indispensable pour un capteur sans fil déporté, où personne n’appuiera jamais sur le bouton reset.

Matériel requis

Une carte nRF52833-DK (Nordic, SoC nRF52833 Cortex-M4F, BLE 5) alimentée par USB : 4 LEDs sur P0.13-P0.16 (actives au niveau bas) et 4 boutons sur P0.11, P0.12, P0.24, P0.25 (actifs bas, pull-up interne à activer). La carte seule. Pour tester, commenter wdt_feed() : la carte redémarre au bout de 2 s (trace du reset sur la console).

Câblage

Aucun câblage. Le watchdog est un périphérique interne (wdt0 dans le devicetree des deux cartes).

Fonctionnement

wdt_install_timeout déclare une fenêtre de 2 s avec callback puis reset CPU core ; wdt_setup arme le compteur ; wdt_feed le recharge. Un while(1) qui ne feed plus = reset garanti.

Exécution

Projet Zephyr : west build -b nrf52833dk/nrf52833 puis west flash (J-Link embarqué) ; console série 115200 sur le connecteur USB UART.

Variantes

Utiliser le callback pour sauvegarder un état avant reset (avec WDT_FLAG_RESET_NONE), enchaîner plusieurs fenêtres, ou couper les horloges externes avant de redormir.

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

← Retour à la fiche