我用的是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栈区内的数据了 |