原创 看门狗在嵌入式 Linux 中的应用

2019-4-3 16:55 2089 18 1 分类: MCU/ 嵌入式

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

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

 

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

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

 

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

image001.png

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

 

 

3). 总结

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


作者: hai.qin_651820742, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-1864768.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论0条评论)

登录后参与讨论
我要评论
0
18
关闭 站长推荐上一条 /2 下一条