一:看门狗(WDT watch dog timer)

  看门狗其实是一个计数器,它的作用就是防止程序陷入死循环或者程序运行跑飞;看门狗是一个硬件,它的工作原理是,初始化给他一个值,它会过一段时间减一,直到这个数减为0,它将会产生一个中断信号或者reset信号,致使我们系统复位,而又时候我们不想让它过一会儿就重启又想预防死机,那么我们就可以在这个数减到快要接进0的时候,给它重新赋值;这样就不会触发reset信号,但当程序跑飞时机器死机时,它就会减到零,进行操作系统复位;

  具体看下图所示:输入时钟为PCLK(该时钟频率等于系统的主频),它经过两级分频(Prescaler和frequency division factor),最后将分频后的时钟作为该定时器的输入时钟,当计数器期满后可以产生中断或者复位信号。

  看门狗计数器公式如下:

  t_watchdog = 1/( PCLK / (Prescaler value + 1) / Division_factor )

  通过tiny4412用户手册我们可以找到看门狗的中断号为75(如下图):

  预分频器Prescaler及分频因子Division factor的值在WTCON(看门狗时钟控制寄存器)中设置,如下图:

  今天的程序是使用watchdog来实现led灯的闪烁,下面贴出代码:

 #ifndef __BUNFLY_H
#define __BUNFLY_H #define ICCICR_CPU0 (*(volatile unsigned long *)0x10480000)
#define ICCPMR_CPU0 (*(volatile unsigned long *)0x10480004)
#define ICDDCR (*(volatile unsigned long *)0x10490000)
#define ICDIPR0_CPU0 (*(volatile unsigned long *)0x10490400)
#define ICDIPTR0_CPU0 (*(volatile unsigned long *)0x10490800)
#define ICDISER0_CPU0 (*(volatile unsigned long *)0x10490100)
#define ICDSGIR (*(volatile unsigned long *)0x10490f00)
#define ICCEOIR_CPU0 (*(volatile unsigned long *)0x10480010)
#define ICCIAR_CPU0 (*(volatile unsigned long *)0x1048000c)
#define ICDIPR2_CPU0 (*(volatile unsigned long *)0x10490408)
#define ICDIPTR2_CPU0 (*(volatile unsigned long *)0x10490808)
#define ICDIPR3_CPU0 (*(volatile unsigned long *)0x1049040c)
#define ICDIPTR3_CPU0 (*(volatile unsigned long *)0x1049080c)
#define ICDIPR16_CPU0 (*(volatile unsigned long *)0x10490440)
#define ICDIPTR16_CPU0 (*(volatile unsigned long *)0x10490840)
#define ICDIPR18_CPU0 (*(volatile unsigned long *)0x10490448)
#define ICDIPTR18_CPU0 (*(volatile unsigned long *)0x10490848)
#define ICDISER2_CPU0 (*(volatile unsigned long *)0x10490108) #define WTCON (*(volatile unsigned long *)0x10060000)
#define WTDAT (*(volatile unsigned long *)0x10060004)
#define WTCNT (*(volatile unsigned long *)0x10060008)
#define WTCLRINT (*(volatile unsigned long *)0x1006000C) #define EXT_INT43CON (*(volatile unsigned long *)0x11000e0c)
#define EXT_INT43_MASK (*(volatile unsigned long *)0x11000f0c)
#define EXT_INT43_PEND (*(volatile unsigned long *)0x11000f4c)
#define GPX3CON (*(volatile unsigned long *)0x11000c60) #define GPM4CON (*(volatile unsigned long *)0x110002e0)
#define GPM4DAT (*(volatile unsigned long *)0x110002e4) #endif //__BUNFLY_H
 #include "bunfly.h"

 void (*udelay)(int) = 0xc3e25f90;
