ARM中断学习,讲的十分到位值得一看

上传人:cl****1 文档编号:486517674 上传时间:2023-05-11 格式:DOCX 页数:5 大小:16.50KB
返回 下载 相关 举报
ARM中断学习,讲的十分到位值得一看_第1页
第1页 / 共5页
ARM中断学习,讲的十分到位值得一看_第2页
第2页 / 共5页
ARM中断学习,讲的十分到位值得一看_第3页
第3页 / 共5页
ARM中断学习,讲的十分到位值得一看_第4页
第4页 / 共5页
ARM中断学习,讲的十分到位值得一看_第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
资源描述

《ARM中断学习,讲的十分到位值得一看》由会员分享,可在线阅读,更多相关《ARM中断学习,讲的十分到位值得一看(5页珍藏版)》请在金锄头文库上搜索。

1、ARM 中断学习,讲的十分到位。值得一看中断向量b HandlerIRQ ;handler for IRQ interrupt 很自然,因为所有的单片机都是那样,中断向量一般放在开头,用过单片机的人都会很熟悉,那就不多说了。异常服务程序这里不用中断( interrupt )而用异常( exception ),毕竟中断只是异常的一种情况,下面主要分析的是 “中断异常 ”说白了,就是我们平时单片机里面用的中断! !所有由器件引起的中断, 例如 TIMER 中断,UART 中断,外部中断等等,都有一个统一的入口, 那就是中断异常 IRQ ! 然后从IRQ 的服务函数里面分辨出, 当前究竟是什么中断,

2、 再跳转到相应的中断服务程序。这样看来, ARM 比单片机要复杂一些了,不过原理是不变的。上面说的就是思路,跟着这个思路来接着分析。HandlerIRQ 很明显是一个标号, 我们找到了HandlerIRQ HANDLER HandleIRQ这里是一个宏定义,我们再找到这个宏,看他是怎么定义的:MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabelsub sp,sp,#4;decrement sp(to store jump address)stmfd sp!,r0;PUSH the work register to stack(lr does

3、not push because it return to originaladdress)ldr r0,=$HandleLabel ;load the address of HandleXXX to r0ldr r0,r0;load the contents(service routine start address) of HandleXXXstr r0,sp,#4 ;store the contents(ISR) of HandleXXX to stackldmfd sp!,r0,pc ;POP the work register and pc(jump to ISR)MEND用 Han

4、dlerIRQ 将这个宏展开之后得到的结果实际是这样的HandlerIRQsub sp,sp,#4;decrement sp(to store jump address)stmfd sp!,r0;PUSH the work register to stack(lr does not push because it return to originaladdress)ldr r0,=HandleIRQ ;load the address of HandleXXX to r0ldr r0,r0;load the contents(service routine start address) of

5、HandleXXXstr r0,sp,#4 ;store the contents(ISR) of HandleXXX to stackldmfd sp!,r0,pc ;POP the work register and pc(jump to ISR )至于具体的跳转原理下面再说,好了,这样的话就容易看的多了,很明显, HandlerIRQ 还是一个标号, IRQ 异常向量就是跳转到这里执行的,这里粗略看 一下,应该是保存现场,然后跳转到真正的处理函数,那么很容易发现了这么一句ldr r0,=HandleIRQ ,没错,我们又找到了一个标号 HandleIRQ ,看来真正的处理函数应该是这个

6、HandleIRQ ,继续寻找AREA RamData, DATA, READWRITE _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00HandleReset# 4HandleUndef# 4HandleSWI# 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ# 4对应上面第二个标号最后我们发现在这里找到了 HandleIRQ , 其实就是 MAP ,这段程序的意思是,从 _ISR_STARTADDRESS 开始,预留 一个变量,每个变量一个标号,预留的空间为 4 个字

7、节,也就是 32BIT ,其实这里放的是真正的 C 写的处理函数的地址,说白 了,就是函数指针 - - 这样做的话就很灵活了接着,我们需要安装 IRQ 处理句柄,说白了,就是设置处理函数的地址,让 PC 指针可以正确的跳转。 于是我们在接着的找到安装句柄的语句; Setup IRQ handlerldr r0,=HandleIRQ ;This routine is neededldr r1,=IsrIRQ;if there is not subs pc,lr,#4 at 0x18, 0x1cstr r1,r0说白了就是将 IsrIRQ 的地址填到 HandleIRQ 对应的地址里面,前面说了

8、HandleIRQ 放的是中断处理的函数的入口地址,我 们继续找 IsrIRQIsrIRQsub sp,sp,#4 ;reserved for PCstmfd sp!,r8-r9ldr r9,=INTOFFSETldr r9,r9ldr r8,=HandleEINT0add r8,r8,r9,lsl #2ldr r8,r8str r8,sp,#8ldmfd sp!,r8-r9,pc要理解这个代码,得先学学 2440 的中断系统了, INTOFFSET 存放的是当前中断的偏移号,根据偏移就知道当前是哪个中断源 发生的中断。注意了,我们说的是中断,而不是异常,看看原来的表是啥样子的 _ISR_ST

9、ARTADDRESSISR_STARTADDRESS=0x33FF_FF00HandleReset# 4HandleUndef# 4HandleSWI# 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ# 4HandleFIQ# 4HandleEINT0# 4HandleEINT1# 4HandleEINT2# 4HandleEINT3# 4可以看到, 前面几个是异常, 从 HandleEINT0 就是 IRQ 异常的向量存放的地方了, 这样就可以理解为什么上面 IsrIRQ 里 面里面要执行那条指令ldr r8,=Han

10、dleEINT0add r8,r8,r9,lsl #2道理很简单, HandleEINT0 就是所有 IRQ 中断向量表的入口,在这个地址上面,加上一个适当的偏移量, INTOFFSET ,那 么我们知道现在,到底是哪个 IRQ 在申请中断了。至于具体怎么跳转的?首先,我们说了, HandleEINT0 开始的一段内存里面,存放的就是中断服务函数的函数指针, ARM 的体系的话,每个指针变 量就是占 4 个字节,这里就解释了,为什么这里为每个标号分配了 4 个字节的空间,里面放的就是函数指针!下面再看看 怎么跳转,继续看 IsrIRQ 里面就实现了跳转了str r8,sp,#8ldmfd sp

11、!,r8-r9,pc其实最核心就是这两句了,先查找到当前中断服务程序的地址,将他放到 R8 里面,然后出栈,弹出给 PC 那么 PC 很自然就 跳到中断服务程序了。 至于这里的堆栈问题又是一个非常棘手的,需要好好的参透 ARM 的中断架构, 需要了解的可以自己仔细 的阅读 ARM 体系结构与编程里面说的很详细。我们这里的重点是研究怎么跳转。最后,我们看看在 C 代码中是怎么安装终端向量的,例如看 按键的外部中断,是怎么具体设置的,参看 /src/keyscan.c 里面的 代码很简单,里面只有 3 个函数KeyScan_Test 是按键测试的主函数Key_ISR 是按键中断服务函数在 KeyS

12、can_Test 里面,我们发现了有这么一句pISR_EINT0 = pISR_EINT2 = pISR_EINT8_23 = (U32)Key_ISR; 可以理解否? Key_ISR 就是上面提到的按键中断服务函数,函数的名字,代表的就是函数的地址! 将中断服务函数的地址,注意了,是地址,这是一个 U32 型的变量。送到几个变量,我们以 pISR_EINT0 作为例子,查看头 文件定义,在 2440addr.h 里面找到/ Interrupt vector#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20)_ISR_STARTAD

13、DRESS 有没有似曾相识的感觉?没错,刚才分析的汇编代码里面就提到了 _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00HandleReset# 4HandleUndef# 4对,地址就是这里,然后 _ISR_STARTADDRESS+0x20 就是跳过前面的异常向量,进入 IRQ 中断向量的入口,所以说到尾 pISR_EINT0 = (U32)Key_ISR;完成的操作就是,将 Key_ISR 的地址存放到HandleEINT0 # 4这个 IRQ 向量表里面!当按键中断发生的时候,发生 IRQ 异常中断当前 PC 值 -4 保存到 LR_I

14、RQ 里面,然后执行b HandlerIRQ 然后是执行HandlerIRQsub sp,sp,#4 ; 预留一个用来存放 PC 地址stmfd sp!,r0 ; 保存 R0 ,因为下面使用了ldr r0,=HandleIRQ ; 将 HandleIRQ (服务程序)的地址装载到 R0ldr r0,r0str r0,sp,#4 ; 保存到刚才预留的地方ldmfd sp!,r0,pc ; 弹出堆栈,恢复 R0 ,并且将刚才计算好的 HandleIRQ 地址弹出到 PC 堆栈是向下生长的,所以 SUB SP,SP,#4 就相当于 PUSH XX ,但是这个 XX 这个时候并没有用,因为这里用的是强

15、制移动 SP 指针实现的。然后得到服务 程序的地址,再将这个值放回刚才预留的栈的空位上面, 最后就是 POP 出 R0 恢复,并且将刚才得到的服务程序的地址送到 PC, 那么实现的效果就是跳转到 HandleIRQ 里面了。接着看刚才是怎么安装的 HandleIRQ 的; Setup IRQ handlerldr r0,=HandleIRQ ;This routine is neededldr r1,=IsrIRQ;if there is not subs pc,lr,#4 at 0x18, 0x1cstr r1,r0可以看出,这里将 IsrIRQ 的地址的值保存到 HandleIRQ 中,也就是说,上面的 IRQ 服务程序,这个时候实际上就是指 IsrIRQ ! 所以接着的事情就是转移到 IsrIRQ 中执行:IsrIRQsubsp,sp,#4 ; 预留一个值来保存PCstmfdsp!,r8-r9ldrr9,=INTOFFSET ; 计算偏移量,下面解释l

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 活动策划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号