前言
我們知道 Watchdog 對故障檢測和系統(tǒng)恢復(fù)都至關(guān)重要,但是如果對 MPU 的 Watchdog 在Linux 系統(tǒng)下是如何工作的不是很了解,就不會讓 Watchdog 發(fā)揮它該有的作用,所以接下來大概講解一下如何測試和使用 linux 系統(tǒng)下的 Watchdog。
1、概括
MP13x/MP15x有兩路獨立的看門狗(IWDG1, IWDG2),其中只有IWDG1才可以被配置到安全區(qū)域下訪問。獨立看門狗是由LSI提供時鐘,外部獨立的32kHz的RC提供時鐘源,所以能保證看門狗在整個MPU系統(tǒng)中獨立安全可靠的運行。另外MP15x還有一個窗口看門狗(WWDG),可以作為Cortex-M4協(xié)處理器的Watchdog,Watchdog還可以作為定時器和低功耗喚醒源,但是這篇LAT不會討論相關(guān)話題。
2、工作原理
對 Watchdog 的寄存器配置和中斷響應(yīng)依賴的是 APB 時鐘,所以在配置 Watchdog 之前,需要先對 APB 時鐘進(jìn)行使能(IWDG1 總線時鐘是通過 IWDG1APBEN 和 IWDG1APBLPEN 位來控制,同理 IWDG2 總線時鐘是通過 IWDG2APBEN 和 IWDG2APBLPEN 位來使能),另外Watchdog 的運行時鐘是由 LSI RC 提供。
默認(rèn)的 Watchdog 工作方式是,一旦 Watchdog 使能,IWDCNT 就開始向下計數(shù),當(dāng)這個值從默認(rèn)的 0xFFF 變?yōu)?0x000 時就會產(chǎn)生 iwdg_out_rst 信號,可以使系統(tǒng)重啟。所以在IWDCNT 在變?yōu)?1 之前就需要刷新 Watchdog 防止系統(tǒng) reset,這里通過把 0x0000AAAA 寫入IWDG_KR 寄存器來刷新 IWDCNT 恢復(fù)默認(rèn)值 0xFFF。由于 Linux 系統(tǒng)很難做到和裸跑程序一樣的實時性,所以喂狗時間盡可能的提前,不宜無限接近 Watchdog 的 timeout 時間。
關(guān)于喂狗時間,由上面的簡單描述可以知道,IWDCNT 的默認(rèn)值 0xFFF 是 Watchdog 的最大超時喂狗時間(窗口看門狗是另外的設(shè)計),所以可以通過 IWDG_PR 寄存器來配置 LSI 運行時鐘的 Prescaler divider,從而配置需要的最大超時時間。例如,默認(rèn)的 Watchdog 工作時鐘源是 32Khz LSI RC,如果把 IWDG_PR 寄存器配置為 0x6(divider / 256),那么 Watchdog 工作時鐘就變?yōu)?125Hz,IWDCNT 從 0xFFF 變?yōu)?0x000 就需要(1/125)*4095 約等于 32 秒鐘。
3、注意問題
1) 一旦 watchdog 使能了,整個系統(tǒng)從 tf-a 到 Linux kernel 各個 啟動階段都需要不斷的喂狗,所以當(dāng)任何一個啟動階段卡頓時間超過喂狗的周期,就會觸發(fā) watchdog 重啟。需要注意的是,盡量不要停掉 kernel 內(nèi)部的定時器喂狗程序。同時需要注意,當(dāng)應(yīng)用程序通過/dev/watchdog 設(shè)備節(jié)點,打開看門狗后,Linux kernel 就停掉定時器喂狗,把喂狗執(zhí)行交給應(yīng)用程序,所以這個時候外部的喂狗程序不能中斷。
2) 前面一直提到 TF-A 打印可以查看到重啟的原因,重啟原因是通過 RCC_MP_RSTSCLRR寄存器來判斷的,如果打印的原因一直是 power-on reset,并沒有看到 watchdog 觸發(fā)的原因。主要因為在 watchdog 重啟系統(tǒng)的時候,可能是外部的 VDD 供電被重啟過,導(dǎo)致 MPU 的狀態(tài)恢復(fù)到冷啟動狀態(tài)。所以這邊硬件要注意 MPU 重啟的時候,盡量不要重啟 VDD 供電。
4、總結(jié)
從 OSTL4.0 開始,Linux kernel 階段和 U-Boot 階段都是通過 smc 服務(wù)接口調(diào)用 optee 安全區(qū)域的 Watchdog 來配置和喂狗的,Linux 可以參考 drivers/watchdog/arm_smc_wdt.c 源碼。舊版本的 Watchdog 使用的是 IWDG2,U-Boot 驅(qū)動(drivers/watchdog/stm32mp_wdt.c)和 Linux 驅(qū)動(drivers/watchdog/stm32_iwdg.c)直接調(diào)用 Watchdog 的寄存器(KR,PR,RLR 等)來實現(xiàn)。另外需要注意,默認(rèn)的 systemd是配置看門狗的,如果發(fā)現(xiàn)/dev/watchdog 設(shè)備節(jié)點不讓訪問,需要根據(jù)上文提到的方法來關(guān)閉 systemd 的喂狗程序。一旦應(yīng)用程序接管了喂狗程序,喂狗不能中斷。