uboot詳解——cpu內部,外部和軟體看門狗
uboot啟動時,當將cpu執行模式設定為管理模式後,就要關閉看門狗了,那麼看門狗是幹什麼的呢?
狗狗是我們的好朋友,有時候,一條好狗狗能夠救主人的性命,”看門狗“是cpu的“好朋友”,它也能夠在cpu出狀況的時候把它救活。
看門狗其實就是一個可以在一定時間內被複位的計數器,當看門狗啟動後,計數器開始自動計數,經過一定時間,cpu就會將這個計數器復位,如果沒有被複位,計數器溢位就會對CPU產生一個復位訊號使系統重啟,這個復位的操作就是“喂狗”。
看門狗就這樣兢兢業業的守著它的主人cpu,當cpu出狀況的時候,就不能喂狗了,看門狗餓了就知道cpu不正常工作了,然後傳送復位訊號讓cpu重新醒過來。
看門狗主要分三種:
1、內建在cpu內部的看門狗
此類看門狗一般是將一個晶片中的定時器來作為看門狗,通過程式的初始化,寫入初值,並啟動定時器。程式按時對定時器賦初值(或復位),以免它餓了。這種看門狗是可以被禁用的(只要停止這個定時器即可),好比對那隻要咬你的狗來個“葵花點穴手”。大部分CPU都內建看門狗,硬體原理可參考各晶片資料手冊。
優點:可以通過程式改變初始時間,也可以隨時禁用
缺點:
2、獨立的看門狗晶片
這種看門狗主要有一個用於喂狗的引腳(一般與CPU的GPIO相連)和一個復位引腳(與系統的RESET引腳相連),如果沒有在一定時間內改變喂狗腳的電平,復位引腳就會改變狀態復位CPU。此類看門狗一上電就開始工作,無法禁用。現在常用的晶片有:CAT705/CAT706、IMP706等等,溢位時間在1.6秒左右。 硬體原理可以參考各晶片資料手冊和《基於Linux的嵌入式系統全程喂狗策略》。
優點:無須配置,上電即用。無法禁用,系統必須按時喂狗,系統恢復能力高。
缺點:
3、軟體看門狗
這其實就是一個監控軟體,對於硬體上出的問題它還是無能為力的,它主要對一些重要的軟體進行監控。
一些重要的程式,必須讓它一直跑著;而且還要時時關心它的狀態——不能讓它出現死鎖現象。(當然,如果一個主程式會出現死鎖,肯定是設計或者程式設計上的失誤。首要做的事是Debug。)但如果時間緊迫可以用軟體看門狗,暫時應急。
這種監控軟體執行不出現介面視窗,具有一定的隱蔽性;它定時判斷目標程序是否執行在當前系統中,如果沒有則啟動目標程序;判斷目標程序是否“無響應”,如果是則終止目標程序;如果目標程序“無響應”的次數超過一定的數量,則重啟整個系統。它的目的也是復位,但是它主要市復位程序,實在不行才復位CPU。
第二種和第三種看門狗,在這裡不作討論,下面將討論怎麼使用內建在cpu內部的看門狗。
因為是內建在cpu內部,所以從電路圖中就找不到看門狗的連線方式了,下面是看門狗的工作原理圖:
從圖中可以看出一下幾點:
1. 看門狗使用的輸入時鐘是PCLK,關於時鐘的知識將在後面進行詳細分析
2. 看門狗的配置涉及到三個暫存器:控制暫存器(WTCON),資料暫存器(WTDAT),計數暫存器(WTCNT)
3.看門狗先將PCLK時鐘進行預分頻 (prescaler),分頻的精度為0~255 (2的8次方-1 ,由WTCON的8-15位進行設定),預分頻後再除以一個分頻因子(division factor,由WTCON的4:3兩位進行設定,一共有4中選擇——16,32,64,128),有PCLK、prescaler和division factor三個變數以後,就可以計算出看門狗計數器遞減時間間隔:
t_watchdog:看門狗計數器遞減時間間隔,單位秒
PCLK:APB匯流排工作始終,單位HZ
prescaler value + 1:預分頻大小,因為從0開始,所以需要加一
division_factor:分頻因子,有4個檔——16,32,64,128
當開發板一上電的時候,系統時鐘是還沒有初始化的,所以PCKL的時鐘大小是和外部時鐘一樣的,cpu連線的外部晶振如下圖:
所以剛上電時,PCKL的大小12MHz,WTCON[15:8]設定為74,除數因子選擇16,通過上面公式可以計算出,看門狗控制器遞減時間間隔0.1毫秒。將WTCNT裡的值設定為0x2710(十進位制10000),那麼看門狗會每過一秒鐘產生一次超時。
我們來看看控制暫存器(WTCON),資料暫存器(WTDAT),計數暫存器(WTCNT)晶片手冊:
從上圖可以看到WTCON的預設狀態:
[0]=1 當看門狗計時器超時的時候,開啟發送reset訊號的功能
[2]=0 超時的時候不傳送中斷
[4:3]=00 預設分頻因子是1/16, division_factor=16
[5]=1 開啟看門狗計數器,看門狗會按照WTCNT中的初始值進行遞減,直到超時
[15:8]=0x80 換成十進位制是128, prescaler=128
因為剛開機的時候,PCLK=12M, prescaler=128, division_factor=16 , 所以可以計算出 t_watchdog=1/(12M/129/16)=(129*16)/(12000000)=0.000172s=0.172ms
上圖是WTDAT暫存器的晶片手冊,預設值是0x800, 十進位制是2048
上圖是計數器暫存器的晶片手冊,預設值也是0x800,十進位制是2048
所以剛上電的時候,看門狗的超時時間是:time_out=2048*0.000172=0.352252s
0.352252s是如此的短暫,所以在開機的時候如果沒有關閉看門狗,它將每隔0.352252s就傳送一次reset訊號重啟cpu,不管uboot執行到哪個階段,都將被看門狗終止並重啟。
從上面可以得出結論,板子重啟時,必須儘早關閉看門狗,以便後面的程式碼順利執行。
看門狗關閉以後,需要在什麼時候開啟呢?我們將會在後面分析uboot和核心程式碼的時候進行分析。
下面將使用一個例子演示對看門狗的操作。
Makefile
[plain] view plain copy- watch_dog.bin:watch_dog.S
- arm-linux-gcc -g -c -o watch_dog.o watch_dog.S
- arm-linux-ld -Ttext 0x000 -g watch_dog.o -o watch_dog_elf
- arm-linux-objcopy -O binary -S watch_dog_elf watch_dog.bin
- clean:
- rm -rf watch_dog.bin *.o watch_dog_elf
watch_dog.S
[plain] view plain copy
- @ 關閉看門狗實驗
- .text
- .global _start
- _start:
- ldr r0, = 0x53000000 @ WTCON暫存器地址載入到r0
- mov r1, #0 @ r1 = 0
- str r1, [r0] @ 將r1裡的值存到r0裡地址裡
通過分析前面的暫存器的設定位可知,只要設定WTCON[5]為0即可,上述程式碼裡,直接將整個WTCON暫存器裡的位設定為0。
[plain] view plain copy
- @開啟看門狗實驗:
- @watch_dog.S
- .text
- .global _start
- _start:
- @ 設定看門狗控制暫存器
- ldr r0, =0x53000000 @ 載入WTCON暫存器地址
- @ 0x4a21 = [15:8]=74, [5]=1, [0]=1
- ldr r1, =0x4a21 @ 將0x4a21儲存到r1裡
- str r1, [r0] @ 將r1裡的值存入r0指向的地址
- @ 設定看門狗計數暫存器,該暫存器的值在上電後被載入, 1秒超時
- ldr r2, =0x53000008 @ 載入WTCNT暫存器地址
- ldr r3, =0x2710 @ 將0x2710儲存到r1裡
- str r3, [r2] @ 將r3裡的值存入r2指向的地址
- bl led_on @ 呼叫led_on程式碼
- loop:
- b loop @ 死迴圈
- led_on:
- ldr r0,=0x56000010
- mov r1,#0x15400
- str r1,[r0]
- ldr r0,=0x56000014
- mov r1,#0x100
- str r1,[r0]
- mov pc,lr
程式開始定義兩個常量地址,分別是WTCON,WTCNT的地址,ENRTY後面是程式的正文部分,首先通過ldr指令載入WTCON的地址到r0裡,將0x4a21這個數載入到r1裡,0x4a21是我們通過設定WTCON [15:8]=74 [7:6]=0,[5]=1,[4:1]=0, [0]=1得到的16進位制數,將其值存入到r0地址裡,這樣WTCON裡就是我們設定各位的值,然後同樣道理再將0x2710存到WTCNT資料暫存器裡,設定資料暫存器的值為0x2710。
為了看到看門狗的重啟效果,我們加入了一個小程式,用來點亮led燈,將上述程式碼在linux下編譯完後,燒寫到NORFLASH裡可以看到每過1秒鐘,開發板的led燈就閃一下。
知識擴充套件
開啟了看門狗之後,控制器會定時的復位,為了防止不停的復位,就要進行“喂狗”操作,喂狗操作相對比較簡單,只要在WTCNT裡的計數減為0之前,將其值重置一個非0的數值即可,看下面的函式:feed_dog(該程式碼僅供讀者參考,光碟原始碼中沒有給出具體例子)
[plain] view plain copy- @ 喂狗程式
- .text
- .global _start
- feed_dog:
- ldr r0, =WTCNT
- ldr r1, =0x2710
- str r1, [r0]
- mov pc, lr
喂狗程式對喂狗的時機必須要合適,否則在定時器還沒來得及發生中斷呼叫watchdog已經超時了,也將引起系統復位重啟,通常系統裡會開啟另外一個時鐘來為整個系統服務,它會定時的“告知”系統,在看門狗定時器超時之前,自動的呼叫喂狗程式。
轉載請宣告!