Tiny4412中断之看门狗

  一:看门狗(WDT watch dog timer)

  看门狗其实是一个计数器它的作用就是防止程序陷入死循环或者程序运行跑飞;看门狗是一个硬件它的工作原理是,初始化给他一个值,它会过一段时间减一,3c产品是什么意思直到看门狗2买哪个版本好这个数减为0,它将会产生一个3c产品是什么意思中断信号或者reset信号,致使我们系统复位,而又时候我们不想让它过一会儿就重启又想预防死机,那么我们就可以在这个数减到系统运维面试题及答案快要接进0的时候,给它重新赋值;这样就不会触发reset信号,但当程序跑飞时机器死机时,它就会减到零,进行操作系统复位;

 具体看下图所示:输入时钟为PCLK(该时钟频率等于系统的主频),它经过两级分频(Prescaler和frequedefine()翻译ncy division factor),最linux后将分频后的时钟作为该定时器的输入时钟,当计数器期满后可以产生中断或者复位信看门狗3号。

  看门狗计数器公式如3c产品是什么意思下:

  t_watchdog = 1/( PCLK / (Prescaler v3ce是什么牌子alue + 1) / Division_factor )

  通过linux系统tiny4412用户手册我们可以找到看门狗的中断号为75(如下图):


                                            Tiny4412中断之看门狗

  预分频器Prescaler及分频因子Division factor的值3c在W看门狗2如何和队友联机T看门狗2手游下载免费CON(看门狗时钟控制寄存器)中设置,如下图:


                                            Tiny4412中断之看门狗

  今天的程序是使用watchdog来实现led灯的闪烁,下面贴出代码

 1 #ifndef __BUNFLY_H
 2 #define() __BUNFLY_H
 3
 4 #define ICCICR_CPU0        (*(volatile unsigned long *)0x10480000)
 5 #define ICCPMR_CPU0        (*(volatile unsigned long *)0x10480004)
 6 #define ICDDCR            (*(volatile unsigned long *)0x10490000)
 7 #define ICDIPR0_CPU0    (*(volatile unsigned long *)0x10490400)
 8 #define ICDIPTR0_CPU0    (*(volatile unsigned long *)0x10490800)
 9 #define ICDISER0_CPU0    (*(volatile unsigned long *)0x10490100)
