GNU ARM汇编--(八)s3c2440的watchdog
来源:互联网 发布:淘宝祛痘产品 编辑:程序博客网 时间:2024/06/06 09:44
从单片机起,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当一个普通的定时器来用.设计如下:
/*watchdog timer with disable resetcopyleft@ dndxhej@gmail.com*/.equ NOINT, 0xc0.equ GPBCON,0x56000010 @led.equGPBDAT,0x56000014 @led.equ GPBUP, 0x56000018 @led.equ GPFCON, 0x56000050 @interrupt config.equEINTMASK, 0x560000a4.equ EXTINT0, 0x56000088.equ EXTINT1, 0x5600008c.equ EXTINT2, 0x56000090.equINTMSK, 0x4A000008.equ EINTPEND, 0x560000a8.equSUBSRCPND, 0x4a000018 .equINTSUBMSK, 0x4a00001c.equ SRCPND, 0X4A000000.equ INTPND, 0X4A000010.equ GPB5_out, (1<<(5*2)) .equ GPB6_out, (1<<(6*2)) .equ GPB7_out, (1<<(7*2)) .equ GPB8_out, (1<<(8*2)) .equ GPBVALUE, (GPB5_out | GPB6_out | GPB7_out | GPB8_out) .equLOCKTIME, 0x4c000000.equMPLLCON, 0x4c000004.equUPLLCON, 0x4c000008.equM_MDIV, 92.equ M_PDIV, 1.equM_SDIV, 1.equU_MDIV, 56.equ U_PDIV, 2.equU_SDIV, 2.equCLKDIVN, 0x4c000014.equDIVN_UPLL, 0.equHDIVN,1.equPDIVN,1 @FCLK : HCLK : PCLK = 1:2:4.equ WTCON, 0x53000000.equ Pre_scaler, 249.equ wd_timer, 1.equ clock_select, 00 @316.equ int_gen, 1 @开中断.equ reset_enable, 0 @关掉重启信号.equ WTDAT,0x53000004.equ Count_reload,50000 @定时器定为2S PCLK = 100M PCLK/(Pre_scaler+1)/clock_select = 100M/(249+1)/16=25k 50000/25k=2s.equ WTCNT,0x53000008.equ Count,50000.global _start_start:bresetldr pc, _undefined_instructionldr pc, _software_interruptldrpc, _prefetch_abortldrpc, _data_abortldrpc, _not_used@birqldr pc, _irqldr pc, _fiq_undefined_instruction:.word undefined_instruction_software_interrupt:.word software_interrupt_prefetch_abort:.word prefetch_abort_data_abort:.word data_abort_not_used:.word not_used_irq:.word irq_fiq:.word fiq.balignl 16,0xdeadbeefreset:ldr r3, =WTCONmovr4, #0x0 strr4, [r3]@ disable watchdog ldrr0, =GPBCONldrr1, =0x15400strr1, [r0]ldrr2, =GPBDATldrr1, =0x160strr1, [r2]bl clock_setupbl delay msr cpsr_c, #0xd2 @进入中断模式 ldr sp, =3072 @中断模式的栈指针定义 msr cpsr_c, #0xd3 @进入系统模式 ldr sp, =4096 @设置系统模式的栈指针@--------------------------------------------ldrr0, =GPBUPldrr1, =0x03f0 strr1, [r0] ldrr0, =GPFCONldrr1, =0x2ea@0x2 strr1, [r0] ldrr0, =EXTINT0@ldrr1, =0x8f888@0x0@0x8f888 @~(7|(7<<4)|(7<<8)|(7<<16)) //低电平触发中断ldrr1, =0xafaaa@0x0@0x8f888 //下降沿触发中断strr1, [r0] ldrr0, =EINTPENDldrr1, =0xf0@0b10000strr1, [r0] ldrr0, =EINTMASKldrr1, =0x00@0b00000strr1, [r0] ldrr0, =SRCPNDldrr1, =0x3ff@0x1@0b11111strr1, [r0] ldrr0, =SUBSRCPNDldrr1, =0x1<<13strr1, [r0] ldrr0, =INTPNDldrr1, =0x3ff@0x1@0b11111strr1, [r0] ldrr0, =INTSUBMSKldrr1, =0x0<<13strr1, [r0] ldrr0, =INTMSKldrr1, =0xfffff000@0b00000strr1, [r0] MRS r1, cpsrBIC r1, r1, #0x80MSR cpsr_c, r1bl mainirq:sub lr,lr,#4stmfdsp!,{r0-r12,lr}bl irq_isrldmfd sp!,{r0-r12,pc}^ irq_isr:ldrr2, =GPBDATldrr1, =0x0e0strr1, [r2] ldr r0,=EINTPEND ldr r1,=0xf0 str r1,[r0] ldrr0, =SRCPNDldrr1, =0x3ff@0b11111strr1, [r0] ldrr0, =SUBSRCPNDldrr1, =0x1<<13strr1, [r0] ldrr0, =INTPNDldrr1, =0x3ff@0b11111strr1, [r0] mov pc,lrdelay:ldr r3,=0xffffffdelay1:sub r3,r3,#1cmp r3,#0x0bne delay1mov pc,lrclock_setup:ldr r0,=LOCKTIMEldr r1,=0xffffffffstr r1, [r0]ldr r0,=CLKDIVNldr r1,=(DIVN_UPLL<<3) | (HDIVN<<1) | (PDIVN<<0)str r1, [r0]ldr r0,=UPLLCONldr r1,=(U_MDIV<<12) | (U_PDIV<<4) | (U_SDIV<<0) @Fin=12M UPLL=48Mstr r1, [r0]nopnopnopnopnopnopnopldr r0,=MPLLCONldr r1,=(M_MDIV<<12) | (M_PDIV<<4) | (M_SDIV<<0) @Fin=12M FCLK=400Mstr r1, [r0]mov pc,lrmain:ldrr0, =WTDATldrr1, =Count_reloadstrr1, [r0]ldrr0, =WTCNTldrr1, =Countstrr1, [r0]ldrr0, =WTCONldrr1, =(Pre_scaler<<8) | (wd_timer<<5) | (clock_select<<3) | (int_gen<<2) | (reset_enable)strr1, [r0]ledloop:ldr r1,=0x1c0str r1,[r2]bl delayldr r1,=0x1a0str r1,[r2]bl delayldr r1,=0x160str r1,[r2]bl delayldr r1,=0x0e0str r1,[r2]bl delayb ledloopundefined_instruction:nopsoftware_interrupt:nopprefetch_abort:nopdata_abort:nopnot_used:nopfiq:nop
程序实现的是:一个正常的流水灯,定时器每隔2s触发一次中断,中断处理中点亮第四个LED.
稍微该一下上面的代码:
.equ int_gen, 0 @关中断
.equ reset_enable, 1 @打开重启信号
打开重启信号,则可以看到每隔2s系统就重启一次.
如果在循环中加入:
ldrr0, =WTCNT @喂狗
ldr r1, =Count
str r1, [r0]
那么,这又是一个标准的流水灯了.而且是有watchdog保护的流水灯了.
- GNU ARM汇编--(八)s3c2440的watchdog
- GNU ARM汇编--(八)s3c2440的watchdog
- GNU ARM汇编--(八)s3c2440的watchdog
- GNU ARM汇编--(九)s3c2440的PWM
- GNU ARM汇编--(十)s3c2440的RTC
- GNU ARM汇编--(九)s3c2440的PWM
- GNU ARM汇编--(十)s3c2440的RTC
- GNU ARM汇编--(十)s3c2440的RTC
- GNU ARM汇编--(六)s3c2440的时钟控制
- GNU ARM汇编--(七)s3c2440的串口控制
- GNU ARM汇编--(六)s3c2440的时钟控制
- GNU ARM汇编--(七)s3c2440的串口控制
- GNU ARM汇编--(六)s3c2440的时钟控制
- GNU ARM汇编--(七)s3c2440的串口控制
- ARM汇编和Gnu汇编的转换
- ARM汇编和Gnu汇编的转换
- GNU GAS (GNU ARM汇编)
- 从arm 到 gnu 的汇编转换
- android 内存泄露 小结
- Hibernate入门BLOG[十五、Hibernate的乐观锁与悲观锁]
- js操作table
- UIImageView详解
- linux的swapper_pg_dir的初始化
- GNU ARM汇编--(八)s3c2440的watchdog
- BMP文件格式详解
- Android的EidtText的一些研究,持续更新中!!!!!
- android源码解析 ---- camera 照相机 摄像机
- 多线程写图像文件的一点小测试(Boost + Gual)
- android notification
- Dialog背景透明无边框
- Component MSCOMCTL.OCX or one of its dependencies not currently registered
- 使用vc++建立一个utility工程