首页 / 操作系统 / Linux / S3C2410A的异常机制[中断处理]
以YLE2410A开发板为例,说说ARM的异常是如何处理滴。;Pre-defined constantsUSERMODE EQU 0x10FIQMODE EQU 0x11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1BMODEMASK EQU 0x1FNOINT EQU 0xC0 ;The location of stacksUserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~ SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~ 首先当然是进行堆栈初始化啦。。。有7种不同的异常处理,因为它们的堆栈是独立滴,所以需要单独进行堆栈分配以及初始化。初始化代码如下: InitStacks;Don"t use DRAM,such as stmfd,ldmfd......;SVCstack is initialized before;Under toolkit ver 2.5, "msr cpsr,r1" can be used instead of "msr cpsr_cxsf,r1"mrs r0,cpsrbic r0,r0,#MODEMASKorr r1,r0,#UNDEFMODE|NOINTmsr cpsr_cxsf,r1 ;UndefModeldr sp,=UndefStackorr r1,r0,#ABORTMODE|NOINTmsr cpsr_cxsf,r1 ;AbortModeldr sp,=AbortStack
orr r1,r0,#IRQMODE|NOINTmsr cpsr_cxsf,r1 ;IRQModeldr sp,=IRQStack orr r1,r0,#FIQMODE|NOINTmsr cpsr_cxsf,r1 ;FIQModeldr sp,=FIQStack
bic r0,r0,#MODEMASK|NOINTorr r1,r0,#SVCMODEmsr cpsr_cxsf,r1 ;SVCModeldr sp,=SVCStack;USER mode has not be initialized.mov pc,lr
做好这个初始化之后呢,当然就是IRQ的分配了。就说说普通的IRQ吧,一般在WINCE下很难用到FIQ滴。嘿嘿。。。一家之言。因为ARM有7种不同的异常处理,所以: LTORG HandlerFIQ HANDLER HandleFIQHandlerIRQ HANDLER HandleIRQHandlerUndef HANDLER HandleUndef;HandlerUndef; sub sp, sp, #4 ;decrement sp(to store jump address); stmfd sp!, {r14} ;PUSH the work register to stack(lr does"t push because it return to original address); ldr r0, =HandleUndef ;load the address of HandleXXX to r0; ldr r0, [r0] ;load the contents(service routine start address) of HandleXXX; str r0, [sp, #4] ;store the contents(ISR) of HandleXXX to stack; ldmfd sp!, {r0, pc} HandlerSWI HANDLER HandleSWIHandlerDabort HANDLER HandleDabortHandlerPabort HANDLER HandlePabort也是需要7种不同的中断向量了哦。这个和单片机是差不多滴。。。一般都是放在前面撒。异常服务程序 这里不用中断(interrupt)而用异常(exception),毕竟中断只是异常的一种情况,