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

本文详细介绍了ARM处理器中断处理的具体步骤。首先,在中断发生时,处理器会转向中断向量表的地址0。随后通过一系列汇编指令跳转到中断处理函数HandlerIRQ,并最终定位到具体的中断服务例程。整个过程涉及堆栈操作、寄存器读写等关键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

步骤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}


 

Rebuild started: Project: Project *** Using Compiler 'V6.22', folder: 'E:\Keil_v5\ARM\ARMCLANG\Bin' Rebuild target 'Target 1' assembling startup_stm32f10x_md.s... Start/core_cm3.c(445): error: non-ASM statement in naked function is not supported 445 | uint32_t result=0; | ^ Start/core_cm3.c(442): note: attribute is here 442 | uint32_t __get_PSP(void) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(465): error: parameter references not allowed in naked functions 465 | "BX lr \n\t" : : "r" (topOfProcStack) ); | ^ Start/core_cm3.c(461): note: attribute is here 461 | void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(479): error: non-ASM statement in naked function is not supported 479 | uint32_t result=0; | ^ Start/core_cm3.c(476): note: attribute is here 476 | uint32_t __get_MSP(void) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(499): error: parameter references not allowed in naked functions 499 | "BX lr \n\t" : : "r" (topOfMainStack) ); | ^ Start/core_cm3.c(495): note: attribute is here 495 | void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); | ^ 4 errors generated. compiling core_cm3.c... compiling misc.c... compiling system_stm32f10x.c... compiling stm32f10x_adc.c... compiling stm32f10x_dac.c... compiling stm32f10x_exti.c... compiling stm32f10x_dbgmcu.c... compiling stm32f10x_dma.c... compiling stm32f10x_crc.c... compiling stm32f10x_cec.c... compiling stm32f10x_bkp.c... compiling stm32f10x_can.c... compiling stm32f10x_flash.c... compiling stm32f10x_pwr.c... compiling stm32f10x_fsmc.c... compiling stm32f10x_
03-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值