By Toradex胡珊逢

1).简介

在嵌入式领域中 Watchdog 看门狗通常被作为用于应对系统或者应用意外崩溃的有效手段。其可以在程序执行出错并无法恢复的情况下,自动重启应用甚至复位整个系统,从而使系统脱离宕机状态,恢复正常业务执行。这对于涉及到人身、财产安全的应用,显得极为重要。本文将基于NXP iMX6 嵌入式平台如何使用看门狗进行介绍,应对 Linux 系统或者应用程序意外崩溃。

本文所演示的iMX6平台来自于Toradex Colibri iMX6 计算机模块,iMX6芯片自带看门狗功能,其硬件和早期的 iMX2 一致,所以看门狗驱动仍然沿用 imx2-wdt。看门狗只支持单用户操作,即只能有一个实例来使用看门狗。因此在 Linux 系统中,用户可以选择由自己的应用直接使用看门狗,但只限于一个进程。看门狗只监控该应用,对于Linux 本身或者其他应用则无法在意外崩溃的情况下触发看门狗复位。或者使用 systemd (183以后的版本)来操作硬件看门狗,同时为用 systemd 所管理的单元提供软件逻辑看门狗。硬件看门狗主要应对 Linux 内核以及 systemd 自身的崩溃,软件逻辑看门狗则可以用于用户自己的应用,且不受数量限制。

2).用户应用操作

./ 首先在 U-Boot 中设置看门狗超时时间,这里设置为 60 秒。

------------------------

setenv defargs $defargs imx2-wdt.timeout=60

saveenv

------------------------

./ 编译完成后运行测试程序。

------------------------

root@colibri-imx6:~# ./wdt-sample-app &

[1] 627

------------------------

./ 终结该测试程序进程。当进程被终结后,看门狗仍旧保持运行,但是无法定时喂狗。因此,在60s 超时后,看门狗会复位系统。

------------------------

root@colibri-imx6:~# kill 627

root@colibri-imx6:~# [ 45.964155] watchdog: watchdog0: watchdog did not stop!

[1]+ Terminated ./wdt-sample-app

------------------------

./ 当模块由于看门狗复位时,可以从U-Boot 启动的串口日志发现复位的原因。

------------------------

U-Boot 2016.11-2.8.5+g02735f4004 (Dec 28 2018 - 01:54:12 +0000)

CPU: Freescale i.MX6DL rev1.1 at 792 MHz

Reset cause: WDOG

I2C: ready

DRAM: 512 MiB

------------------------

3). Systemd操作

a).对于需要使用看门狗监控多个应用,可以使用systemd来操作。Systemd提供硬件看门狗和软件看门狗支持。硬件看门狗用于监控Linux内核以及systemd自身的运行,一旦出现内核崩溃的情况,看门狗超时将触发系统复位。在systemd中使用硬件看门狗非常简单,只需要配置/etc/systemd/system.conf中的RuntimeWatchdogSec=参数,将其设置超时时间即可。在规定时间如果没有喂狗,将触发复位。systemd通常会在所设置时间的一半为间隔进行喂狗。ShutdownWatchdogSec=则可以设置关机超时时间,如果系统在该时间内没有完成关机,也将系统复位。

./为了触发内核崩溃的情况,我们需要开启内核调试的MAGIC_SYSRQ功能,该选项在Toradex默认的Linux BSP中是关闭的。打开后重新编译内核。

------------------------

CONFIG_MAGIC_SYSRQ=y

CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1

CONFIG_DEBUG_KERNEL=y

------------------------

./设置超时时间为60秒,RuntimeWatchdogSec=60。 启动查看系统日志,显示硬件看门狗超时时间被设置为1分钟。

------------------------

root@colibri-imx6:/etc/systemd# dmesg|grep watchdog

[ 3.137012] systemd[1]: Hardware watchdog 'imx2+ watchdog', version 0

[ 3.147564] systemd[1]: Set hardware watchdog to 1min.

------------------------

./然后我们用下面命令触发内核崩溃。

------------------------

echo c > /proc/sysrq-trigger

------------------------

./一分钟以后,由于systemd没有对进行喂狗操作,系统将复位后重新启动。

b).除了硬件看门狗外,sytemd还提供软件看门狗,每个systemd service都可以使用。service需要读取WATCHDOG_USEC=参数,确定看门狗超时时间,并在该时间范围内使用sd_notify("WATCHDOG=1")喂狗,同样喂狗的时间间隔为WATCHDOG_USEC=所设置的一半。

./用户只要在对应的systemd service文件中设置WatchdogSec=参数即可,而WATCHDOG_USEC=将根据前面的参数自动被设置。在应用程序中以WatchdogSec/2的间隔调用sd_notify函数发送"WATCHDOG=1"进行喂狗操作。例如

------------------------

// Systemd servier文件(/etc/systemd/system/test.service),用于启动用户应用

[Unit]

Description=Watchdog Test service

[Service]

ExecStart=/home/root/wdt-sw-test

WatchdogSec=30s

Restart=on-failure

StartLimitInterval=5min

StartLimitBurst=4

StartLimitAction=reboot

[Install]

WantedBy=multi-user.target

------------------------

./用户应用,并定期执行喂狗操作(编译的时候需要使用-lsystemd链接systemd库文件)。

在应用初始化后需要通知systemd管理器本应用正常启动,sd_notify (0, "READY=1");。然后根据WATCHDOG_USEC变量设置喂狗间隔。在应用中我们将模拟一次超时喂狗,从而引起应用重启。

./下面是运行日志。起初应用程序wdt-sw-test由systemd加载启动,PID=396,并以15s间隔喂狗(该时间源自WatchdogSec=30s)。当喂狗超时后,systemd会发送信号SIGABRT终止该进程,并重启该应用,新PID=647。

1adc4fcf4a6de2a12e733117d566c42d.png

./在service文件中,我们还配置了StartLimitBurst和StartLimitInterval以及StartLimitAction参数。这使得在StartLimitInterval时间内应用启动次数超过StartLimitBurst后,将不被允许再次启动,并触发StartLimitAction的操作。具体描述请参考systemd.unit。

3).总结

看门狗对于关键应用,以及大多数的一般应用来讲是一个很重要的功能,其能够应对Linux系统或者应用崩溃的情况,避免用户设备处于失控的状态。当整个系统只有一个嵌入式设备作为决策控制单元时,对于关键的安全应用,根据单一故障准则,我们还建议引入辅助控制单元,例如额外的MCU等做同步监测,或者使用保险丝、热电偶等,当出现超限情况,能够执行紧急操作,从而进一步提高设备的安全性。

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