看門狗定時(shí)器 (WDT) 是一種硬件,它監(jiān)視代碼的執(zhí)行情況,以在軟件崩潰時(shí)重置處理器。多年來(lái),嵌入式世界一直在激烈爭(zhēng)論它們的重要性。不少工程師認(rèn)為 WDT 是不必要的。他們聲稱,更好的解決方案是編寫不會(huì)崩潰的固件。這是一種崇高的情操,因?yàn)橥昝朗且粋€(gè)崇高而令人欽佩的目標(biāo)。
然而,很少有產(chǎn)品能達(dá)到這樣的質(zhì)量水平。隨著軟件規(guī)模的擴(kuò)大,即使是對(duì)質(zhì)量毫不妥協(xié)的關(guān)注也很難達(dá)到完美。一個(gè)百萬(wàn)行的程序,如果代碼的正確率達(dá)到 99.99%(這個(gè)數(shù)字遠(yuǎn)遠(yuǎn)高于絕大多數(shù)組織所達(dá)到的數(shù)字),就會(huì)有 100 個(gè)潛伏的錯(cuò)誤。其中任何一個(gè)都可能使系統(tǒng)崩潰或更糟——將其置于危險(xiǎn)的操作模式。(唉,一般的嵌入式系統(tǒng)只刪除了所有錯(cuò)誤的 95% 。1
錯(cuò)誤不是唯一的問(wèn)題。完美設(shè)計(jì)和構(gòu)建的硬件在其上執(zhí)行完美代碼仍然可能失敗。
宇宙射線越來(lái)越多地在數(shù)字系統(tǒng)中引起問(wèn)題。它們主要由來(lái)自太空的高能質(zhì)子組成,可以與 IC 上的晶體管和翻轉(zhuǎn)位相互作用。在微處理器的早期,這些威脅比今天要小得多,因?yàn)楣に噹缀纬叽绾艽蟆枰罅磕芰縼?lái)實(shí)現(xiàn)位翻轉(zhuǎn)。如今,由于 45 nm 的幾何形狀是常規(guī)的,而 28 nm 并不少見(jiàn),并且每年都會(huì)出現(xiàn)較小的節(jié)點(diǎn),因此問(wèn)題變得更加嚴(yán)重。
在 1990 年代,IBM 發(fā)現(xiàn)一臺(tái)典型的計(jì)算機(jī)每個(gè)月每 256 MB 的 RAM 都會(huì)遇到一次由宇宙射線引起的錯(cuò)誤。2從那時(shí)起,幾何形狀已經(jīng)縮小了很多,所以問(wèn)題可能變得更糟了。
英特爾認(rèn)為,未來(lái)宇宙射線可能會(huì)成為越來(lái)越多的計(jì)算機(jī)錯(cuò)誤來(lái)源。他們的專利 7,309,866 使用 MEMS 傳感器來(lái)檢測(cè)進(jìn)入的宇宙射線,然后向電路發(fā)出信號(hào)以采取糾正措施。3
H. Kobayashi 等人。發(fā)現(xiàn)宇宙射線和其他粒子的誤差在 180 nm 幾何結(jié)構(gòu)的設(shè)備中是 250 nm 幾何結(jié)構(gòu)的兩倍多。4
Tezzaron Semiconductor 2004 年的一篇論文表明,SRAM 和邏輯是宇宙射線擾動(dòng)的主要受害者。5作者聲稱,具有 1 GB SRAM 的系統(tǒng)每?jī)芍軙?huì)出現(xiàn)一次軟錯(cuò)誤,而丹佛的問(wèn)題比海平面的問(wèn)題嚴(yán)重十倍。
令人驚訝的是,一個(gè)只有 10 飛庫(kù)侖電荷的粒子有足夠的能量來(lái)翻轉(zhuǎn) SRAM 位。6十年前,較大的細(xì)胞需要五倍的能量。
底線:即使是完美編寫的代碼也可能崩潰。只有看門狗定時(shí)器可以幫助崩潰的系統(tǒng)恢復(fù)。
出色的 WDT
由于 WDT 是最后一道防線,因此其設(shè)計(jì)必須預(yù)見(jiàn)到任何故障模式。有人可能會(huì)問(wèn),“偉大的看門狗有什么特點(diǎn)?”
首先,WDT 必須獨(dú)立于 CPU。無(wú)論處理器發(fā)現(xiàn)自己處于何種奇怪模式,看門狗定時(shí)器都必須正常工作。此外,一旦在初始化時(shí)設(shè)置,處理器所做的任何事情都不能禁用或重新編程看門狗。否則,流氓程序可能會(huì)意外禁用此保護(hù)機(jī)制,使其無(wú)用。
WDT 必須始終在任何情況下(除非可能出現(xiàn)硬件故障)使系統(tǒng)恢復(fù)運(yùn)行。這意味著向 CPU 發(fā)出硬復(fù)位。沒(méi)有其他選擇可以保證讓崩潰的處理器起死回生。
一些 WDT 發(fā)出不可屏蔽的中斷而不是復(fù)位。這個(gè)想法是 NMI 的服務(wù)例程可以對(duì)堆棧進(jìn)行快照并記錄調(diào)試信息。唉,沒(méi)有理由相信處于任意功能失調(diào)模式的 CPU 會(huì)響應(yīng)任何中斷。在調(diào)用服務(wù)例程之前需要進(jìn)行大量處理。在許多處理器上,如果堆棧指針具有奇數(shù)或未對(duì)齊的地址,則不會(huì)啟動(dòng)中斷服務(wù)程序;實(shí)際上,它們可能會(huì)進(jìn)入雙總線故障模式,其中 CPU 關(guān)閉,只有硬復(fù)位才能恢復(fù)操作。
然而,NMI 方法很有趣。有時(shí)使用的一種替代方法是發(fā)出 NMI,并啟動(dòng)計(jì)時(shí)器。幾毫秒后,計(jì)時(shí)器將復(fù)位 CPU。然后,如果 NMI 服務(wù)例程有效,它會(huì)記錄調(diào)試信息,但不可避免的硬重置可確保設(shè)備恢復(fù)運(yùn)行。
當(dāng)系統(tǒng)控制危險(xiǎn)硬件時(shí),看門狗獨(dú)立于可能受損的 CPU 將系統(tǒng)置于安全狀態(tài)是至關(guān)重要的。移動(dòng)機(jī)械、危險(xiǎn)輻射等必須禁用、停放或以其他方式脫離,因?yàn)槿绻布收蠈?dǎo)致處理器崩潰,重置可能無(wú)法工作。
當(dāng)今的嵌入式系統(tǒng)通常具有非常復(fù)雜的外圍設(shè)備;在某些情況下,I/O 可能比微處理器復(fù)雜得多。WDT 復(fù)位序列必須確保這些設(shè)備恢復(fù)到已知狀態(tài)。當(dāng)代碼崩潰時(shí),它可能會(huì)向外圍設(shè)備發(fā)出奇怪的數(shù)據(jù)流。如果外圍設(shè)備的設(shè)計(jì)使得 CPU 并不總是能夠?qū)⒃O(shè)備置于已知的正確狀態(tài),則這些設(shè)備需要從 WDT 進(jìn)行硬復(fù)位。
最后,如果可能的話,最好留下調(diào)試面包屑。前面提到的 NMI/deferred-reset 就是一個(gè)例子。將堆棧和其他關(guān)鍵參數(shù)保存到開(kāi)發(fā)人員可以訪問(wèn)的非易失性內(nèi)存區(qū)域中。不幸的是,重置會(huì)破壞所有處理器狀態(tài)信息,但通常有特定于應(yīng)用程序的數(shù)據(jù)可以幫助診斷問(wèn)題,例如指向狀態(tài)機(jī)表的指針。在重置后初始化它們之前,請(qǐng)保存它們。如果有實(shí)時(shí)時(shí)鐘,還要保存復(fù)位時(shí)間。
內(nèi)部 WDT
看門狗可分為兩大類:處理器芯片上的看門狗和硬件設(shè)計(jì)人員添加的外部設(shè)備。大多數(shù)微控制器都有一個(gè)內(nèi)部看門狗,盡管它們的功效差異很大。
一個(gè)例子是美心(nee Dallas) DS80C320 / DS80C323,一個(gè) 8031 變種,已經(jīng)存在了很長(zhǎng)一段時(shí)間。這部分在看門狗中有兩個(gè)非常好的功能。首先,可以對(duì)其進(jìn)行編程以產(chǎn)生中斷,但 512 個(gè)周期后它將重置 CPU,因此調(diào)試面包屑很容易保存。此外,可以限制對(duì) WDT 寄存器的訪問(wèn);必須背靠背執(zhí)行兩個(gè)特定的移動(dòng)指令,然后只有一個(gè)三周期的窗口可以進(jìn)行 WDT 寄存器訪問(wèn)。這極大地降低了惡意代碼禁用保護(hù)機(jī)制的機(jī)會(huì)。然而,人們想知道如果在這些指令之間發(fā)生中斷會(huì)發(fā)生什么。大概不會(huì)發(fā)生 WDT 訪問(wèn),因此無(wú)法啟用該功能。顯然,軟件工程師在執(zhí)行此序列時(shí)必須禁用中斷。
飛思卡爾的 MCF520x系列則完全不同。要給看門狗發(fā)癢,必須向看門狗服務(wù)寄存器發(fā)出兩次寫操作,但在這些操作之間可能會(huì)發(fā)生任意數(shù)量的指令。如果 CPU 崩潰并運(yùn)行隨機(jī)代碼,這可能會(huì)破壞可靠操作。從好的方面來(lái)說(shuō),復(fù)位狀態(tài)寄存器確實(shí)記錄了先前的復(fù)位是由于外部硬件信號(hào)還是由于 WDT 超時(shí),這是重新啟動(dòng)后記錄錯(cuò)誤的有用方法??梢詫?duì)看門狗進(jìn)行編程以產(chǎn)生復(fù)位或中斷;后者是一個(gè)非常糟糕的主意。如果堆棧因錯(cuò)誤或惡意代碼而變得奇怪,系統(tǒng)將進(jìn)入雙總線故障。中斷不會(huì)使 CPU 恢復(fù)正常運(yùn)行;只有重置會(huì)。
意法半導(dǎo)體新系列STM32F4Cortex?-M4 CPU 有兩個(gè)獨(dú)立的看門狗。一個(gè)從它自己的內(nèi)部 RC 振蕩器運(yùn)行。這意味著各種事情都可能在 CPU 中崩潰,而 WDT 仍然會(huì)觸發(fā)。還有一個(gè)“窗口看門狗”(WWDT),它要求代碼經(jīng)常對(duì)它進(jìn)行撓癢癢,但不要太頻繁。這是一種非常有效的方法,可以確保隨機(jī)寫入保護(hù)機(jī)制的崩潰代碼不會(huì)導(dǎo)致 WDT 抖動(dòng),并且 WWDT 可以在復(fù)位被斷言之前不久產(chǎn)生中斷。
有趣的是,其中一些部件還包括一個(gè)“模擬看門狗”,如果 A/D 的輸入超過(guò)編程限制,它會(huì)觸發(fā)中斷。可以監(jiān)控電源并檢測(cè)掉電。在控制危險(xiǎn)硬件的系統(tǒng)中,這種早期警告可用于在電源超出操作限制之前將系統(tǒng)置于安全狀態(tài)。Microchip 的
許多PIC24F系列都具有 WWDT,NXP 的一些部件(例如LPC18xx和LPC43xx系列)也是如此。NXP 的部件可以配置為,一旦啟用,軟件就不可能關(guān)閉 WDT,從而提供更多保護(hù),防止代碼運(yùn)行異常。
這些處理器都沒(méi)有向外界發(fā)出超時(shí)發(fā)生的信號(hào)。如果軟件不能保證正確的重新初始化,設(shè)計(jì)人員可能必須斷言一個(gè)并行 I/O 位來(lái)復(fù)位外部硬件。
外部 WDT
很少有微處理器(與微控制器相反)具有內(nèi)部看門狗定時(shí)器,而且在許多情況下,內(nèi)部 WDT 不能提供特定應(yīng)用所需的可靠性。在這些情況下,設(shè)計(jì)應(yīng)該增加外部硬件,以監(jiān)控系統(tǒng)操作并在需要時(shí)發(fā)出復(fù)位。
在使用兩個(gè)或更多 CPU 的系統(tǒng)中,讓每個(gè)處理器監(jiān)視另一個(gè)處理器的操作是合理的。
有許多 WDT 芯片可用。通常,它們的操作不受軟件控制,因此崩潰的程序無(wú)法禁用它們的功能。此外,它們還在上電期間斷言復(fù)位,從而無(wú)需這些外部組件。
Maxim 的 MAX6751 是一種外部WWDT。它有一個(gè) WWDT,其超時(shí)由電容器控制,如圖 1 所示。
圖 1:MAX6751 的超時(shí)時(shí)間由一對(duì)電容器設(shè)置(由 Maxim 提供)。Texas Instruments 的TPS3126 類似于沒(méi)有窗口功能的 WWDT。它們適用于各種電源電壓和延遲時(shí)間,價(jià)格低廉,采用 SOT-23 封裝。圖 2 概述了它們的配置。
圖 2:TI 的 TPS3126 監(jiān)控電源并具有 WDT(德州儀器提供)。TI 還擁有包括TPS386000
在內(nèi)的一系列部件,可監(jiān)控四個(gè)獨(dú)立的電源軌并包括一個(gè)具有固定延遲的 WDT。其中一個(gè)電壓監(jiān)視器可以處理負(fù)電源。如果有任何超出公差,則激活單獨(dú)的“RESET”輸出。作為開(kāi)漏,它們可以被線或在一起?;蛘?,可以將這些連接到輸入引腳,以便 CPU 知道哪個(gè)電源低,并采取適當(dāng)?shù)拇胧?,如圖 3 所示
圖 3:TPS386000 監(jiān)控四個(gè)電源(由 Texas Instruments 提供)。
Analog Devices 的ADM699是一款簡(jiǎn)單的 WDT,它還可以監(jiān)控一個(gè)電源。圖 4 顯示了它的實(shí)現(xiàn)。
圖 4:ADM699 的設(shè)計(jì)非常簡(jiǎn)潔(由 Analog Devices 提供)。
現(xiàn)在一些微處理器對(duì)復(fù)位輸入非常挑剔,只允許相對(duì)較快的轉(zhuǎn)換速率和信號(hào)電平。開(kāi)漏驅(qū)動(dòng)只能通過(guò)使用非常低值的上拉電阻來(lái)滿足這些要求,這會(huì)增加功耗。ADI 公司有多個(gè)組件,例如ADM6316,它們使用推挽輸出來(lái)滿足這些嚴(yán)格的要求。圖 5 顯示了該部件的框圖。
圖 5:ADM6316 具有推挽式驅(qū)動(dòng)器(由 Analog Devices 提供)。
軟件考慮
如果代碼構(gòu)造不正確,即使是最好的看門狗電路也只是一個(gè)很差的安全機(jī)制。唉,在大多數(shù)系統(tǒng)中,開(kāi)發(fā)人員在沒(méi)有考慮設(shè)計(jì)的情況下在整個(gè)代碼中撒上看門狗的癢癢。
最重要的考慮是確保所有代碼都正確運(yùn)行,而不僅僅是其中的一部分。因此,永遠(yuǎn)不要在中斷服務(wù)例程中放置 WDT 滴答聲,也永遠(yuǎn)不要將 RTOS 任務(wù)用于此活動(dòng)。如果主代碼使中斷甚至 RTOS 的調(diào)度程序崩潰,它可能會(huì)繼續(xù)運(yùn)行,因此看門狗永遠(yuǎn)不會(huì)超時(shí)。
在單線程設(shè)計(jì)中,使用類似狀態(tài)機(jī)的架構(gòu)。示例代碼如圖 6 所示。
圖 6:處理非多任務(wù) WDT 的代碼。
這里的主循環(huán)首先將變量“state”設(shè)置為 0x5555。它調(diào)用 wdt_a() 檢查值是否正確;如果沒(méi)有,它會(huì)停止并且 WDT 重置系統(tǒng)。否則,“狀態(tài)”中的值會(huì)通過(guò)添加偏移量來(lái)更改。請(qǐng)注意,看門狗沒(méi)有被撓癢癢。
在循環(huán)結(jié)束時(shí)(我們已經(jīng)執(zhí)行了所有代碼),再次調(diào)整“狀態(tài)”并調(diào)用 wdt_b()?,F(xiàn)在,如果“狀態(tài)”沒(méi)有正確地循環(huán)遍歷它的所有更改——表明我們確實(shí)運(yùn)行了整個(gè)循環(huán)——代碼停止并且 CPU 被重置。否則看門狗會(huì)被觸發(fā)并且“狀態(tài)”設(shè)置為零。請(qǐng)注意,如果代碼崩潰并進(jìn)入 wdt_b(),“狀態(tài)”將不正確并且會(huì)發(fā)生重置。
在多任務(wù)應(yīng)用程序中,每個(gè)任務(wù)每次啟動(dòng)時(shí)都會(huì)在數(shù)據(jù)結(jié)構(gòu)中增加一個(gè)與任務(wù)相關(guān)聯(lián)的值。低優(yōu)先級(jí)任務(wù)偶爾會(huì)檢查數(shù)據(jù)結(jié)構(gòu)并檢查以確保數(shù)據(jù)合理。如果一個(gè)任務(wù)經(jīng)常運(yùn)行,數(shù)量會(huì)很大;相反,慢任務(wù)的數(shù)量會(huì)很少。如果一切正常,任務(wù)會(huì)觸發(fā) WDT,將值歸零,然后返回。否則它會(huì)停止并啟動(dòng)重置。
如果存在代碼無(wú)法處理或恢復(fù)的異常(例如,被零除或 malloc() 失?。?,請(qǐng)編寫一個(gè)禁用中斷和暫停的處理程序??撮T狗將使系統(tǒng)恢復(fù)活力。
結(jié)論
看門狗定時(shí)器是防止代碼崩潰的最后一道防線,因此必須精心設(shè)計(jì)和實(shí)施。如今,許多微控制器都包含非常復(fù)雜的 WDT,并且能夠抵御異常運(yùn)行的程序的欺騙?;蛘撸褂猛獠?WDT;可能最安全的選擇是支持窗口化。此外,請(qǐng)仔細(xì)構(gòu)建代碼,以使錯(cuò)誤的軟件不會(huì)落入 tickle 例程中,并防止計(jì)時(shí)器重置 CPU。
評(píng)論
查看更多