基于ARM 的嵌入式系统程序开发要点--(四)异常处理机制的设计

 【序】 毕业在即,以前做的ARM和uC/OS的项目也忘的差不多了,近日将以前的项目温习了下,对ARM程序开发的启动部分代码及中断程序的编写进行了详细研究。在网上获此佳作 《基于ARM 的嵌入式系统程序开发要点》,对ARM上的裸机程序开发进行了详细陈述,包括启动的中断向量的设置、存储器配置、堆栈初始化、应用程序环境的拷贝准备、主程序的调用等以及ARM和Thumb代码的交互、重映射的处理,分析精妙,本人觉得把此文研读透了应付嵌入式ARM的面试基本没问题,在此与大家共享。

蓝色部分是本人还有点疑问的,欢迎朋友们指正,谢谢。

不知道什么原因上传后排版就变了,并且图不好传上来,在此只发关键章节,对此感兴趣的朋友可以来信索取全部文档。

                                                                                                              sailor_forever

                                                                                                                                                       

基于 ARM 的嵌入式系统程序开发要点
整理 : sailor_forever  [email protected]
原作者: ARM-CHINA-040415A  http://www.arm.com
 

(四)异常处理机制的设计

异常或中断是用户程序中最基本的一种执行流程或形态,这部分对ARM

构下异常处理程序的编写作一个全面的介绍。

ARM一共有7 种类型的异常,按优先级从高到低排列如下:

Reset

Data Abort

FIQ

IRQ

Prefetch Abort

SWI

Undefined instruction

请注意在ARM 的文档中,使用术语exception 来描述异常Exception 主要

是从处理器被动接受异常的角度出发描述,而interrupt 带有向处理器主动申请的

色彩。在本文中,对异常中断不作严格区分,都是指请求处理器打断

正常的程序执行流程,进入特定程序循环的一种机制。

 

1.异常响应流程

如以前介绍异常向量表时所提到过的,每一个异常发生时,总是从异常向量

表开始起跳的,最简单的一种情况是:

-1 异常向量表

向量表里面的每一条指令直接跳向对应的异常处理函数。其中FIQ_Handler()

可以直接从地址0x1C处开始,省下一条跳转指令。但是当执行跳转的时候有2 个问题需要讨论:跳转范围和异常分支。

 

11 跳转范围

我们知道ARM 的跳转指令B)是有范围限制的(±32MB,但很多情况

下不能保证所有的异常处理函数都定位在向量表的32MB 范围内,需要大于32MB 长跳转(有多条指令),而且因为向量表空间的限制只能由一条指令完成。这可以通过下面二种方法实现。

 

(a) MOV PC, #imme_value

把目标地址直接赋给PC 寄存器。

但是这条指令受格式限制并不能处理任意立即数,只有当这个立即数能够表示为一个8-bit 数值通过循环右移偶数位而得到,才是合法的。例如:MOV PC, #0x30000000 是合法的,因为0x30000000 可以通过0x03 循环右移4 位而得到。而 MOV PC, #30003000 就是非法指令。

 

(b) LDR PC, [PC+offset]

把目标地址先存储在某一个合适的地址空间,然后把这个存储器单元上的32

位数据传送给PC 来实现跳转

这种方法对目标地址值没有要求,可以是任意有效地址。但是存储目标地址

的存储器单元必须在当前指令的±4KB 空间范围内

注意在计算指令中引用的offset 数值的时候,要考虑处理器流水线中指令预

取对PC 值的影响,三级预取指令,即 pc为当前地址加 82个指令),以图-2 的情况为例:

offset = address location – vector address – pipeline effect

= 0xFFC – 0x4 – 0x8

= 0xFF0

-2 Literal pool 实现跳转

 

12 异常分支

ARM内核只有二个外部中断输入信号nFIQ nIRQ,但对于一个系统来说,

中断源可能多达几十个。为此,在系统集成的时候,一般都会有一个异常控制器

来处理异常信号。

-3 中断系统

这时候,用户程序可能存在多个IRQ/FIQ 的中断处理函数,为了从向量表

开始的跳转最终能找到正确的处理函数入口,需要设计一套处理机制和方法。

-4 中断分支

 

(a) 硬件处理

有的系统在ARM 的异常向量表之外,又增加了一张由中断控制器控制的特

殊向量表(IRQ中断)。当由外设触发一个中断以后,PC 能够从IRQ中断处自动跳到由AIC保存的这张特殊向量表中去,特殊向量表中的每个向量空间对应一个具体的中断源,共32个,AT91RM9200采用了这种方法。

举例来说,下面的系统一共有20 个外设中断源,特殊向量表被直接放置在

普通向量表后面。

-5 额外的硬件异常向量表

当某个外部中断触发之后,首先触发ARM 的内核异常,中断控制器检测到

ARM 的这种状态变化,再通过识别具体的中断源,使PC 自动跳转到特殊向量

表中的对应地址,从而开始一次异常响应。需要检查具体的芯片说明,是否支持这类特性。(和软件处理方法中的2区别在于此向量表是由硬件中断控制器保存的,而2中的中断向量表是用户自己定义的)

 

(b) 软件处理

多数情况下是用软件来处理异常分支,典型的是44b02410。因为软件可以通过读取中断控制器(INTOFFSET)来获得中断源的详细信息

-6 软件控制中断分支

因为软件设计的灵活性,用户可以设计出比上图更好的流程控制方法来。下

面是一个例子:

-7 灵活的软件分支设计

Int_vector_table 是用户自己开辟的一块存储器空间,里面按次序存放异常处

理函数的地址IRQ_Handler() 从中断控制器获取中断源信息,然后再从

Int_verctor_table 中的对应地址单元得到异常处理函数的入口地址,完成一次异

常响应的跳转。这种方法的好处是用户程序在运行过程中,能够很方便地动态改

变异常服务内容(动态改变异常处理函数的入口地址即可,2410采取了此方法)。

 

2.异常处理函数的设计

21 异常发生时处理器的动作

当任何一个异常发生并得到响应时,ARM 内核自动完成以下动作:

你可能感兴趣的:(ARM和uC/OS)