ARM S3C2410 看门狗设置原理及源码

时间:2021-12-17 14:45:08

s3c2410 watchdog的操作 

对于s3c2410的watchdog来说,PCLK是它唯一的时钟信号源。 
s3c2410用了3个寄存器对watchdog进行操作,3个寄存器分别为:WTCON,WTDAT,WTCNT。
WTCON:watchdog控制寄存器 
WTDAT:watchdog数据寄存器 
WTCNT:watchdog记数寄存器 




Watchdog根据PCLK,Prescaler Value,Clock Select会产生一个watchdog自己的工作周期, t_watchdog= 1/ (PCLK / (Prescaler value + 1) / Division_factor)我们把这个工作周期记为,watchdog在一个 t_watchdog周期结束时会产生一个记数递减信号,每当这个信号产生时,WTCNT中的值便减1,若在WTCNT递减为0(Timer Out)的时候软件层还没有重新往WTCNT中写入数值(喂狗),则watchdog触发Reset Signal,系统重起。 


根据上述的描述,我们可以更形象地描述watchdog的工作原理和3个寄存器之间的相互关系: 

WTCNT通过WTDAT得到一个值,watchdog在每个t_watchdog周期里向WTCNT发送一个递减信号,当WTCNT的值递减到0的时候则发生time out,重而重起系统。 

1:void enable_watchdog() 
2:{ 
3:                rWTCON=0x7F81; 
4:                rWTDAT=0x8000; 
5:                rWTCON|=1<<5; 
6:} 

rWTCON,rWTDAT分别为寄存器WTCON,WTDAT的地址解引用,我如下定义他们 

#define        rWTCON                (*(volatile unsigned int *)0x53000000) 
#define        rWTDAT                (*(volatile unsigned int *)0x53000004) 


从上面的设置我们可知寄存器WTCON的值为0x7F81,分解出来得: 

Prescaler Value               =255 
Division_factor                =16(Clock Select=16) 
Interrupt Generation       =0(不产生中断) 
Reset                            =1(开启Reset Signal) 

注1:事实上,WTDAT和WTCNT这两个寄存器在系统上电之后会被硬件自动的填入两个初始值0x8000,开启watchdog之后, WTCNT并没有马上就把WTDAT中的值装入,而是使用初始值0x8000。在发生第一次time out之后,WTDAT寄存器中的值才会被真正的装载进WTCNT寄存器中 

Prescaler Value位于寄存器WTCON的8至15位,其值为0~255 
Division_factor由寄存器WTCON中的3~4位(Clock Select)决定,其值可以为00,01,10,11分别代表Division_factor的值为16,32,64,128 

关于各个寄存器的详细信息请参考s3c2410的操作手册 

看门狗应用程序的设计流程: 

1设置看门狗中断操作,包括全局中断,看门狗使能,看门狗中断向量的定义 

2看门狗WTCON的设计,其中包括预分频因子,分频器的分频值,中断使能和复位使能 

3对看门狗寄存器WTDAT和看门狗计数寄存器WTCON的设置 

4启动看门狗定时器


S3C2410 看门狗只要有两个功能

1、作为常规时钟,并且可以产生中断

2、作为看门狗定时器使用,当时钟减到0时(超时),它将产生一个128个时钟(PLCK)的时钟信号。

 

看门狗的设置:

1、 看门狗的外部时钟源是有PLCK提供的, plck 通过预分频 和 与比例因子 产生适合看门狗的时钟。

    t_watchdog = 1/[PLCK/(prescale value +1)/division_factor]

    上面就是它的计算公式。

2、相关寄存器的介绍

  WTCON watchdog控制寄存器

  看门狗控制寄存器能够禁止或者允许看门狗时钟,从四个不同的时钟源中挑选时钟信号,允许或禁止中断,并且能允许或禁止看门狗时钟输出。如果用户想要使用看门狗作为普通时钟,应该中断使能,禁止看门狗定时器复位。

 

  WTDAT――看门狗定时器数据寄存器
  WTDAT 用于设置看门狗定时器的超时时间值,在初始化看门狗过程中,WTDAT 的值不会自动加载到定时计数器中,首次使用定时器超时值为其初始值即0x8000,以后该寄存器的值会被自动加载到WTCNT 寄存器中。


  WTCNT――看门狗定时器计数寄存器

  WTCNT 为看门狗定时器工作的时间计数器的当前计数值,注意在初始化看门狗操作后,看门狗数据寄存器(WTDAT)的值不能自动装到看门狗计数寄存器(WTCNT)中,所以看门狗被允许之前应该初始化看门狗计数寄存器的值。

 

