一種高可靠MCU系統(tǒng)監(jiān)控方案
1 目前MCU系統(tǒng)監(jiān)控中的問題
對于單片機系統(tǒng),一般都需要監(jiān)控電路來提高系統(tǒng)的可靠性。包括用電壓比較器對電源的監(jiān)控和看門狗對程序的監(jiān)控。為防止系統(tǒng)程序受干擾“飛掉”,常用看門狗定時器,這種方式對于系統(tǒng)進入死循環(huán)時很有效,而程序“飛掉”時極有可能跳過一段程序,正好進入另一條指令的開頭。尤其在RISC系統(tǒng)中,絕大部分是單周期指令,容易遇到這種情況,此時程序會繼續(xù)運行下去,使看門狗失效。跳過的這段程序,可能包括一些接口控制執(zhí)行指令,或某些數(shù)據(jù)的輸入輸出,或條件判斷,整個系統(tǒng)會因此而運行紊亂,或直接產(chǎn)生故障。系統(tǒng)出現(xiàn)這類故障時很難立即察覺。
1. 在運用極其廣泛的一類MCU系統(tǒng),如分段定時控制系統(tǒng)中,象家用電器的電腦控制微波爐、洗衣機、電飯煲;電力行業(yè)的發(fā)電機轉速控制;冶金行業(yè)的連鑄、焊管及流水線系統(tǒng)等,都可能會在系統(tǒng)運行中遇到分段定時控制或某一區(qū)域內(nèi)運行狀態(tài)與前段運行
狀態(tài)密切相關的情況。此時簡單地用看門狗電路作系統(tǒng)監(jiān)控,一旦出現(xiàn)系統(tǒng)死鎖而復位,將會使啟動以后的整個運行過程失效,這種方法顯然是行不通的。
2. 對于分時多任務系統(tǒng),其中的某個或幾個任務出現(xiàn)死鎖,而又有一個或多個任務仍正常運行的情況下,看門狗定時器可能會被“蒙蔽”而失去監(jiān)控作用。
3. 在一個程序運行周期很短,或系統(tǒng)根據(jù)不同運行狀況的程序處理時間相差很大的情況下,看門狗定時周期難以定得合適,此時若出現(xiàn)干擾死機可能因難于及時發(fā)現(xiàn)并解決而造成故障。
如果有一種方法,使系統(tǒng)在運行過程中能夠自行感知程序運行狀況,出現(xiàn)問題能夠隨時察覺;發(fā)現(xiàn)故障立即報警、停止運行或復位,甚至可以自動糾錯,使程序恢復正確的運行,以實現(xiàn)對程序的最佳監(jiān)控,那將是比較理想的。
2 系統(tǒng)在線自行跟蹤基本方法
系統(tǒng)在線運行過程中,如果能夠隨時將系統(tǒng)運行的過程即系統(tǒng)當前程序的實際流程路線自動記錄下來,就有辦法將預期的運行路線與之比較,從而避免程序出現(xiàn)不可預測的死鎖。打個比方,設想有一輛在公路上行駛的汽車,只要知道該汽車在各個岔路口的走向,就可以描繪出這輛汽車整個的行駛路線,但是難以保證汽車可能會在一條單一路線上行駛時拋錨。如果每隔一定距離以及重要路段設上“哨卡”,就能更加細致地了解到汽車的行駛情況,一旦出現(xiàn)問題就能立即知道事故出現(xiàn)的具體路段。同理,在程序運行過程中也可以通過人為設置的“哨卡”來記錄程序當前的運行路線。在多數(shù)情況下,這些“哨卡”對系統(tǒng)運行并沒有太大的影響。 實際上,這些“哨卡”就是可以任意插入流程中的簡短程序段,每一個“哨卡”有一個特定的“標志碼”以使我們能夠知道程序到底運行到何處。將這些標記按出現(xiàn)的順序記錄在存儲器中,就能依此知道CPU“行駛”的具體路線。當然,對系統(tǒng)的運行狀態(tài)了解得越細致,程序的運行時間會越長。應將它們設置在重要的數(shù)據(jù)讀寫或接口操作處,各分支路口和相對獨立的程序塊入口處,盡量減小對系統(tǒng)的影響。
下面以GMS97C51單片機構成的MCU系統(tǒng)為例說明系統(tǒng)對自身運行路線的跟蹤記錄方法。
如圖1所示,設系統(tǒng)CPU為97C51,外接一片SRAM 6116來作運行記錄,為防止掉電和死機的影響,將RAM用后備電池保護起來(系統(tǒng)上電初始化程序應包括將6116清零,清零程序在此略去)。
在系統(tǒng)原來程序段中需要設“哨卡”的地方插入語句:
這樣,僅插入6個字節(jié)對原來程序的存儲空間并無多大影響,所有的“哨卡”共用一個子程序。
假設總共“哨卡”數(shù)量少于256個,用一個字節(jié)來作標志,每一個“哨卡”都會有一個獨立的標志號,通過查詢RAM記錄內(nèi)容就可知道程序的實際運行路線了。這里我們還發(fā)現(xiàn)程序自行跟蹤的一個額外的作用,即只需一個讀RAM的簡單裝置,此方法就可用來作程序開發(fā)過程中的仿真調(diào)試而無須PC機及仿真器。
若系統(tǒng)無法用到并行總線,可將6116換成串行存儲器,如美國Xicor公司的非易失性RAM X24C45,程序則應作相應改動。插入“哨卡”后應考慮對原系統(tǒng)運行時間上的影響。
3 利用自行跟蹤方式對系統(tǒng)的實時監(jiān)控
在作系統(tǒng)監(jiān)控的應用中,系統(tǒng)必須對自身運行狀況作實時監(jiān)控。利用上面的方式,在系統(tǒng)中加上監(jiān)控程序,系統(tǒng)對自身運行情況亦可作自行監(jiān)測。但這樣一來,不僅會對原來程序造成較大影響,而且會因為系統(tǒng)本身可能受到干擾或其它原因而癱瘓,因而是不可靠的。對于高可靠性要求的系統(tǒng),有必要另加一套監(jiān)控系統(tǒng)來對原系統(tǒng)及監(jiān)控系統(tǒng)自身作專門監(jiān)護,從后面的討論中可知,這外加的系統(tǒng)可以是廉價、小巧、安全可靠和高效的。
在實時監(jiān)控過程中,可以省掉對程序運行路線的存儲記錄而直接判斷。系統(tǒng)電路如圖2所示。它進一步減小了對原系統(tǒng)的影響而又提高了運行效率。在監(jiān)控系統(tǒng)運行過程中,應從以下三個方面來考慮:
圖2 系統(tǒng)電路如
1. 監(jiān)控系統(tǒng)對原系統(tǒng)的精確跟蹤;
2. 利用軟件狗防止主系統(tǒng)死鎖;
3. 對監(jiān)控系統(tǒng)自身的監(jiān)控。
系統(tǒng)非正常運行除硬件與電源系統(tǒng)的問題之外,難以琢磨的主要是軟件系統(tǒng)。程序受到干擾產(chǎn)生故障有兩種情況:
一是CPU沒有按既定程序運行,系統(tǒng)指針“飛”到其它指令代碼地址處,好象非法執(zhí)行了一個跳轉語句。這種情況存在很大的潛在危險性,利用看門狗技術難以察覺,可能帶來難以預料的事故,且無論哪一類結構的指令系統(tǒng)都無法排除。此時利用在線跟蹤技術發(fā)揮其監(jiān)控作用是一個有效方法??梢栽诔绦蜻\行的各個路口和重要的操作前后插入“哨卡”,并將“哨卡”在系統(tǒng)程序中均勻分布,用專門的監(jiān)控CPU實時跟蹤,與已預存在監(jiān)控系統(tǒng)中的正確路線比較,可及時排除原系統(tǒng)軟件產(chǎn)生的故障,有時還可以使系統(tǒng)從其產(chǎn)生誤操作之前的一個“哨卡”處恢復系統(tǒng)的正常運行。
二是CPU沒有按既定程序運行,系統(tǒng)指針“飛”到非指令代碼地址處。此時最易產(chǎn)生死機,程序完全失去控制。用看門狗可以最終發(fā)現(xiàn)此問題,但若不及時排除故障有可能因時間的延誤或程序執(zhí)行無法預知的操作擾亂數(shù)據(jù)和信號,產(chǎn)生故障。
在多任務系統(tǒng)中,其中某一個任務死鎖,用看門狗可能無法感知,因為其它任務仍在不時發(fā)出“喂狗”信號。
在采用監(jiān)控CPU自行跟蹤的系統(tǒng)中,監(jiān)控CPU可以對每一個任務分別設置軟件看門狗,利用“哨卡”發(fā)出“喂狗”信號。因“哨卡”可人為地依時間均勻設置,一旦系統(tǒng)死鎖,或下一個“哨卡”信號未到而超時,即可及時發(fā)現(xiàn)故障在哪一“哨卡”附近發(fā)生,并可能及時排除故障,繼續(xù)按原路線運行正確的系統(tǒng)程序。
對于以上兩種情況,若CPU監(jiān)控系統(tǒng)本身出現(xiàn)故障。又有以下兩個方面:
(1)在主系統(tǒng)中的監(jiān)控配合程序(即“哨卡”程序)自身出現(xiàn)問題,此時監(jiān)控系統(tǒng)會認為是原系統(tǒng)程序的問題,包括在上述兩種情況之中,逃不出對原系統(tǒng)程序的監(jiān)測,可用同樣的方法在監(jiān)控程序中同時解決。
(2)監(jiān)控CPU的監(jiān)控程序出現(xiàn)問題,又分別有兩種可能:
①監(jiān)控程序代碼執(zhí)行順序錯誤。即監(jiān)控系統(tǒng)指針未按預定程序運行。此時監(jiān)控CPU會認為是主CPU而非自身程序出現(xiàn)了問題。監(jiān)控程序會很快循環(huán)一周而處于等待狀態(tài),程序本身不會混亂。此時監(jiān)控系統(tǒng)會將原系統(tǒng)或整個系統(tǒng)強行復位,或將原系統(tǒng)程序從前一“哨卡”處恢復運行。
②監(jiān)控系統(tǒng)程序指針“飛入”非程序指令代碼處而造成死機。由于監(jiān)控系統(tǒng)是可以預知的單一任務系統(tǒng),此時可用CPU片外的硬件看門狗作監(jiān)控CPU的硬件監(jiān)控,而將整個系統(tǒng)復位,或根據(jù)主系統(tǒng)情況恢復監(jiān)控系統(tǒng)本身的運行。在設計過程中應使這種情況盡可能少發(fā)生。
雖然監(jiān)控系統(tǒng)可能出現(xiàn)問題,但從以上討論來看,所有問題都可得到解決。整體而言采用監(jiān)控系統(tǒng)的自行跟蹤方式可以大大提高整個系統(tǒng)的可靠性。然而也要求監(jiān)控系統(tǒng)本身具有高的穩(wěn)定性與可靠性,以提高整個系統(tǒng)的性能。另外,監(jiān)控系統(tǒng)最好要有獨立穩(wěn)定的供電電源。
4 自行跟蹤監(jiān)控系統(tǒng)的實現(xiàn)
接口電路參見圖2,將安插在原來程序的“哨卡”所發(fā)出的信號稱作“路標特征碼”或“路標碼”。監(jiān)控CPU可以直接從與主系統(tǒng)的接口處得到這些“路標碼”,而不必將它們存入存儲器中。對于并行總線結構可以方便地用鎖存器,如74HC273,將“路標碼”傳送給監(jiān)控CPU。對于片內(nèi)總線結構的CPU,可以用串口或移位寄存器,甚至單一的I/O口線來傳送信號。這里以并行總線結構的MCS-51系列單片機GMS97C51為例說明。
4.1 監(jiān)控系統(tǒng)的軟件準備數(shù)據(jù)結構
設主系統(tǒng)有如圖3所示的部分程序結構,它包括了大部分程序可能出現(xiàn)的結構。在程序中插入“哨卡”的“路標碼”如圖中數(shù)字所標,程序經(jīng)過這些“哨卡”時會將相應的“路標碼”實時反映在接口處,監(jiān)控CPU收到“路標碼”信息后將其與系統(tǒng)固有的程序結構進行比較。
圖3結構可以簡化成圖4形式。為了比較這些代碼出現(xiàn)的位置,這里考慮一種數(shù)據(jù)結構,將原系統(tǒng)的整個流程圖通過這種數(shù)據(jù)結構存放在監(jiān)控CPU的ROM中,形成一個存放原來程序結構的數(shù)據(jù)庫。從某段程序的入口開始,一直到遇見分支,設置一個連續(xù)數(shù)據(jù)區(qū)。不同的連續(xù)程序段形成的連續(xù)數(shù)據(jù)區(qū)之間,由這種數(shù)據(jù)結構中的地址字節(jié)來連接。自然每個“路標碼”還會有一個絕對存放地址。在這個數(shù)據(jù)結構中給每個“路標碼”后帶一個字節(jié)的相對轉移地址,用來存放當前“路標碼”出現(xiàn)后下一個“路標碼”在此數(shù)據(jù)庫中的相對地址。假設原系統(tǒng)程序設置的“哨卡”少于256個,數(shù)據(jù)區(qū)之間的地址不會相距太遠,則每一個數(shù)據(jù)項由“路標碼”與相對地址碼兩個字節(jié)組成,轉移地址在-128~+127字節(jié)范圍內(nèi)可以找到。在散轉或判斷語句中,可能并列出現(xiàn)的下一“哨卡”數(shù)據(jù)項連續(xù)排列在一起,以立即數(shù)#0作為結束,它們之間表示“或”的關系,在程序的某一次運行之中只有其中的一個數(shù)據(jù)項對應的語句會被遇到,數(shù)據(jù)項結構如圖5所示。256個“路標碼”所形成的數(shù)據(jù)庫最大可有768字節(jié)。圖3所示程序結構可以圖6形式存于數(shù)據(jù)庫中。對于多任務系統(tǒng)必須在每一數(shù)據(jù)項中增加一個字節(jié)的“任務號”,以便于識別不同任務的程序結構。由于多任務系統(tǒng)的數(shù)據(jù)庫會比較龐雜,可用增加的這個字節(jié)的高四位表示任務號,低四位與另一字節(jié)作為用12位表示的轉移地址,作用范圍可擴大到4KB。
(a)作為示意,圖中字母表示每一個數(shù)據(jù)區(qū)的首地址,數(shù)據(jù)區(qū)中的相對跳轉地址指向其相應的地址位置。在實際數(shù)據(jù)區(qū)中地址字節(jié)應為相對量。
4.2 監(jiān)控系統(tǒng)的程序實現(xiàn)
監(jiān)控系統(tǒng)的主要程序流程見圖7所示。在程序正常運行的情況下,唯一能夠打破此數(shù)據(jù)結構圖而出現(xiàn)例外的只有一種情況,即主程序運行過程中出現(xiàn)了中斷服務程序。而在每一個中斷服務程序起始后即會有一“哨卡”提供其特征碼,以使監(jiān)控程序在當前數(shù)據(jù)區(qū)找不到對應的數(shù)碼時,能為中斷服務程序的跟蹤提供一個入口。但監(jiān)控程序一定要將中斷入口前的“路標碼”數(shù)據(jù)庫地址壓棧。以使中斷服務程序結束時能接上前面的“連環(huán)套”。
監(jiān)控系統(tǒng)設置定時器作為主系統(tǒng)的軟看門狗。監(jiān)控CPU每接收到一次被刷新的“路標碼”,就將軟定時器復位一次,若定時器溢出則表示“路標碼”已經(jīng)有過長時間未被刷新??烧J為原系統(tǒng)出現(xiàn)了故障。對于多任務系統(tǒng),可以設置一個公共時基,在每一次時基定時中斷中給每一任務的定時時鐘加1(每一個任務有一個獨立的時鐘寄存器,存放累積的時基個數(shù)),并判斷每一任務的時基數(shù)是否大于設定的數(shù)值,若大于即表示該任務已超過看門狗定時周期,該任務出現(xiàn)了故障需要處理。依此可彌補硬件定時器數(shù)量上的不足,也簡化了程序。在每一次刷新“路標碼”時會將相應任務的時鐘寄存器
清零,即將此看門狗復位。
另外,路標碼在數(shù)據(jù)庫中的轉移范圍若超出了相對尋址范圍,例如程序在完成一個大循環(huán)后的“哨卡”地址,可由專門的長轉移標志提供相應的入口地址。
圖7 監(jiān)控系統(tǒng)核心程序流程圖
分析監(jiān)控程序的流程圖,會發(fā)現(xiàn)實現(xiàn)監(jiān)控程序并不困難。在此基礎上,在不同的系統(tǒng)開發(fā)中還可有許多應用,例如將主系統(tǒng)重要寄存器與程序指針在“哨卡”處作刷新保存,監(jiān)控程序將“哨卡”狀態(tài)緩存一步,并保存前一“哨卡”地址。一旦出現(xiàn)問題,可將程序返回該“哨卡”處恢復原來狀態(tài)繼續(xù)運行。具體實現(xiàn)方法在此不作詳述。
5 監(jiān)控系統(tǒng)的完善
前面以一種簡單的情況和工作方式說明了監(jiān)控系統(tǒng)的運行過程。然而在實際運行過程中,由于監(jiān)控過程全部自動完成,監(jiān)控系統(tǒng)工作的穩(wěn)定性和嚴密性有重要的意義。主系統(tǒng)在運行過程中發(fā)生數(shù)據(jù)突變或者出現(xiàn)程序在相鄰“哨卡”之間的非法跳變,此時用以上的簡單跟蹤方式難以直接察覺。因此,在監(jiān)控CPU與主系統(tǒng)之間的數(shù)據(jù)信息交流是必要的。另外,要保證“哨卡”設置得嚴密,必須保證監(jiān)控CPU有比主CPU快得多的運行速度。下面簡要探討一下對監(jiān)控系統(tǒng)的完善方案。
5.1 對寄存器數(shù)據(jù)的監(jiān)控
在程序運行過程中的數(shù)據(jù)突變和程序計數(shù)指針的非法跳變最終影響的是寄存器的數(shù)據(jù)值。在相鄰“哨卡”之間不會有分支、循環(huán)語句,僅會涉及到置數(shù)、傳送、運算、接口操作,對這些流程的破壞也最終反映到寄存器數(shù)據(jù)的改變上。監(jiān)控系統(tǒng)要探知這些寄存器數(shù)據(jù)的變化只有通過主系統(tǒng)與監(jiān)控系統(tǒng)的信息交換。提高系統(tǒng)可靠性是以降低原系統(tǒng)實際運行速度為代價的,在“哨卡”程序中輸出相關寄存器內(nèi)容,過程如下:
在“哨卡”程序中,首先向監(jiān)控CPU傳送“哨卡”標志號;
接著依次傳送相關寄存器的內(nèi)容或特定的數(shù)據(jù);
最后輸出立即數(shù)#0,作為當前“哨卡”數(shù)據(jù)傳送結束標志。
在每個哨卡數(shù)據(jù)傳送過程中,由于監(jiān)控系統(tǒng)是與主系統(tǒng)配合設計的,并不是獨立可脫離的控制模塊,因此監(jiān)控系統(tǒng)在特定的各個標志號的“哨卡”所接收到的數(shù)據(jù),監(jiān)控系統(tǒng)已可預知該數(shù)據(jù)來源,可以作相應的靈活處理,或是為下一“哨卡”要得到的寄存器數(shù)據(jù)作準備,或是與上一“哨卡”儲備的相關寄存器數(shù)據(jù)作比較,因此寄存器數(shù)據(jù)的傳送數(shù)量也是靈活可變的。開發(fā)人員在作系統(tǒng)設計時,可以對原系統(tǒng)的數(shù)據(jù)內(nèi)容作嚴密處理,還可將有關寄存器數(shù)據(jù)作預先運算后輸出給監(jiān)控CPU,以保證寄存器內(nèi)容的準確性并簡化步驟。相應于監(jiān)控系統(tǒng)數(shù)據(jù)結構的改變,每一“哨卡”數(shù)據(jù)項中增加了一個字節(jié),作為該“哨卡”傳送數(shù)據(jù)的RAM存放區(qū)地址代碼。由于寄存器內(nèi)容在監(jiān)控CPU的RAM中只作暫存,可互相覆蓋,并不需消耗多大RAM空間。
簡略地說,監(jiān)控系統(tǒng)針對主系統(tǒng)從各“哨卡”傳送的數(shù)據(jù)以中斷方式所作出如下的響應:
(1)一旦有數(shù)據(jù)刷新#0標志,即表示有新的“哨卡”標志數(shù)據(jù)從主系統(tǒng)輸出,在對標志號進行判斷無誤之后,即準備進行寄存器數(shù)據(jù)的判斷。
(2)監(jiān)控CPU捕捉到接口的刷新數(shù)據(jù)信號后(在圖8中,可由MSP430的10腳TA0判別刷新信號;圖2中可由C2051的6腳判別刷新信號),在其中斷程序中,將接口傳送數(shù)據(jù)存于該“路標碼”數(shù)據(jù)項所確定的RAM地址,依次存放。監(jiān)控系統(tǒng)對這些數(shù)據(jù)進行簡單的運算或比較。在處理結果與預期不符時采取相應的恢復或拯救措施。
有了對寄存器數(shù)據(jù)的監(jiān)控,可不必對原系統(tǒng)設置過密的“哨卡”,并可防止不是由程序計數(shù)指針的變化造成的寄存器數(shù)據(jù)值的突變。
5.2 監(jiān)控過程中運行速度的
配合
數(shù)據(jù)的傳送過程中,主系統(tǒng)程序相當于在作延時操作,并沒有額外加重監(jiān)控系統(tǒng)負擔,只影響了主系統(tǒng)運行速度,在設計時應作考慮。如果有中斷在此過程中發(fā)生,監(jiān)控系統(tǒng)亦能判別(參照圖7的中斷部分)。
為保證監(jiān)控CPU在主系統(tǒng)下一“哨卡”標志號發(fā)出之前將當前“哨卡”程序全部處理完,對“哨卡”的設置間隔是有限制的。主系統(tǒng)程序中“哨卡”的設置應考慮到監(jiān)控CPU的程序負擔。必要時如果系統(tǒng)允許,甚至可為監(jiān)控系統(tǒng)作延時操作,以安置“哨卡”程序。
可以看出,完成系統(tǒng)監(jiān)控的監(jiān)控CPU需要有足夠快的速度,一般來說,監(jiān)控程序的一個循環(huán)需要二十多條語句或稍長。應用于低電壓系統(tǒng),這里推薦一種性能好、速度快、低價格、低功耗的RISC處理器?/FONT>TI公司最新推出的MSP430。其指令周期僅125ns,片內(nèi)4KB+256B FLASH ROM(MSP430 F112)。假設主系統(tǒng)采用MCS-51系列,使用6MH z晶振時,指令周期為2μs,則主系統(tǒng)一條指令的執(zhí)行時間監(jiān)控系統(tǒng)可至少執(zhí)行16條指令。而且MSP430自帶硬件看門狗,另外僅需一片電壓監(jiān)控芯片即可簡單地設計出整個監(jiān)控硬件系統(tǒng)如圖8所示。
6 結語
可見,利用自行跟蹤的方法來提高系統(tǒng)可靠性,只適用于對速度要求不高的系統(tǒng)。需要注意的是要提高系統(tǒng)的可靠性,需要在硬件、軟件和外部條件上作整體考慮。對于隨機數(shù)據(jù)和運算處理數(shù)據(jù),更多的應從主系統(tǒng)本身的程序處理來考慮。抗干擾處理沒有絕對可靠的方法,這一切都建立在以整個系統(tǒng)本身已有一定的抗干擾能力,與環(huán)境干擾強度差距不大為基礎,并從軟硬件設計整體考慮的前提下作為高可靠性系統(tǒng)的監(jiān)測才有意義。本文所介紹的方法僅作為一種可行性探討,以期各位同行在實踐中不斷完善。