《ARM Cortex-R 学习指南》-【第十五章】-启动代码

文摘   2024-09-26 07:05   安徽  

第十五章 启动代码

本章讨论在基于ARM处理器的系统中运行的启动代码。它研究了处理器在复位后立即运行的代码,针对的是裸机系统。
裸机系统是指不使用操作系统而直接运行代码的系统。

15.1 启动裸机系统

当处理器复位时,它会在异常向量表中的复位向量位置开始执行。异常向量表的位置可能在地址0x00000000或地址0xFFFF0000。复位处理程序代码必须执行以下部分或全部操作:

  • 在多核系统中,将非主核心置于休眠状态。

  • 初始化异常向量。

  • 初始化内存系统,包括MPU。

  • 初始化核心模式的堆栈和寄存器。

  • 初始化任何关键的I/O设备。

  • 执行VFP的必要初始化。

  • 启用中断。

  • 更改核心模式或状态。

  • 调用main()应用程序。

首先需要考虑的是异常向量表的位置。必须确保它包含一组有效的指令,以便分支到相应的处理程序。

GNU汇编器中的_start指令可以告诉链接器将代码定位在特定地址,并且可以用于将代码放置在向量表中。在主程序执行期间,您可能希望从TCM访问向量表,以便快速访问异常处理程序。系统可能配置为在处理器启动前,使用从接口将启动代码从非易失性存储器复制到TCM中。

当核心复位后,预取单元可能会在启动代码复制到位于向量表的TCM中时被阻塞。当启动代码复制到TCM中时,预取逻辑被释放,并将直接从TCM中获取代码。

或者,向量表和异常处理程序也可能作为上电复位初始化代码的一部分,从外部ROM复制到TCM中。当代码复制到TCM后,TCM将被重新定位到向量表基地址。

下文示例1展示了一个可以放置在异常向量表中的代码示例。

然后,您可能需要为您的应用程序可能使用的各种模式初始化堆栈指针。下示例2展示了为FIQ和IRQ模式初始化堆栈指针的代码。

接下来的步骤是设置缓存、MPU和分支预测器。示例3展示了这类代码的示例。您需要先禁用MPU和缓存,并使缓存失效。示例代码针对的是Cortex-R7处理器。

对于Cortex-R4和Cortex-R5处理器,数据缓存失效可以通过一条CP15指令完成,即MCR p15, 0, r0, c15, c5, 0,但对于Cortex-R7处理器,启动代码必须显式地循环遍历缓存行并使其失效。

在Cortex-R4和Cortex-R5处理器中,分支预测在处理器复位后会自动启用。而在Cortex-R7中,分支预测可以在分支目标地址缓存失效后安全启用。启用分支预测通常会提高初始化代码的性能。


之后,您可以对MPU的一些区域进行编程,如下示例4中的示例代码所示。

Tcm可能必须在内存映射中重新定位并作为引导代码的一部分启用。如下示例5所示。

如果系统中存在二级缓存,并且在没有操作系统的情况下运行,此时也可能需要使其失效并启用。此外,还必须启用VFP访问权限。

接下来的步骤将取决于系统的具体情况。例如,可能需要:

  • 对将保存未初始化C变量的内存进行零初始化。

  • 将其他变量的初始值从ROM映像复制到RAM。

  • 设置应用程序的堆栈和堆空间。

  • 初始化C库函数。

  • 调用顶级构造函数(对于C++代码)。

  • 执行其他标准的嵌入式C初始化。

对于多核处理器,例如Cortex-R7处理器,常见的方法是允许集群中的单个核心执行系统初始化。如果相同的代码在不同的核心上运行,它将导致核心进入WFI状态并休眠,如第16章《电源管理》所述。CPU0初始化SCU标签RAM后,其他核心可能会醒来。示例6展示了示例代码,该代码确定它正在运行的处理器,然后根据是否在CPU0上运行,或者跳转到初始化代码,或者进入休眠状态。SMP操作系统通常会在稍后唤醒次要核心。



ARM研习社
嵌入式软件、C语言、ARM、Linux、内核、驱动、操作系统
 最新文章