watchdog_wdt.c

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

Seguro anti-bloqueo: el watchdog hardware del nRF reinicia el chip si el firmware deja de alimentarlo en 2 segundos. Imprescindible para un sensor inalámbrico remoto donde nadie pulsará nunca el reset.

Hardware

Una placa nRF52833-DK (Nordic, SoC nRF52833 Cortex-M4F, BLE 5) alimentada por USB: 4 LED en P0.13-P0.16 (activos a nivel bajo) y 4 botones en P0.11, P0.12, P0.24, P0.25 (activos a bajo, pull-up interno a activar). Solo la placa. Para probar, comenta wdt_feed(): la placa se reinicia a los 2 s (traza del reset en la consola).

Cableado

Sin cableado. El watchdog es un periférico interno (wdt0 en el devicetree de ambas placas).

Funcionamiento

wdt_install_timeout declara una ventana de 2 s con callback y luego reset del núcleo; wdt_setup arma el contador; wdt_feed lo recarga. Un while(1) que deja de alimentar = reset garantizado.

Ejecución

Proyecto Zephyr: west build -b nrf52833dk/nrf52833 y luego west flash (J-Link embarcado); consola serie 115200 en el conector USB UART.

Variantes

Usar el callback para guardar estado antes del reset (con WDT_FLAG_RESET_NONE), encadenar varias ventanas, o apagar relojes externos antes de volver a dormir.

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

← Volver a la ficha