從0學(xué)ARM Cortex-A9 看門狗入門
本文轉(zhuǎn)載自微信公眾號(hào)「一口Linux」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系一口Linux公眾號(hào)。
一、概念
看門狗的簡(jiǎn)稱是WDT(Watch Dog Timer),exynos4412scp中的看門狗定時(shí)器(WDT)是一種定時(shí)裝置。
1. 工作原理
由(一般需要客戶編寫)軟件讀寫定時(shí)器相關(guān)的寄存器,打開(kāi)看門狗,并設(shè)定計(jì)數(shù)時(shí)間(以秒或分鐘計(jì)算),定時(shí)器計(jì)數(shù)計(jì)滿,由軟件清零,以表明系統(tǒng)狀態(tài)正常,這時(shí),定時(shí)器計(jì)數(shù)重新開(kāi)始,反復(fù),否則,看門狗認(rèn)為系統(tǒng)異?;蛴衅渌囟ㄊ录l(fā)生,觸發(fā)系統(tǒng)復(fù)位信號(hào),或提供中斷,系統(tǒng)正常后重復(fù)定時(shí)器計(jì)數(shù)。
這樣只要軟件正常運(yùn)行,就不會(huì)出現(xiàn)復(fù)位或觸發(fā)中斷。當(dāng)軟件死機(jī)或運(yùn)行出錯(cuò)時(shí),由看門狗定時(shí)器對(duì)系統(tǒng)進(jìn)行復(fù)位或觸發(fā)中斷,從而保證系統(tǒng)的正常運(yùn)行。
看門狗的定時(shí)時(shí)間可以由用戶設(shè)定,這樣可以根據(jù)需要在指定的時(shí)間內(nèi)復(fù)位系統(tǒng)。
2. 作用
看門狗的作用是微處理器收到干擾進(jìn)入錯(cuò)誤狀態(tài)后,使系統(tǒng)在一定時(shí)間間隔內(nèi)復(fù)位。因此看門狗是保證系統(tǒng)長(zhǎng)期、可靠和穩(wěn)定運(yùn)行的有效措施。目前大部分的嵌入式芯片內(nèi)部都集成了看門狗定時(shí)器來(lái)提高系統(tǒng)運(yùn)行的可靠性。
4412處理器的看門狗是當(dāng)系統(tǒng)由于噪音和系統(tǒng)錯(cuò)誤而出現(xiàn)故障后,用于處理器的復(fù)位操作,也可以作為一個(gè)通用的16位定時(shí)器來(lái)請(qǐng)求中斷操作??撮T狗定時(shí)器產(chǎn)生128個(gè)PCLK周期的復(fù)位信號(hào)。主要特性有如下兩個(gè)。
1)通用的中斷方式的16位定時(shí)器。
2)當(dāng)計(jì)數(shù)器減到0(發(fā)生溢出)時(shí),產(chǎn)生128個(gè)PCLK周期的復(fù)位信號(hào)。
3. Watchdog Timer Block Diagram
Watchdog Timer Block Diagram
看門狗模塊包括一個(gè)預(yù)比例因子放大器,一個(gè)四分頻的分頻器,一個(gè)16位計(jì)數(shù)器。
看門狗的時(shí)鐘信號(hào)源來(lái)自PCLK,為了得到寬范圍的看門狗信號(hào),PCLK先被預(yù)分頻,然后再進(jìn)過(guò)分頻器分頻。預(yù)分頻比例因子和分頻器的分頻值,都可以由看門狗控制寄存器(WTCON)決定,預(yù)分頻比例因子的范圍是0~255,分頻器的分頻比可以是16、32、64或128??撮T狗定時(shí)器時(shí)鐘周期的計(jì)算如下:
clock分頻公式
式中Prescaler value 為預(yù)分頻比例放大器的值;Divison_factor是四分頻的分頻比,可以是16、32、64或128。
4. 工作流程
一旦看門狗定時(shí)器被允許,看門狗定時(shí)器數(shù)據(jù)寄存器(WTDAT)的值就不能被自動(dòng)地裝在到看門狗定時(shí)器(WTCNT)中。因此,看門狗啟動(dòng)前要將一個(gè)初始值寫入看門狗計(jì)數(shù)器(WTCNT)中。
【注意】 當(dāng)4412用嵌入式ICE調(diào)試時(shí),看門狗定時(shí)器的復(fù)位功能就不被啟動(dòng),看門狗定時(shí)器能從CPU內(nèi)核信號(hào)判斷出當(dāng)前CPU是否處于調(diào)試狀態(tài)。如果看門狗定時(shí)器確定當(dāng)前模式是調(diào)試模式,盡管看門狗產(chǎn)生溢出信號(hào),但是仍然不會(huì)產(chǎn)生復(fù)位信號(hào)。
每個(gè)時(shí)鐘周期都會(huì)將看門狗定時(shí)計(jì)數(shù)器WTCNT里的值減1,當(dāng)計(jì)數(shù)器WTCNT里的值變?yōu)?時(shí)開(kāi)始執(zhí)行超時(shí)操作。
首先,判斷看門狗控制寄存器里bit2 WTCON[2]設(shè)置情況, 如果為1則產(chǎn)生中斷信號(hào),引起系統(tǒng)中斷, 如果為0不做任何操作,進(jìn)入復(fù)位信號(hào)產(chǎn)生器,如果WTCON[0]位為1,則產(chǎn)生控制器復(fù)位信號(hào),否則不做任何操作。每次超時(shí)操作之后,看門狗WTCON會(huì)自動(dòng)加載看門狗數(shù)據(jù)寄存器WTDAT里的用戶設(shè)置值,繼續(xù)執(zhí)行遞減操作。
二、寄存器設(shè)置
1)看門狗定時(shí)器控制寄存器(WTCON)
WTCON
WTCON寄存器的內(nèi)容包括:
- WDT timer:[5] 用戶是否啟動(dòng)看門狗定時(shí)器、
- Clock select:[4:3] 4個(gè)分頻比的選擇、
- Interrupt generation:[2] 是否允許中斷產(chǎn)生、
- Reset enable/disable: [0] 是否允許復(fù)位操作等。
1) 使用起看門狗功能 開(kāi)啟看門狗復(fù)位功能、允許中斷、16分頻、開(kāi)啟看門狗定時(shí)器、Prescaler value設(shè)置為249
- WDT.WTCON = (249 << 8) | (1 << 5) | (1 << 2)|(1 << 0);
2)當(dāng)普通定時(shí)器使用 如果用戶想把看門狗定時(shí)當(dāng)做一般定時(shí)器使用,應(yīng)該中斷使能,禁止看門狗定時(shí)器復(fù)位。
- WDT.WTCON = (249 << 8) | (1 << 5) | (1 << 2);
2) 看門狗定時(shí)器數(shù)據(jù)寄存器(WTDAT)
WTDAT用于指定超時(shí)時(shí)間,在看門狗把復(fù)位功能禁止并打開(kāi)中斷使能后,此時(shí)看門狗定時(shí)器就是一個(gè)普通的定時(shí)器,使用方法和普通定時(shí)器一樣。
當(dāng)使用復(fù)位功能后,由于WTCNT的值減到0時(shí),系統(tǒng)就會(huì)復(fù)位,所以WTDAT的值裝不進(jìn)看門狗計(jì)數(shù)寄存器(WTCNT)中。復(fù)位后初始值為0x8000。
3) 看門狗計(jì)數(shù)寄存器(WTCNT) 喂狗用
WTCNT包含看門狗定時(shí)器工作的時(shí)候,計(jì)數(shù)器的當(dāng)前計(jì)數(shù)值。WTCNT描述如下:
WTCNT
4) WTCLRINT
寫入任意值清中斷。
WTCLRINT
三、看門狗定時(shí)器的程序編寫
1、看門狗軟件程序設(shè)計(jì)流程
因?yàn)榭撮T狗是對(duì)系統(tǒng)地復(fù)位或中斷的操作,所以不需要外圍的硬件電路。要實(shí)現(xiàn)看門狗的功能,只需要對(duì)看門狗的寄存器組進(jìn)行操作,即對(duì)看門狗的控制寄存器(WTCON)、看門狗數(shù)據(jù)寄存器(WTDAT)、看門狗計(jì)數(shù)寄存器(WTCNT)的操作。
「其一般流程如下:」
設(shè)置看門狗中斷操作,包括全局中斷和看門狗中斷使能及看門狗中斷向量的定義,如果只是進(jìn)行復(fù)位操作,這一步不用設(shè)置。
對(duì)看門狗控制寄存器(WTCON)的設(shè)置,包括設(shè)置預(yù)分頻比例因子、分頻器的分頻值,中斷使能和復(fù)位使能等。
對(duì)看門狗數(shù)據(jù)寄存器(WTDAT)和看門狗計(jì)數(shù)寄存器(WTCNT)的設(shè)置。
啟動(dòng)看門狗定時(shí)器。
- void do_irq(void)
- {
- static int a = 1;
- int irq_num;
- irq_num = CPU0.ICCIAR&0x3ff; //獲取中斷號(hào)
- switch(irq_num)
- { case 75:
- printf("in the WDT interrupt!\n");
- //WDT.WTCNT = 25000;//喂狗
- WDT.WTCLRINT = 0;
- ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 11); //清GIC中斷標(biāo)志位
- break;
- }
- CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num; //清cpu中斷標(biāo)志位
- }
- void wdt_init(void)
- {
- WDT.WTCON = (249 << 8) | (1 << 5) | (1 << 2)|(1 << 0);//復(fù)位使能
- //WDT.WTCON = (249 << 8) | (1 << 5) | (1 << 2); //關(guān)閉復(fù)位使能
- WDT.WTDAT = 25000;
- ICDDCR = 1; //使能分配器
- ICDISER.ICDISER2 = ICDISER.ICDISER2 | (0x1 << 11); //使能相應(yīng)中斷到分配器
- ICDIPTR.ICDIPTR18 = ICDIPTR.ICDIPTR18 & (~(0xff << 24))|(0x1 << 24); //選擇CPU接口
- CPU0.ICCPMR = 255; //中斷屏蔽優(yōu)先級(jí)
- CPU0.ICCICR = 1; //使能中斷到CPU
- }
- int main (void)
- {
- wdt_init();
- printf("hello reset!\n");
- while(1)
- {
- WDT.WTCNT = 25000;//喂狗,如果一旦停止喂狗,系統(tǒng)就reset
- mydelay_ms(100);
- }
- return 0;
- }
上述是正確運(yùn)行的代碼,將WDT.WTCNT = 25000; 注釋掉,就會(huì)停止喂狗,超時(shí)后系統(tǒng)就會(huì)reset。
本文轉(zhuǎn)載自微信公眾號(hào)「一口Linux」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系一口Linux公眾號(hào)。