Linux看門狗管理及在DM8168芯片上的應(yīng)用
摘要:隨著智能手機(jī)及平板為代表的嵌入式設(shè)備的普及,對(duì)系統(tǒng)的可靠性提出較高的要求。以TI TMS320DM8168芯片為例,詳細(xì)介紹了Linux系統(tǒng)從U—Boot啟動(dòng)、內(nèi)核啟動(dòng)到文件系統(tǒng)加載及用戶程序啟動(dòng)過(guò)程中,看門狗的啟用及管理,通過(guò)不同階段管理看門狗,可以保證系統(tǒng)在任意可能出現(xiàn)問(wèn)題的階段,可以自動(dòng)重啟以修復(fù)故障,從而有效提高系統(tǒng)的可靠性。
關(guān)鍵詞:Linux;看門狗;DM8168
引言
隨著智能終端及移動(dòng)互聯(lián)網(wǎng)的發(fā)展,Linux系統(tǒng)被應(yīng)用到越來(lái)越多的嵌入式設(shè)備中,如移動(dòng)通信基站、Android(基于Linux內(nèi)核)智能手機(jī)、智能手環(huán)等。不同領(lǐng)域的應(yīng)用都對(duì)Android/Linux系統(tǒng)的可靠性及可用性有嚴(yán)格的要求。在嵌入式系統(tǒng)中,CPU必須可靠工作,即使因?yàn)槟撤N錯(cuò)誤或異常進(jìn)入錯(cuò)誤狀態(tài),系統(tǒng)應(yīng)該可以自動(dòng)復(fù)位,看門狗也可以在系統(tǒng)進(jìn)入錯(cuò)誤狀態(tài)后的一段時(shí)間內(nèi)重啟復(fù)位,以實(shí)現(xiàn)系統(tǒng)自動(dòng)從故障恢復(fù)。
1 看門狗的概念
看門狗是一個(gè)進(jìn)行累加計(jì)數(shù)的定時(shí)器,在其啟動(dòng)后,如果在設(shè)定的時(shí)間間隔內(nèi)對(duì)定時(shí)器清零(俗稱“喂狗”操作),定時(shí)器就不會(huì)溢出,也不會(huì)產(chǎn)生復(fù)位信號(hào);如果在設(shè)定的時(shí)間間隔內(nèi),沒有對(duì)定時(shí)器清零,定時(shí)器就會(huì)溢出產(chǎn)生復(fù)位信號(hào),從而實(shí)現(xiàn)系統(tǒng)重啟。根據(jù)實(shí)現(xiàn)方式的不同,可以分為硬件看門狗和軟件看門狗。
硬件看門狗是利用定時(shí)器電路實(shí)現(xiàn),其輸出連接到電路的復(fù)位端,程序在設(shè)定間隔內(nèi)對(duì)定時(shí)器清零。因此程序正常工作時(shí),定時(shí)器不會(huì)溢出;如果程序出現(xiàn)故障,未能在設(shè)定間隔周期內(nèi)執(zhí)行清零操作,就使得看門狗定時(shí)器溢出,產(chǎn)生復(fù)位信號(hào)并重啟系統(tǒng)。軟件看門狗原理上同硬件看門狗一樣,只是將硬件電路上的定時(shí)器用操作系統(tǒng)內(nèi)部的軟件定時(shí)器代替,這樣可以簡(jiǎn)化硬件電路設(shè)計(jì)。但軟件定時(shí)器在可靠性方面不如硬件定時(shí)器,在一些異常的情形下,比如處理器或操作系統(tǒng)內(nèi)部發(fā)生故障時(shí),會(huì)導(dǎo)致軟件定時(shí)器不可用,也就無(wú)法檢測(cè)到這些故障。
2 Linux系統(tǒng)對(duì)看門狗的支持
Linux內(nèi)核從1.3.51版本開始提供硬件、軟件看門狗的驅(qū)動(dòng)支持。隨著內(nèi)核版本不斷更新與發(fā)展,Linux內(nèi)核對(duì)各種不同類型的硬件看門狗提供了廣泛的支持。根據(jù)訪問(wèn)方式的不同,Linux系統(tǒng)下的設(shè)備驅(qū)動(dòng)程序分為字符設(shè)備及塊設(shè)備??撮T狗在Linux系統(tǒng)下作為字符設(shè)備來(lái)處理,/dev/watchdog是一個(gè)主設(shè)備號(hào)為10、從設(shè)備號(hào)為130的字符設(shè)備節(jié)點(diǎn)。
Linux系統(tǒng)下的硬件看門狗,必須有硬件電路支持,設(shè)備節(jié)點(diǎn)/dev/watchdog對(duì)應(yīng)著真實(shí)的物理設(shè)備,不同類型的硬件看門狗設(shè)備由相應(yīng)的硬件驅(qū)動(dòng)管理。
軟件看門狗則由Linux內(nèi)核模塊通過(guò)定時(shí)器機(jī)制實(shí)現(xiàn),此時(shí)設(shè)備節(jié)點(diǎn)/dev/watchdog并不對(duì)應(yīng)真實(shí)的物理設(shè)備,只是為應(yīng)用提供了一個(gè)與操作硬件看門狗相同的接口。各種不同類型的硬件看門狗電路,不僅提供了驅(qū)動(dòng)程序支持,還提供了一個(gè)基于定時(shí)器的純軟件看門狗驅(qū)動(dòng),其驅(qū)動(dòng)程序的源碼位于Linux內(nèi)核源碼下面的/drivers/watchdog目錄。
與Linux下的軟件看門狗相比,硬件看門狗具有更高的可靠性?;贚inux內(nèi)核的定時(shí)器實(shí)現(xiàn)的軟件看門狗,當(dāng)內(nèi)核或中斷出現(xiàn)異常時(shí),將會(huì)失效。而硬件看門狗由自身的硬件電路控制,獨(dú)立于內(nèi)核,無(wú)論當(dāng)前系統(tǒng)狀態(tài)如何,如果硬件看門狗在設(shè)定的時(shí)間間隔內(nèi)沒有被執(zhí)行寫操作,仍會(huì)重新啟動(dòng)系統(tǒng)。
Linux系統(tǒng)下面的軟件、硬件看門狗對(duì)應(yīng)用程序而言是透明的。應(yīng)用程序操作軟件看門狗的方式如下:打開設(shè)備/dev/watchdog,在設(shè)定的時(shí)間間隔內(nèi)對(duì)/dev/watchdog設(shè)備執(zhí)行寫操作。在任意時(shí)刻,只能有一個(gè)看門狗驅(qū)動(dòng)模塊被加載,管理/dev/watchdog設(shè)備節(jié)點(diǎn)。如果系統(tǒng)沒有硬件看門狗電路,可以加載軟件看門狗驅(qū)動(dòng)模塊。
3 Linux系統(tǒng)下看門狗的訪問(wèn)
前文提到,Linux系統(tǒng)將看門狗作為一個(gè)字符設(shè)備來(lái)管理。本節(jié)將以TI公司推出的高清視頻處理芯片TMS320DM8168(以下簡(jiǎn)稱DM8168)芯片為例,介紹Linux下訪問(wèn)及操作看門狗的邏輯層次。
DM8168芯片將高清多通道系統(tǒng)的所有捕獲、壓縮、顯示以及控制功能整合于同一芯片,芯片內(nèi)部集成了硬件看門狗,外圍連接電路如圖1所示。硬件看門狗溢出同時(shí)產(chǎn)生復(fù)位(Reset)及中斷信號(hào)(Interrupt),復(fù)位信號(hào)會(huì)復(fù)位整個(gè)芯片,中斷信號(hào)可以在捕獲到中斷事件后,在中斷處理函數(shù)中增加一些額外的操作(比如將收到的看門狗溢出中斷的時(shí)間寫進(jìn)日志,然后再?gòu)?fù)位等)。
Linux系統(tǒng)訪問(wèn)硬件接口需通過(guò)設(shè)備驅(qū)動(dòng)程序接口實(shí)現(xiàn),硬件看門狗也不例外。
如圖2所示,Linux系統(tǒng)下操作看門狗需要以下3個(gè)層次:
①Hardware Layer-硬件層,指硬件設(shè)備,通常提供GPIO;
②Kernel Layer-內(nèi)核層,內(nèi)核通過(guò)設(shè)備驅(qū)動(dòng)程序訪問(wèn)并控制硬件設(shè)備;
③Usee Space-用戶空間,應(yīng)用程序通過(guò)內(nèi)核驅(qū)動(dòng)提供的API接口(通常以打開文件或ioctl方式),提供訪問(wèn)硬件設(shè)備的接口,比如打開看門狗(int fd = open(“/dev/wat chdog”,O_RDWR))。
4 Linux系統(tǒng)下看門狗的管理
Linux啟動(dòng)過(guò)程依次為U—Boot、內(nèi)核及文件系統(tǒng),最后是應(yīng)用程序啟動(dòng)。在Linux系統(tǒng)啟動(dòng)過(guò)程中,啟用看門狗可以有效監(jiān)測(cè)系統(tǒng)狀態(tài),若異常導(dǎo)致看門狗溢出,系統(tǒng)會(huì)自動(dòng)復(fù)位以試修復(fù)問(wèn)題,從而提高系統(tǒng)的可靠性及健壯性。本節(jié)以DMS168開發(fā)板為例,介紹Linux各個(gè)啟動(dòng)階段看門狗的管理。
4.1 U—Boot啟動(dòng)階段
開發(fā)板上電后,執(zhí)行U—Boot的第一條指令,然后順序執(zhí)行U—Boot啟動(dòng)函數(shù)。U—Boot啟動(dòng)內(nèi)核的過(guò)程如下:
①硬件設(shè)備初始化。
②加載U—Boot第二階段代碼到RAM空間。
③設(shè)置好堆棧,跳轉(zhuǎn)到start_armboot函數(shù)入口。
④start_armboot是U—Boot執(zhí)行的第一個(gè)C語(yǔ)言函數(shù)。[!--empirenews.page--]
⑤初始化本階段使用的硬件設(shè)備。
⑥檢測(cè)系統(tǒng)內(nèi)存映射。
⑦將內(nèi)核從Flash讀取到RAM中。
⑧設(shè)置內(nèi)核啟動(dòng)參數(shù),然后啟動(dòng)硬件看門狗,通過(guò)訪問(wèn)控制寄存器來(lái)實(shí)現(xiàn)。該階段可以設(shè)置看門狗超時(shí)溢出時(shí)間為120 s。以DM8168芯片為例(后面的代碼都是基于該芯片實(shí)現(xiàn)),相關(guān)代碼為:
__raw_writel(0xBBBB,WDT_WSPR);
__raw_writel(0x4444,WDT_WSPR);
__raw_writel(wdt_trgr_time,WDT_WTGR);
這樣如果后續(xù)的內(nèi)核解壓及啟動(dòng)出錯(cuò),看門狗超時(shí)可以復(fù)位開發(fā)板以重啟,重新加載內(nèi)核并試圖修復(fù)。
⑨完成系統(tǒng)初始化工作,U—Boot進(jìn)入主循環(huán)程序,處理用戶輸入的命令。在abortboot中,關(guān)閉看門狗,向控制寄存器依次寫入:
__raw_writel(0xAAAA,WDT_WSPR);
__raw_writel(0x5555,WDT_WSPR);
若收到用戶中斷,U—Boot自動(dòng)啟動(dòng)的命令后,關(guān)閉看門狗,以方便用戶調(diào)試U—Boot、設(shè)置內(nèi)核相關(guān)參數(shù)等信息。
⑩如果沒有收到用戶中斷命令,U—Boot會(huì)拷貝內(nèi)核鏡像并解壓內(nèi)核,開始啟動(dòng)內(nèi)核調(diào)用。
4.2 內(nèi)核啟動(dòng)階段
在U—Boot加載了內(nèi)核之后,系統(tǒng)就進(jìn)入內(nèi)核啟動(dòng)階段,此時(shí),看門狗的管理控制也要由內(nèi)核來(lái)接管。內(nèi)核啟動(dòng)主要包括內(nèi)核自解壓、注冊(cè)及加載硬件驅(qū)動(dòng)程序、Flash分區(qū)等。
在內(nèi)核啟動(dòng)時(shí),內(nèi)核程序會(huì)注冊(cè)硬件看門狗的驅(qū)動(dòng)程序,并執(zhí)行probe探針函數(shù),此時(shí),內(nèi)核接管U—Boot階段的看門狗,即先關(guān)閉看門狗,然后再重新打開看門狗,并加載新的超時(shí)時(shí)長(zhǎng),此處設(shè)置wdt_trgr_time=120 s。
__raw_writel(0xAAAA,WDT_WSPR);
__raw_writel(0x5555,WDT_WSPR);
__raw_writel(0xBBBB,WDT_WSPR);
__raw_writel(0x4444,WDT_WSPR);
__raw_writel(wdt_trgr_time,WDT_WTGR);
這樣可以保證文件系統(tǒng)在掛載或解壓出錯(cuò)時(shí),看門狗沒有進(jìn)行喂狗操作,從而導(dǎo)致120 s超時(shí)后重啟。
在注冊(cè)完硬件驅(qū)動(dòng)程序之后,內(nèi)核會(huì)掛載根文件系統(tǒng)并進(jìn)行解壓。
4.3 應(yīng)用程序啟動(dòng)階段
文件系統(tǒng)啟動(dòng)后,用戶的應(yīng)用進(jìn)程也會(huì)開始啟動(dòng)。在這個(gè)階段,通常會(huì)創(chuàng)建一個(gè)獨(dú)立的守護(hù)進(jìn)程,來(lái)接管看門狗。守護(hù)進(jìn)程啟動(dòng)時(shí),首先關(guān)閉內(nèi)核階段啟動(dòng)的看門狗,并重新啟動(dòng)看門狗設(shè)置超時(shí)時(shí)長(zhǎng),實(shí)現(xiàn)接管內(nèi)核階段看門狗的功能。在看門狗啟動(dòng)后,守護(hù)進(jìn)程可以周期性地進(jìn)行喂狗操作,并通過(guò)心跳的方式同用戶進(jìn)程通信,在收不到用戶進(jìn)程的心跳包消息時(shí),即停止喂狗操作,這樣看門狗會(huì)超時(shí)溢出導(dǎo)致系統(tǒng)重啟,以進(jìn)行故障修復(fù)。
守護(hù)進(jìn)程通過(guò)看門狗中斷響應(yīng)函數(shù),實(shí)現(xiàn)重啟系統(tǒng)等操作,以恢復(fù)系統(tǒng)可用性。
至此,Linux從U—Boot啟動(dòng)直到應(yīng)用程序完成過(guò)程中,看門狗都有相應(yīng)的啟動(dòng)及管理。
4.4 看門狗管理小結(jié)
Linux系統(tǒng)下,U—Boot啟動(dòng)后打開硬件看門狗,保證內(nèi)核解壓及啟動(dòng)出現(xiàn)異常時(shí)重啟;內(nèi)核啟動(dòng)階段,接管U—Boot下的看門狗并設(shè)置時(shí)間,可以保證文件系統(tǒng)掛載、解壓及啟動(dòng)出現(xiàn)異常時(shí)重啟系統(tǒng);在進(jìn)入文件系統(tǒng)后,守護(hù)進(jìn)程接管內(nèi)核階段的看門狗,并定期地執(zhí)行喂狗操作,這樣在用戶進(jìn)程出現(xiàn)異常(退出)時(shí),守護(hù)進(jìn)程可以監(jiān)測(cè)到異常,停止喂狗操作,看門狗超時(shí)復(fù)位系統(tǒng)。嵌入式系統(tǒng)中,重啟是從故障中修復(fù)的最簡(jiǎn)單有效的方法,通過(guò)在啟動(dòng)的不同階段啟用硬件看門狗,可以有效保障系統(tǒng)異常時(shí)重啟。
5 DM8168看門狗的管理
除了前文提到的Linux系統(tǒng)下看門狗的基礎(chǔ)管理,DM8168芯片的硬件看門狗外圍輸出引腳,可以同時(shí)支持Reset和Interrupt信號(hào),功能更加強(qiáng)大。
如果只是期望看門狗超時(shí)后能重啟復(fù)位板卡,參考前節(jié)提到的方法,依次在Linux啟動(dòng)的各個(gè)階段啟用及管理看門狗即可,因?yàn)榭撮T狗的溢出引腳直接連接電源及復(fù)位管理模塊。
此外,如果想在看門狗超時(shí)溢出時(shí)增加一些額外的處理,可以采用捕獲中斷信號(hào)的方法。具體流程如下:
①注冊(cè)硬件看門狗中斷處理函數(shù),實(shí)現(xiàn)程序?yàn)閛map_irq=platform_get_resource(pdev,IORESOURCE_IRQ,0); //獲得中斷標(biāo)號(hào)
ret=request_irq(omap_irq,omap_wdt_irqhdl,0,pdev->name,wdev); //注冊(cè)中斷
其中omap_wdt_irqhdl為看門狗的中斷處理函數(shù)。
②在硬件看門狗中斷處理函數(shù)中可以增加一些附加的處理,需要注意的是,此時(shí)需要設(shè)置另外一組寄存器WDT_WDLY,以保證在復(fù)位前捕獲到中斷信號(hào)。
中斷處理函數(shù)omap_wdt_irqhdl的關(guān)鍵實(shí)現(xiàn)程序?yàn)椋?/p>
采用此方法后,看門狗超時(shí)產(chǎn)生中斷信號(hào),系統(tǒng)捕獲到中斷信號(hào)后自動(dòng)觸發(fā)中斷響應(yīng)函數(shù),可以更靈活地處理(比如不復(fù)位系統(tǒng),保留現(xiàn)場(chǎng)以便定位問(wèn)題)。
結(jié)語(yǔ)
本文以TI公司的TMS320DM8168芯片為例,詳細(xì)介紹了Linux系統(tǒng)從U—Boot啟動(dòng)、內(nèi)核啟動(dòng)到文件系統(tǒng)加載及用戶程序啟動(dòng)過(guò)程中看門狗的啟用及管理,通過(guò)不同階段管理看門狗,可以保證系統(tǒng)在任何一個(gè)可能出現(xiàn)問(wèn)題的階段,自動(dòng)重啟以修復(fù)故障,從而有效提高系統(tǒng)的可靠性。在嵌入式設(shè)備越來(lái)越普及的今天,設(shè)備自恢復(fù)功能會(huì)具有極大的競(jìng)爭(zhēng)力。