看門狗在嵌入式 Linux 中的應(yīng)用
By Toradex胡珊逢
1). 簡介
在嵌入式領(lǐng)域中 Watchdog 看門狗通常被作為用于應(yīng)對系統(tǒng)或者應(yīng)用意外崩潰的有效手段。其可以在程序執(zhí)行出錯并無法恢復(fù)的情況下,自動重啟應(yīng)用甚至復(fù)位整個系統(tǒng),從而使系統(tǒng)脫離宕機狀態(tài),恢復(fù)正常業(yè)務(wù)執(zhí)行。這對于涉及到人身、財產(chǎn)安全的應(yīng)用,顯得極為重要。本文將基于NXP iMX6 嵌入式平臺如何使用看門狗進行介紹,應(yīng)對 Linux 系統(tǒng)或者應(yīng)用程序意外崩潰。
本文所演示的iMX6平臺來自于Toradex Colibri iMX6 計算機模塊,iMX6芯片自帶看門狗功能,其硬件和早期的 iMX2 一致,所以看門狗驅(qū)動仍然沿用 imx2-wdt。看門狗只支持單用戶操作,即只能有一個實例來使用看門狗。因此在 Linux 系統(tǒng)中,用戶可以選擇由自己的應(yīng)用直接使用看門狗,但只限于一個進程??撮T狗只監(jiān)控該應(yīng)用,對于Linux 本身或者其他應(yīng)用則無法在意外崩潰的情況下觸發(fā)看門狗復(fù)位。或者使用 systemd (183以后的版本)來操作硬件看門狗,同時為用 systemd 所管理的單元提供軟件邏輯看門狗。硬件看門狗主要應(yīng)對 Linux 內(nèi)核以及 systemd 自身的崩潰,軟件邏輯看門狗則可以用于用戶自己的應(yīng)用,且不受數(shù)量限制。
2). 用戶應(yīng)用操作
./ 首先在 U-Boot 中設(shè)置看門狗超時時間,這里設(shè)置為 60 秒。
------------------------
setenv defargs $defargs imx2-wdt.timeout=60
saveenv
------------------------
./ 編譯完成后運行測試程序。
------------------------
root@colibri-imx6:~# ./wdt-sample-app &
[1] 627
------------------------
./ 終結(jié)該測試程序進程。當進程被終結(jié)后,看門狗仍舊保持運行,但是無法定時喂狗。因此,在60s 超時后,看門狗會復(fù)位系統(tǒng)。
------------------------
root@colibri-imx6:~# kill 627
root@colibri-imx6:~# [ 45.964155] watchdog: watchdog0: watchdog did not stop!
[1]+ Terminated ./wdt-sample-app
------------------------
./ 當模塊由于看門狗復(fù)位時,可以從U-Boot 啟動的串口日志發(fā)現(xiàn)復(fù)位的原因。
------------------------
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). 對于需要使用看門狗監(jiān)控多個應(yīng)用,可以使用 systemd 來操作。Systemd 提供硬件看門狗和軟件看門狗支持。硬件看門狗用于監(jiān)控 Linux 內(nèi)核以及 systemd 自身的運行,一旦出現(xiàn)內(nèi)核崩潰的情況,看門狗超時將觸發(fā)系統(tǒng)復(fù)位。在 systemd 中使用硬件看門狗非常簡單,只需要配置 /etc/systemd/system.conf 中的RuntimeWatchdogSec= 參數(shù),將其設(shè)置超時時間即可。在規(guī)定時間如果沒有喂狗,將觸發(fā)復(fù)位。systemd 通常會在所設(shè)置時間的一半為間隔進行喂狗。ShutdownWatchdogSec= 則可以設(shè)置關(guān)機超時時間,如果系統(tǒng)在該時間內(nèi)沒有完成關(guān)機,也將系統(tǒng)復(fù)位。
./ 為了觸發(fā)內(nèi)核崩潰的情況,我們需要開啟內(nèi)核調(diào)試的 MAGIC_SYSRQ 功能,該選項在 Toradex 默認的 Linux BSP 中是關(guān)閉的。打開后重新編譯內(nèi)核。
------------------------
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
CONFIG_DEBUG_KERNEL=y
------------------------
./ 設(shè)置超時時間為60秒,RuntimeWatchdogSec=60。 啟動查看系統(tǒng)日志,顯示硬件看門狗超時時間被設(shè)置為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.
------------------------
./ 然后我們用下面命令觸發(fā)內(nèi)核崩潰。
------------------------
echo c > /proc/sysrq-trigger
------------------------
./ 一分鐘以后,由于 systemd 沒有對進行喂狗操作,系統(tǒng)將復(fù)位后重新啟動。
b). 除了硬件看門狗外,sytemd 還提供軟件看門狗,每個 systemd service 都可以使用。service 需要讀取 WATCHDOG_USEC= 參數(shù),確定看門狗超時時間,并在該時間范圍內(nèi)使用 sd_notify("WATCHDOG=1") 喂狗,同樣喂狗的時間間隔為 WATCHDOG_USEC= 所設(shè)置的一半。
./ 用戶只要在對應(yīng)的 systemd service 文件中設(shè)置 WatchdogSec= 參數(shù)即可,而 WATCHDOG_USEC= 將根據(jù)前面的參數(shù)自動被設(shè)置。在應(yīng)用程序中以 WatchdogSec/2 的間隔調(diào)用 sd_notify 函數(shù)發(fā)送 "WATCHDOG=1"進行喂狗操作。例如
------------------------
// Systemd servier 文件(/etc/systemd/system/test.service),用于啟動用戶應(yīng)用
[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
------------------------
./ 用戶應(yīng)用 wdt-sw-test.c,并定期執(zhí)行喂狗操作(編譯的時候需要使用 -lsystemd 鏈接 systemd 庫文件)。
在應(yīng)用初始化后需要通知 systemd 管理器本應(yīng)用正常啟動,sd_notify (0, "READY=1");。然后根據(jù) WATCHDOG_USEC 變量設(shè)置喂狗間隔。在應(yīng)用中我們將模擬一次超時喂狗,從而引起應(yīng)用重啟。
./ 下面是運行日志。起初應(yīng)用程序 wdt-sw-test 由 systemd 加載啟動,PID=396,并以15s間隔喂狗(該時間源自WatchdogSec=30s)。當喂狗超時后,systemd 會發(fā)送信號 SIGABRT 終止該進程,并重啟該應(yīng)用,新 PID=647。
./ 在 service 文件中,我們還配置了 StartLimitBurst 和 StartLimitInterval 以及 StartLimitAction 參數(shù)。這使得在 StartLimitInterval 時間內(nèi)應(yīng)用啟動次數(shù)超過 StartLimitBurst 后,將不被允許再次啟動,并觸發(fā) StartLimitAction 的操作。具體描述請參考 systemd.unit。
4). 總結(jié)
看門狗對于關(guān)鍵應(yīng)用,以及大多數(shù)的一般應(yīng)用來講是一個很重要的功能,其能夠應(yīng)對 Linux系統(tǒng)或者應(yīng)用崩潰的情況,避免用戶設(shè)備處于失控的狀態(tài)。當整個系統(tǒng)只有一個嵌入式設(shè)備作為決策控制單元時,對于關(guān)鍵的安全應(yīng)用,根據(jù)單一故障準則,我們還建議引入輔助控制單元,例如額外的 MCU 等做同步監(jiān)測,或者使用保險絲、熱電偶等,當出現(xiàn)超限情況,能夠執(zhí)行緊急操作,從而進一步提高設(shè)備的安全性。
*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。