多工看門狗, 餵狗方法

2021-04-20 18:51:49 字數 3549 閱讀 3694

看門狗分硬體看門狗和 軟體看門狗。硬體看門狗是利用乙個定時器電路,其定時輸出連線到電路的復位端,程式在一定時間範圍內對定時器清零(俗稱「餵狗」),因此程式正常工作時, 定時器總不能溢位,也就不能產生復位訊號。如果程式出現故障,不在定時週期內復位看門狗,就使得看門狗定時器溢位產生復位訊號並重啟系統。軟體看門狗原理 上一樣,只是將硬體電路上的定時器用處理器的內部定時器代替,這樣可以簡化硬體電路設計,但在可靠性方面不如硬體定時器,比如系統內部定時器自身發生故障 就無法檢測到。當然也有通過雙定時器相互監視,這不僅加大系統開銷,也不能解決全部問題,比如中斷系統故障導致定時器中斷失效。

看門狗本身不是用來解決系統出現的問題,在除錯過程中發現的故障應該要查改設計本身的錯誤。加入看門狗目的是對一些程式潛在錯誤和惡劣環 境干擾等因素導致系統宕機而在無人干預情況下自動恢復系統正常工作狀態。看門狗也不能完全避免故障造成的損失,畢竟從發現故障到系統復位恢復正常這段時間 內怠工。同時一些系統也需要復位前保護現場資料,重啟後恢復現場資料,這可能也需要一筆軟硬體的開銷。

圖1:(a) 多工系統看門狗示意圖;(b) 相應的看門狗復位邏輯圖。

在單任務系統中看門狗工作原理如上所述,容易實現。在多工系統中情況稍為複雜。假如每個任務都像單任務系統那麼做,如圖1(a)所示,只要有乙個 任務正常工作並定期「餵狗」,看門狗定時器就不會溢位。除非所有的任務都故障,才能使得看門狗定時器溢位而復位,如圖1(b)。

而往往我們需要的是只要有乙個任務故障,系統就要求復位。或者選擇幾個關鍵的任務接受監視,只要乙個任務出問題系統就要求復位,如圖2(a)所示,相應的看門狗復位邏輯如圖2(b)所示。

在多工系統中通過建立乙個監視任務taskmonitor,它的優先順序高於被監視的任務群task1、task2...taskn。 taskmonitor在task1~taskn正常工作情況下,一定時間內對硬體看門狗定時器清零。如果被監視任務群有乙個task_x出現故 障,taskmonitor就不對看門狗定時器清零,也就達到被監視任務出現故障時系統自動重啟的目的。另外任務taskmonitor自身出故障時,也 不能及時對看門狗定時器清零,看門狗也能自動復位重啟。接下來需要解決乙個問題是:監視任務如何有效監視被監視的任務群。

圖2:(a) 多工系統看門狗示意圖;(b) 正確的看門狗復位邏輯圖。

在taskmonitor中定義一組結構體來模擬看門狗定時器組,

typedef struct

uint32 curcnt, lastcnt;

bool runstate;

int taskid;

} struct_watch_dog;

該結構體包括被監視的任務號taskid,用來模擬「餵狗」的變數curcnt、lastcnt(具體含義見下文),看門狗狀態標誌runstate用來控制當前任務是否接受監視。

被監視的任務task1~taskn呼叫自定義函式createwatchdog(int taskid)來建立看門狗,被監視任務一段時間內要求「餵狗」,呼叫resetwatchdog(int taskid),這個「餵狗」動作實質就是對看門狗定時器結構體中的變數curcnt加1操作。taskmonitor大部分時間處於延時狀態,假設硬體 看門狗定時是2秒,監視任務可以延時1.5秒,接著對建立的看門狗定時器組一一檢驗,延時前儲存curcnt的當前值到lastcnt,延時後比較 curcnt與lastcnt是否相等,都不相等系統才是正常的。需要注意的是curcnt和lastcnt資料位元組數太小,而「餵狗」過於頻繁,可能出 現curcnt加1操作達到乙個迴圈而與lastcnt相等。

如果有任意一組的curcnt等於lastcnt,認為對應接受監視的任務沒有「餵狗」動作,也就檢測到該任務出現故障需要重啟,這時候 taskmonitor不對硬體看門狗定時器清零,或者延時很長的時間,比如10秒,足以使得系統重啟。反之,系統正常,task1~taskn定期對 taskmonitor「餵狗」,taskmonitor又定期對硬體看門狗「餵狗」,系統就得不到復位。還有一點,被監視任務可以通過呼叫 pausewatchdog(int taskid)來取消對應的看門狗,實際上就是對struct_watch_dog結構體中的runstate操作,該標誌體現看門狗有效與否。

