打印
[ZLG-ARM]

LPC213X ucos-II 中断处理的改进

[复制链接]
2350|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
枯竹|  楼主 | 2008-4-8 17:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我使用LPC2136做了一个项目,使用的是ZLG提供的UCOS-II V2.52的模板。其中用到了LPC2136的2个串口,波特率为115200。在调试测序时,发现串口总是莫名其妙的丢失数据,溢出标志置位。本来FIFO触发字符个数为8,后改触发字符个数为1时故障依然。经过调试后发现,当多个中断同时触发时,CPU来不及处理所致。分析中断部分源程序,发现每次中断服务程序退出时,都要查找一次最高优先级的任务,完成一次任务的切换,中断处理比较耗时,针对这个问题,我修改了部分代码,使程序在执行完所有的被挂起的中断后再进行任务的查找和切换。程序改进后效果明显,没再出现数据丢失的现象。我把我的经验和教训写在这里,希望给大家以借鉴,少走弯路,避免出现和我一样的问题。
另外,当改动STARTUP.S的启动代码时,一定要确保异常向量表的累加和为零!!!!

相关帖子

沙发
枯竹|  楼主 | 2008-4-8 17:50 | 只看该作者

一部分代码

INT32U InstallHandler(INT32U routine, INT8U vector, INT8U channel, INT8U irq_mode)
{
    INT32U old_routine;
    volatile INT32U    *addr;
    
    addr = (volatile INT32U *)&VICVectAddr0;
    old_routine = addr[vector];
    if (vector > 15 || channel > 20)
        return old_routine;        
    
    addr[vector] = routine;
    addr = (volatile INT32U *)&VICVectCntl0;
    addr[vector] = 0x20 | channel;
    if (FIQ_MODE == irq_mode)
        VICIntSelect |= (1 << channel);
    VICIntEnable = 1 << channel;
    
    return old_routine;
}


void IRQ_Def_Exception(void)
{    
    //VICVectAddr = 0;                   // change it to your code  ÕâÒ»¾äÌ滻Ϊ×Ô¼ºµÄ´úÂë
}

        void VICInit(void)
{
    //extern void IRQ_Handler(void);
    //extern void Timer0_Handler(void);
    unsigned long *vec_addr;
    unsigned long *ctr_addr;
    unsigned char i;

    
    vec_addr = (unsigned long *)&VICVectAddr0;
    ctr_addr = (unsigned long *)&VICVectCntl0;
    VICIntEnClr = 0xffffffff;
    VICDefVectAddr = (uint32)IRQ_Def_Exception;
    VICVectAddr = 0;
    for (i=0; i<16; i++)
    {
        *vec_addr = (unsigned long)IRQ_Def_Exception;
        *ctr_addr = 0;
        vec_addr++;
        ctr_addr++;
    }
 }


typedef  void  (*BSP_PFNCT)(void);



/*********************************************************************************************************/
void IRQ_Handle_Exception (void)
{
    BSP_PFNCT    pfnct;
    while(1)
    {
        pfnct = (BSP_PFNCT)VICVectAddr;
        //VICVectAddr =  0;
        if (pfnct != (BSP_PFNCT)0)
        {
            pfnct ();
            VICVectAddr =  0;
            if (pfnct == IRQ_Def_Exception)
            {
                break;
            }
        }
        else
        {
            VICVectAddr =  0;
            break;
        }
    }    
}

使用特权

评论回复
板凳
lhzw2001| | 2008-4-15 18:52 | 只看该作者

LZ能不能做个详细点的说明呢?

使用特权

评论回复
地板
ljt8015| | 2012-7-1 10:19 | 只看该作者
发现每次中断服务程序退出时,都要查找一次最高优先级的任务,完成一次任务的切换.

能不能将 别的中断服务退出时的任务切换  取消掉么?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

4

帖子

0

粉丝