10 #define ICDSGIR            (*(volatile unsigned long *)0x10490f00)
11 #define ICCEOIR_CPU0    (*(volatile unsigned long *)0x10480010)
12 #define ICCIAR_CPU0        (*(volatile unsigned long *)0x1048000c)
13 #define ICDIPR2_CPU0    (*(volatile unsigned long *)0x10490408)
14 #define ICDIPTR2_CPU0    (*(volatile unsigned long *)0x10490808)
15 #define ICDIPR3_CPU0    (*(volatile unsigned long *)0x1049040c)
16 #define ICDIPTR3_CPU0    (*(volatile unsigned long *)0x1049080c)
17 #define ICDIPR16_CPU0    (*(volatile unsigned long *)0x10490440)
18 #define ICDIPTR16_CPU0    (*(volatile unsigned long *)0x10490840)
19 #define ICDIPR18_CPU0    (*(volatile unsigned long *)0x10490448)
20 #define ICDIPTR18_CPU0    (*(volatile unsigned long *)0x10490848)
21 #define ICDISER2_CPU0    (*(volatile unsigned long *)0x10490108)
22
23 #define WTCON             (*(volatile unsigned long *)0x10060000)
24 #define WTDAT             (*(volatile unsigned long *)0x10060004)
25 #define WTCNT             (*(volatile unsigned long *)0x10060008)
26 #define WTCLRINT         (*(volatile unsigned long *)0x1006000C)
27
28 #define EXT_INT43CON    (*(volatile unsigned long *)0x11000e0c)
29 #define EXT_INT43_MASK    (*(volatile unsigned long *)0x11000f0c)
30 #define EXT_INT43_PEND    (*(volatile unsigned long *)0x11000f4c)
31 #define GPX3CON         (*(volatile unsigned long *)0x11000c60)
32
33 #define GPM4CON    (*(volatile unsigned long *)0x110002e0)
34 #define GPM4DAT (*(volatile unsigned long *)0x110002e4)
35
36 #endif    //__BUNFLY_H
  1 #include "bunfly.h"
  2
  3 void (*udelay)(int) = 0xc3e25f90;
  4 int (*printf)(char *, ...) = 0xc3e114d8;
  5 void enable_mmu();
  6 void init_table(unsigned long *addr);
  7 void memcpy(unsigned char *dest, unsigned char *src, int len);
  8 extern unsigned long  vector_start;
  9 void do_irq();
 10 void led_on();
 11 void led_off();
 12
 13 int main()
 14 {
 15     memcpy(0x70000000, vector_start, 0x1000);
 16     enable_mmu();
 17
 18     *(unsigned long *)0x47000000 = do_irq;
 19
 20     //step 1: set cpu permit interrupt
 21     __asm__ __volatile__(
 22         "mrs r0, cpsr\n"
 23         "bic r0,r0, #0x80\n"
 24         "msr cpsr, r0\n"
 25         :::"r0"
 26     );
 27
 28     //step 2: set GIC (cgi) enable
 29     ICCICR_CPU0 = 1; //中断总开关
 30     ICCPMR_CPU0 =0xff;//设置最低优先级(门槛)
 31     ICDDCR = 1; //本中断开关
 32     ICDIPR18_CPU0 = (100 << 24);//设置本中断优先级
 33     ICDIPTR18_CPU0 = (1 << 24);//选择指定的cpu进行中断处理
 34     ICDISER2_CPU0 = (1 << 11);//启用本中断
 35
 36     //step 3: set watch dog timer
 37     WTCNT = 32768;
 38     WTDAT = 32768;
 39     WTCON = (1 << 2) | (3 << 3) | (1 << 5) | (95 << 8);
 40
 41     printf("welcom back\n");
 42 }
 43
 44 void do_irq()
 45 {
 46     WTCLRINT = 0;//清中断
 47     printf("wang wang wang\n");
 48     static int flags = 1;
 49     if(flags) {
 50         led_on();
 51         flags = 0;
 52     }
 53     else {
 54         led_off();
 55         flags = 1;
 56     }
 57 }
 58
 59 void led_on()
 60 {
 61     GPM4CON &= ~0xffff;
 62     GPM4CON |= 0x1111;
 63     GPM4DAT &= ~0xf;
 64 }
 65
 66 void led_off()
 67 {
 68
 69     GPM4CON &= ~0xffff;
 70     GPM4CON |= 0x1111;
 71     GPM4DAT |= 0xf;
 72 }
 73
 74 void memcpy(unsigned char *dest, unsigned char *src, int len)
 75 {
 76     int i = 0;
 77     for(i = 0; i < len; i++) {
 78         dest[i] = src[i];
 79     }
 80 }
 81
 82 void enable_mmu()
 83 {
 84     /*构建*/
 85     unsigned long addr = 0x50000000;
 86     init_table(addr);
 87     /*打开mmu*/
 88     unsigned long mmu = 0;
 89     mmu = 1 | (1 << 1) | (1 << 3) | (1 << 8);
 90     __asm__ __volatile__ (
 91         "mov r0, #3\n"
 92         "MCR p15, 0, r0, c3, c0, 0\n"//设置为管理员
 93         "MCR p15, 0, %0, c2, c0, 0\n"//设置地址
 94         "MCR p15, 0, %1, c1, c0, 0\n"//开启mmu
 95         :
 96         :    "r" (addr), "r" (mmu)
 97         :
 98     );
 99
100 }
101
102 __asm__(
103
104 "vector: \n"
105 "    b reset\n"
106 "    b und\n"
107 "    b swi\n"
108 "    b pre_abt\n"
109 "    b data_abt\n"
110 "    .word 0x0\n"
111 "    b irq\n"
112 "    b fiq\n"
113 "reset:\n"
114 "und:\n"
115 "    mov sp, #0x47000000\n"
116 "    stmdb sp!, {r0-r12, lr}\n"
117
118 "    ldr r3, =0x47000004\n"
119 "    ldr r2, [r3]\n"
120 "    blx r2\n"
121
122 "    mov sp, #0x47000000\n"
123 "    ldmdb sp, {r0-r12, pc}^    \n"
124
125 "swi:\n"
126 "    mov sp, #0x47000000\n"
127 "    stmdb sp!, {r0-r12, lr}^\n"
128
129 "    mov sp, #0x47000000\n"
130 "    ldmdb sp, {r0-r12, pc}^    \n"
131
132 "pre_abt:\n"
133
134 "data_abt:\n"
135 "    mov sp, #0x47000000\n"
136 "    sub lr, lr, #4\n"
137 "    stmdb sp!, {r0-r12, lr}\n"
138
139 "    ldr r3, =0x47000008\n"
140 "    ldr r2, [r3]\n"
141 "    blx r2\n"
142
143 "    mov sp, #0x47000000\n"
144 "    ldmdb sp, {r0-r12, pc}^    \n"
145 "irq:\n"
146
147 "    mov sp, #0x47000000\n"
148 "    sub lr, lr, #4\n"
149 "    stmdb sp!, {r0-r12, lr}\n"
150
151 "    ldr r3, =0x47000000\n"
152 "    ldr r2, [r3]\n"
153 "    blx r2\n"
154
155 "    mov sp, #0x47000000\n"
156 "    ldmdb sp, {r0-r12, pc}^    \n"
157
158 "fiq:\n"
159
160     ".global vector_start\n"
161 "vector_start: \n"
162     ".word vector \n "
163
164 );
165
166 void init_table(unsigned long *addr)
167 {
168     unsigned long va = 0;
169     unsigned long phys = 0;
170
171     //0x40000000-0x80000000 -> 0x40000000-0x80000000    
172     for(va = 0x40000000; va < 0x80000000; va += 0x100000) {
173         phys = va;
174         addr[va >> 20] = phys | 2;
175     }
176
177     //0x10000000-0x14000000 -> 0x10000000-0x140000000    
178     for(va = 0x10000000; va < 0x14000000; va += 0x100000) {
179         phys = va;
180         addr[va >> 20] = phys | 2;
181     }
182     //0x10000000-0x14000000 -> 0x10000000-0x140000000    
183     for(va = 0x0; va < 0x10000000; va += 0x100000) {
184         phys = va + 0x70000000;
185         addr[va >> 20] = phys | 2;
186     }
187
188 }