arm9-裸机中断过程分析(2012-02-07 11:12)

步骤1:发生中断后,跳到地址0的中断向量表;b  HandlerIRQ ;handler for IRQ interrupt
步骤2:然后跳到,中断函数HandlerIRQ ,这个函数就做了并且只是了一件事取出全局变量HandleIRQ 地址上的函数并且使pc跳到该函数,

 //堆栈是满降方式就是说 ,sp指向满的地方,当压栈时,先sp自减4然后存数据到sp所指地址,这里仅仅是取出数据到pc没其他操作

具体实现代码如下:    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


 

步骤3:因为在系统复位的时候,  全局变量HandleIRQ处被安放了汇编函数IsrIRQ

代码如下:

;===========================================================
  	; Setup IRQ handler
	ldr	r0,=HandleIRQ       ;This routine is needed
	ldr	r1,=IsrIRQ	  ;if there is not 'subs pc,lr,#4' at 0x18, 0x1c
	str	r1,[r0]

//在这里,IsrIRQ函数就是从cpu寄存器里面得到中断偏移,然后根据偏移,和标号HandleEINT0(也就是定义在内存地址_ISR_STARTADDRESS上的HandleEINT0地址)

相加得到具体中断处理函数的地址,然后从这个地址取出中断函数(这个中断函数就是在c语言中用户自己放上去的,比如pISR_TIMER0= (uint32) OSTickISR;pISR_TIMER0就是定义在地址_ISR_STARTADDRESS上的变量),然后跳到中断函数,

 

IsrIRQ
	sub	sp,sp,#4       ;reserved for PC
	stmfd	sp!,{r8-r9}

	ldr	r9,=INTOFFSET
	ldr	r9,[r9]
	ldr	r8,=HandleEINT0
	add	r8,r8,r9,lsl #2
	ldr	r8,[r8]
	str	r8,[sp,#8]
	ldmfd	sp!,{r8-r9,pc}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值