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,从而跳转到中断服务程序。
新迪数字与西门子将在工业数字化领域开展深度合作
三星智能手机Android Pie计划2019年全面更新
2017 Qualcomm 4G/5G 峰会
耐能凭AI芯片产品荣膺中国IC设计成就奖
消防应急疏散指示系统在某工业厂房项目的应用
基于ARM中的IRQ的中断处理
工业物联网平台在实现分布式设备管理方面的应用
模块化仪器应对射频测试的复杂需求
未来的行业你最看重哪一行
联通5G服务套餐出炉:每月赠送100G流量,网速125MB/s
关键时刻!台企力助华为自建供应链!
高通基带加持,一探iPhone 12的内部结构
浅析低成本负端5v2.4a同步整流芯片U7711
盘点机器人行业相关的10大技术应用
卫星天线简易手动极轴座的制作,Satellite Antenna
Wolfspeed不断发展以应对供应挑战并推出高性能Gen 3+芯片
如何在不牺牲质量的情况下降低PCB组装成本
PCB规则驱动设计的经验总结
Molex收购 Keyssa 无线连接器技术 华为获TM Forum行业杰出贡献奖
SK海力士量产超高速DRAM‘HBM2E’ 人工智能迎来新春天