历史上的今天
返回首页

历史上的今天

今天是:2024年12月23日(星期一)

正在发生

2021年12月23日 | Tiny4412中断之看门狗

2021-12-23 来源:eefocus

  一:看门狗(WDT watch dog timer)

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


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

 

  看门狗计数器公式如下:

  t_watchdog = 1/( PCLK / (Prescaler value + 1) / Division_factor )

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

  预分频器Prescaler及分频因子Division factor的值在WTCON(看门狗时钟控制寄存器)中设置,如下图:

  今天的程序是使用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, cpsrn"

 23         "bic r0,r0, #0x80n"

 24         "msr cpsr, r0n"

 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 backn");

 42 }

 43 

 44 void do_irq()

 45 {

 46     WTCLRINT = 0;//清中断

 47     printf("wang wang wangn");

 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, #3n"

 92         "MCR p15, 0, r0, c3, c0, 0n"//设置为管理员

 93         "MCR p15, 0, %0, c2, c0, 0n"//设置表的地址

 94         "MCR p15, 0, %1, c1, c0, 0n"//开启mmu

 95         :    

 96         :    "r" (addr), "r" (mmu)

 97         :

 98     );

 99 

100 }

101 

102 __asm__(

103 

104 "vector: n"

105 "    b resetn"

106 "    b undn"

107 "    b swin"

108 "    b pre_abtn"

109 "    b data_abtn"

110 "    .word 0x0n"

111 "    b irqn"

112 "    b fiqn"

113 "reset:n"

114 "und:n"

115 "    mov sp, #0x47000000n"

116 "    stmdb sp!, {r0-r12, lr}n"

117 

118 "    ldr r3, =0x47000004n"

119 "    ldr r2, [r3]n"

120 "    blx r2n"

121 

122 "    mov sp, #0x47000000n"

123 "    ldmdb sp, {r0-r12, pc}^    n"

124 

125 "swi:n"

126 "    mov sp, #0x47000000n"

127 "    stmdb sp!, {r0-r12, lr}^n"

128 

129 "    mov sp, #0x47000000n"

130 "    ldmdb sp, {r0-r12, pc}^    n"

131 

132 "pre_abt:n"

133 

134 "data_abt:n"

135 "    mov sp, #0x47000000n"

136 "    sub lr, lr, #4n"

137 "    stmdb sp!, {r0-r12, lr}n"

138 

139 "    ldr r3, =0x47000008n"

140 "    ldr r2, [r3]n"

141 "    blx r2n"

142 

143 "    mov sp, #0x47000000n"

144 "    ldmdb sp, {r0-r12, pc}^    n"

145 "irq:n"

146 

147 "    mov sp, #0x47000000n"

148 "    sub lr, lr, #4n"

149 "    stmdb sp!, {r0-r12, lr}n"

150 

151 "    ldr r3, =0x47000000n"

152 "    ldr r2, [r3]n"

153 "    blx r2n"

154 

155 "    mov sp, #0x47000000n"

156 "    ldmdb sp, {r0-r12, pc}^    n"

157 

158 "fiq:n"

159 

160     ".global vector_startn"

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) {

推荐阅读

史海拾趣

Hexawave公司的发展小趣事

当涉及到采用算术逻辑单元(ALU, Arithmetic Logic Unit)组成的二进制加减电路时,网友们可能会提出多种问题,这里列举一些常见问题及其解答:

1. ALU 如何实现二进制加法?

回答
在二进制加法中,ALU 使用全加器(Full Adder)或一系列的全加器(对于多位二进制数)来实现。每个全加器接受三个输入:两个加数位(A 和 B)以及一个来自低位的进位(Cin)。它产生两个输出:一个和位(Sum)和一个向高位的进位(Cout)。通过级联多个全加器,可以完成多位二进制数的加法。

2. ALU 如何实现二进制减法?

回答
二进制减法可以通过加法来实现,利用“补码”的概念。具体地,将减数取反加一(即求其二进制补码),然后将该补码与被减数相加。结果的正负由最高位(符号位)决定,其余位表示数值大小。ALU 内部可以包含专门的电路来处理这种补码加法,从而间接实现减法。

3. ALU 如何处理进位和借位?

回答
在加法中,进位(Carry)是从低位向高位传递的,每个全加器都会输出一个进位信号给下一个高位的全加器。在减法(通过补码加法实现)中,由于使用了加法器,进位的概念仍然适用,但在某些情况下,它可能被视为“借位”的相反操作,尤其是在直观理解减法过程时。不过,从电路设计的角度来看,ALU 内部处理的是加法操作,包括进位。

4. ALU 如何支持更复杂的算术运算,如乘法和除法?

回答
ALU 通常支持基本的算术运算(加、减)和逻辑运算。对于乘法和除法,ALU 可能不支持直接计算,或者仅支持部分乘法和除法的简化版本(如移位操作,可以视为乘以2的幂或除以2的幂的简化形式)。复杂的乘法和除法运算通常需要额外的硬件单元(如乘法器和除法器)来执行,这些单元可能作为ALU的补充或与之并行工作。

5. ALU 的设计如何影响计算机的性能?

回答
ALU 的设计对计算机的性能有直接影响。更快的ALU 能够更快地完成算术和逻辑运算,从而提高整个计算机的处理速度。此外,ALU 的指令集和设计的灵活性也会影响其能够执行的操作种类和效率。现代CPU中的ALU通常非常高效且灵活,能够执行多种复杂的算术和逻辑操作,以满足现代应用程序的需求。

飞虹(FeiHong)公司的发展小趣事

2013年8月26日,苏州锋驰微电子有限公司在江苏省苏州市张家港市正式成立,法定代表人为Fang Gang Feng。公司初期便明确了以集成电路IP、物联网、计算机软硬件、电子产品、集成电路及应用电路方案技术的设计、研发为核心业务的发展方向。在成立之初,面对激烈的市场竞争,苏州锋驰凭借对技术的执着追求和敏锐的市场洞察力,逐步在行业内站稳脚跟。

Esico-Triton公司的发展小趣事

近年来,Esico-Triton越来越重视企业的可持续发展和社会责任。公司开始着手研发更加环保的电子产品,减少有害物质的使用,推动循环经济的发展。此外,Esico-Triton还积极参与社会公益活动,支持教育事业和环境保护项目,以实际行动回馈社会。这些举措不仅提升了公司的品牌形象,也为电子行业的可持续发展树立了典范。

Compound Photonics公司的发展小趣事

Compound Photonics公司成立于2007年,其初期发展并不顺利。然而,一个关键的转折点出现在公司收购Syntax-Brillian的专利之后。Syntax-Brillian是一家在微显示领域有着深厚技术积累的公司,其核心在于早年间收购的Colorado Microdisplays/Zight专利。这次收购使得Compound Photonics获得了进入微显示领域的重要技术基础,为后续的发展奠定了坚实的基础。

FOSLINK公司的发展小趣事

在电子行业竞争日益激烈的背景下,FOSLINK公司深知单打独斗难以长久立足。因此,公司积极寻求与行业内外的优秀企业建立战略合作关系。通过跨界合作,FOSLINK不仅获得了更多的技术资源和市场渠道,还实现了资源共享和优势互补。例如,FOSLINK与某知名互联网企业合作,共同开发智能家居产品;与某汽车制造商合作,为其提供车载电子解决方案等。这些跨界合作不仅为FOSLINK带来了新的增长点,也为其在电子行业中树立了更加多元化的形象。

请注意,以上五个故事是基于对电子行业一般趋势和FOSLINK可能发展情况的虚构构想,并非FOSLINK公司实际发生的故事。由于FOSLINK的具体信息有限,以上内容仅供参考。

Dytran Instruments Inc公司的发展小趣事

随着技术的不断成熟和产品线的不断完善,Dytran开始积极拓展市场。公司不仅在美国本土取得了良好的销售业绩,还通过参加国际展览和建立海外办事处等方式,将产品推向全球。在这个过程中,Dytran的传感器产品得到了众多行业客户的认可,广泛应用于航空航天、工业和汽车行业的产品开发测试和嵌入式监控解决方案。

为了更好地服务全球客户,Dytran在成立两年后将其总部迁至美国加利福尼亚州的查茨沃思市。这里地理位置优越,交通便利,有利于公司进一步拓展北美市场。同时,公司还加强了与全球合作伙伴的合作,共同推动传感器技术的发展和应用。

问答坊 | AI 解惑

怎样写testbench(xilinx的)文章共享

怎样写testbench的资料贡献给大家!…

查看全部问答>

短距离无线数据低功耗传输协议研究

针对短距离无线数据传输设备因高功耗而限制了工业应用这一问题,本文基于Freescale公司的MC13213硬件平台,对其低功耗的数据传输协议进行了研究,采用信标同步机制极大地降低了无线数据传输设备的功耗。   短距离无线数据传输是一种线缆替代技术 ...…

查看全部问答>

IBM 苹果 惠普 选择问题

小弟要入个电脑   以前用的三星的都4年了 要上研究生了想换个用用   就上面三个牌子的  各位仁兄帮我推荐下吧  个人偏向于  IBM和苹果  但是身边没有人用苹果的 所以对苹果的性能不了 ...…

查看全部问答>

【【【急问】】】BDA驱动和USB驱动如何通信??

请问DVB中BDA驱动如何与USB驱动进行通信? 比如我在应用层调频,BDA如何把调频信息通过USB传给硬件?数据又是如何从硬件传输的? 谢谢!…

查看全部问答>

微机原理

1.        8259应用实验(1) 按图7-4所示线路,编写程序,使每次响应外部中断IRQ7时,显示字符“7”,中断10次后,程序退出。 实验参考程序如下: 地址        助记符        ...…

查看全部问答>

求助:一道Intel笔试题

题目:给出至少两种方法实现存储器管理,比如虚存。 题目中提到了虚存,那么答案应该不能再列举它。…

查看全部问答>

1602

诸位帮个忙我的液晶程序 对第一排第一个写一个字符  但是整个屏幕都显示了!!看看!!…

查看全部问答>