ARM 启动代码详解

上传人:ji****72 文档编号:37524129 上传时间:2018-04-17 格式:DOC 页数:6 大小:64.50KB
返回 下载 相关 举报
ARM 启动代码详解_第1页
第1页 / 共6页
ARM 启动代码详解_第2页
第2页 / 共6页
ARM 启动代码详解_第3页
第3页 / 共6页
ARM 启动代码详解_第4页
第4页 / 共6页
ARM 启动代码详解_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《ARM 启动代码详解》由会员分享,可在线阅读,更多相关《ARM 启动代码详解(6页珍藏版)》请在金锄头文库上搜索。

1、ARM 启动代码详解(启动代码详解(Vectors.c、Init.s、Target.c、 Target.h)4.2启动代码是芯片复位后进入 C 语言的 main()函数前执行的一段代码,主要是为 运行 C 语言程序提供基本运行环境,如初始化存储器系统等。ARM 公司只设计内核,不 自己生产芯片,只是把内核授权给其它厂商,其它厂商购买了授权且加入自己的外设后生 产出各具特色的芯片。这样就促进了基于 ARM 处理器核的芯片多元化,但也使得每一种 芯片的启动代码差别很大,不易编写出统一的启动代码。ADS(针对 ARM 处理器核的 C 语言编译器)的策略是不提供完整的启动代码,启动代码不足部分或者由厂

2、商提供,或者 自己编写。启动代码划分为4个文件:Vectors.c、Init.s、Target.c、 Target.h。Vectors.c 包含 异常向量表、堆栈初始化及中断服务程序与 C 程序的接口。Init.s 包含统初始化代码,并跳 转到 ADS 提供的初始化代码。Target.c 和 Target.h 包含目标板特殊的代码,包括异常处理 程序和目标板初始化程序。这样做的目的是为了尽量减少汇编代码,同时把不需要修改的 代码独立出来以减少错误。 4.2.1 Vectors.c 文件的编写文件的编写 4.2.1.1 中断向量表中断向量表 VectorsLDR PC, ResetAddrLDR

3、 PC, UndefinedAddrLDR PC, SWI_AddrLDR PC, PrefetchAddrLDR PC, DataAbortAddrDCD 0xb9205f80LDR PC, PC, #-0xff0LDR PC, FIQ_Addr ResetAddr DCD Reset UndefinedAddr DCD Undefined SWI_Addr DCD SoftwareInterrupt PrefetchAddr DCD PrefetchAbort DataAbortAddr DCD DataAbort nouse DCD 0 IRQ_Addr DCD IRQ_Handler

4、FIQ_Addr DCD FIQ_Handler 异常是由内部或外部源产生的以引起处理器处理的一个事件。ARM 处理器核支持7种类型 的异常。异常出现后,CPU 强制从异常类型对应的固定存储地址开始执行程序。这个固定 的地址就是异常向量。向量从上到下依次为复位、未定义指令异常、软件中断、预取指令 中止、预取数据中止、保留的异常、IRQ 和 FIQ。IRQ 向量“LDR PC, PC, #-0xff0” 使 用的指令与其它向量不同。在正常情况下这条指令所在地址为0X00000018。当 CPU 执行 这条指令但还没有跳转时,PC 的值为0X00000020,0X00000020减去 0X0000

5、0FF0为 0XFFFFF030,这是向量中断控制器(VIC)的特殊寄存器 VICVectAddr。这个寄存器保存 当前将要服务的 IRQ 的中断服务程序的入口,用这一条指令就可以直接跳转到需要的中断 服务程序中。至于在保留的异常向量“DCD 0xb9205f80”位置填数据0xb9205f8是为了使向量表中所有的数据32位累加和为0。 4.2.1.2 初始化初始化 CPU 堆栈堆栈 InitStack MOV R0, LR MSR CPSR_c, #0xd2 ;设置中断模式堆栈LDR SP, StackIrq MSR CPSR_c, #0xd1 ;设置快速中断模式堆栈LDR SP, Stac

6、kFiqMSR CPSR_c, #0xd7 ;设置中止模式堆栈LDR SP, StackAbtMSR CPSR_c, #0xdb ;设置未定义模式堆栈LDR SP, StackUndMSR CPSR_c, #0xdf ;设置系统模式堆栈LDR SP, StackSysMOV PC, R0 StackIrq DCD (IrqStackSpace + IRQ_STACK_LEGTH * 4 - 4) StackFiq DCD (FiqStackSpace + FIQ_STACK_LEGTH * 4 - 4) StackAbt DCD (AbtStackSpace + ABT_STACK_LEGTH

7、 * 4 - 4) StackUnd DCD (UndtStackSpace + UND_STACK_LEGTH * 4 - 4) StackSys DCD (SysStackSpace + SYS_STACK_LEGTH * 4 -4 ) ;/* 分配堆栈空间 */AREA MyStacks, DATA, NOINIT IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;中断模式堆栈 FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;快速中断模式堆栈 AbtStackSpace SPACE ABT_STACK_LEGTH * 4

