基于ARM中的IRQ的中断处理

控制/MCU

1877人已加入

描述

Startup中断向量表

;*******************************************************************************

; Exception vectors

;*******************************************************************************

LDR PC, Reset_Addr ; 地址为0x8000 0000

LDR PC, Undefined_Addr

LDR PC, SWI_Addr

LDR PC, Prefetch_Addr

LDR PC, Abort_Addr

NOP ; Reserved vector

LDR PC, IRQ_Addr

LDR PC, FIQ_Addr

; *******************************************************************************

; Exception handlers address table

;*******************************************************************************

Reset_Addr DCD __program_start ;地址为0x8000 0020

Undefined_Addr DCD UndefinedHandler

SWI_Addr DCD SWIHandler

Prefetch_Addr DCD PrefetchAbortHandler

Abort_Addr DCD DataAbortHandler

DCD 0 ; Reserved vector

IRQ_Addr DCD IRQHandler

FIQ_Addr DCD FIQHandler

;*******************************************************************************

; Peripherals IRQ handlers address table

;*******************************************************************************

PRCCUCMU_Addr DCD PRCCUCMUIRQHandler ;地址为0x8000 0040

对于嵌入式系统来说,一般将上面产生的代码放在flash中,地址0x8000 0000(该sector同时remap到0x0000 0000)。将__program_start,UndefinedHandler等地址放到指令缓冲池中。从而可以实现全局范围内跳转。根据ARM指令长度可知,上述__program_start的地址存放的物理地址是0x8000 0020,根据ARM流水线的情况,LDR PC, Reset_Addr产生汇编语言指令为LDR PC, [PC, #24]。

当IRQ中断发生时,程序跳转到IRQHandler处。

IRQHandler

IRQHandler

SUB lr,lr,#4 ; Update the link register

SaveContext r0,r12 ; Save the workspace plus the current

; return address lr_ irq and spsr_irq.

LDR lr, =ReturnAddress; Read the return address.

LDR r0, =EIC_base_addr

LDR r1, =IVR_off_addr

ADD pc,r0,r1 ; Branch to the IRQ handler.

ReturnAddress

; Clear pending bit in EIC (using the proper IPRx)

LDR r0, =EIC_base_addr

LDR r2, [r0, #CICR_off_addr] ; Get the IRQ channel number

CMP r2,#31

SUBHI r2, r2, #32

MOV r3,#1

MOV r3,r3,LSL r2

STRHI r3,[r0, #IPR1_off_addr] ; Clear the corresponding IPR bit.

STRLS r3,[r0, #IPR0_off_addr] ; Clear the corresponding IPR bit.

RestoreContext r0,r12 ; Restore the context and return to the.。。

; 。。.program execution.

其中,EIC_base_addr为0xFFFF FC00,IVR的地址是0xFFFF FC18,通过执行该寄存器中的指令可进入到相应的中断服务程序,该寄存器可在通过install中断向量服务程序时进行设置。例如该IVR寄存器的值为0xE59FF468,则表示LDR PC, [PC, #1128]。其实就是跳转到指令缓冲区中定义Timer2中断服务程序。

Interrupt Vector Register和Source Interrupt Registers的设置

extern u32 PRCCUCMU_Addr;

u8 Counter=0;

u32 Offset = (u32)&PRCCUCMU_Addr; //PRCCUCMU_Addr地址为0x8000 0040

u32 Tmp=0;

/* IVR = high half of load PC instruction (LDR PC,) */

EIC-》IVR = 0xE59F0000; //0xE59F0000,根据Instruction format表示一条无条

//件执行的语句,该指令向目的寄存器PC传递值,

//指令中的F,表示r15即PC

/* Read the offset of the interrupt vectors table address */

Offset = (Offset+0x3E0)《《16; //偏移地址问什么要加上0x3E0? 是因为

//0x8000 0040 + 0x3E0 《《 16 = 0x0420 0000,

//中断发生后,SIR的高16bits会传递到IVR的低

//16bit作为偏移地址,而IVR地址为0xFFFF FC18

//0xFFFF FC18 + 0x420 + 0x8(流水线影响)=

//0x1 0000 0040,由于ARM为32bits,故即为

//0x40(该地址同时映射到0x8000 0040处)

/* Initialize SIRn registers with the equivalent low half of load PC instruction */

for(Counter=64; Counter!=0; Counter--)

{

EIC-》SIRn[64-Counter] = Offset|0xF0000000; //为什么0xF000 0000,是因为LDR PC, [PC, #0ffset],

//源寄存器和目的寄存器都是PC

Offset += 0x00000004 《《 16;

}

上面的程序片断设置IVR和SIRn等。这样当IRQ中断发生时,PC首先跳转到0xFFFF FC18处,即执行IVR寄存器中的指令LDR PC, [PC, #offset],从指令缓冲池中取出中断服务程序的地址给PC,从而跳转到中断服务程序。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分