Raspberry Pi Hardware Watchdog: Wiring bcm2835_wdt to systemd Safely
Enable the bcm2835 watchdog on a Raspberry Pi, hand it to systemd with RuntimeWatchdogSec, verify the chain via /proc/1/fd, and avoid reboot loops.
03 Oct 2025, 13:56 UTC

What the watchdog buys you, and what it does not
A Raspberry Pi left running headless can hang in a way that leaves the network unreachable and the board unresponsive to SSH. The SoC includes a hardware watchdog timer: a countdown that the kernel, or a userspace process, must reset periodically. If the countdown reaches zero, the chip resets the board without any software cooperation. That is the whole value — it works when nothing else does.
It does not fix power problems, SD card wear, or a network outage. It only converts "hung forever" into "rebooted after N seconds".
How the chain is assembled
Three layers must line up:
- Firmware/device tree: the watchdog peripheral must be enabled so the kernel binds a driver.
- Kernel driver:
bcm2835_wdtcreates/dev/watchdogand exposes a timeout under/sys/class/watchdog/. - A feeder: something must write to the device before the timeout expires. systemd can do this for the kernel watchdog, or your own daemon can.
If any layer is missing, the board behaves exactly as before and you get no protection — silently.
Worked configuration
Assume Raspberry Pi OS Bookworm or later. On Bookworm the boot partition is mounted at /boot/firmware; on older releases the same file is /boot/config.txt. Check which exists before editing.
Step 1 — enable the peripheral
Edit the boot config as root:
# /boot/firmware/config.txt (Bookworm and later)
# older images: /boot/config.txt
dtparam=watchdog=onReboot, then confirm the driver bound:
ls -l /dev/watchdog
lsmod | grep bcm2835_wdt
cat /sys/class/watchdog/watchdog0/timeoutExpected: /dev/watchdog exists, the module is listed, and the sysfs file reports the driver's current timeout in seconds. If /dev/watchdog is missing, the overlay name or the file path is wrong — fix that before continuing.
Step 2 — let systemd own the timer
systemd's PID 1 opens /dev/watchdog and pets it as part of its main loop, so a kernel or PID 1 stall triggers a reset. Add a drop-in rather than editing the vendor file:
# /etc/systemd/system.conf.d/watchdog.conf
[Manager]
RuntimeWatchdogSec=15s
RebootWatchdogSec=2minRuntimeWatchdogSec is the timeout while the system is up; RebootWatchdogSec covers the shutdown and reboot window. Apply with a reboot — see the rollback note below about why a live re-exec is riskier on a remote box.
Step 3 — check that PID 1 actually holds the device
sudo ls -l /proc/1/fd | grep watchdog
systemctl show --property=Watchdog
wdctl # util-linux; may need installingExpected: PID 1 has an open descriptor on /dev/watchdog, and systemctl reports the value you set. If /proc/1/fd shows nothing, systemd did not arm the watchdog — usually because the device node is absent or the drop-in landed in the wrong directory (system.conf.d, not system.conf).
Making an application participate
The kernel watchdog cannot see an application deadlock; a process stuck in a loop still lets the kernel pet the timer. To cover that, the service must report liveness itself:
# /etc/systemd/system/myapp.service.d/watchdog.conf
[Service]
WatchdogSec=30s
Restart=on-watchdog
NotifyAccess=mainThe application must call sd_notify(WATCHDOG=1) at least every WatchdogSec — via libsystemd or a language binding. A shell wrapper calling systemd-notify will not work with the default NotifyAccess=main, because the notification must come from the main process; either notify from the app itself or set NotifyAccess=all deliberately.
The trap: if you set WatchdogSec and the app never notifies, systemd treats the service as failed and restarts it on every interval. On a device with no console that looks like a crash loop.
Limits worth knowing before you rely on it
- Reset, not repair. In-flight writes are lost. Journaling filesystems usually recover, but "usually" is not a guarantee for databases or raw SD-card images.
- Boot-time hangs are only partly covered. If the board hangs before the kernel loads the watchdog driver, nothing resets it.
- Timeout granularity is driver-limited. The bcm2835 driver rounds to values the hardware counter supports; read
/sys/class/watchdog/watchdog0/timeoutrather than assuming your configured number is exact. - A busy system is not a hung system. Long garbage-collection pauses, heavy SD-card I/O, or a slow boot can exceed a short timeout and cause a reboot that makes things worse. Start long (60s or more), then tighten.
- Undervoltage is not fixed by a reset. If the supply sags, the board may reboot into the same condition. Check the kernel's undervoltage messages before blaming software.
Common mistakes
- Editing
/boot/config.txton a Bookworm image, where the live file is/boot/firmware/config.txt. - Enabling the overlay and stopping there, without confirming the driver loaded.
- Trying to feed
/dev/watchdogfrom a non-root process; the device node is root-only by default. - Setting
WatchdogSecon a service that never sendsWATCHDOG=1. - Testing with a 5-second timeout on a device you can only reach over the network.
Verifying the chain, and rolling back
The only test that proves the chain is a deliberate missed feed. On a bench unit with a serial console or physical access, stop the process that feeds the watchdog and time how long until the board resets. For a systemd-managed kernel watchdog you cannot easily stop PID 1 from petting, so the practical commissioning check is the descriptor in /proc/1/fd plus a documented manual power-cycle test.
To roll back: remove dtparam=watchdog=on from the boot config and delete /etc/systemd/system.conf.d/watchdog.conf, then reboot. Do not assume that removing RuntimeWatchdogSec and running systemctl daemon-reexec safely disarms the timer — whether closing /dev/watchdog disarms it or triggers a reset depends on the driver's nowayout setting, and that is worth confirming on your kernel before doing it on a remote device. A reboot is the predictable path.
Watchdog behaviour varies with kernel and driver version, so treat the timeout values above as starting points and confirm them on the image you actually deploy.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.