LPCARM中断喂狗正确方法及异常模拟裸奔程序详解
其他
3945 人阅读
|
1 人回复
|
2007-08-09
TA的每日心情 | 无聊 2015-2-5 09:31 |
|---|
签到天数: 1 天 连续签到: 1 天 [LV.1]初来乍到
童生
- 积分
- 66
|
[table=98%,#cccccc][tr][td]雁塔菜农 发表于 2006-12-26 21:36:00 [/td][/tr][tr][td][table=98%][tr][td]/*-----------------------------------------------------------------------------------------------------------
????????? LPCARM中断喂狗正确方法及异常模拟裸奔程序详解(别名ARM疯狗)
雁塔菜农HotPower?? 2006.12.26 21:32?? 于菜地Http://HotPower.21ic.org/
------------------------------------------------------------------------------------------------------------*/
#i nclude ?//ARM菜鸟HotPower创建定义文件(最新为倒塌版)
/*---------------------------------------------------------------------------------
注意:(今天是菜农时代伟人的113年诞辰日,特发此帖!!!)
? (姊妹篇--LPCARM主程序喂狗正确方法及异常模拟裸奔程序详解)---随后发布
菜农累了,不想多费口舌,先自己看明白吧。欢迎拍砖有利于菜农进一步改进
参见N驳"中断喂狗缺点论"http://bbs.21ic.com/club/bbs/ShowAnnounce.asp?id=2385486
LPC213XDEF.H文件请在user1/46/archives/2006/16994.html下载
可将LPC213XDEF.H拷贝到Keil\ARM\INC\PHILIPS目录下
点击下栽本裸奔程序详解完整包:uploadfile-/2006-12/1226389582.rar
----------------------------------------------------------------------------------*/
/*---------------------------------------------------------
??????? 时钟参数定义
---------------------------------------------------------*/
#define Fosc 11059200
#define Fcclk (Fosc * 4)
#define Fcco (Fcclk * 4)
#define Fpclk (Fcclk / 4) * 1
/*---------------------------------------------------------
??????? 申请系统变量
---------------------------------------------------------*/
__noinit__ volatile unsigned int PFCount;//申请掉电计数器(复位不初始化)
__noinit__ volatile unsigned int WdtCount;//申请软狗计数器(复位不初始化)
__noinit__ volatile unsigned int MainLoopAddr;//主程序循环地址寄存器(用于模拟主程序飞后的随机地址)
__noinit__ volatile unsigned int SystemRamTest;//RAM不初始化(用于判别是否是首次上电或内存完好情况)
/*---------------------------------------------------------
??????? 系统函数声明
---------------------------------------------------------*/
void SystemInit(void);//系统初始化
void VicInit(void);//向量中断初始化
void PortInit(void);//IO初始化
void Timer0Init(void);//定时器初始化
void KeyInit(void);//键盘初始化
void VicIntSetup(void);//向量中断设置
void Enable_WDT(unsigned int);//使能看门狗(并设置复位参数)
void Reset_WDT(void);//复位看门狗(首次实际是启动看门狗)
void MainLoop(void);
void __swi(0) Enable_IRQ(void);//开放向量中断总开关
void __SWI_0????? (void) {
int tmp;
? __asm
? {
??? MRS tmp, SPSR
??? BIC tmp, tmp, #0x80
??? MSR SPSR_c, tmp
? }
}
void __swi(1) Disable_IRQ(void);//关闭向量中断总开关
void __SWI_1?????? (void) {
int tmp;
? __asm
? {
??? MRS tmp, SPSR
??? ORR tmp, tmp, #0x80
??? MSR SPSR_c, tmp
? }
}
void __swi(2) Enable_FIQ(void);//开放快速中断总开关
void __SWI_2????? (void) {
int tmp;
? __asm
? {
??? MRS tmp, SPSR
??? BIC tmp, tmp, #0x40
??? MSR SPSR_c, tmp
? }
}
void __swi(3) Disable_FIQ(void);//关闭快速中断总开关
void __SWI_3?????? (void) {
int tmp;
? __asm
? {
??? MRS tmp, SPSR
??? ORR tmp, tmp, #0x40
??? MSR SPSR_c, tmp
? }
}
void __swi(4) Enable_VIC(void);//开放对VIC的写入保护
void __SWI_4????? (void) {
? VIC-> rotection = 0;//开放对VIC的写入保护
}
#define Disable_VIC() VIC-> rotection = 1;//关闭在用户级对VIC的一些写操作,保护在用户级VIC不被以外改写
/*----------------------------------------------------------------------
?? 外部中断0异常处理程序(按P0.1关闭定时器0,使定时器0中断不能喂硬狗!)
----------------------------------------------------------------------*/
extern void FIQ_EINT0 (void) __irq
{
? T0->TIMER_TCR &= ~0x01;//关闭定时器0(使定时器0中断不能喂狗)
? VIC->SoftIntClr = (1 EXT_INT = (1 VectAddr = 0;
}
/*-----------------------------------------------------------------------------
?? 外部中断1异常处理程序(按P0.3改写定时器0中断地址,使定时器0中断不能喂硬狗!)
------------------------------------------------------------------------------*/
void IRQ_EINT1 (void) __irq
{
? VIC->VectAddrs[2] = (unsigned int)PFCount;//修改中断服务程序地址,制造中断程序飞
? VIC->SoftIntClr = (1 EXT_INT = (1 VectAddr = 0;
}
/*----------------------------------------------------------------------------
?? 外部中断2异常处理程序(按P0.7改写主循环地址,定时器0中断正常也不能喂硬狗!)
-----------------------------------------------------------------------------*/
void IRQ_EINT2 (void) __irq
{
? MainLoopAddr = (unsigned int)T0->TIMER_TC;//修改主循环程序地址,制造主程序飞
? VIC->SoftIntClr = (1 EXT_INT = (1 VectAddr = 0;
}
/*----------------------------------------------------------------------
?????? 定时器0中断
----------------------------------------------------------------------*/
void IRQ_Timer0 (void) __irq
{
? if (WdtCount > 0) {//说明主程序在运行中,即程序正常。
??? WdtCount = 0;//软狗计数器复位
??? Reset_WDT();//复位看门狗,首次实际是启动看门狗
? }
? T0->TIMER_IR = 0x01;//清除中断标志,相当于VIC->IRQStatus &= ~(1 SoftIntClr = (1 VectAddr = 0x00;??//通知VIC中断处理结束
}
/*----------------------------------------------------------------------
?????? 系统默认中断处理
----------------------------------------------------------------------*/
void IRQ_Default (void) __irq
{
unsigned int status;
? status = VIC->IRQStatus | VIC->FIQStatus;//合并2种中断一起处理
? switch(status) {
??? case (1 EXT_INT = (1 SoftIntClr = (1 IODIR??????? = 0x00000000;//设置P0口为输入
? P1->IODIR??????? = 0x00000000;//设置P1口为输入
}
/*----------------------------------------------------------------------
???? 定时器初始化函数
----------------------------------------------------------------------*/
void Timer0Init(void)
{
? T0->TIMER_TC?? = 0;???//时器设置为0
? T0->TIMER_PR?? = 0;???//时钟不分频
? T0->TIMER_MCR? = 0x03;??//设置T0MR0匹配后复位T0TC,并产生中断标志
? T0->TIMER_MR0? = Fpclk / 200;?//5mS定时
? T0->TIMER_TCR? = 0x01;??//启动定时器
? T0->TIMER_IR?? = 0x01;??//清除中断标志
}
/*----------------------------------------------------------------------
???? 向量中断设置函数
----------------------------------------------------------------------*/
void VicIntSetup(void)
{
unsigned int i;
? VIC->VectCntls[0] = VICIntSel_Enable | VICIntSel_EINT1;//设置外部中断1分配VIC最高优先级
? VIC->VectAddrs[0] = (unsigned int)IRQ_EINT1;//设置中断服务程序地址
? VIC->IntEnable |= (1 VectCntls[1] = VICIntSel_Enable | VICIntSel_EINT2;//设置外部中断2分配VIC次优先级
? VIC->VectAddrs[1] = (unsigned int)IRQ_EINT2;//设置中断服务程序地址
? VIC->IntEnable |= (1 VectCntls[2] = VICIntSel_Enable | VICIntSel_Time0;//设置定时器0中断通道分配最高优先级
? VIC->VectAddrs[2] = (unsigned int)IRQ_Timer0;//设置中断服务程序地址
? VIC->IntEnable |= (1 IntSelect?? = (1 DefVectAddr = (unsigned int)IRQ_Default;//定义除VIC->VectAddrs[0]~VIC->VectAddrs[15]外的中断函数
?
? for (i = 0; i < 16; i ++) {
??? if ((VIC->VectCntls & VICIntSel_Enable) == 0) {//该中断向量未使能
?? VIC->VectAddrs = (unsigned int)IRQ_Default;//全部以默认中断来处理
//?? VIC->VectAddrs = (unsigned int)0;//全部以复位来处理
?}
? }
? INTCON->EXT_INT = (1 |
|
|
|
|
|
|
|
|
TA的每日心情 | 衰 2013-2-8 09:34 |
|---|
签到天数: 2 天 连续签到: 1 天 [LV.1]初来乍到
秀才
- 积分
- 335
|
沙发
什么是什么
发表于 2007-8-9 18:22:16
|
只看该作者
RE:LPCARM中断喂狗正确方法及异常模拟裸奔程序详解
|
|
|
|
|
|
|
|