Hardware Watchdog¶
A flight computer that stops running is worse than one that crashes. A crash runs a fault handler, prints something and can reboot while a wedged kernel does none of that. The board simply goes quiet until someone power-cycles it, and on a vehicle in the air nobody can.
This subsystem resets the board when the kernel stops running.
It is enabled with CONFIG_AURORA_WATCHDOG and pairs with
flight state recovery so the reset resumes the flight
rather than rebooting into a disarmed vehicle.
What it supervises¶
Kernel liveness, and deliberately nothing else.
A dedicated thread does nothing but feed a task-watchdog channel on a
timer.
If that thread stops being scheduled for
CONFIG_AURORA_WATCHDOG_TIMEOUT_MS, the board resets.
The feeder is preemptible on purpose: if a higher-priority
thread spins and starves everything below it, the board is not doing
useful work and resetting is the right outcome.
What it does not supervise¶
It does not watch sensor data flow, and that is a design decision rather than an omission.
An earlier attempt fed the watchdog from the state machine’s zbus loop. That loop waits on sensor messages, so a sensor that stopped producing looked identical to a wedged kernel. Worse, an I2C bus wedge on this hardware survives a warm reset, so the board came back up with the same dead bus, failed to feed again and reset in a loop. It never recovered, and a reset loop mid-flight is strictly worse than the fault it was trying to catch.
A sensor that goes quiet is a degraded flight the software should fly through. See sensors for how bus faults are handled.
Why the hardware fallback is not optional¶
CONFIG_AURORA_WATCHDOG selects CONFIG_TASK_WDT_HW_FALLBACK and the
whole design rests on it.
Zephyr’s task watchdog is driven by the kernel timer. The failures this subsystem exists to catch include a stopped kernel clock, and a supervisor that runs off the clock it is supervising stops with it. The hardware watchdog behind it (on ESP32 the TIMG MWDT) runs off its own clock and fires regardless of what the CPU is doing.
This is the same reason CONFIG_TASK_WDT alone is not enough and why the
fallback cannot be turned off while keeping the guarantee.
Board requirements¶
The board must expose a hardware watchdog through the watchdog0 alias
and the node has to be enabled.
On many SoC devicetrees the watchdog nodes are status = "disabled" by
default, so an alias alone is not sufficient and the device will not be
ready at runtime:
/ {
aliases {
watchdog0 = &wdt0;
};
};
&wdt0 {
status = "okay";
};
A node left disabled is caught at
runtime: aurora_watchdog_setup() returns -ENODEV and logs that kernel
liveness is unsupervised.
Configuration¶
Symbol |
Default |
Meaning |
|---|---|---|
|
2000 |
How long the feeder may go unscheduled before the board resets |
|
500 |
How often the feeder feeds the channel |
|
10 |
Feeder thread priority |
|
1024 |
Feeder thread stack |
The timeout is to be kept comfortably above the feed interval. Ordinary scheduling jitter, a logging burst or a flash write must not be enough to trip it. The default leaves room for three missed cycles.
Note
On Xtensa the feeder stack carries more than the function itself suggests. Any interrupt taken while the thread runs pushes a base save area plus spilled registers onto the interrupted thread’s stack, so a thread can be pushed over its limit by an interrupt it never asked for.
Usage¶
#include <aurora/lib/watchdog.h>
int main(void)
{
/* Early, and before anything that can wedge. */
(void)aurora_watchdog_setup();
/* --snip-- */
return 0;
}
Set it up early. The failures it catches run no fault handler and print nothing, so any window before it is armed is a window in which the board can go silently dead.
After a watchdog reset¶
The reset cause is readable through hwinfo and is reported as
RESET_WATCHDOG on the next boot.
The state machine uses exactly that to decide whether to
resume the flight it was in, so the two subsystems are normally enabled
together.
Warning
CONFIG_TASK_WDT_HW_FALLBACK_PAUSE_HALTED_BY_DBG defaults to y, which
pauses the hardware watchdog while a debugger has the CPU halted.
That is convenient for JTAG work, but it means watchdog behaviour cannot
be observed with a debugger attached.
Test it on a free-running board.
API Reference¶
-
enum aurora_wdt_source¶
Liveness sources recorded in the breadcrumb.
Purely observational. See
aurora_watchdog_kickfor why these must never gate the feed.Values:
-
enumerator AURORA_WDT_SRC_IMU¶
IMU samples arriving at the state machine.
-
enumerator AURORA_WDT_SRC_BARO¶
Baro samples arriving at the state machine.
-
enumerator AURORA_WDT_SRC_STATE¶
State machine updates completing.
-
enumerator AURORA_WDT_SRC_COUNT¶
-
enumerator AURORA_WDT_SRC_IMU¶
-
int aurora_watchdog_setup(void)¶
Start watchdog supervision.
Installs the hardware watchdog behind the task watchdog and starts the feeder thread. Safe to call once, from application init.
- Return values:
0 – on success.
-ENODEV – if the hardware watchdog device is not ready.
-errno – as reported by the task watchdog subsystem.
-
static inline void aurora_watchdog_kick(enum aurora_wdt_source src)¶
-
static inline void aurora_watchdog_report(void)¶