/***************************************************
*说 明 :ARM中断区别-LPC2142与S3C2440的区别
***************************************************/
LPC 与三星ARM的区别就是三星固定了中断向量的地址,而LPC的就没有。例如三星的S3C2440
所有的中断源都有相对应的中断向量。
关于三星ARM
(1)使用向量中断
ENTRY
b ResetHandler ; 0x00
b HandlerUndef ; 0x04
b HandlerSWI ; 0x08
b HandlerPabort ; 0x0c
b HandlerDabort ; 0x10
b . ; 0x14
b HandlerIRQ ; 0x18
b HandlerFIQ ; 0x1c
ldrpc,=HandlerEINT0 ; 0x20
ldrpc,=HandlerEINT1
ldrpc,=HandlerEINT2
ldrpc,=HandlerEINT3
ldrpc,=HandlerEINT4567
ldrpc,=HandlerTICK ; 0x34
b.
b.
ldrpc,=HandlerZDMA0 ; 0x40
ldrpc,=HandlerZDMA1
ldrpc,=HandlerBDMA0
ldrpc,=HandlerBDMA1
ldrpc,=HandlerWDT
ldrpc,=HandlerUERR01 ; 0x54
b.
b.
ldrpc,=HandlerTIMER0 ; 0x60
ldrpc,=HandlerTIMER1
ldrpc,=HandlerTIMER2
ldrpc,=HandlerTIMER3
ldrpc,=HandlerTIMER4
ldrpc,=HandlerTIMER5 ; 0x74
b.
b.
ldrpc,=HandlerURXD0 ; 0x80
ldrpc,=HandlerURXD1
ldrpc,=HandlerIIC
ldrpc,=HandlerSIO
ldrpc,=HandlerUTXD0
ldrpc,=HandlerUTXD1 ; 0x94
b.
b.
ldrpc,=HandlerRTC ; 0xa0
b.
b.
b.
b.
b .
b.
ldrpc,=HandlerADC ; 0xb4
精析:很大不同的是ldr pc,=HandlerEINT0开始不同,三星ARM恰当利用了这些地址,很方便完成中断的跳转。
(2)不使用向量中断
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
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}
.. . . . .
HandleADC # 4
HandleRTC # 4
HandleUTXD1 # 4
HandleUTXD0 # 4
.. . . . .
HandleEINT3 # 4
HandleEINT2 # 4
HandleEINT1 # 4
HandleEINT0 # 4 ; 0xc1(c7)fff84
精析:
很大不同的是IsrIRQ,还有的是IsrIRQ没有进行sub lr,lr,#4的操作。
原因是这里没有出现过函数调用,那么lr仍然
是进入中断前保存的lr的值.由于当函数加上__irq关键字(中断服务函数)时,
编译器在执行中断服务函数之前自动添加上
sub lr,lr,#4
stmfd sp!,{r0-r3,r12,lr}(只压栈r0-r3,r12,lr原因时ARM内核进入中断时默认压栈r4-r7)
.....
ldmfd sp!,{r0-r3,r12,pc}^
注意:IsrIRQ是不可重入的。
; 在这里不出现sub lr,lr,#4原因是这里没有出现过函数调用,那么lr仍然
; 是进入中断前保存的lr的值.由于当函数加上__irq关键字(中断服务函数)时,
; 编译器在执行中断服务函数之前自动添加上
; sub lr,lr,#4
; stmfd sp!,{r0-r3,r12,lr}(只压栈r0-r3,r12,lr原因时ARM内核进入中断时默认压栈r4-r7)
; .....
; ldmfd sp!,{r0-r3,r12,pc}^
; 注意:IsrIRQ是不可重入的。
关于LPC的ARM
LPC的ARM我们要着重关心VICVectAddr寄存器,为什么这样说呢?
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC,FIQ_Addr
精析:
LDR PC,[PC,#-0xff0]的地址为0x18,那么这时PC的指向值是什么呢?我们可以这样计算得到
PC=0x18+8-0xff0=0xfffff030,恰好是VICVectAddr寄存器的地址,而且VICVectAddr保存的是要执行的中断例程的地址,因为当中断发生时,硬件自动把如VICVectAdd0、VICVectAddr1的值复制到VICVectAddr中。
因此,LPC只要设置好VICVectAdd0类似的地址就可以实现中断了。
上一篇:ARM9中断调试(1)
下一篇:S3C2440 I2C实现
推荐阅读最新更新时间:2024-03-16 15:28