大家對自己寫的程式通常都很有自信,但人算不如天算,總是在幾萬次的執行當中會遇到當機,而且你還不知道原因,因為Bug出現的機率低,造成除錯很困難。如果無法與Bug直球對決,那麼閃過它也是一種方法, watch dog 由此應運而生,它提供代客Reset的服務。Watch Dog會緊盯處理器Processor,萬一Processor當機了, 它會自動Reset Processor,這樣系統就會穩定許多。
watch dog-概念
watch dog 的想法很簡單,就是Processor利用外部的電路來Reset自己。
Processor為了證明自己還活著,每隔一段時間會傳送Clear訊號給 watch dog timer,一旦Clear訊號久久沒送出來, watch dog 就會視為當機,隨後便送出Reset給Processor,我用下面這張圖來表示,我想各位會更清楚。

事實上 watch dog 本身是個計時器Timer它可以從0數到N,所以也稱為 watch dog timer (WDT),WDT一旦數到N就會發送Reset的訊號給Processor,而WDT也設計成可以接受Clear訊號,用來讓Timer重新計數,只要WDT不要數到N就永遠不會送出Reset。
Timer算時間的方式不外乎0上數到N,N下數到0,有些是用除頻的方式,只要能計算時間,實作方式可以說五花八門。
在大型的DSP系統中,可能會有好幾個Watch Dog看守不同的Function Unit,每個Unit在reset的時候由於無法對外部的請求做回應,因此需要搭配一些機制,避免因為一個Unit當機而牽連了其他Unit跟著當機。
應用實例
我直接做個電路板來當例子,我使用PIC系列的PIC12F1840,它是一顆8腳的8bit MCU,它內含了振盪器,也就是說接上電源就能馬上使用,真是太方便了,下圖就是我的實驗平台。至於3.3V的整流器是我做其他實驗要用的,在這篇文章裡並不會用到。

我的程式很簡單,就是下面這幾行,其中clrwdt就是組合語言的指令,asm( )可以用來崁入組合語言指令。這個程式的功能只有在RA0的腳位輸出0與1交替訊號而已,所以理論上在RA0會測量到一個穩定的方波。
#pragma config WDTE = ON //watch dog turn ON #include <pic12f1840.h> unsigned char c=0; void main(void) { unsigned char i; TRISA=0x00; //設定PORT A為輸出 while(1) { c=(unsigned char)(c^0x01); //做XOR運算 1變0, 0變1 PORTA=c; //輸出, 只有PORTA.0 也就是RA0有變化而已 for(i=0;i<20;i++); //delay, 模擬function的執行時間 asm("clrwdt"); //以組合語言發送WDT clear指令 } return; }
由於我有啟動WDT,如果沒有在時限內送出clrwdt,MCU就會被Reset,而Reset這段時間由於程式重新跑到XOR運算需要額外的時間,會造成方波在這時候的寬度變得比較寬,從示波器上看起來就會有些抖動,如下圖這般。
如果這個現象10 sec才發生一次,你會發現這些細微的差異進而更正它嗎? 身為工程師就是要具有相當敏銳的覺察力,所謂見微知著,你才能防範於未然。

單晶片的WDT
接下來看比較硬體的東西,我列出PIC12F1840的WDT方塊圖,在datasheet page81,它其實很容易理解,左邊看似一堆輸入訊號,其實就是用來決定要如何啟動WDT而已,只要有啟動,中間的震盪器便會振出固定的31KHz頻率週期,而後方的23 bit prescaler是用來除頻的,除越多頻率就越低,到達Timeout的時間就越久,講白話些就是用來設定WDT的時間。

那除下來到底是多少時間一個循環呢? Datasheet裡面已經幫我們算好了,但它只是大概算一下,所以才會寫上nominal,我摘要在下圖,從1m sec到256 sec都可以選。
時間的選擇取決於你的程式一趟要跑多久,Timeout的時間必須要大於程式執行的時間,否則你的程式還沒跑完就會被Reset。別以為自己不會犯這種錯,當你的程式越寫越長的時候,到了某個時候你就會遇到一直莫名其妙的當機發生,如果你又忘了watch dog的存在,你就會在原地Debug到海枯石爛都找不出原因,原先想拿來穩定系統的WDT屆時就變成了你Debug的夢靨。
好好善用 watch dog 能幫助你改善系統的穩定度喔,這樣對 watch dog 是否有更清楚了呢?

Be the first to comment