开发环境与平台

开发板:粤嵌的GEC210开发板
处理器:s5pv210
处理器内核:Cortex-A8
开发环境:Keil4

看门狗的作用与本质

当嵌入式系统运行时受到外部干扰或者系统错误,程序有时会出现死机或“跑飞”,导致整个系统瘫痪。在对系统稳定性要求较高的场合,为了防止这一现象的发生,需要“看门狗”(WATCHDOG)的电路。看门狗的作用就是当系统死机或“跑飞”时,恢复系统的运行。

看门狗本质上是定时器电路,通过设定倒计时时间产生复位信号。在倒计时信号结束前进行"喂狗"就不会产生复位信号。当系统发生死机或者跑飞的情况,势必执行不了喂狗的操作,一旦倒计时结束就会产生复位信号,系统就会复位而不是一直系统系统移植崩溃下去,从而保证了系统的稳定性。


S5PV210看门狗的功能

android 10 触发看门狗 arm 看门狗_android 10 触发看门狗

1、定时器功能

可以作为常规定时器使用,它是一个十六位的定时器,并且可以产生中断,中断名为WDT。

2、复位功能(即看门狗的功能)

作为看门狗定时器使用,当时钟计数减为0(超时)时,它将产生一个复位信号。


S5PV210看门狗结构

android 10 触发看门狗 arm 看门狗_#include_02


看门狗工作原理图示:

android 10 触发看门狗 arm 看门狗_android 10 触发看门狗_03


S5PV210看门狗定时时间的计算

看门狗定时器溢出一次的时间主要跟一下因素有关:
1、预分频器
8位,取值为0-255
2、再分频器
取值为16、32、64、128。

看门狗定时器溢出一次的时间
t_wdg=1 / (PCLK/(Prescaler+1) / Division factor)。

Prescaler为预分频器的值,Division factor为再分频器的值

上面看门狗定时器溢出一次的时间还不是最终的时间。看门狗最终的定时周期为

T =  WDGDAT  *   t_wdg

WDGDAT 为看门狗数据寄存器的值。


S5PV210相关寄存器

1、看门狗控制寄存器

android 10 触发看门狗 arm 看门狗_寄存器_04


2、看门狗计数寄存器

android 10 触发看门狗 arm 看门狗_#include_05


3、看门狗数据寄存器

android 10 触发看门狗 arm 看门狗_看门狗_06


4、看门狗中断清除寄存器

android 10 触发看门狗 arm 看门狗_android 10 触发看门狗_07


实验

利用S5PV210看门狗定时器产生4s的定时,4S内如果按键K1按下,修改WTCNT的值避免计数器溢出(喂狗),否则系统重启。


编程

s5pv210.h:

//看门狗相关寄存器定义
typedef struct 
{
	unsigned int WTCON;
	unsigned int WTDAT;
	unsigned int WTCNT;
	unsigned int WTCLRINT;
}wtdog;
#define WDG (*(volatile wtdog *)0xE2700000)

watchdog.c:

#include "s5pv210.h"
#include "watchdog.h"

#define FOUR_SEC_WDG  1        //设置看门狗4S喂狗

//看门狗初始化
void WD_init(void)
{
#if FOUR_SEC_WDG
	WDG.WTCNT = 0xF424;	
	WDG.WTDAT = 0xF424;		  //设置看门狗重装载寄存器值为62500	* 0.000064s = 4s 
	WDG.WTCON = 0x00004131;	  //初始化看门狗的分频系数65、再分频系数为64(最终频率为1/64 MHZ)、使能看门狗定时器	
#else
	WDG.WTCNT = 0x7a12;	
	WDG.WTDAT = 0x7a12;		  //设置看门狗重装载寄存器值为31250	* 0.000064s = 2s 
	WDG.WTCON = 0x00004131;	  //初始化看门狗的分频系数、再分频系数、使能看门狗定时器
#endif 
	
}

//喂狗
void feed_dog(void)	
{
#if FOUR_SEC_WDG
	WDG.WTCNT = 0xF424;	 //	62500	* 0.000064s = 4s 
#else 
	WDG.WTCNT = 0x7a12;	 // 31250	* 0.000064s = 2s 
#endif
}

main.c:

#include "watchdog.h"
#include "clock.h"
#include "led.h"
#include "key.h"
#include "beep.h"
#include "delay.h"

void Main(void)
{
	clock_init();
	key_init();
	led_init();
	led_on_off();
	WD_init();
	
	for(;;)
	{
		if(key_Scan() == 1)
		{
			feed_dog();
		
		}
	}
}

实验主要通过灯的亮灭指示系统的看门狗定时器的溢出导致系统复位,当一直按下按键喂狗时系统就不会复位,灯也就会长亮。


注意事项:

在手册可以查看如下一段话:
an initial value must be written to the watchdog timer count(WTCNT) register, before the watchdog timer starts
意思是初始化看门狗计数寄存器一定要在看门狗启动之前。所以不能启动看门狗之后再初始化看门狗计数寄存器。