watchdog_wdt.c
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;
}