看门狗(watch dog timer 看门狗定时器)。大家想象这样一个场景:家门口有一只狗,这个狗定时会饿(譬如说 2 小时一饿),够饿了会胡乱咬死人。人进进出出要想保证安全必须提前喂狗(必须在上次喂过后的2小时内喂狗才行)。如果超时没喂狗就会被咬死,如果提前喂狗没关系,但是本次喂狗时间就会从这里开始计算。
现实中因为一些外部因素,电子设备经常会跑飞或者死机(譬如极端炎热、极端寒冷、工业复杂场合)。在这种情况下我们希望设备自动复位而不需要人工干预(无人值守)。看门狗用来完成这个工作。看门狗其实是我们 SoC 内部的一个定时器(类似于闹钟,类似于门口的狗),定好时间之后看门狗定时器会去计时,时间到之前(狗饿了之前)必须去重新置位看门狗定时器(喂狗),如果没有喂狗则系统会被强制复位。
系统在正常工作时,系统软件会自己去喂狗,所以看门狗定时器不会复位。但是系统一旦故障跑飞啥的,看门狗就没人喂了,然后下一个周期就会自动复位,达到我们期望的效果。
物理特性上看门狗其实是个定时器(跟现实中的闹钟类似),硬件上就是SoC内部的一个内部外设。
原理图:看门狗不用分析原理图,因为看门狗属于内部外设,且没有外部相关的原件与他有关,所以不需要原理图分析,原理图上根本找不到和看门狗有关的地方。
数据手册:在数据手册的Section7.3。
WTCON(0xE2700000),其中bit5是看门狗的开关:0代表关,1代表开
root@ubuntu:/home/aston/workspace/git_xxxx# cat led.S
/** 文件名: led.S* 作者: xxx* 描述: 演示汇编关闭看门狗 */#define GPJ0CON 0xE0200240
#define GPJ0DAT 0xE0200244 #define WTCON 0xE2700000.global _start //解决 make 编译警告: arm-linux-ld: warning: cannot find entry symbol _start; defaulting to 00000000// 把 _start 链接属性改为外部,这样其他文件就可以看见 _start 了
_start://第 1 步,关看门狗(向 WTCON 的 bit5 写入 0 即可)ldr r0, =WTCONldr r1, =0x0str r1, [r0]//之后的为功能代码//第一步: 把所有引脚设置成输出模式 ldr r0, =0x11111111 //从后面的 = 可以看出用的是 ldr 伪指令,因为需要编译器来判断这个数ldr r1, =GPJ0CON //是合法立即数还是非法立即数,一般写代码都用 ldr 伪指令str r0, [r1] // 寄存器间接寻址。功能是把 r0 中的数写入到 r1 中的数为地址的内存中去//要实现流水灯,只要在主循环中实现 1 圈的流水显示效果即可
flash://第 1 步: 点亮 LED1, 其他熄灭ldr r0, =~(1 << 3) ldr r1, =GPJ0DATstr r0, [r1] //把 0 写入到 GPJ0DAT 寄存器中,引脚即输出低电平,LED 点亮//然后延时bl delay // 使用 bl 进行函数调用//第 2 步: 点亮 LED2, 其他熄灭ldr r0, =~(1 << 4) ldr r1, =GPJ0DATstr r0, [r1] //把 0 写入到 GPJ0DAT 寄存器中,引脚即输出低电平,LED 点亮//然后延时bl delay // 使用 bl 进行函数调用//第 3 步: 点亮 LED3, 其他熄灭ldr r0, =~(1 << 5) ldr r1, =GPJ0DATstr r0, [r1] //把 0 写入到 GPJ0DAT 寄存器中,引脚即输出低电平,LED 点亮//然后延时bl delay // 使用 bl 进行函数调用b flashb . // . 代表当前这一句指令的地址,这个就是高大上的死循环//延时函数
delay:ldr r2, =10000000ldr r3, =0x0
delay_loop:sub r2, r2, #1 // r2 = r2 -1cmp r2, r3 // cmp 会影响 z 标志位,如果 r2 等于 r3 则 z =1,下一句中 eq 就会成立bne delay_loopmov pc, lr // 函数调用返回
为什么要关看门狗?
源自朱有鹏老师.