int (*printf)(char *, ...) = 0xc3e114d8;
void enable_mmu();
void init_table(unsigned long *addr);
void memcpy(unsigned char *dest, unsigned char *src, int len);
extern unsigned long vector_start;
void do_irq();
void led_on();
void led_off(); int main()
{
memcpy(0x70000000, vector_start, 0x1000);
enable_mmu(); *(unsigned long *)0x47000000 = do_irq; //step 1: set cpu permit interrupt
__asm__ __volatile__(
"mrs r0, cpsr\n"
"bic r0,r0, #0x80\n"
"msr cpsr, r0\n"
:::"r0"
); //step 2: set GIC (cgi) enable
ICCICR_CPU0 = ; //中断总开关
ICCPMR_CPU0 =0xff;//设置最低优先级(门槛)
ICDDCR = ; //本中断开关
ICDIPR18_CPU0 = ( << );//设置本中断优先级
ICDIPTR18_CPU0 = ( << );//选择指定的cpu进行中断处理
ICDISER2_CPU0 = ( << );//启用本中断 //step 3: set watch dog timer
WTCNT = ;
WTDAT = ;
WTCON = ( << ) | ( << ) | ( << ) | ( << ); printf("welcom back\n");
} void do_irq()
{
WTCLRINT = ;//清中断
printf("wang wang wang\n");
static int flags = ;
if(flags) {
led_on();
flags = ;
}
else {
led_off();
flags = ;
}
} void led_on()
{
GPM4CON &= ~0xffff;
GPM4CON |= 0x1111;
GPM4DAT &= ~0xf;
} void led_off()
{ GPM4CON &= ~0xffff;
GPM4CON |= 0x1111;
GPM4DAT |= 0xf;
} void memcpy(unsigned char *dest, unsigned char *src, int len)
{
int i = ;
for(i = ; i < len; i++) {
dest[i] = src[i];
}
} void enable_mmu()
{
/*构建表*/
unsigned long addr = 0x50000000;
init_table(addr);
/*打开mmu*/
unsigned long mmu = ;
mmu = | ( << ) | ( << ) | ( << );
__asm__ __volatile__ (
"mov r0, #3\n"
"MCR p15, 0, r0, c3, c0, 0\n"//设置为管理员
"MCR p15, 0, %0, c2, c0, 0\n"//设置表的地址
"MCR p15, 0, %1, c1, c0, 0\n"//开启mmu
:
: "r" (addr), "r" (mmu)
:
); } __asm__( "vector: \n"
" b reset\n"
" b und\n"
" b swi\n"
" b pre_abt\n"
" b data_abt\n"
" .word 0x0\n"
" b irq\n"
" b fiq\n"
"reset:\n"
"und:\n"
" mov sp, #0x47000000\n"
" stmdb sp!, {r0-r12, lr}\n" " ldr r3, =0x47000004\n"
" ldr r2, [r3]\n"
" blx r2\n" " mov sp, #0x47000000\n"
" ldmdb sp, {r0-r12, pc}^ \n" "swi:\n"
" mov sp, #0x47000000\n"
" stmdb sp!, {r0-r12, lr}^\n" " mov sp, #0x47000000\n"
" ldmdb sp, {r0-r12, pc}^ \n" "pre_abt:\n" "data_abt:\n"
" mov sp, #0x47000000\n"
" sub lr, lr, #4\n"
" stmdb sp!, {r0-r12, lr}\n" " ldr r3, =0x47000008\n"
" ldr r2, [r3]\n"
" blx r2\n" " mov sp, #0x47000000\n"
" ldmdb sp, {r0-r12, pc}^ \n"
"irq:\n" " mov sp, #0x47000000\n"
" sub lr, lr, #4\n"
" stmdb sp!, {r0-r12, lr}\n" " ldr r3, =0x47000000\n"
" ldr r2, [r3]\n"
" blx r2\n" " mov sp, #0x47000000\n"
" ldmdb sp, {r0-r12, pc}^ \n" "fiq:\n" ".global vector_start\n"
"vector_start: \n"
".word vector \n " ); void init_table(unsigned long *addr)
{
unsigned long va = ;
unsigned long phys = ; //0x40000000-0x80000000 -> 0x40000000-0x80000000
for(va = 0x40000000; va < 0x80000000; va += 0x100000) {
phys = va;
addr[va >> ] = phys | ;
} //0x10000000-0x14000000 -> 0x10000000-0x140000000
for(va = 0x10000000; va < 0x14000000; va += 0x100000) {
phys = va;
addr[va >> ] = phys | ;
}
//0x10000000-0x14000000 -> 0x10000000-0x140000000
for(va = 0x0; va < 0x10000000; va += 0x100000) {
phys = va + 0x70000000;
addr[va >> ] = phys | ;
} }