实验程序
  由于看门狗是对系统的复位或者中断的操作,所以不需要外围的硬件电路。要实现看门狗的功能,只需要对看门狗的寄存器组进行操作。即对看门狗的控制寄存器(WTCON)、看门狗数据寄存器(WTDAT)、看门狗计数寄存器(WTCNT)的操作。
  设计流程如下:
  1.设置看门狗中断操作,包括全局中断和看门狗中断的使能,看门狗中断向量的定义。频值、中断使能和复位使能等。
  2.对看门狗数据寄存器(WTDAT)和看门狗计数寄存器(WTCNT)的设置。
  3.启动看门狗定时器。

 

 

主功能函数

view plain
  1. int Main(void)  
  2. {  
  3. ChangeClockDivider(1,1);  
  4. ChangeMPllValue(0xa1,0x3,0x1);  
  5. Port_Init();  
  6. Uart_Select(0);  
  7. Uart_Init(0,115200);  
  8. Uart_Printf("watchdog test is beginning/n");  
  9. watchdog_test();  
  10. while(1);  
  11. }  
  12. 看门狗复位功能程序实现  
  13. void watchdog_test(void)  
  14. {  
  15. //Prescaler value=100; lock division factor=128 ;PCLK=67.5MHz  
  16. //t_watchdog=1/[PCLK/(Prescaler value+1)/Division_factor]=0.0002  
  17. //disable watchdog  
  18. rWTCON=((100<<8)|(3<<3));  
  19. // 看门狗时钟周期T=WTCNT*t_watchdog=3S  
  20. //看门狗喂狗  
  21. rWTDAT=15000;  
  22. rWTCNT=15000;  
  23. //disable watchdog interrupt  
  24. rWTCON &= ~(3<<1);  
  25. //enable Watchdog timer;reset signal.  
  26. rWTCON|=((1<<5)|(1<<0));  
  27. while(1);  
  28. }   

 看门狗定时器功能程序实现

view plain
  1. void watchdog_test(void)  
  2. {  
  3. {  
  4. //initialize interrupt registers  
  5. ClearPending(BIT_WDT);  
  6. //建立WatchDog 中断  
  7. pISR_WDT=(unsigned)watchdog_int;  
  8. //Prescaler value=100、clock division factor=128  
  9. //t_watchdog=1/[PCLK/(Prescaler value+1)/Division_factor]=0.00025856  
  10. //disable watchdog  
  11. rWTCON=((100<<8)|(3<<3));  
  12. // 看门狗时钟周期T=WTCNT*t_watchdog=4S  
  13. //看门狗喂狗  
  14. rWTDAT=15000;  
  15. rWTCNT=15000;  
  16. rWTCON|=((1<<5)|(1<<2));//enable Watchdog timer ang watchdog interrupt  
  17. //rWTCON|=((1<<5)|(1<<2)|1);//watchdog 复位,时间间隔为4S。  
  18. rWTCON|=(1<<5)|(1<<2);//每4S watchdog 一次中断。  
  19. // 设置watchdog 为IRQ 中断模式  
  20. rINTMOD&=0xFFFFFDFF;  
  21. //开中断  
  22. EnableIrq(BIT_WDT);  
  23. while(f_ucSencondNo<11);  
  24. }  
  25. /**** watchdog_int ****/  
  26. void __irq watchdog_int(void)  
  27. {  
  28. //清除中断  
  29. ClearPending(BIT_WDT);  
  30. f_ucSencondNo++;  
  31. if(f_ucSencondNo<11)  
  32. Uart_Printf("%ds",f_ucSencondNo);  
  33. else  
  34. {  
  35. //mask watchdog timer interrupt  
  36. DisableIrq(BIT_WDT);  
  37. Uart_Printf("watch dog is ok/n");