分类:
2012-08-31 11:06:42
原文地址:arm系统的中断解析 作者:embededgood
(一) ARM7TDMI内核CPU在响应中断后会切换到异常模式下:FIQ中断是进入快中断模式,IRQ中断时进入中断模式(ARM7TDMI内核有7种模式: 用户模式,系统模式,快中断模式,中断模式,管理模式,中止模式和未定义模式,其中后5种被称为异常模式,由程序状态寄存器的M4M3M2M1M0这5位 来决定,其实ARM7的模式管理的这5位和51单片机状态寄存器的RS1RS0两位的作用相似)。 进入哪一种中断模式是由前面寄存器的配置决定的。
(二)irq中断又有向量中断和非向量中断之分,向量中断就是不同的中断有不同的入口地址,非向量中断就只有一个入口地址,进去了在判断中断标志来识别具体是哪个中断。向量中断实时性好,非向量中断简单。 同样由寄存器来决定。
(三)在程序中:
0x0 - 0x1c 叫异常向量表
0x20 - 0xc0 叫中断向量表
RAM区用户定义中断向量表,叫二级中断向量表(有时候0x00--0xc0就叫做中断向量表)
向量模式中断
异常向量表后紧接中断向量表,没有二级中断向量表,中断向量表里放的是中断服务程序的入口地址.
从0x18到中断向量表的跳转是由硬件自行完成的.
ENTRY
b ResetHandler ; 0x00
b HandlerUndef ; 0x04
b HandlerSWI ; 0x08
b HandlerPabort ; 0x0c
b HandlerDabort ; 0x10
b . ; 0x14
b HandlerIRQ ; 0x18
b HandlerFIQ ; 0x1c
ldr pc,=HandlerEINT0 ; 0x20 ;里面放的是中断处理函数的地址.
ldr pc,=HandlerEINT1
ldr pc,=HandlerEINT2
ldr pc,=HandlerEINT3
ldr pc,=HandlerEINT4567
ldr pc,=HandlerTICK ; 0x34
b .
b .
ldr pc,=HandlerZDMA0 ; 0x40
ldr pc,=HandlerZDMA1
ldr pc,=HandlerBDMA0
ldr pc,=HandlerBDMA1
ldr pc,=HandlerWDT
ldr pc,=HandlerUERR01 ; 0x54
b .
b .
ldr pc,=HandlerTIMER0 ; 0x60
ldr pc,=HandlerTIMER1
ldr pc,=HandlerTIMER2
ldr pc,=HandlerTIMER3
ldr pc,=HandlerTIMER4
ldr pc,=HandlerTIMER5 ; 0x74
b .
b .
ldr pc,=HandlerURXD0 ; 0x80
ldr pc,=HandlerURXD1
ldr pc,=HandlerIIC
ldr pc,=HandlerSIO
ldr pc,=HandlerUTXD0
ldr pc,=HandlerUTXD1 ; 0x94
b .
b .
ldr pc,=HandlerRTC ; 0xa0
b .
b .
b .
b .
b .
b .
ldr pc,=HandlerADC ; 0xb4
3.非向量模式中断:
这个比较复杂,
原理: irq request -> 0x18 ->
HandlerIRQ(一个宏) -> HandleIRQ(一个内存地址,里面是IsrIRQ函数的地址) ->
IsrIRQ(根据I_ISPR,来判断哪个中断发生) -> 二级中断向量表(RAM高端) ->
转到中断服务程序的入口地址(此图根据44b0init.s得来,不是下面的代码的运行方式)
0x0 - 0x1c 叫异常向量表
0x20 - 0xc0 叫中断向量表
RAM区用户定义中断向量表,叫二级中断向量表
2.向量模式中断
异常向量表后紧接中断向量表,没有二级中断向量表,中断向量表里放的是中断服务程序的入口地址.
从0x18到中断向量表的跳转是由硬件自行完成的.
ENTRY
b ResetHandler ; 0x00
b HandlerUndef ; 0x04
b HandlerSWI ; 0x08
b HandlerPabort ; 0x0c
b HandlerDabort ; 0x10
b . ; 0x14
b HandlerIRQ ; 0x18
b HandlerFIQ ; 0x1c
ldr pc,=HandlerEINT0 ; 0x20 ;里面放的是中断处理函数的地址.
ldr pc,=HandlerEINT1
ldr pc,=HandlerEINT2
ldr pc,=HandlerEINT3
ldr pc,=HandlerEINT4567
ldr pc,=HandlerTICK ; 0x34
b .
b .
ldr pc,=HandlerZDMA0 ; 0x40
ldr pc,=HandlerZDMA1
ldr pc,=HandlerBDMA0
ldr pc,=HandlerBDMA1
ldr pc,=HandlerWDT
ldr pc,=HandlerUERR01 ; 0x54
b .
b .
ldr pc,=HandlerTIMER0 ; 0x60
ldr pc,=HandlerTIMER1
ldr pc,=HandlerTIMER2
ldr pc,=HandlerTIMER3
ldr pc,=HandlerTIMER4
ldr pc,=HandlerTIMER5 ; 0x74
b .
b .
ldr pc,=HandlerURXD0 ; 0x80
ldr pc,=HandlerURXD1
ldr pc,=HandlerIIC
ldr pc,=HandlerSIO
ldr pc,=HandlerUTXD0
ldr pc,=HandlerUTXD1 ; 0x94
b .
b .
ldr pc,=HandlerRTC ; 0xa0
b .
b .
b .
b .
b .
b .
ldr pc,=HandlerADC ; 0xb4
关于向量irq中断两张向量表的跳转需要说明的部分是:ARM7TDMI 在矢量模式下,当从 0X18
地址处取指令时候,中断控制器会在数据总线上加载分支指令,这些分支指令使程序计数器能够对应到每一个中断源的向量地址。这些跳转到每一个中断源向量地址
的分支指令由中断控制器产生。
例如:假设 EINT0 是 IRQ 中断,EINT0 的向量地址为:0X20(见向量表),那么中断控制器必须产生0X18---0X20的分支指令。
中断控制器产生的机器码为:
0XEA000000。在各个中断源对应的中断向量地址中,存放着跳转到相应中断服务程序的程序代码。在相应向量地址处分支指令的机器代码如下计算:
矢量中断模式的机器指令代码=0XEA000000+((<目标地址>-<向量地址>-0X8)>>2)
,机器代码一般由反汇编后自动产生
非向量模式中断:
这个比较复杂,
原理: irq request -> 0x18 ->
HandlerIRQ(一个宏) -> HandleIRQ(一个内存地址,里面是IsrIRQ函数的地址) ->
IsrIRQ(根据I_ISPR,来判断哪个中断发生) -> 二级中断向量表(RAM高端) ->
转到中断服务程序的入口地址(此图根据44b0init.s得来,不是下面的代码的运行方式)
此处代码比上图的运行方式少了一个环节:没有HandlerIRQ这个阶段.
ENTRY
b ResetHandler ; for debug
b HandlerUndef ; handlerUndef
b HandlerSWI ; SWI interrupt handler
b HandlerPabort ; handlerPAbort
b HandlerDabort ; handlerDAbort
b . ; handlerReserved
b IsrIRQ
b HandlerFIQ
. . . . . .
IsrIRQ
sub sp,sp,#4 ; reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=I_ISPR
ldr r9,[r9]
mov r8,#0x0
0 movs r9,r9,lsr #1 ;移位,c为最后一位被移出的.如果最后一位是1,那么C置位,
bcs %F1 ;如果C置位,跳.
add r8,r8,#4
b %B0
1 ldr r9,=HandleADC
add r9,r9,r8
ldr r9,[r9]
str r9,[sp,#8]
ldmfd sp!,{r8-r9,pc}
. . . . . .
HandleADC # 4
HandleRTC # 4
HandleUTXD1 # 4
HandleUTXD0 # 4
. . . . . .
HandleEINT3 # 4
HandleEINT2 # 4
HandleEINT1 # 4
HandleEINT0 # 4 ; 0xc1(c7)fff84
需要说明的是: 结合这些,再看看程序中的代码。在无矢量中断模式,通过分析IISPR/FISPR 寄存器,IRQ/FIQ 处理器将移动PC到相应的ISR。HandleXXX 地址包含每个响应的ISR程序的起始地址。
总之,fiq自己处理,矢量irq硬件协同快速处理,非矢量irq软件工作挺多(说得可能不太准确,请包涵 :) )
(四)虽然我们可以选择让多个中断源(VICIntSelect)产生FIQ,但是只应该为所有可能的FIQ中断请求指定一个中断服务例程。因此,
若有多于一个中断源归类为FIQ,则FIQ中断服务例程必须读取VICFIQStatus的内容来决定如何操作处理该中断请求。不过,我们强烈建议大家只
将一个中断归类为FIQ,因为把不止一个中断源归类为FIQ会延长中断潜伏期。
在中断服务例程结束的地方,从外设级清除中断标志将会影响若干
VIC寄存器(VICRawIntr、VICFIQStatus和VICIRQStatus)的对应位。另外,在服务下一个中断之前,我们必须在中断返回
之前对VICVectAddr执行写操作。该写操作会清除内部中断优先级硬件中的相关中断标志。
为了禁能VIC中的中断,我们需要向
VICIntEnClr寄存器中的对应位写1来清除VICIntEnable寄存器中的相关位。这同样适用于VICSoftInt和
VICSoftIntClear。例如,假设VICSoftInt当前值为0x0000
0005,我们要清除位0,则向VICSoftIntClear写入0x0000
0001将实现该目的。在此之后,如果想再次向VICSoftIntClear写入值来完成对VICSoftInt相同位的清除操作,就必须先向
VICSoftIntClear赋值0x0000 0000。可见,向Clear寄存器写入1对目标寄存器来说只生效一次
假设UART0和SPI0都归类为向量IRQ(UART0的优先级比SPI0的高),而UART1和I2C归类为非向量IRQ。以下可能是设置VIC时使用的代码:
最大行业软件2012-12-01 10:32:36
PTC Creo Elements/Pro 5.0 M070 Working for Win32-ISO 1DVD(最新多语言正式版包括简、繁体中文)
PTC Creo Elements/Pro 5.0 M070 Working for Win64-ISO 1DVD
PTC Creo Elements View (ex Product View) v10 F000 build 93 Pro Multilanguage Win32 1CD
PTC Creo Elements View (ex Product View) v10 F000 build 93 Pro Multilanguage Win64 1CD
PTC Pro/E WildFire+Pro/Mechancia 4.0 M110 Working for Win32-ISO 1DVD(最新多语言正式版包括简、繁体中文)
PTC Pro/E Wil