GNU ARM汇编--(八)s3c2440的watchdog

来源:互联网 发布:ubuntu 宽带测速 编辑:程序博客网 时间:2024/06/06 09:52

GNU ARM汇编--(八)s3c2440的watchdog 

http://blog.csdn.net/dndxhej/article/details/7694193

从单片机起,watchdog就是必不可少的.在各种应用环境中,程序很可能跑飞或死掉,这时候就需要通过watchdog来保证整个系统重新恢复到正常状态.

        照旧,给出s3c2440的datasheet说明:

概述:
    watchdog timer用于由于噪声或者系统错误引起的程序跑飞了的情况下恢复处理器的正常操作.它可以被用作一个可以请求中断服务的普通16bit的内部定时器.watchdog timer产生128 PCLK的重启信号.
特点:
    有中断请求的普通内部定时器模式
    当定时器计数为0(超时)时,产生内部的长达128PCLK周期的重启信号


watchdog timer的操作:
    F18-1显示watchdog timer的功能框图.watchdog timer只使用PCLK作为它的时钟源.PCLK先由一个8bit的prescaler进行分频,接下来还会再次分频.


    Prescaler的值和分频因子由watchdog timer控制寄存器(WTCON)决定.有效的预分频值的范围是(0--2^8-1),因为是8bit的分频器.分频因子可选为16,32,64,128.


WTDAT&WTCNT
    一旦watchdog timer启用了,watchdog timer数据寄存器(WTDAT)的值不会自动的重新加载到计数寄存器(WTCNT).所以,在watchdog timer启动前一定要向watchdog timer的计数寄存器(WTCNT)中写入一个初始值.


watchdog timer special registers
WTCON
    WTCON允许user打开或关闭watchdog timer,从4个不同的源中选择时钟信号,开关中断以及开关watchdog timer的输出.watchdog timer用来s3c2440启动后的重启,如果不想处理器重启,watchdog timer要被禁用.在loader开始时,watchdog timer又没初始化的时候,应该将watchdog timer禁用.
    如果user想使用watchdog timer提供的正常定时器功能,那就打开中断,关闭watchdog timer.
Register   Address     R/W               Description            Reset Value
WTCON      0x53000000  R/W    Watchdog timer control register      0x8021
                                    Bit                  Descrition                        Initial State
Prescaler value         [15:8]     预分频的值(0--255)                        0x80
Watchdog timer           [5]        watchdog timer的开关位                1(开)
Clock select               [4:3]      时钟分频因子 00:16 01:32               00
                              10:64 11:128
Interrupt generation     [2]       中断的开关位                                     0
Reset enable/diaable   [0]       输出重启信号的开关                         1


WTDAT
    WTDAT用来指定超时的期限.在最开始的操作中WTDAT的值不会自动的加载到计数器中.使用初始值0x8000就可以驱动第一次超时.以后的话,WTDAT的值就会自动重加载到WTCNT中.
Register         Address       R/W            Description                        Reset Value
WTDAT        0x53000004  R/W    Watchdog timer data register        0x8000
                                    Bit                Description                 Initial State
Count reload value    [15:0]         重加载的计数值                 0x8000


WTCNT
    WTCNT包含正常操作下watchdog timer的当前计数值.值得注意的是,在watchdog timer最初被启用的时候,WTDAT的内容不会自动的加载到WTCNT中,所以WTCNT一定要给一个初始值.
Register     Address     R/W            Description                                   Reset Value
WTCNT        0x53000008  R/W    Watchdog timer count register          0x8000
                                 Bit                Description               Initial State
Count value          [15:0]           定时器的当前计数值        0x8000


        我们先将watchdog的输出重启信号的开关关掉,将中断打开,把watchdog timer当一个普通的定时器来用.设计如下:

