在ARM中,有一个硬件部分叫WATCH DOG。这个硬件,一向在做一件工作:便是,从某一数值,一向数,各一段时间减一,隔一段时间减一,直到减到0的时分将会触发重启或许中止。而有时分,为了防备死机,咱们在操作系统跑起来的时分会有一个特定的程序来做一件工作:减到特定是值的时分数值将会从头置到100.这样,看门狗将会循环往复做一件工作:一向数数,而不会死机。
这个程序叫做看护程序:又叫做喂狗程序。
看门狗的逻辑运算图如下:
今日,有看门狗来写了一个程序:隔一段时间来触发一个中止,每次中止来的时分,将会让板子上面的灯和蜂鸣器做出相应的反映:
首要:在头文件中将详细的寄存器声明:
1 2 #define gpiobase 0x113 #define GPM4CON (*(volatile unsigned long *)(gpiobase + 0x02E0)) 4 #define GPM4DAT (*(volatile unsigned long *)(gpiobase + 0x02E4))5 #define GPX3CON (*(volatile unsigned long *)(gpiobase + 0x0C60))6 #define GPX3DAT (*(volatile unsigned long *)(gpiobase + 0x0C64))7 #define GPD0CON (*(volatile unsigned long *)(gpiobase + 0x4A0))8 #define GPD0DAT (*(volatile unsigned long *)(gpiobase + 0x4A4))9 10 #define ICC 0x1048011 12 #define ICCICR_CPU0 (*(volatile unsigned long *)(ICC + 0x0)) 13 #define ICCPMR_CPU0 (*(volatile unsigned long *)(ICC + 0x4)) 14 #define ICCBPR_CPU0 (*(volatile unsigned long *)(ICC + 0x8)) 15 #define ICCIAR_CPU0 (*(volatile unsigned long *)(ICC + 0xC)) 16 #define ICCEOIR_CPU0 (*(volatile unsigned long *)(ICC + 0x0010)) 17 #define ICCRPR_CPU0 (*(volatile unsigned long *)(ICC + 0x0014)) 18 #define ICCHPIR_CPU0 (*(volatile unsigned long *)(ICC + 0x0018)) 19 #define ICCABPR_CPU0 (*(volatile unsigned long *)(ICC + 0x001C)) 20 #define INTEG_EN_C_CPU0 (*(volatile unsigned long *)(ICC + 0x0040)) 21 #define ICCIIDR (*(volatile unsigned long *)(ICC + 0x00FC))22 23 #define ICD 0x1049024 25 #define ICDDCR (*(volatile unsigned long *)(ICD + 0x0))26 #define ICDICTR (*(volatile unsigned long *)(ICD + 0x4))27 #define ICDIIDR (*(volatile unsigned long *)(ICD + 0x8))28 #define ICDISR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0080))29 #define ICDISER0_CPU0 (*(volatile unsigned long *)(ICD + 0x0100))30 #define ICDISER2_CPU0 (*(volatile unsigned long *)(ICD + 0x0108))31 #define ICDICER0_CPU0 (*(volatile unsigned long *)(ICD + 0x0180))32 #define ICDISPR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0200))33 #define ICDICPR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0280))34 #define ICDABR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0300))35 #define ICDIPR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0400))36 #define ICDIPR1_CPU0 (*(volatile unsigned long *)(ICD + 0x0404))37 #define ICDIPR2_CPU0 (*(volatile unsigned long *)(ICD + 0x0408))38 #define ICDIPR3_CPU0 (*(volatile unsigned long *)(ICD + 0x040C))39 #define ICDIPR4_CPU0 (*(volatile unsigned long *)(ICD + 0x0410))40 #define ICDIPR5_CPU0 (*(volatile unsigned long *)(ICD + 0x0414))41 #define ICDIPR6_CPU0 (*(volatile unsigned long *)(ICD + 0x0418))42 #define ICDIPR7_CPU0 (*(volatile unsigned long *)(ICD + 0x041C))43 #define ICDIPR18_CPU0 (*(volatile unsigned long *)(ICD + 0x448))44 45 #define ICDIPTR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0800))46 #define ICDIPTR1_CPU0 (*(volatile unsigned long *)(ICD + 0x0804))47 #define ICDIPTR18_CPU0 (*(volatile unsigned long *)(ICD + 0x0848))48 #define ICDSGIR (*(volatile unsigned long *)(ICD + 0x0F00))49 50 51 #define WTCON (*(volatile unsigned long *)0x10060)52 #define WTDAT (*(volatile unsigned long *)0x10064)53 #define WTCNT (*(volatile unsigned long *)0x10068)54 #define WTCLRINT (*(volatile unsigned long *)0x1006C) 55 56 57
在首要的文件中:
1 #include"regs.h"2 3 int (*printf)(char *, ...) = 0xc3e114d8;4 int(*delay)(int)=0xc3e25f90;5 6 void init_ttb(unsigned long *addr);7 void enable_mmu(void);8 unsigned long data_abort_init();9 void memcopy(unsigned long* dest,unsigned long* source,int len);10 void do_irq();11 void pwm_on(void);12 void pwm_off(void);13 void led_on(void);14 void led_on(void);15 16 17 18 int main()19 {20 *(unsigned long *)0x66 = do_irq;21 22 //产生反常时会进入反常形式跳转到0 4地址处理反常事情 23 unsigned long source_addr=data_abort_init();24 //反常事情处理函数25 printf("swi_souce addr is %x\n",source_addr);26 //将反常处理地址的值放到0x6427 memcopy(0x60,source_addr,0x1);28 29 enable_mmu();30 //内存映射将0x04映射到0x6004 31 32 //step 1: cpu cpsr33 __asm__ __volatile__(34 "mrs r0, cpsr\n"35 "bic r0, r0, #0x80\n"//设置CPSR的I位,将IRQ位翻开36 "msr cpsr, r0\n"37 ::: "r0"38 );39 40 //step 2: GIC 41 ICCICR_CPU0 = 1;//CPU接口操控寄存器42 ICCPMR_CPU0 = 0xff;//中止优先标志寄存器43 44 //7545 ICDDCR = 1;46 //ICDIPR0_CPU0 = (0x00 << 0);47 ICDIPR18_CPU0 = (0x0 << 24);48 //ICDIPTR0_CPU0 = 1;49 ICDIPTR18_CPU0 = (0x1 << 24);50 //ICDISER0_CPU0 = (1 << 0);51 ICDISER2_CPU0 = (1 << 11);52 53 //step 3: interrupt source watchdog54 WTCON = 0 (1 << 2) (3 << 3) (1 << 5) (250 << 8);55 WTCNT = 0x8;56 WTDAT = 0x1;57 58 printf("welcome back! \n");59 60 61 }62 63 void pwm_on(void)64 {65 GPD0CON &= ~0xffff;66 GPD0CON = 0x1;//装备寄存器为267 GPD0DAT = 0x1;//date=0xf68 }69 70 void pwm_off(void)71 {72 GPD0CON &= ~0xffff;73 GPD0CON = 0x0;74 // GPD0DAT &=0x0 ;//date=0xf75 76 }77 void led_off(void)78 {79 GPM4CON &= ~0xffff;//清零80 GPM4CON = 0x0;//03位清零81 GPM4DAT = 0x0;//date=0xf封闭置一82 }83 void led_on(void)84 {85 GPM4CON &= ~0xffff;86 GPM4CON = 0x1;//装备寄存器3-0--3-3全为1,全为输出形式87 GPM4DAT &= ~0xf;//翻开置0-4位为088 }89 90 void do_irq()91 {92 unsigned long data = ICCIAR_CPU0;93 unsigned long irq_id = data & 0x3ff;94 unsigned long cpu_id = (data >> 10) & 0x7;95 ICCEOIR_CPU0 = irq_id (cpu_id << 10);96 printf("irq is %d, cpu is %d\n", irq_id, cpu_id);97 98 pwm_on();99 led_on();100 printf("hello dog!\n");101 delay(6);102 pwm_off();103 led_off();104 WTCLRINT = 0x1;105 }106 107 void memcopy(unsigned long* dest, unsigned long* source,int len)108 {109 int i=0;;110 for(i=0;i> 20] = pa 2;217 //2的意图是将0-2方位为10此刻将是小页形式4K218 }219 220 //00-10 ==== 6070221 for(va=0x00; va<=0x10; va+=0x100){pa = va+0x60;223 addr[va >> 20] = pa 2;224 }225 226 //10-14 ==== 1014227 for(va=0x10; va<=0x14; va+=0x100){228 pa = va;229 addr[va >> 20] = pa 2;230 }231 232 //30-40 ==== 5060233 for(va=0x30; va<0x40; va+=0x100){234 pa = va + 0x20;235 addr[va >> 20] = pa 2;236 }237 }
首要看主函数部分:
39
40 //step 2: GIC
41 ICCICR_CPU0 = 1;//CPU接口操控寄存器
42 ICCPMR_CPU0 = 0xff;//中止优先标志寄存器
43
44 //75
45 ICDDCR = 1;
46 //ICDIPR0_CPU0 = (0x00 << 0);
47 ICDIPR18_CPU0 = (0x0 << 24);
48 //ICDIPTR0_CPU0 = 1;
49 ICDIPTR18_CPU0 = (0x1 << 24);
50 //ICDISER0_CPU0 = (1 << 0);
51 ICDISER2_CPU0 = (1 << 11);
52
53 //step 3: interrupt source watchdog
54 WTCON = 0 (1 << 2) (3 << 3) (1 << 5) (250 << 8);
55 WTCNT = 0x8;
56 WTDAT = 0x1;
57
58 printf(“welcome back! \n”);
还有:
90 void do_irq()
91 {
92 unsigned long data = ICCIAR_CPU0;
93 unsigned long irq_id = data & 0x3ff;
94 unsigned long cpu_id = (data >> 10) & 0x7;
95 %&&&&&%CEOIR_CPU0 = irq_id (cpu_id << 10);
96 printf(“irq is %d, cpu is %d\n”, irq_id, cpu_id);
97
98 pwm_on();
99 led_on();
100 printf(“hello dog!\n”);
101 delay(6);
102 pwm_off();
103 led_off();
104 WTCLRINT = 0x1;
105 }
其间,各个寄存器详见:1352芯片手册。
运转成功:
将会发现板子,各一段时间就会叫一次。LED会闪耀一次!
改动WTDAT的值就会修正叫的频率!