Tiny4412中断之看门狗的更多相关文章

  1. linux内核中断之看门狗

    一:内核中断 linux内核中的看门狗中断跟之前的裸板的中断差不多,在编写驱动之前,需要线把内核自带的watch dog模块裁剪掉,要不然会出现错误:在Device Drivers /Watchdog ...

  2. STM32之独立看门狗与窗口看门狗总结

    一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...

  3. S3C2440看门狗解析

    个PCLK周期的复位信号 也就是说,在某些环境下,看门狗可以当做定时器使用,当他中断的时候并不发生复位,只发生中断,我看看图 看门狗的中断和复位信号是可以依靠wtcon来切断的(看门狗的时钟是无法切断 ...

  4. STM32之独立看门狗(IWDG)与窗口看门狗(WWDG)总结

    一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...

  5. nano100B的看门狗讲解

    看门狗定时器的用途是在软件出问题时执行系统复位功能,这可以防止系统无限期地挂起.除此之外,看门狗定时器还支持将CPU 从掉电模式唤醒的功能.看门狗定时器包含一个18 位的自由运行计数器,定时溢出间隔可 ...

  6. STM32(10)——窗口看门狗

    简介: 窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障.除非递减计数器的值在 T6 位 (WWDG->CR 的第六位)变成 0 ...

  7. STM32窗口看门狗和独立看门狗的区别,看门狗介绍及代码演示

    一.介绍: STM32看门狗分为独立看门狗和窗口看门狗两种,其两者使用调条件如下所示, IWDG和WWDG两者特点如下图所示: 独立看门狗的手册资料: 窗口看门狗的手册资料:             ...

  8. 【单片机】CH32V103C8T6 ——窗口看门狗

    本章教程通过串口调试助手打印显示程序运行状态,具体现象如下: 若计数器值在上窗口值和下窗口值0X40之间的时候,进行喂狗操作,计数器重新计数,程序正常运行,串口打印显示:The program run ...

  9. MSP430的看门狗常见用法以及中断函数的书写方法

    今天下午看了一下MSP430的看门狗的基本用法 看门狗是为了防止程序跑飞而设定的,但是由于看门狗是一个类似于定时器,因此可以把他当作定时器来使用 示例代码:用看门狗定时器使一个led闪烁 #inclu ...

随机推荐

  1. AngularJS进阶(三)HTML:让表单、文本框只读,不可编辑的方法

    HTML:让表单.文本框只读,不可编辑的方法 有时候,我们希望表单中的文本框是只读的,让用户不能修改其中的信息,如使<input type="text" name=" ...

  2. Linux的常用命令(2) - 关机

    关机命令 shutdown‑h now 立即进行关机 shutdown‑r now 现在重新启动计算机 -t sec : -t后面加秒数,即"过几秒后关机" -k      : 不 ...

  3. 用jquery+Asp.Net实现省市二级联动

    页面html: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ddlAjax. ...

  4. 增量会话对象——DeltaSession

    在集群环境中为了使集群中各个节点的会话状态都同步,同步操作是集群重点解决的问题,一般来说有两种同步策略,其一是每次同步都把整个会话对象传给集群中其他节点,其他节点更新整个会话对象:其二是对会话中增量修 ...

  5. Android特效专辑(十)——点击水波纹效果实现,逻辑清晰实现简单

    Android特效专辑(十)--点击水波纹效果实现,逻辑清晰实现简单 这次做的东西呢,和上篇有点类似,就是用比较简单的逻辑思路去实现一些比较好玩的特效,最近也是比较忙,所以博客更新的速度还得看时间去推 ...

  6. fastDFS与Java整合上传下载

    由于项目需要整合个文件管理,选择使用的是fastDFS. 整合使用还是很方便的. 准备 下载fastdfs-client-java源码 源码地址 密码:s3sw 修改pom.xml 第一个plugin ...

  7. jquery左右折叠框

    网站左右折叠框: <!DOCTYPE html> <html> <style> #Kefclose,#Kefopen{position:absolute;left: ...

  8. 如何在Visual Studio 2017中使用C# 7+语法

    前言 之前不知看过哪位前辈的博文有点印象C# 7控制台开始支持执行异步方法,然后闲来无事,搞着,搞着没搞出来,然后就写了这篇博文,不喜勿喷,或许对您有帮助. 在Visual Studio 2017配置 ...

  9. 深入了解Map

    联系 Java中的Map类似于OC的Dictionary,都是一个个键值对组成,一键对应一值.我在之前的文章中讲解过Set,其实在JAVA底层Set依赖的也是Map,那我们都知道,Set是单列的(只有 ...

  10. 大型B2C网站高性能可伸缩架构技术探秘

    大型B2C网站高性能可伸缩架构技术探秘 2010-07-21 08:51 狂放不羁 JavaEye 字号:T | T 向您介绍大型B2C网站高性能的网站架构技术,包括缓存的使用.应用程序和数据库的拆分 ...