这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » ucos,ii ucos-ii中断结构及中断嵌套的问题

共2条 1/1 1 跳转至

ucos,ii ucos-ii中断结构及中断嵌套的问题

院士
2006-09-17 18:14:16     打赏
ucos,ii ucos-ii中断结构及中断嵌套的问题



关键词: ucos-ii     中断     结构     嵌套     问题    

院士
2006-12-22 22:43:00     打赏
2楼
ucos-ii中断结构及中断嵌套的问题
中断处理流程
   1:IRQ中断发生后调用UCOS_IRQHandler()
   2:UCOS_IRQHandler()先压栈
   3:后调用OSIntEnter()
   4:根据IRQ偏移量查找处理函数
   5:用户中断处理函数
   6:OSIntExit()
   7:如果发生中断切换调用INTCTXSW否则恢复现场至中断前任务
代码如下:
UCOS_IRQHandler
   stmfd sp!,{r0-r12,lr}

        bl OSIntEnter
        bl C_IRQHandler
        bl OSIntExit

        ldr r0,=OSIntCtxSwFlag  调用OSIntCtxSw后置1
        ldr r1,[r0]
        cmp r1,#1
        beq _IntCtxSw

        ldmfd sp!,{r0-r12,lr}
        subs pc,lr,#4
_IntCtxSw
        mov r1,#0
        str r1,[r0]

        ldmfd sp!,{r0-r12,lr}
        stmfd sp!,{r0-r3}
        mov r1,sp
        add sp,sp,#16
        sub r2,lr,#4

        mrs r3,spsr
        orr r0,r3,#NOINT
        msr spsr_c,r0

        ldr r0,=.+8
        movs pc,r0

        stmfd sp!,{r2}              ; push old task's pc
        stmfd sp!,{r4-r12,lr}       ; push old task's lr,r12-r4
        mov r4,r1                   ; Special optimised code below
        mov r5,r3
        ldmfd r4!,{r0-r3}
        stmfd sp!,{r0-r3}           ; push old task's r3-r0
        stmfd sp!,{r5}              ; push old task's psr
        mrs r4,spsr
        stmfd sp!,{r4}              ; push old task's spsr
        
        ; OSPrioCur = OSPrioHighRdy
        ldr r4,=OSPrioCur
        ldr r5,=OSPrioHighRdy
        ldrb r5,[r5]
        strb r5,[r4]
        
        ; Get current task TCB address
        ldr r4,=OSTCBCur
        ldr r5,[r4]
        str sp,[r5]                 ; store sp in preempted tasks's TCB

        bl OSTaskSwHook             ; call Task Switch Hook

        ; Get highest priority task TCB address
        ldr r6,=OSTCBHighRdy
        ldr r6,[r6]
        ldr sp,[r6]                 ; get new task's stack pointer

        ; OSTCBCur = OSTCBHighRdy
        str r6,[r4]                 ; set new current task TCB address

        ldmfd sp!,{r4}              ; pop new task's spsr
        msr SPSR_cxsf,r4
        ldmfd sp!,{r4}              ; pop new task's psr
        msr CPSR_cxsf,r4

        ldmfd sp!,{r0-r12,lr,pc}    ; pop new task's r0-r12,lr & pc
void C_IRQHandler(void)  //void C_IRQHandler(void)
{
        U32 wTemp;

        wTemp = rINTOFFSET<<2;
        ((void(*)(void))(*((U32 *)(aISR_EINT0+wTemp))))();
}

void __vWDTInterrupt()
{
        
        rSRCPND &= BIT_WDT;                  // Clear pending bit -- Watchdog timer
        rINTPND &= BIT_WDT;
        
        OSTimeTick();
}

   我现在用看门狗做时钟中断,没有其他中断时一切正常,但是我加了个串口中断后发现以下问题,
串口中断如下:
void __irq Uart1Task(void)
{     
   rINTSUBMSK|=(BIT_SUB_RXD1|BIT_SUB_TXD1|BIT_SUB_ERR1);
   
   if(rSUBSRCPND&BIT_SUB_RXD1)
   {
      Uart0RxBuffer[Uart0RxInSp++] =(char)RdURXH1();
   }

   rSUBSRCPND&=(BIT_SUB_RXD1|BIT_SUB_ERR1);    // Clear Sub int pending
   rINTSUBMSK&=~(BIT_SUB_RXD1|BIT_SUB_ERR1);
   
   rSRCPND &= BIT_UART1;
   rINTPND &= BIT_UART1;   
}

1:中断响应慢,而且丢数据,我发送几个数据后串口才开始响应中断,但前几个数据都丢失,本以为是优先级低,采取了取消优先级,及建立高于看门狗优先级的INT0中断,取消掉任务中的关中断及WHILE(1)等,但是问题依旧。
2:接受1-3个中断后出现指令异常,修改void C_IRQHandler(void)如下
C_IRQHandler(void)
{
        U32 wTemp;

        wTemp = rINTOFFSET<<2;
        Uart_Printf("IRQ Int 0x%x\n",rINTOFFSET);
        ((void(*)(void))(*((U32 *)(aISR_EINT0+wTemp))))();
},监控中断出现号
收到如下信息:
IRQ Int 0x9    (0x9看门狗中断)
IRQ Int 0x9
IRQ Int 0x9
IRQ Int 0x17   (0x17串口中断)
IRQ Int 0x17
IRQ Int 0x17
IRQ Int 0x9
Undefined instruction exception!!!
第2个问题我怀疑是中断级的任务切换出了问题,但第1个现在还不是很清楚,请各位给看看。 1: 哦?怎么没人理? 2: 搞定了,大家注意下带_IRQ前缀的用法。   通过反汇编,发现带_irq的函数,在ADS中编译的时候会在前边会增加保存LR的指令,而且在函数返回时,会增加将当前LR中地址减4赋给PC的指令,如果对中断的处理就这一个函数,那是没问题的,但是如果在中断嵌套的时候增加此前缀,就会让函数再次执行后发生异常,因为在中断发生的时候LR中的地址已经加过4了。因为对开发工具不熟,所以同样移植过来的代码就不能用了,请大家注意呀。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]