44b0X的中断控制(转)
已有 587 次阅读2007-4-17 09:38
|系统分类:ARM|
s3c44b0
44b0X的中断控制
ITSN小组成员:jian84000
中断控制是所示嵌入式系统中不可或缺的一部分。对于不同的处理器,虽然中断控制的原理是基本一致的,但其管理方式往往都有很大的区别。学过51系列单片机的刚开始学ARM人会觉得ARM的中断管理系统很复杂,因为在51中中断向量几乎不用你管。主要是因为在ARM系统中中断源多,且为了实现不同系统对实时性的要求不同而进行多优先级的管理的造成的。
1、ARM7TDMI内核的中断
至于中断的概念这里就说的,下面我来介绍一下ARM7TDMI内核下的中断。
和51单片机只有一种模式不同,ARM7TDMI内核CPU在响应中断后会切换到异常模式下:FIQ中断是进入快中断模式,IRQ中断时进入中断模式(ARM7TDMI内核有7种模式:用户模式,系统模式,快中断模式,中断模式,管理模式,中止模式和未定义模式,其中后5种被称为异常模式,由程序状态寄存器的M4M3M2M1M0这5位来决定,其实ARM7的模式管理的这5位和51单片机状态寄存器的RS1RS0两位的作用相似)。
1.1、中断处理过程
ARM7进入及退出快中断模式和中断模式的过程(中断响应过程)如下:
① 将下一条指令的地址复制到LR(R14)中(在ARM状态下)。
② 将CPSR复制到适当的SPSR(各种模式处CPSR是共用一个的,而SPSR在不同异常模式下是不同的)。
③ 根据异常将CPSR模式强制设为快中断模式或中断模式。
④ 强制PC从相关的异常向量处取指。(到此完成进入中断服务程序的动作)
⑤ 执行异常服务程序。
⑥ 将LR中的值减去偏移量后移入PC。ARM状态快中断模式和中断模式下这个偏移量为4,因为LR保存的是由于FIQ或IRQ占先面没有被执行的指令的地址。
⑦ 将SPSR的值复制回CPSR中。
⑧ 清零在入口置位的中断禁止标志。
1.2、异常向量表
一旦产生IRQ中断,微控制器会切换到IRQ模式,并且跳转到向量表0x0000018地址处执行程序。而一旦产生FIQ中断,微控制器会切换到FIQ模式,并且跳转到向量表0x000001C地址处执行程序。所示,在0x00000080处和0x0000001C处必须各有一条跳转指令,分别跳转的IRQ和FIQ中断处理的代码处。在0x00000000处的一般向量表称为异常向量表,定义如下:
ENTRY
b ResetHandler for debug
b HandlerUndef handlerUndef
b HandlerSWI SWI interrupt handler
b HandlerPabort handlerPAbort
b HandlerDabort handlerDAbort
b . handlerReserved
b HandlerIRQ 这里是IRQ中断入口处0x00000018
b HandlerFIQ 这里是FIQ中断入口处0x0000001C
ResetHandler、HandlerUndef等只是地址标签,是由用户自己在这些异常处理代码的开始处定义的。
2、44b0X的中断
2.1、44b0X的启动时中断的初始化
44B0的初始化程序就是初始化各个关键的寄存器,建立中断向量,然后转移到主函数去执行程序。不过44B0不支持地址映射,所以程序不COPY到RAM种执行。44B0初始化对我们广大初学者来说,比较难理解的是中断的处理和一些少见的操作符号。下面我来一段一段地分析。
2.1.1、44b0的中断子程序地址
就是存放在初始化程序最后的一段:
^ _ISR_STARTADDRESS
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;Don't use the label 'IntVectorTable',
;because armasm.exe cann't recognize this label correctly.
;the value is different with an address you think it may be.
;IntVectorTable
HandleADC # 4
HandleRTC # 4
HandleUTXD1 # 4
HandleUTXD0 # 4
HandleSIO # 4
… …
HandleEINT3 # 4
HandleEINT2 # 4
HandleEINT1 # 4
HandleEINT0 # 4 0xc1(c7)fff84
这段第一行 "^"符号表示在RAM区开辟空间。 ^ _ISR_STARTADDRESS 表示在RAM的_ISR_STARTADDRESS处开辟一段空间。这里开辟的空间是用来存放中断服务程序及其他异常处理程序地址的。每个中断或其他异常都开辟4个字节的空间,这是因为RAM区的程序地址要4个字节才能放得下。而中断程序的地址是应用程序在使用这个中断时,将中断服务程序的地址存入这对应的空间内。_ISR_STARTADDRESS一般是定义在RAM的最后一段空间,可以在一些配置文件中找到这个标签,如:Option.inc。
2.1.2、IRQ中断
44B0的IRQ中断有两种装断模式 一种是非向量IRQ中断,一种是向量IRQ中断。
当有两个中断同时发生时,前者是由软件方式来判断决定先执行那个中断服务,而后者是由硬件逻辑来决定的。
非向量IRQ中断的执行过程
(1) 中断允许并且外部中断请示产生。
(2) PC自动跳转一0x00000018处
也就是异常向量表:
b ResetHandler
b HandlerUndef
b HandlerSWI
b HandlerPabort
b HandlerDabort
b .
b HandlerIRQ 这里是非向量IRQ中断入口处0x00000018
b HandlerFIQ
(3)由 b HandlerIRQ指令跳转到下面的HandlerIRQ HANDLER HandleIRQ宏调用处
LTORG
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
这个宏的定义是这样的:
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 decrement sp(to store jump address)
stmfd sp!,{r0} PUSH the work register to stack
;(lr does't push because it return to original address)
ldr r0,=$HandleLabel 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} POP the work register and pc(jump to ISR)
MEND
作用是使标签HandleLabel单元的地址数据装载到PC当中,也就是使程跳转到HandleLabel地址单元中存放的程序地址处。
比如上面执行HandlerIRQ HANDLER HandleIRQ宏调用时是将
如下一段代码的首地址IsrIRQ装入PC,就是下面这段代码在软件上实现在多个中断同时发生时选择一个中断并进入其中断服务程序。
;One of the following two routines can be used for non-vectored interrupt.
IsrIRQ using I_ISPR register.
sub sp,sp,#4 reserved for PC
stmfd sp!,{r8-r9}
IMPORTANT CAUTION
if I_ISPC isn't used properly, I_ISPR can be 0 in this routine.
ldr r9,=I_ISPR 读中断服务挂起寄存器,存入r9中
ldr r9,[r9]
mov r8,#0x0
0
movs r9,r9,lsr #1 从低位向上搜索r9中的第1个为"1"的位
bcs %F1
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}
那么为什么说HandleIRQ单元内存放的地址数据是IsrIRQ呢,请看在复位异常处理子程序ResetHanlder里有这样一段代码:
;****************************************************
* Setup IRQ handler *
****************************************************
ldr r0,=HandleIRQ
ldr r1,=IsrIRQ
str r1,[r0]
这就是每次程序复位时将IsrIRQ地址数据装入HandleIRQ单元的。
(4)IsrIRQ子程序的最后一条指令会使程序转入用户的中断服务子程序。
(5)中断返回。
向量IRQ中断的执行过程
IRQ向量模式中断比非向量模式少了一个过程,就是调用IsrIRQ子程序的过程
因为向量模式下,当IRQ中断发生时不是跳转到0x00000018(b HandlerIRQ)处的,而是跳转到0x00000020之后的某个中断向量处。0x00000020之后的代码如下所示:
VECTOR_BRANCH
ldr pc,=HandlerEINT0 mGA H/W interrupt vector table
ldr pc,=HandlerEINT1
ldr pc,=HandlerEINT2
ldr pc,=HandlerEINT3
ldr pc,=HandlerEINT4567
ldr pc,=HandlerTICK mGA
b .
b .
ldr pc,=HandlerZDMA0 mGB
ldr pc,=HandlerZDMA1
ldr pc,=HandlerBDMA0
ldr pc,=HandlerBDMA1
ldr pc,=HandlerWDT
ldr pc,=HandlerUERR01 mGB
b .
b .
ldr pc,=HandlerTIMER0 mGC
ldr pc,=HandlerTIMER1
ldr pc,=HandlerTIMER2
ldr pc,=HandlerTIMER3
ldr pc,=HandlerTIMER4
ldr pc,=HandlerTIMER5 mGC
b .
b .
ldr pc,=HandlerURXD0 mGD
ldr pc,=HandlerURXD1
ldr pc,=HandlerIIC
ldr pc,=HandlerSIO
ldr pc,=HandlerUTXD0
ldr pc,=HandlerUTXD1 mGD
b .
b .
ldr pc,=HandlerRTC mGKA
b .
b .
b .
b .
b . mGKA
b .
b .
ldr pc,=HandlerADC mGKB
b .
b .
b .
b .
b . mGKB
b .
b .
具体跳转到那一句,就看有什么中断产生。如果多个中断同时产生则硬件逻辑可产根据IRQ中断优先级控制寄存器内设定的优先级来决定跳转之处。
比如有两个中断定时器0中断和外部中断1同时产生了,如果外部中断1的优先级比定时器0的中断优先级高,则硬件逻辑会自动使PC转到ldr pc,=HandlerEINT1处,执行这条指令后PC就跳转到宏HandlerEINT1 HANDLER HandleEINT1 而这个会将HandleEINT1单内的地址数据装入PC。与HandleIRQ单元是存放地址IsrIRQ不一样,是直接HandleEINT1存放的外部中断1的服务程序地址的。所以这种模式下是由硬件来中断优先级的,不需要IsrIRQ子程序来处理。
2.1.3 FIQ中断
由于FIQ中断中没有优先级之分,也没有向量模式或非向量模式之分,因此比起IRQ中断来说要简单得多,它的执行过程与在只有一个中断源的情况下的向量模式IRQ的过程是一样的。