"); //-->
一.启动代码的功能与实现
启动代码主要是在主程序运行之前初始化系统硬件及软件的运行环境,它的主要功能包括以下几个方面:
■ 建立异常向量表
■ 初始化系统堆栈
■ 初始化硬件
■ 应用程序执行环境初始化
■ 跳转至主函数
下面我们来分别讲解一下:
1. 建立异常向量表
异常向量表一般位于启动代码的开始部分,它是用户程序与启动代码之间以及启动代码的各部分之间联系的纽带。它由一个一个的跳转函数组成,它就像一个普通的散转函数,只不过散转的过程中有硬件机制参与,当系统发生异常时,ARM处理器会通过硬件机制强制将PC指针指向异常向量表中对应的异常跳转函数存储的地址,然后程序会跳转到相应的异常中断服务程序去执行。下面我们来逐步了解一下异常向量表。
ARM有7种异常,它们分别是:
复位异常,当开发板上电或复位时进入;
未定义指令异常,当遇到无法识别的指令时进入;
软中断异常,当发生软中断时进入;
预取中止异常,发生指令预取错误时进入;
数据中止异常,对数据访问不能完成时进入;
IRQ异常,当发生IRQ中断时进入;
FIQ异常,当发生FIQ中断时进入;
除了这7种异常之外,异常向量表中还有一个保留位置,所以建立异常向量表需要开辟一块大小为8×4字节的空间,每个异常占据一个字(4个字节)的空间,这一个字的空间包含的是一个跳转指令,通过这条指令使PC指向相应异常处理函数的入口,具体的异常处理函数在别处实现。
异常向量表中指令、存储地址等对照表如表1所示:
表1
地址 |
指令 |
异常名称 |
进入时处理器模式 |
0x00 |
B Reset |
复位异常 |
管理模式 |
0x04 |
B HandlerUndef |
未定义指令异常 |
未定义模式 |
0x08 |
B HandlerSWI |
软中断异常 |
管理模式 |
0x0c |
B HandlerPabort |
指令预取异常 |
中止模式 |
0x10 |
B HandlerDabort |
数据中止异常 |
中止模式 |
0x14 |
B . |
保留 |
—— |
0x18 |
B HandlerIRQ |
IRQ中断异常 |
中断模式 |
0x1c |
B HandlerFIQ |
FIQ中断异常 |
快中断模式 |
异常向量表有关的代码如下:
CODE32 //表明是ARM指令
AREA startup,CODE,READONLY //AREA表明段,startup是段名,CODE表明是代码段,//READONLY是性质-只读
ENTRY //函数入口
B ResetInit //复位异常
B HandlerUndef //未定义异常
B HandlerSWI //软中断异常
B HandlerPabort //取指中止异常
B HandlerDabort //数据中止异常
B . //保留
B HandlerIRQ //中断异常
B HandlerFIQ //快中断异常
ARM要求异常向量表必须存储在0地址处,这样当开发板上电或复位时,PC会指向0地址处,进而跳转到复位异常处理函数函数ResetInit,这个函数负责完成系统的初始化工作,即初始化堆栈、初始化硬件、初始化应用程序执行环境、跳转至主函数;发生其他异常时ARM通过硬件机制将PC指向异常向量表对应的位置,进而跳转至相应的异常处理函数。
复位异常的处理函数完成的功能我们下面会讲解(2至5大点),在此不再赘述,我们来分别看一下其他异常处理函数是怎么处理的。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。