根据ARM的芯片大都为杂乱的片上体系,这种杂乱体系里的大都硬件模块都是可装备的,需求由软件来设置其需求的作业状况。因而在用户的应用程序之前,需求由专门的一段代码来完结对体系的初始化。我们这类代码直接面临处理器内核和硬件控制器进行编程,一般都是用汇编语言。一般通用的内容包含:
中止向量表
初始化存储器体系
初始化仓库
初始化有特殊要求的断口,设备
初始化用户程序碑文环境
改动处理器形式
呼叫主应用程序
1. 中止向量表
ARM要求中止向量表有必要放置在从0地址开端,接连8X4字节的空间内。
每逢一个中止产生今后,ARM处理器便强制把PC指针置为向量表中对应中止类型的地址值。由于每个中止只占有向量表中1个字的存储空间,只能放置一条ARM指令,使程序跳转到存储器的其他地方,再碑文中止处理。
中止向量表的程序完结一般如下一共:
AREA Boot ,CODE, READONLY
ENTRY
B ResetHandler
B UndefHandler
B SWIHandler
B PreAbortHandler
B DataAbortHandler
B
B IRQHandler
B FIQHandler
其间关键字ENTRY是指定编译器保存这段代码,由于编译器或许会以为这是一段亢余代码而加以优化。链接的时分要保证这段代码被链接在0地址处,而且作为整个程序的进口。
2. 初始化存储器体系
(1)存储器类型和时序装备
一般Flash和SRAM同归于静态存储器类型,能够合用同一个存储器端口;而DRAM由于有动态刷新和地址线复用等特性,一般配有专用的存储器端口。
存储器端口的接口时序优化是非常重要的,这会影响到整个体系的功用。由于一般体系运转的速度瓶颈都存在于存储器拜访,所以存储器拜访时序应尽或许的快;而一起又要考虑到由此带来的安稳性问题。
(2)存储器地址散布
一种典型的状况是发动ROM的地址重映射。
3. 初始化仓库
由于ARM有7种碑文状况,每一种状况的仓库指针寄存器(SP)都是独立的。因而,对程序中需求用到的每一种形式都要给SP界说一个仓库地址。办法是改动状况寄存器内的状况位,使处理器切换到不同的状况,让后给SP赋值。留意:不要切换到User形式进行User形式的仓库设置,由于进入User形式后就不能再操作CPSR回到其他形式了,或许会对接下去的程序碑文形成影响。
这是一段仓库初始化的代码示例,其间只界说了三种形式的SP指针:
MRS R0,CPSR
BIC R0,R0,#MODEMASK 安全起见,屏蔽形式位以外的其他位
ORR R1,R0,#IRQMODE
MSR CPSR_cxfs,R1
LDR SP,=UndefStack
ORR R1,R0,#FIQMODE
MSR CPSR_cxsf,R1
LDR SP,=FIQStack
ORR R1,R0,#SVCMODE
MSR CPSR_cxsf,R1
LDR SP,=SVCStack
4. 初始化有特殊要求的端口,设备
5. 初始化应用程序碑文环境
映像一开端总是存储在ROM/Flash晒干的,其RO部分即能够在ROM/Flash晒干碑文,也能够转移到速度更快的RAM中碑文;而RW和ZI这两部分是有必要转移到可写的RAM里去。所谓应用程序碑文环境的初始化,便是完结必要的从ROM到RAM的数据传输和内容清零。
下面是在ADS下,一种常用存储器模型的直接完结:
LDR r0,=|Image$$RO$$Limit| ;得到RW数据源的开端地址
LDR r1,=|Image$$RW$$Base| ;RW区在RAM里的碑文区开端地址
LDR r2,=|Image$$ZI$$Base| ;ZI区在RAM晒干的开端地址
CMP r0,r1 ;比较它们是否持平
BEQ �
0 CMP r1,r3
LDRCC r2,[r0],#4
STRCC r2,[r1],#4
BCC �
1 LDR r1,=|Image$$ZI$$Limit|
MOV r2,#0
2 CMP r3,r1
STRCC r2,[r3],#4
BCC �
程序完结了RW数据的劳动和ZI区域的清零功用。其间引用到的4个符号是由链接器榜首输出的。
|Image$$RO$$Limit|:一共RO区末地址后边的地址,即RW数据源的开端地址
|Image$$RW$$Base|:RW区在RAM里的碑文区开端地址,也便是编译器选项RW_Base指定的地址
|Image$$ZI$$Base|:ZI区在RAM晒干的开端地址
|Image$$ZI$$Limit|:ZI区在RAM晒干的完毕地址后边的一个地址
程序先把ROM里|Image$$RO$$Limt|开端的RW初始数据劳动到RAM晒干|Image$$RW$$Base|开端的地址,当RAM这边的方针地址抵达|Image$$ZI$$Base|后就一共RW区的完毕和ZI区的开端,接下去就对这片ZI区进行清零操作,直到遇到完毕地址|Image$$ZI$$Limit|
6. 改动处理器形式
由于在初始化过程中,许多操作需求在特权形式下才干进行(比如对CPSR的修正),所以要特别留意不能过早的进入用户形式。
内核级的中止使能也能够考虑在这一步进行。假如体系中别的存在一个专门的中止控制器,这么做总是安全的。
7. 呼叫主应用程序
当一切的体系初始化作业完结之后,就需求把程序流程转入主应用程序。最简略的一种状况是:
IMPORT main
B main
直接从发动代码跳转到应用程序的主函数进口,当然主函数姓名能够由用户随意界说。
在ARM ADS环境中,还别的供给了一套体系级的呼叫机制。
IMPORT __main
B __main
__main()是编译体系供给的一个函数,担任完结库函数的初始化和初始化应用程序碑文环境,最终主动跳转到main()函数。