8、;中止义模式堆栈 UndtStackSpace SPACE UND_STACK_LEGTH * 4 ;未定义模式堆栈 SysStackSpace SPACE SYS_STACK_LEGTH * 4 ; 系统模式堆栈 因为程序需要切换模式,而且程序退出时 CPU 的模式已经不再是管理模式而是系统模式 LR 已经不再保存返回程序地址,所以程序首先把返回地址保存到 R0中,同时使用 R0返 回。然后程序把处理器模式转化为 IRQ 模式,并设置 IRQ 模式的堆栈指针。其中变量 Stacklrq 保存着 IRQ 模式的堆栈指针的初始值,Irqstackspace 是分配给 IRQ 模式的堆栈空 间的开

9、始地址,IRQ_STACK_LEGTH 是用户定义的常量,用于设置 IRQ 模式的堆栈空间 的大小。程序使用同样的方法设置 FIQ 模式堆栈指针、中止模式堆栈指针、未定义堆栈指 针和系统模式堆栈指针。 程序使用编译器分配的空间作为堆栈,而不是按照通常的做法把堆栈分配到 RAM 的顶端, 之所以这样是因为这样做不必知道 RAM 顶端位置,移植更加方便;编译器给出的占用 RAM 空间的大小就是实际占用的大小,便于控制 RAM 的分配。对于 LPC2106来说,中 止模式是不需要分配堆栈空间的,这是因为 LPC2106没有外部总线,也没有虚拟内存机制, 如果出现取数据中止或取指令中止肯定是程序有问题

10、。而一般情况下也不需要模拟协处理 器指令或扩充指令,未定义中止也就意味着程序有错误,也不需要分配堆栈空间。 4.2.1.3 异常处理代码与异常处理代码与 C 语言的接口程序语言的接口程序C/OS-中断服务子程序流程图如图4-1所示:图4-1 中断服务子程序流程图 异常处理代码与 C 语言的接口程序如下: MACRO $IRQ_Label HANDLER $IRQ_ExceptionEXPORT $IRQ_Label ;输出的标号IMPORT $IRQ_Exception ;引用的外部标号 $IRQ_LabelSUB LR, LR, #4 ;计算返回地址STMFD SP!, R0-R3, R12

11、, LR ;保存任务环境MRS R3, SPSR ;保存状态STMFD SP!, R3LDR R2, =OSIntNesting ;OSIntNesting+LDRB R1, R2ADD R1, R1, #1STRB R1, R2BL $IRQ_Exception ;调用 c 语言的中断处理程序MSR CPSR_c, #0x92 ;关中断BL OSIntExitLDR R0, =OSTCBHighRdyLDR R0, R0LDR R1, =OSTCBCurLDR R1, R1CMP R0, R1LDMFD SP!, R3MSR SPSR_cxsf, R3LDMEQFD SP!, R0-R3,

12、R12, PC ;不进行任务切换LDR PC, =OSIntCtxSw ;进行任务切换MEND Undefined ;未定义指令b Undefined PrefetchAbort ;取指令中止b PrefetchAbort DataAbort ;取数据中止b DataAbort IRQ_Handler HANDLER IRQ_Exception ;中断 FIQ_Handler ;快速中断b FIQ_Handler Timer0_Handler HANDLER Timer0 ;定时器0中断 未定义指令异常、取指令中止异常、取数据中止异常均是死循环,其中原因在上一小节已 经说明。而快速中断在本应用

13、中并未使用,所以也设置为死循环。LPC2106使用向量中断 控制器,各个 IRQ 中断的人口不一样,所以使用了一个宏来简化中断服务程序与 C 语言 的接口编写。由 ARM 处理器核的文档可知,处理器进入 IRQ 中断服务程序时(LR4) 的值为中断返回地址,为了使任务无论在主动放弃 CPU 时还是中断时堆栈结构都一样,在 这里先把 LR 减4。其它的部分与 C/OS-要求的基本一致。ARM 处理核在进入中断服务 程序时处理器模式变为 IRQ 模式,与任务的模式不同,它们的堆栈指针 SP 也不一样,而 寄存器应当保存到用户的堆栈中,为了减少不必要的 CPU 时间和 RAM 空间的浪费,本移 植仅

14、在必要时将处理器的寄存器保存到用户的堆栈中,其它时候还是保存到 IRQ 模式的堆 栈中。同时,从编译器的函数调用规范可知,C 语言函数返回时,寄存器 R4R11、SP 不 会改变,所以只需要保存 CPSR、R0R3、R12和返回地址 LR,在后面保存 CPSR 是为了 必要时将寄存器保存到用户堆栈比较方便。 在异常处理代码与 C 语言的接口程序中没有与中断服务子程序流程图中的判断语句对应的 语句。判断语句是为了避免在函数 OSIntCtxsw()调整堆栈指针,这个调整量是与编译器、 编译器选项、C/OS -配置选项都相关的变量。在这里进行这些处理相对其它处理器结构 可能增加的处理器时间很少,但对于 ARM 来说,由于中断(IRQ)有独立的堆栈,在这里 这样做就需要把所有寄存器从中断的堆栈拷贝到任务的堆栈,需要花费比较多的额外时间。 而变量 OSIntNesting 为0时,并不一定会进行任务切换,所以本移植没

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号