Watchdog Timers in Production Devices
A watchdog that only resets the MCU hides the fault it was meant to reveal. Feeding it correctly, logging before the reset, and the one reset reason that is always worth trusting.
The independent watchdog on a production device gets a reputation it does not deserve. Engineers assume it is a safety net; on most products it is a silencer that converts a diagnosable fault into a mystery reboot.
The fix is not a bigger timeout. It is a record of why the last reset happened, written before the reset occurs.
Feed it from one place, and only one place
The single most common defect I see is feeding the watchdog from more than one task, or from an interrupt. Both make the feed meaningless: a task can feed it while another task is already stuck, so the system reports healthy while failing.
Feed it in exactly one place, at the end of the main loop, and only when the whole loop completed:
for (;;) {
sample_sensors();
run_state_machine();
flush_telemetry();
service_uart();
/* Only reached if every stage above finished. This is the point. */
wdt_feed(&wdt);
}
If any stage hangs, the feed stops, and the reset is a true statement about system health rather than a race between feeders.
Write the reason down before you reset
The reset clears RAM. So anything you want to know afterwards has to be somewhere the reset will not clear — RTC backup registers, a separate FRAM, or on most STM32 parts the flash option bytes and the reset flags in the RCC peripheral status register.
static void wdt_callback(void)
{
/* RCC->CSR survives a software reset; bIWDGRSTF does not clear itself
until it is explicitly cleared, so this reads back after a reset. */
wdt_persist_reason(REASON_STALLED_IN_STAGE(stage_counter));
__HAL_RCC_BACKUP_SRAM_CLK_ENABLE();
backup_sram->fault_stage = stage_counter;
HAL_DBGMCU_EnableDBGSleepMode(); /* halt before the reset so we can catch it */
}
The bIWDGRSTF flag is the one value that is always worth trusting, and it is worth reading on boot and reporting upward before you clear anything.
Distinguish watchdog from brownout
Both end in a reset, and they are not the same fault:
| Cause | Reset flag | Typical meaning |
|---|---|---|
| Watchdog | bIWDGRSTF |
Software stopped making progress |
| Brownout | bBORRSTF |
Rail collapsed, or supply cannot meet peak demand |
| Software | bSFTRSTF |
Deliberate restart, or a fault handler escalating |
| Pin | bPINRSTF |
External pull |
A device that browns out under motor load and one that deadlocks in a control loop produce the same symptom from the customer’s side. Reading the flag at boot is the difference between a support ticket and a solved problem.
Make the reset visible to the user
If a device resets in the field and nothing changes, the customer will describe it as “it just restarts”. Log the reset reason, the uptime before it, and the last fault stage, then surface it somewhere the person holding the device can see it. On an industrial unit, that is a status register an operator can read; on a connected product, it is a field on the telemetry payload.
The checklist I use before release
- Exactly one feed point, at the end of the main loop
- Timeout derived from the worst-case measured loop time, with margin — not a round number
- Fault stage persisted outside RAM, written before the reset
- Reset flags read at boot and reported, then cleared
- A deliberately induced hang verified to produce a clean, diagnosable reset
- Supply droop measured with the real load, not a bench supply
The last item catches more field faults than everything above it combined. The watchdog tells you the system stopped; the brownout investigation tells you why, and it is usually the reason.