這種方式可監視的最大任務數由struct_watch_dog結構資料的個數決定。程式中應該有乙個變數記錄當前已建立的看門狗數,判斷被監視任務task1~taskn是否「餵狗」只需比較curcnt與lastcnt的值n次。

圖3:系統復位邏輯圖。

硬體看門狗監視taskmonitor任務,taskmonitor任務又監視其他的被監視任務task1~taskn,形成這樣一種鏈條。這種方 式系統的故障圖表示如圖3所示。被監視任務task1~taskn及taskmonitor都是或的關係,因此被監視的任一任務發生故障,硬體電路看門狗 就能復位。

為實現多工系統的看門狗監視功能額外增加了taskmonitor任務,這個任務占用執行時間多少也是乙個重要問題。假設 taskmonitor任務乙個監視週期延時1.5秒,此外需要執行儲存當前計數值,判斷是否「餵狗」等語句,它的cpu占用時間是很小的。用乙個具體的 試驗證實,使用50m工作頻率的cpu(s3c4510),移植vxworks作業系統,cache不使能條件下監視10個任務,每個監視週期占用 220~240微秒。可見該任務絕大多數時間都處於任務延時狀態。

被監視任務可能有獲取訊息、等待乙個訊號量等的語句,往往這個訊息、訊號量的等待是無限期的等待。這就需要將這類語句作一些修改。比如在vxworks中將一次無期限的獲取訊號量操作

semtake(semid, wait_forever); // wait_forever為無限時間等待

分解為

do resetwatchdog; // 「餵狗」操作

}while(semtake(semid, sysclkrateget( )) != ok); // 1s內的等待訊號量操作

多次的時間範圍內的獲取訊號量操作,這樣才能保證及時「餵狗」。

另外需要注意的是系統中是否有的任務優先順序比taskmonitor高並且長時間處於執行狀態,taskmonitor長時間得不到排程,使得看門狗錯誤復位。良好的任務劃分,配置是不應該出現這種高優先順序任務長期執行狀況的。

ps:第二種,方案

小弟在uclinux的應用中需要同時啟動5個程序,並行執行,且工作環境比較惡劣。為保證系統能夠在無人職守的情況下執行正常(至少要保證某個程序出現 問題時系統能夠自動重啟這幾個程序,有嚴重問題程序重啟失敗時,整個系統能夠自動重新啟動),我使用了乙個軟看門狗機制,其工作機制如下:

系統啟動時自動啟動乙個後台監控程序,由後台程序啟動5個功能程序。後台監控程序負責清除硬體看門狗和監控各個功能程序通過fifo發過來的註冊資訊(注 冊資訊中帶有系統時間time),如果某個程序超過10s沒有新的註冊資訊到,則監控程序認為此功能程序已經出現問題,它將終止所有功能程序,重新啟動各 個程序。如果重新啟動功能程序失敗,則監控程序將停止餵狗,讓整個系統重新啟動。

各個功能程序中每個處理週期都要通過fifo向後台監控程序傳送註冊資訊。由於程序都是訊號喚醒的,因而各個功能程序中都使用定時器訊號sigalrm喚醒程序(一般定時2s),並在訊號控制代碼中設定標誌,由程序判斷此標誌並進行註冊。

在實際應用中測試發現,有時候會出現程序超時未註冊的情況,但檢查程序源**並沒有發現問題,系統的心跳時間是10ms,正常情況下應該不會出現註冊超時的現象啊?是我的處理機制有問題嗎?這種情況下有更好的監控機制嗎?

Linux 軟體看門狗 watchdog 餵狗

linux 自帶了乙個 watchdog 的實現,用於監視系統的執行,包括乙個核心 watchdog module 和乙個使用者空間的 watchdog程式。核心 watchdog 模組通過 dev watchdog 這個字元裝置與使用者空間通訊。使用者空間程式一旦開啟 dev watchdog 裝...

Linux 軟體看門狗 watchdog 餵狗

linux 自帶了乙個 watchdog 的實現,用於監視系統的執行,包括乙個核心 watchdog module 和乙個使用者空間的 watchdog程式。核心 watchdog 模組通過 dev watchdog 這個字元裝置與使用者空間通訊。使用者空間程式一旦開啟 dev watchdog 裝...

硬體看門狗和軟體看門狗

看門狗,又叫watchdog timer,從本質上來說就是乙個定時器電路,一般有乙個輸入和乙個輸出,其中的輸入叫做餵狗,輸出一般連線到另外乙個部分的復位端,另外乙個部分就是所要處理的部分,暫且稱之為mcu。在mcu正常工作的時候,每隔一段時間輸出乙個訊號到餵狗端,給看門狗電路清零,如果在超過規定的時...