看門(mén)狗(watch dog)是一個(gè)定時(shí)器,可以設(shè)置一個(gè)定時(shí)時(shí)間,計(jì)時(shí)到時(shí)會(huì)把MCU復(fù)位,所以MCU必須要在定時(shí)時(shí)間到之前將計(jì)數(shù)值重置(這個(gè)動(dòng)作通常稱為喂狗)。
在嵌入式系統(tǒng)中加入看門(mén)狗,可以監(jiān)測(cè)MCU是否還在正常運(yùn)行,如果軟件跑進(jìn)死循環(huán)、或者出現(xiàn)其他錯(cuò)誤,導(dǎo)致不能及時(shí)重置看門(mén)狗計(jì)時(shí)器,則時(shí)間一到MCU就會(huì)被復(fù)位,重新回到初始狀態(tài),以此跳出錯(cuò)誤狀態(tài)。
Stm32內(nèi)部帶有獨(dú)立看門(mén)狗、窗口看門(mén)狗。獨(dú)立看門(mén)狗使用時(shí),只要喂狗時(shí)間不大于設(shè)定的時(shí)間就可以,是最常用的看門(mén)狗用法;而窗口看門(mén)狗,需要喂狗時(shí)間在一個(gè)上下限范圍內(nèi),才能重置看門(mén)狗計(jì)時(shí)器。
下面我們就分別學(xué)習(xí)一下這兩種看門(mén)狗的使用。
1)stm32的獨(dú)立看門(mén)狗(IWDG)
我們?cè)谥暗拇谥袛喙こ躺闲薷模员阌诖蛴?shù)值查看。
使用cubemx打開(kāi)串口中斷的工程,然后另存為IWDG工程,打開(kāi)獨(dú)立看門(mén)狗,并設(shè)置分頻系數(shù)和重載計(jì)數(shù)值:
然后,切換到clock configuration頁(yè)面,可以看到IWDG的時(shí)鐘來(lái)自于內(nèi)部的低速RC振蕩器,頻率是40kHz:
結(jié)合設(shè)置的分頻系數(shù)和重載計(jì)數(shù)值,我們可以計(jì)算出看門(mén)狗的定時(shí)時(shí)間:
64*1000/40kHz = 1.6s
生成keil工程文件,打開(kāi),我們可以看到main函數(shù)中已經(jīng)有初始化IWDG的代碼,MX_IWDG_Init()這個(gè)函數(shù)設(shè)置了我們的分頻和計(jì)數(shù)值,并啟動(dòng)了看門(mén)狗。
在使用時(shí),我們?cè)谥餮h(huán)中,需要在每1.6s之內(nèi)喂一次狗(調(diào)用一次HAL_IWDG_Refresh()函數(shù))。如下圖所示,代碼中是每1s喂一次狗,右邊的運(yùn)行結(jié)果可以看出,程序一直在正常運(yùn)行,沒(méi)有被復(fù)位:
而如果我們改變延時(shí)的參數(shù),變成每2s喂狗一次,則可以看到,程序會(huì)被復(fù)位:
2)stm32的窗口看門(mén)狗(WWDG)
仍然在之前的串口中斷工程上修改,以便于打印數(shù)值查看。
使用cubemx打開(kāi)串口中斷的工程,然后另存為WWDG工程,打開(kāi)窗口看門(mén)狗,并設(shè)置分頻系數(shù)、窗口值、計(jì)數(shù)值,并使能早期喚醒中斷:
這幾個(gè)參數(shù)的含義解釋一下:
分頻系數(shù)比較好理解,WWDG的主時(shí)鐘是PCLK1(APB1的時(shí)鐘),這里設(shè)置為8,則分頻為PCLK1/8/4096;
窗口看門(mén)狗的計(jì)時(shí)器是減法計(jì)數(shù),從設(shè)置的WWDG free-running downcounter value向下計(jì)數(shù),如果不喂狗,計(jì)到0x3F時(shí),會(huì)復(fù)位MCU;因此WWDG free-running downcounter value設(shè)置的值必須大于0x3F;而其最大值不能超過(guò)0x7F,圖中設(shè)置的就是最大值0x7F;
WWDG window value的值必須在0x3F和WWDG free-running downcounter value之間,圖中設(shè)置的值時(shí)0x70,表示W(wǎng)WDG計(jì)時(shí)器從0x7F向下遞減時(shí),要減到0x70之下后,才能有效喂狗(即喂狗的窗口區(qū)間在0x3F ~ WWDG window value之間)。
使能早期喚醒中斷,并開(kāi)啟中斷,這里使用中斷主要是為了方便指示出是否已到窗口時(shí)間內(nèi):
然后,到clock configuration頁(yè)面下,可以看到PCLK1的頻率為36M:
依據(jù)以上信息,可以計(jì)算出喂狗的窗口:
PCLK1/8/4096 = 1099Hz;
(0x7F-0x3F)/ 1099 = 58ms;
(0x7F-0x70)/1099 = 14ms;
所以,喂狗的窗口時(shí)間約為14ms~58ms。
生成keil工程,打開(kāi)后,在wwdg.c中添加早期窗口看門(mén)狗中斷額回調(diào)函數(shù),只是置一個(gè)標(biāo)志位:
在主循環(huán)中,檢測(cè)標(biāo)志位,如果有,則說(shuō)明已經(jīng)到窗口時(shí)間,需要盡快喂狗;
程序代碼和運(yùn)行結(jié)果如下圖:
可以看到,喂狗的操作起到了作用,程序沒(méi)有被復(fù)位。
3)關(guān)于看門(mén)狗使用的幾個(gè)要點(diǎn)
在實(shí)際工程應(yīng)用中,使用看門(mén)狗要注意幾個(gè)要點(diǎn),否則可能發(fā)揮不了它的作用:
a)喂狗的操作,必須要在主循環(huán)里,而不能放在定時(shí)器中斷里!這是很多初學(xué)者容易犯的錯(cuò)誤!因?yàn)?,如果出現(xiàn)了主循環(huán)跑飛或者陷入某個(gè)死循環(huán),定時(shí)器中斷可能還在正常運(yùn)行,定期進(jìn)入中斷喂狗,則看門(mén)狗不能復(fù)位系統(tǒng),起不到監(jiān)測(cè)系統(tǒng)正常運(yùn)行的作用;
b)如果是多任務(wù)系統(tǒng),比如使用了實(shí)時(shí)操作系統(tǒng),有多個(gè)任務(wù)在運(yùn)行,使用看門(mén)狗時(shí),需要依據(jù)任務(wù)功能來(lái)設(shè)置喂狗規(guī)則:在一定時(shí)間內(nèi)必定會(huì)運(yùn)行的一組任務(wù),需要每個(gè)任務(wù)都執(zhí)行到之后才喂狗一次,保證所有任務(wù)都被監(jiān)測(cè);可能會(huì)被阻塞、或者間隔時(shí)間很長(zhǎng)(超過(guò)看門(mén)狗計(jì)時(shí)時(shí)間)運(yùn)行一次的任務(wù),則不能與喂狗操作相關(guān)聯(lián),避免正常運(yùn)行時(shí)被意外復(fù)位。
好了,本節(jié)看門(mén)狗相關(guān)的知識(shí)就講解到這里。
評(píng)論
查看更多