免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1275 | 回复: 0
打印 上一主题 下一主题

ARM的异常处理 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-28 09:35 |只看该作者 |倒序浏览

刚接触ARM,对它的异常返回理解不是很好,总认为丢了两条指令没有执行,看了这个明白了,后面有一个PC的修正过程,修正的偏移量根据异常的类型不同!
ARM的异常处理
       对于ARM核,可以且只能识别7种处理器异常,每种异常都对应一种ARM处理器模式,当发生异常时,ARM处理器就切换到相应的异常模式,并调用异常处理程序进行处理。
       ARM核异常处理的一般过程是:
       (1)保存异常返回地址到r14_(确切的说是当前PC);
       (2)保存当前CPSR到SPSR_;
       (3)改写CPSR以切换到相应的异常模式和处理器状态(ARM状态);
       (4)禁止IRQ(如果进入FIQ则禁止FIQ);
       (5)跳转到相应异常向量表入口(例如IRQ跳转到IRQ_Handler入口);
       【注】复位异常处理会禁止所有中断,另外由于不用返回,因此不需要作(1)(2)步。

       上面的异常处理操作都是由ARM核硬件逻辑自动完成的,软件则需要完成以下工作:
       (1)为ARM核建立异常向量表。ARM体系结构中定义了各种异常的入口地址,例如复位异常的入口地址为0x0,发生复位时,ARM核自动跳转到0x0处开始执行。因此,需要在各入口地址处放一条跳转指令,跳转到相应的异常处理服务程序。因此,异常向量表就是从0x0地址开始的8个字(除了7条跳转到上述异常处理程序的跳转指令外,还有一个保留字)。
       (2)为各种处理器模式设置堆栈:由于异常处理程序中需要用到通用寄存器,因此,进入异常时,应该保存要使用的寄存器,保存方法是将其压入本异常模式下的堆栈,异常处理完毕后返回时,从堆栈中恢复通用寄存器的值。
(3)编写异常处理服务程序。异常服务程序应首先保护中断现场(将相关寄存器压入堆栈),并判断中断源以执行相应的服务子程序,完成后恢复中断现场并返回。典型的异常处理例程框架如下(以IRQ和FIQ为例):
SUBS      LR, LR, #4                   ;事先修正返回地址
STMFD  SP!, { reglist, LR }        ;保护现场
; ...                                            ;异常处理程序主体
LDMFD  SP!, { reglist, PC }^      ;恢复现场,(^表示将SPSR恢复到CPSR),并将LR出栈送PC返回
注意,各种处理器异常对返回地址的修正是不一样的。可以参考相关资料[1][2][3]。
       也可以在返回时修正LR,例如:
       STMFD  SP!, { reglist, LR }        ;保护现场
       ; ...                                            ;异常处理程序主体
       LDMFD  SP!, { reglist, LR }        ;恢复现场
    ;[从SPSR中恢复CPSR]
       SUBS      PC, LR, #4                   ;修正返回地址并返回

       因此,ARM处理器核心所能处理的就是异常向量表中的7种异常。而在一个具体的ARM芯片中,通常会有多个外部FIQ/IRQ中断源,还会提供一个中断控制器对这些中断源进行集中管理,因此,上面的IRQ/FIQ异常处理例程可以作为一个顶层服务程序,在程序主体中对中断源进行判决,跳转到相应的服务子程序。

       注意,本文只阐述个人对ARM处理器的异常处理机制的理解,对于具体某一ARM处理器芯片的IRQ/FIQ中断处理,需要对具体芯片的中断控制系统有正确的认识和理解。另外,对于可重入中断以及优先级中断处理,需要参考文献(2)的相关章节并加以深入理解。


What is the vector table on earth?
       中断向量表到底是什么呢?《ADS Developer Guide》中的定义如下:“中断向量表是一块32字节保留区域,通常在内存映像的底部。每种异常被分配一个字的空间。”这实际上指的是0x0地址开始的跳转到7种异常处理入口的7条跳转指令外加一个保留入口(8个字共32字节)。
       在《ARM嵌入式系统开发——软件设计与优化》中定义如下:“向量表的入口(entry)是一些跳转指令,跳转到专门处理某个异常或中断的子程序。每个入口包含一条跳转指令。”
       对于具体的ARM芯片,通常可以有多个IRQ/FIQ异常中断源,例如PXA270一共有34个外设级中断源可以发出IRQ/FIQ中断请求。如果要使用多个IRQ/FIQ中断,同样的,需要建立IRQ/FIQ中断向量表,这个表的条目(或入口,即entry):
(1)可以是跳转到对应ISR的指令机器码(使用“LDR PC, =ISR_Addr”伪指令跳转到对应入口以执行跳转指令,其中ISR_Addr是条目的地址标号);
(2)也可以是对应ISR的入口地址(在IRQ/FIQ异常处理程序中使用“LDR PC, [Rn, #ISR_OFFSET]”进行散转,Rn中事先保存IRQ_Table的基址,注意ISR_OFFSET相对于该LDR指令的地址(PC值)的偏移量不可超过4KB,亦即1K个字)。

【参考资料】
(1)《ARM体系结构与编程》
(2)《ARM嵌入式系统开发——软件设计与优化》
(3)《ADS Developers Guide》
(4)《ARM Architecture Reference Manual(2nd Edition)》


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/74524/showart_1094136.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP