企业 个人 用户名 密码   忘记密码?
站内 站外
风格设定:
论坛 博客 会展
论坛 博客 会展
 
ARM中断实现过程的个人笔记
作者:    时间:2007-07-24    来源: 
 
      

决定开始学习嵌入式后,最先做的事情就是要熟悉ARM指令及其伪指令伪操作。ARM指令的助记符其实都是其具体功能的单次缩写,所以学习的过程中最好利用网络,从一些文献或书籍中找到ARM指令助记符的全称,这样方便记忆。学完之后,我做了整理了一个有关这方面的笔记.


接下来的学习过程中,比较难以理解的是ARM的中断过程和存储系统。ARM中断的实现有些书上看一两遍也不见得能够完全理解,当然可能只对于像我一样跨专业的朋友来说存在这个问题。这次只谈中断。由于是初学者,难免会出错,敬请各位指正。

当一个程序正常执行过程中,CPU可能检测到有某个中断源发出中断请求,这时ARM硬件实现了程序强制跳转,在这之前保存了相关信息,以便程序正常返回。如果是发生了Reset中断,程序实现系统初始化设置。
开始比较难以理解的是中断产生后,程序都进行了哪些操作。我就从跟踪PC作为分析的主线。以发生FIQ中断为例。(只以ROM起始地址为0为例,不为0的情况参照存储地址映射)
最简单的是中断发生后,PC=0x08,在此地址处存放一个跳转指令,跳转到相关处理程序。当然多数情况中断处理程序可能比较复杂,并且要处理多种中断的情况下,采用一步映射两步跳转(我自己起的名字,不一定妥当)。如下图所示:

一步映射指,在RAM地址中建立一个中断向量表,图中该表起始地址为0x400000,在该表中存放的是中断处理函数的入口地址。两步跳转是指,当中断发生时,由于系统硬件强制程序跳转到了0x08处,在该地址处是一个跳转指令,跳转到中断函数地址解析程序IRQ_Handler,完成一步跳转。解析程序(IRQ_Handler)的作用无非是把中断向量表内中断处理函数(SystemIrqHandler)的入口地址赋值给PC,如图所示PC=0x003000280,完成第二步跳转,开始处理中断。在中断处理函数的最后,恢复中断开始时保存的相关寄存器的值,完成中断。

下面以一个实例来具体说明中断建立及实现的过程。

首先通过伪指令建立一个中断向量表,用于存放中断程序的入口地址(如上图中的中断向量表,注意,此时表中还未赋值):
;/*EXCEPTIONHANDLERVECTORTABLE*/

^DRAM_BASE
HandleReset#4
HandleUndef#4
HandleSwi#4
HandlePrefetch#4
HandleAbort#4
HandleReserv#4
HandleIrq#4
HandleFiq#4


然后定义一个连续的数据段,并把中断处理函数的入口地址值赋给各字单元
ExceptionHandlerTable
DCDUserCodeArea
DCDSystemUndefinedHandler
DCDSystemSwiHandler
DCDSystemPrefetchHandler
DCDSystemAbortHandler
DCDSystemReserv
DCDSystemIrqHandler
DCDSystemFiqHandler


下面从程序的开始处分析:
AREAInit,CODE,READONLY
ENTRY
/*ROM起始地址向量表*/
BReset_Handler
BUndefined_Handler
BSWI_Handler
BPrefetch_Handler
BAbort_Handler
NOPReservedvector
BIRQ_Handler
BFIQ_Handler
/*B跳转范围限于+-32M内*/


/*以下是地址解析程序*/
IRQ_Handler
SUBsp,sp,#4
STMFDsp!,{r0}FD满递减堆栈执行寄存器压栈操作.
LDRr0,=HandleIrq//对应程序开始处以伪指令定义的向量表
LDRr0,[r0]//中断处理函数的地址赋给R0.
STRr0,[sp,#4]//中断处理函数的地址入栈
LDMFDsp!,{r0,pc}//实现程序跳转,目前没明白为什么又给r0赋值?


上面提到了还没有给中断向量表赋值,下面代码把中断处理函数的地址放到DRAM中断向量表里
EXCEPTION_VECTOR_TABLE_SETUP
LDRr0,=HandleReset
LDRr1,=ExceptionHandlerTable
MOVr2,#8
ExceptLoop
LDRr3,[r1],#4
STRr3,[r0],#4
SUBSr2,r2,#1DownCount
BNEExceptLoop;;


下面是中断处理函数
SystemIrqHandler
IMPORTISR_IrqHandler
STMFDsp!,{r0-r7,lr}
BLISR_IrqHandler
LDMFDsp!,{r0-r7,lr}
SUBSpc,lr,#4

它实际上只调用了下面的C语言的中断处理函数,其他什么也没做。
voidISR_IrqHandler(void)
{
IntOffSet=(U32)INTOFFSET;
(IntOffSet>>2)
(*InterruptHandlers[IntOffSet>>2])();//Callinterruptserviceroutine
}

以上编程思路是,先在系统初始化时重新建立一个中断向量表,并把相关的中断处理函数的地址放到中断向量表中。当系统监测到有中断源请求服务后,硬件实现pc跳转到地址0x08处,执行一个跳转指令BIRQ_Handler,然后执行地址解析程序,把中断向量表中的中断处理函数的入口地址赋给pc,开始响应中断。在中断处理函数的最后,执行
LDMFDsp!,{r0-r7,lr}
SUBSpc,lr,#4
实现中断的返回。

标签:  ARM指令  ARM中断  中断向量表


  发表评论

昵称: 验证码:
内容:
 
相关新闻
 · ARM中断实现过程的个人笔记
最新资讯
 · 便携电子产品电源测试的理想选择--吉时
 · 各种白光LED驱动电路特性评比
 · GPS技术在ITS的发展中得到了广泛的
 · 电子工程师心声:销售与我无关
 · 关于你的一生--IT人职业规划
 · 通过自适应曝光校正技术来改进拍照手机的
 · 嵌入式操作系统Nucleus下触摸屏驱
 · 模拟器件将投产手机3轴加速度传感器
 
  站内 站外
  Copyright(C)2008 Electronic Design & Application World All rights reserved.  《电子设计应用》杂志社 版权所有
联系电话:(86)10-66421136 66421836 66423836   传真:(86)10-66423936   京ICP备05012822号