查看: 3786|回复: 1

LPCARM中断喂狗正确方法及异常模拟裸奔程序详解

[复制链接]
  • TA的每日心情
    无聊
    2015-2-5 09:31
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2007-8-9 17:46:11 | 显示全部楼层 |阅读模式
    分享到:
    [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-&gtrotection = 0;//开放对VIC的写入保护
    }
    #define Disable_VIC() VIC-&gtrotection = 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]初来乍到

    发表于 2007-8-9 18:22:16 | 显示全部楼层

    RE:LPCARM中断喂狗正确方法及异常模拟裸奔程序详解

    老大,你这题目名字好过分啊
    呵呵
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-11-25 10:37 , Processed in 0.139789 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.