Using systemd to control the hardware watchdog
This guide describes a method for controlling the hardware watchdog via systemd.
We assume that a Yocto BSP has already been built according to the instructions in this wiki for the desired Module.
However, the services and scripts should also work with Linux systems outside the Yocto build system (Ubuntu, Debian, etc.).
Global control with systemd (PID 1)
Systemd’s global feeding is enabled by setting RuntimeWatchdogSec
in the manager configuration. The file is located at /etc/systemd/system.conf
.
Any non-zero, non-off value for this variable causes systemd to open the device (by default /dev/watchdog0
) and feed it at a safe cadence.
Only one process can hold a watchdog device. If a separate daemon or application opens /dev/watchdog0
first, systemd’s RuntimeWatchdogSec will not take effect until the device becomes free. If multiple watchdog drivers are present, choose the one you want to use (or set WatchdogDevice=
) and disable the others to avoid unexpected resets.
Systemd service
A service can declare Type=notify
and WatchdogSec=
in its unit. Systemd then provides the environment variable WATCHDOG_USEC
to the service process and expects periodic heartbeats.
The application announces it is ready, then sends “I’m alive” messages at an interval derived from WATCHDOG_USEC
. If systemd does not receive the heartbeat on time, it flags a watchdog timeout for that unit and reacts immediately according to the unit policy. A common choice is to restart the service (Restart=on-watchdog
); you can also escalate to a system reboot with FailureAction=reboot
.
Test instructions
To test this, we created a meta-layer (meta-watchdog.zip). In this, we integrate a service (wd-demo.service) that starts a shell script (wd-demo.sh), which periodically reports its activity back to systemd via the systemd-notify function (systemd-notify “WATCHDOG=1”
).
To integrate the meta-layer (meta-watchdog.zip), unzip the ZIP archive under ~/workspace/{build folder}/ci-meta-tqmx86/sources
.
In order for Yocto to include the layer in the build, it must be entered in conf/bblayers.conf
.
echo 'BBLAYERS += "${BSPDIR}/sources/meta-watchdog"' >> conf/bblayers.conf
To ensure that the script and the service ultimately end up in the image, the following must also be added to conf/local.conf
:
IMAGE_INSTALL:append = " systemd-watchdog-dropin watchdogtest "
Then build the Yocto image as usual.
To stop the script in the live system, you must first determine the process ID of the service.
z.B. PID=$(systemctl show -p MainPID --value wd-demo.service)
You can then stop the process with the following command:
kill -STOP ${PID}
The system will then reboot after ~10 seconds.
Sources: