在此区分下中断和异常:异常要切换处理器的模式到相应异常模式比如:FIQ,IRQ,未定义指令,指令预取中止等。中断也是一种异常,他切换模式到FIQ ,IRQ,(也就是说你切换的模式为FIQ/IRQ时就为中断)。问题的难点就是切换到这个异常的中断处理方法与其他的:(未定义,预取址,SWI,数据中止)是不同的。因为arm920t内核的中断严格意义上只有两个是给用户来用的,一个事FIQ,另一个是IRQ;但是为了增加中断的数量,芯片集成商采取了中断复用的方法。比如arm处理器常见的 UART,IIC,SPI,DMA,中断等;他们发生中断后其实都跳到了IRQ的地址(0x0000,0018);即他们选择了复用IRQ来实现。跳到这个地址后再怎么办呢这个就决定于芯片集成商了
我们看看S3C2440和S3C2410是怎么处理的;
b ResetHandler ;开机或复位就跳到这里地址是:0x00000000
b HandlerUndef ;转跳到Undefined mode程序入口0x04
b HandlerSWI ;转跳到SWI 中断程序入口0x08
b HandlerPabort ;转跳到PAbort(指令异常)程序入口0x0c
b HandlerDabort ;转跳到DAbort(数据异常)程序入口0x10
b . ;保留0x14
b HandlerIRQ ;转跳到IRQ 中断程序入口0x18
b HandlerFIQ ;转跳到FIQ 中断程序入口0x1c
上面这段就是一级中断向量表,基本上arm7,arm920,arm926都是这样处理的跳到0x18后跳到HANDLER调用
//////////////////////////////////////////////////////////////////
这段程序用于把异常服务(有人称为中断)程序的首地址装载到pc中,
在此有人称之为“加载程序”。
本初始化程序定义了一个数据区(在文件最后),存放相应中断服务程序的首地址。每个字空间都有一个标号,以Handle***命名。
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;用来存储PC地址
stmfd sp!,{r} ;把将要使用的r寄存器入栈
ldr r,=$HandleLabel;给寄存器r赋值
ldr r,[r] ;给寄存器r赋值,将r的地址放入r
str r,[sp,#4] ;将对应的中断函数首地址入栈
ldmfd sp!,{r,pc} ;弹出工作寄存器ro和PC,也就完成了到ISR的跳转
MEND
;异常中断宏调用
LTORG
HandlerFIQ HANDLER HandleFIQ
从一级表跳到这里HandlerIRQ HANDLER HandleIRQ ;这是宏处理的调用如上调用后跳到二级向量表
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
///////////////////////////////////////////////////////////////////
;该函数的作用是计算实际的中断,计算出是dma,iic,uart,外部中断等
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}
///////////////////////////////////////////////////////////////////////////////////
; 设置缺省中断处理函数
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at x18, x1c
str r1,[r0]
///////////////////////////////////////////////////////////////////////////////////
;二级中断向量表
ALIGN
AREA RamData, DATA, READWRITE
^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=x33FF_FF00
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4;此地保存了IsrIRQ;中断处理函数宏调用后就跳到这里再跳到IsrIRQ函数
HandleFIQ # 4
///////////////////////////////////////////////////////////////////////////////////
;三级向量表由IsrIRQ处理后就跳到这里来至于是哪一个,取决于是什么中断
;不要使用标签'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
;@x33FF_FF2
HandleEINT # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleCAM # 4 ; Added for 2440.
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
;@0x33FF_FF60
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleNFCON # 4 ; Added for 244.
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
;@0x33FF_FFA0
END
阅读(1646) | 评论(0) | 转发(0) |