1. 看門狗原理
Watchdog原理上就是一個定時器。定時器timer對時鐘進行計數(shù),當定時器溢出時,產(chǎn)生復位信號,使得整個系統(tǒng)復位。在程序或嵌入式系統(tǒng)中,需要定期的對看門狗timer進行復位重新計數(shù),定時器不會溢出復位系統(tǒng),從而保證系統(tǒng)的正常運行。當某種原因(例如干擾)引起程序跑飛或者進入死循環(huán)時,程序不能定期的復位看門狗timer, 計數(shù)溢出產(chǎn)生復位信號,導致系統(tǒng)復位。
設本系統(tǒng)程序完整運行一周期的時間是T1,看門狗的定時周期為T2,T2>T1,在程序運行一周期后就修改定時器的計數(shù)值,只要程序正常運行,定時器就不會溢出,若因為程序“跑飛”或者進入死循環(huán),那么系統(tǒng)不能在T1時刻修改時間的計數(shù)值,一直計數(shù)直到T2時刻溢出,引發(fā)系統(tǒng)復位,使系統(tǒng)重新運行,從而起到監(jiān)控作用。
從上面的解釋中可以看出,Watchdog的作用就是為了防止系統(tǒng)因意外“跑飛”,導致整個系統(tǒng)癱瘓時,恢復(reset)系統(tǒng)運行。
2. S3C2410看門狗控制
1)作為常規(guī)定時器使用,并且可以產(chǎn)生中斷
2)作為看門狗定時器使用,期滿時,它可以產(chǎn)生128個時鐘周期的復位信號
具體看下圖所示:輸入時鐘為PCLK(該時鐘頻率等于系統(tǒng)的主頻),它經(jīng)過兩級分頻(Prescaler和frequency division factor),最后將分頻后的時鐘作為該定時器的輸入時鐘,當計數(shù)器期滿后可以產(chǎn)生中斷或者復位信號。
看門狗定時器計數(shù)值的計算公式如下:
1)輸入到計數(shù)器的時鐘周期
t_watchdog = 1/( PCLK / (Prescaler value + 1) / Division_factor )
預分頻器Prescaler及分頻因子Division factor的值由用戶在WTCON(看門狗時鐘控制寄存器)中設置。
2)看門狗的定時周期
T = 計數(shù)值(WTCNT初值-WTCNT當前值) * t_watchdog
WTCNT為看門狗數(shù)據(jù)寄存器,用來設置計數(shù)多少個時鐘周期。乘以時鐘周期就是定時的總時間了。
3.看門狗在函數(shù)Delay()中的使用
void Delay(int time)
{
// time=0: adjust the Delay function by WatchDog timer.
// time>0: the number of loop time
// resolution of time is 100us.
int i,adjust=0;
if(time==0)
{
time = 200;
adjust = 1;
delayLoopCount = 400;
//PCLK/1M,Watch-dog disable,1/64,interrupt disable,reset disable
rWTCON = ((PCLK/1000000-1)<<8)|(2<<3);//使( PCLK / (Prescaler value + 1)為1M,最后使看門狗的計數(shù)頻率為1/64M,得到計數(shù)周期為64us。
rWTDAT = 0xffff; //必需在寄存器WTDAT里面存有一個值,在watchdog開啟之后這個值會被自動加載進寄存器WTCNT中
rWTCNT = 0xffff; //第一次寫初值時,WTDAT不會自動加載給WTCNT,所以必須手動將WTCNT賦初值
rWTCON = ((PCLK/1000000-1)<<8)|(2<<3)|(1<<5);//看門狗啟動定時
}
for(;time>0;time--)
for(i=0;i if(adjust==1) { rWTCON = ((PCLK/1000000-1)<<8)|(2<<3);//看門狗停止計時。 i = 0xffff - rWTCNT;//每過一個計數(shù)周期(64us),WTCNT中的值便減1,rWTCNT的初值為0xffff ,用for循環(huán)延時一段時間后讓看門狗停止計數(shù),通過i = 0xffff – rWTCNT(停止時當前計數(shù)值),算出計數(shù)次數(shù),200*400(delayLoopCount的值)cycle runtime = 64*i us delayLoopCount=8000000/(i*64);//200*400/64*i=delayLoopCount/100us -> delayLoopCount=80000*100/(64*i),算出100us需要delayLoopCount值多少(8000000/(i*64)),最后如主程序調(diào)用Delay(10000)(在之前應先執(zhí)行Delay(0)),執(zhí)行兩條for語句,相當于10000×delayLoopCount=10000×1us=1s。 }