【ARMv7-M】复位向量与启动过程
关于ARMv7上电复位后,通过复位向量初始化堆栈位置、PC指针,然后跳转到汇编入口,开始执行系统初始化等等操作,熟悉了解这个过程,对于嵌入式系统软件开发来说至关重要。不同的SOC在BootROM与Flash的地址分配上,可能有差别,但总体从复位开始,到程序正常启动运行的大概流程是通用的。
先看一幅图:
上图描述了在 ARMv7-M 架构(常用于 Cortex-M 系列处理器)中,中断向量表的定义、存储位置以及在系统启动时的关键重映射机制。其核心工作流程可分为以下几个部分:
1. 物理存储与逻辑映射
系统中有两个关键的中断向量表副本:
物理存储位置 (Flash): 中断向量表通常被永久地烧录在非易失性存储器(Flash)的起始位置(例如
0x0800_0000
)。图中Flash Memory
区域的中断向量表
组件即代表此物理副本。逻辑映射地址 (BootROM): 然而,ARM 架构规定,CPU 在上电或复位后,会固定地从地址
0x0000_0000
开始获取主栈指针(MSP)的初始值和复位异常向量。图中BootROM
框架内的中断向量表
组件代表的就是这个逻辑地址空间。
2. 重映射机制 (VTOR)
这两个地址空间最初并不重合。为了解决这个问题,ARMv7-M 引入了向量表偏移寄存器(VTOR)。
启动阶段: 在芯片启动初期,硬件可能会自动将 Flash 物理地址(
0x0800_0000
)映射到逻辑地址(0x0000_0000
),使得 CPU 能够正确读取到存储在 Flash 中的向量表。这是一种简单的硬件重映射。运行阶段: 在软件初始化后,可以通过配置 VTOR 寄存器,将中断向量表的逻辑地址直接指向物理存储地址(即
0x0800_0000
)。图中的虚线箭头通过VTOR重新映射
形象地表示了这一过程。完成重映射后,所有后续的中断发生时,CPU 都会根据 VTOR 指向的地址(Flash 中的物理向量表)来查找并执行对应的中断服务程序。
3. 初始化流程
图中的 复位向量
指向 复位句柄处理函数
,该函数是系统启动后执行的第一个程序,它负责关键的初始化操作:
.data 段初始化: 将已初始化的全局变量、静态变量的初始值从 Flash(
DATA_init
)复制到 SRAM 中的运行时位置(DATA_runtime
),如蓝色箭头所示。.bss 段清零: 将未初始化的全局变量、静态变量所在的内存区域(
BSS
)全部清零,如绿色箭头所示。栈初始化: 使用向量表中最开始的条目「初始化 SP」的值来设置主栈指针,图中通过隐藏线暗示了栈指针的初始值来源于向量表。
总结
中断向量表在物理上存储于 Flash,但通过 VTOR 重映射机制,使其在逻辑上能够响应 CPU 从 0x0000_0000
地址开始访问中断向量的要求。复位异常是启动流程的触发器,其服务函数不仅引导程序跳转到主应用程序,更肩负着完成数据段初始化、为 C 语言运行环境做好准备的关键任务。