打印
[ZLG-ARM]

LPC23xx中断嵌套问题

[复制链接]
2583|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
云痕|  楼主 | 2008-6-24 17:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用的是lpc2378的片子,没做嵌套保护,在没有发生中断嵌套的情况下,响应是正常的,中断相关函数:
install_irq(UART1_INT, (void *)UART1_Handler, UART1_IRQ_level)//使能
{
    DWORD *vect_addr;
    DWORD *vect_cntl;
      
    VICIntEnClr |= 1 << IntNumber;    /* Disable Interrupt */
    if ( IntNumber >= VIC_SIZE )
    {
        return ( FALSE );
    }
    else 
    {
        /* find first un-assigned VIC address for the handler */
        vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4);
        vect_cntl = (DWORD *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + IntNumber*4);
        *vect_addr = (DWORD)HandlerAddr;    /* set interrupt vector */
        *vect_cntl = Priority;
        VICIntEnable |= 1 << IntNumber;    /* Enable Interrupt */
        return( TRUE ); 
    }
}
void  UART1_Handler (void)  __irq
{
}
想用smart2200模板里的中断嵌套处理实现中断嵌套
模板代码:
    CODE32

    AREA    IRQ,CODE,READONLY

    MACRO
$IRQ_Label HANDLER $IRQ_Exception_Function 

        EXPORT  $IRQ_Label                      ; The label for exports 输出的标号
        IMPORT  $IRQ_Exception_Function         ; The imported labels 引用的外部标号

$IRQ_Label
        SUB     LR, LR, #4                      ; Calculate the returning address 计算返回地址
        STMFD   SP!, {R0-R3, R12, LR}           ; Protects the task environments 保存任务环境
        MRS     R3, SPSR                        ; Protects the status variable 保存状态
        STMFD   SP, {R3,LR}^                    ; Protects SPSR and SP in user status, Notice: DO NOT write back.保存SPSR和用户状态的SP,注意不能回写
                                                ; If the SP is written back, it should be adjusted to its appropriate value later.如果回写的是用户的SP,所以后面要调整SP
        NOP
        SUB     SP, SP, #4*2

        MSR     CPSR_c, #(NoInt | SYS32Mode)    ; Switch to the System Mode 切换到系统模式 
        BL      $IRQ_Exception_Function         ; call the C interrupt handler funtion 调用c语言的中断处理程序

        MSR     CPSR_c, #(NoInt | IRQ32Mode)    ; Switch bak to IRQ mode 切换回irq模式
        LDMFD   SP, {R3,LR}^                    ; Recover SPSR and SP in user status, Notic: DO NOT write back. 恢复SPSR和用户状态的SP,注意不能回写
                                                ; If the SP is written back, it should be adjusted to its appropriate value later.如果回写的是用户的SP,所以后面要调整SP
        MSR     SPSR_cxsf, R3
        ADD     SP, SP, #4*2                    ; 

        LDMFD   SP!, {R0-R3, R12, PC}^          ; 
    MEND
该怎么处理?该如何调用这个宏?感觉UART1_Handler内声明的变量是在IRQ栈区内的,使能嵌套后,实际执行在sys模式下了,就存在sys模式下调用irq栈区内的数据了

相关帖子

沙发
云痕|  楼主 | 2008-7-3 16:23 | 只看该作者

好,准备仿冒你的这个了

使用特权

评论回复
板凳
云痕|  楼主 | 2008-7-4 15:15 | 只看该作者

嵌套问题

改造了下:
 LDR     PC, IRQ_Addr    ;地址0x18
IRQ_Addr        DCD     IRQ_Handler            ;0x38
IRQ_Handler  
        SUB     LR, LR, #4                      ; Calculate the returning address 计算返回地址 
        STMFD   SP!, {R0-R3, R12, LR}           ; Protects the task environments 保存任务环境 
        MRS     R3, SPSR                        ; Protects the status variable 保存状态 
        STMFD   SP, {R3,LR}^                    ; Protects SPSR and SP in user status, Notice: DO NOT write back.保存SPSR和用户状态的SP,注意不能回写 
                                                ; If the SP is written back, it should be adjusted to its appropriate value later.如果回写的是用户的SP,所以后面要调整SP 
        NOP 
        SUB     SP, SP, #4*2 
 
        MSR     CPSR_c, #Mode_SYS:OR:I_Bit:OR:F_Bit      ; Switch to the System Mode 切换到系统模式  
;       MSR     CPSR_c, #Mode_SYS:OR:F_Bit
             
        LDR R0,  =0xFFFFFF00           ;VICVectAddr  0xFFFFFF00
        LDR PC,  [R0]              
 
        MSR     CPSR_c, #Mode_IRQ:OR:I_Bit      ; Switch bak to IRQ mode 切换回irq模式 
        LDMFD   SP, {R3,LR}^                    ; Recover SPSR and SP in user status, Notic: DO NOT write back. 恢复SPSR和用户状态的SP,注意不能回写 
                                                ; If the SP is written back, it should be adjusted to its appropriate value later.如果回写的是用户的SP,所以后面要调整SP 
        MSR     SPSR_cxsf, R3 
        ADD     SP, SP, #4*2                    ;  
 
        LDMFD   SP!, {R0-R3, R12, PC}^          ;  

中断处理函数基本类似如下:
void  TIMER0_Handler(void) __irq
{
 VICIntEnClr = 1 << TIMER0_INT; //禁止T1中断
__asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode }

function();
    VICVectAddr = 0x0;            
    VICIntEnable = 1 << TIMER0_INT; 
}

IRQ_Handler部分基本是盗版ZLG的,改了下,有2个问题
1,     MSR     CPSR_c, #Mode_SYS:OR:F_Bit    
这句原本是打算仅关闭FIQ中断也禁止的,可一旦写成 MSR     CPSR_c, #Mode_SYS:OR:F_Bit后,单步调试时箭头在LDR R0,  =0xFFFFFF00 行首后单步执行,立马跑到数据异常入口。
2,改成MSR     CPSR_c, #Mode_SYS:OR:F_Bit:I_BIT 后,在只有单个中断产生时能够正常响应和退出中断程序。在有第二个更高优先级中断产生时,程序跳出未执行完的低优先中断,进入高优先级的中断处理函数,可当高优先中断处理完毕后,程序不是回去执行前面未执行完的低优先中断处理函数,而是和所有中断都处理完毕一样,感觉是LR寄存器被破坏了,可又不知道改怎么改,哪位大侠指点下?

使用特权

评论回复
地板
云痕|  楼主 | 2008-7-4 15:46 | 只看该作者

加LR后继续飞

在LDR R0,  =0xFFFFFF00           ;VICVectAddr  0xFFFFFF00
前加ADD LR, PC,#4*2,还是差不多,单中断是没问题,再来一个,在执行到LDMFD   SP!, {R0-R3, R12, PC}^  时飞到Undef_Handler了,该怎么处理?有什么建议没?

使用特权

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

本版积分规则

28

主题

75

帖子

0

粉丝