[cpp] view plaincopyprint?
  1. /* 
  2. watchdog timer with disable reset 
  3. copyleft@  dndxhej@gmail.com 
  4. */  
  5.   
  6. .equ   NOINT, 0xc0  
  7.   
  8. .equ    GPBCON, 0x56000010      @led  
  9. .equ    GPBDAT, 0x56000014      @led  
  10. .equ   GPBUP,        0x56000018    @led  
  11. .equ    GPFCON, 0x56000050      @interrupt config  
  12. .equ    EINTMASK, 0x560000a4  
  13. .equ    EXTINT0,  0x56000088  
  14. .equ    EXTINT1,  0x5600008c  
  15. .equ    EXTINT2,  0x56000090  
  16. .equ    INTMSK,  0x4A000008  
  17. .equ   EINTPEND,     0x560000a8  
  18.   
  19. .equ    SUBSRCPND,  0x4a000018   
  20. .equ    INTSUBMSK,  0x4a00001c  
  21.   
  22.   
  23.   
  24. .equ   SRCPND,   0X4A000000  
  25. .equ   INTPND,   0X4A000010  
  26.   
  27.   
  28.   
  29.   
  30. .equ GPB5_out,  (1<<(5*2))    
  31. .equ GPB6_out,  (1<<(6*2))    
  32. .equ GPB7_out,  (1<<(7*2))    
  33. .equ GPB8_out,  (1<<(8*2))    
  34.         
  35. .equ GPBVALUE,    (GPB5_out | GPB6_out | GPB7_out | GPB8_out)    
  36.   
  37. .equ    LOCKTIME, 0x4c000000  
  38. .equ    MPLLCON, 0x4c000004  
  39. .equ    UPLLCON, 0x4c000008  
  40. .equ    M_MDIV, 92  
  41. .equ   M_PDIV, 1  
  42. .equ    M_SDIV, 1  
  43. .equ    U_MDIV, 56  
  44. .equ   U_PDIV, 2  
  45. .equ    U_SDIV, 2  
  46.   
  47. .equ    CLKDIVN, 0x4c000014  
  48. .equ    DIVN_UPLL, 0  
  49. .equ    HDIVN,  1  
  50. .equ    PDIVN,  1    @FCLK : HCLK : PCLK = 1:2:4  
  51.   
  52.   
  53. .equ    WTCON,  0x53000000  
  54. .equ    Pre_scaler,  249  
  55. .equ    wd_timer,   1  
  56. .equ    clock_select,   00   @316  
  57. .equ    int_gen,    1     @开中断  
  58. .equ    reset_enable,   0  @关掉重启信号  
  59.   
  60. .equ    WTDAT,0x53000004  
  61. .equ    Count_reload,50000    @定时器定为2S PCLK = 100M   PCLK/(Pre_scaler+1)/clock_select = 100M/(249+1)/16=25k   50000/25k=2s  
  62.   
  63. .equ    WTCNT,0x53000008  
  64. .equ    Count,50000  
  65.   
  66.   
  67.   
  68.   
  69.   
  70. .global _start  
  71. _start:     b   reset  
  72.         ldr     pc, _undefined_instruction  
  73.         ldr     pc, _software_interrupt  
  74.         ldr pc, _prefetch_abort  
  75.         ldr pc, _data_abort  
  76.         ldr pc, _not_used  
  77.         @b  irq  
  78.         ldr     pc, _irq  
  79.         ldr     pc, _fiq  
  80.   
  81.   
  82.   
  83. _undefined_instruction:     .word undefined_instruction  
  84. _software_interrupt:        .word software_interrupt  
  85. _prefetch_abort:        .word prefetch_abort  
  86. _data_abort:            .word data_abort  
  87. _not_used:          .word not_used  
  88. _irq:               .word irq  
  89. _fiq:               .word fiq  
  90.   
  91. .balignl 16,0xdeadbeef  
  92.   
  93. reset:  
  94.   
  95.   
  96.     ldr     r3, =WTCON  
  97.     mov r4, #0x0                       
  98.     str r4, [r3]    @ disable watchdog      
  99.   
  100.     ldr r0, =GPBCON  
  101.     ldr r1, =0x15400  
  102.     str r1, [r0]  
  103.   
  104.     ldr r2, =GPBDAT  
  105.     ldr r1, =0x160  
  106.     str r1, [r2]  
  107.   
  108.     bl clock_setup  
  109.     bl delay  
  110.   
  111.   
  112.     msr cpsr_c, #0xd2 @进入中断模式  
  113.     ldr sp, =3072 @中断模式的栈指针定义  
  114.   
  115.     msr cpsr_c, #0xd3 @进入系统模式  
  116.     ldr sp, =4096 @设置系统模式的栈指针  
  117.   
  118. @--------------------------------------------  
  119.   
  120.     ldr r0, =GPBUP  
  121.     ldr r1, =0x03f0    
  122.     str r1, [r0]        
  123.      
  124.     ldr r0, =GPFCON  
  125.     ldr r1, =0x2ea@0x2      
  126.     str r1, [r0]    
  127.   
  128.     ldr r0, =EXTINT0  
  129.     @ldr    r1, =0x8f888@0x0@0x8f888      @~(7|(7<<4)|(7<<8)|(7<<16))   //低电平触发中断  
  130.     ldr r1, =0xafaaa@0x0@0x8f888      //下降沿触发中断   
  131.     str r1, [r0]    
  132.   
  133.     ldr r0, =EINTPEND  
  134.     ldr r1, =0xf0@0b10000  
  135.     str r1, [r0]    
  136.   
  137.     ldr r0, =EINTMASK  
  138.     ldr r1, =0x00@0b00000  
  139.     str r1, [r0]    
  140.   
  141.   
  142.   
  143.     ldr r0, =SRCPND  
  144.     ldr r1, =0x3ff@0x1@0b11111  
  145.     str r1, [r0]    
  146.   
  147.     ldr r0, =SUBSRCPND  
  148.     ldr r1, =0x1<<13  
  149.     str r1, [r0]    
  150.   
  151.     ldr r0, =INTPND  
  152.     ldr r1, =0x3ff@0x1@0b11111  
  153.     str r1, [r0]    
  154.   
  155.     ldr r0, =INTSUBMSK  
  156.     ldr r1, =0x0<<13  
  157.     str r1, [r0]    
  158.   
  159.     ldr r0, =INTMSK  
  160.     ldr r1, =0xfffff000@0b00000  
  161.     str r1, [r0]    
  162.   
  163.     MRS r1, cpsr  
  164.     BIC r1, r1, #0x80  
  165.     MSR cpsr_c, r1  
  166.   
  167.   
  168.     bl     main  
  169.   
  170. irq:  
  171.     sub     lr,lr,#4  
  172.     stmfd   sp!,{r0-r12,lr}  
  173.   
  174.   
  175.     bl irq_isr  
  176.     ldmfd  sp!,{r0-r12,pc}^   
  177.   
  178.   
  179. irq_isr:  
  180.   
  181.     ldr r2, =GPBDAT  
  182.     ldr r1, =0x0e0  
  183.     str r1, [r2]  
  184.   
  185.   
  186.          ldr r0,=EINTPEND  
  187.          ldr r1,=0xf0  
  188.          str r1,[r0]   
  189.   
  190.     ldr r0, =SRCPND  
  191.     ldr r1, =0x3ff@0b11111  
  192.     str r1, [r0]    
  193.   
  194.     ldr r0, =SUBSRCPND  
  195.     ldr r1, =0x1<<13  
  196.     str r1, [r0]    
  197.   
  198.     ldr r0, =INTPND  
  199.     ldr r1, =0x3ff@0b11111  
  200.     str r1, [r0]    
  201.   
  202.     mov pc,lr  
  203.   
  204.   
  205. delay:  
  206.       
  207.     ldr r3,=0xffffff  
  208.   
  209. delay1:  
  210.     sub r3,r3,#1  
  211.   
  212.     cmp r3,#0x0  
  213.   
  214.     bne delay1  
  215.   
  216.     mov pc,lr  
  217.   
  218.   
  219. clock_setup:  
  220.   
  221.     ldr r0,=LOCKTIME  
  222.     ldr r1,=0xffffffff  
  223.     str r1, [r0]  
  224.   
  225.     ldr r0,=CLKDIVN  
  226.     ldr r1,=(DIVN_UPLL<<3) | (HDIVN<<1) | (PDIVN<<0)  
  227.     str r1, [r0]  
  228.   
  229.     ldr r0,=UPLLCON  
  230.     ldr r1,=(U_MDIV<<12) | (U_PDIV<<4) | (U_SDIV<<0)   @Fin=12M  UPLL=48M  
  231.     str r1, [r0]  
  232.     nop  
  233.     nop  
  234.     nop  
  235.     nop  
  236.     nop  
  237.     nop  
  238.     nop  
  239.     ldr r0,=MPLLCON  
  240.     ldr r1,=(M_MDIV<<12) | (M_PDIV<<4) | (M_SDIV<<0)    @Fin=12M  FCLK=400M  
  241.     str r1, [r0]  
  242.   
  243.   
  244.   
  245.     mov pc,lr  
  246.   
  247.   
  248. main:  
  249.   
  250.     ldr r0, =WTDAT  
  251.     ldr r1, =Count_reload  
  252.     str r1, [r0]  
  253.   
  254.     ldr r0, =WTCNT  
  255.     ldr r1, =Count  
  256.     str r1, [r0]  
  257.   
  258.     ldr r0, =WTCON  
  259.     ldr r1, =(Pre_scaler<<8) | (wd_timer<<5) | (clock_select<<3) | (int_gen<<2) | (reset_enable)  
  260.     str r1, [r0]  
  261. ledloop:  
  262.   
  263.     ldr r1,=0x1c0  
  264.     str r1,[r2]  
  265.     bl delay  
  266.   
  267.     ldr r1,=0x1a0  
  268.     str r1,[r2]  
  269.     bl delay  
  270.   
  271.     ldr r1,=0x160  
  272.     str r1,[r2]  
  273.     bl delay  
  274.   
  275.     ldr r1,=0x0e0  
  276.     str r1,[r2]  
  277.     bl delay  
  278.   
  279.     b ledloop  
  280.   
  281.   
  282.   
  283.   
  284. undefined_instruction:  
  285.             nop  
  286. software_interrupt:  
  287.             nop  
  288. prefetch_abort:   
  289.             nop  
  290. data_abort:  
  291.             nop  
  292. not_used:  
  293.             nop  
  294. fiq:  
  295.             nop  

        程序实现的是:一个正常的流水灯,定时器每隔2s触发一次中断,中断处理中点亮第四个LED.

        稍微该一下上面的代码:

.equ    int_gen,    0     @关中断
.equ    reset_enable,   1  @打开重启信号

打开重启信号,则可以看到每隔2s系统就重启一次.

如果在循环中加入:

ldrr0, =WTCNT     @喂狗
ldr r1, =Count
str r1, [r0]

那么,这又是一个标准的流水灯了.而且是有watchdog保护的流水灯了.


0 0
原创粉丝点击