STM32启动过程,FLASH地址为啥不是0x0?

在 STM32 微控制器中,程序起始地址看似不符合预期(例如 FLASH 基地址为 0x08000000 而非 0x0),这一现象主要源于 ARM Cortex-M 架构的特殊设计和 STM32 的存储器映射机制。以下是详细解释:

1. Cortex-M 的向量表重定位机制

Cortex-M 处理器(如 STM32 采用的)在复位后,会从地址 0x00000000 处读取初始栈顶指针(MSP),并从地址 0x00000004 处获取复位向量(即程序入口地址)。但 STM32 的 FLASH 实际物理地址是 0x08000000,这就产生了地址不一致的问题。

解决方案

STM32 通过存储器映射机制,将 FLASH 的内容映射到地址 0x0 处。当 CPU 访问 0x0 地址时,实际上访问的是 0x08000000 处的 FLASH 内容。这种映射是硬件自动完成的,对软件透明。

2. STM32 的存储器映射

STM32 的存储器空间被划分为多个区域,典型映射如下:

  • 0x0000 0000 ~ 0x1FFF FFFF:系统存储器(SRAM、引导程序等)
  • 0x0800 0000 ~ 0x08FF FFFF:主 FLASH 存储器
  • 0x2000 0000 ~ 0x200F FFFF:SRAM
  • 0x4000 0000 ~ 0x5FFF FFFF:外设寄存器

关键机制

  • 系统存储器映射:复位后,0x0 地址默认映射到 FLASH(0x08000000),因此程序可以从 0x0 开始执行。
  • Boot 引脚配置:通过设置 BOOT0/BOOT1 引脚,可以改变 0x0 地址的映射,例如映射到系统存储器(用于 ISP 下载)或 SRAM(用于调试)。

3. 向量表地址寄存器(VTOR)

Cortex-M 允许通过VTOR 寄存器动态重定位向量表。默认情况下,VTOR 指向 0x0,即映射后的 FLASH 起始地址。如果需要(例如在 IAP 升级时),可以通过代码修改 VTOR 指向 SRAM 中的新向量表:

SCB->VTOR = 0x20000000;  // 将向量表重定位到SRAM (0x20000000)

4. 为什么 FLASH 物理地址是 0x08000000?

  • 历史原因:ARM 架构早期(如 ARM7/ARM9)采用冯・诺伊曼架构,程序和数据共用地址空间,0x0 通常是实际的起始地址。
  • Cortex-M 的改进:Cortex-M 采用哈佛架构,程序和数据有独立的总线,允许更灵活的存储器映射。STM32 将 FLASH 放在 0x08000000 是为了给系统存储器(如引导程序)留出空间。
  • 兼容性:通过映射机制,Cortex-M 保持了与传统 ARM 架构的启动流程兼容性(仍从 0x0 读取向量表)。

5. 启动流程示例

当 STM32 复位时:

  1. CPU 从0x00000000(实际映射到 0x08000000)读取栈顶指针。
  2. 0x00000004(实际为 0x08000004)读取复位向量(即Reset_Handler函数地址)。
  3. 执行Reset_Handler,初始化系统时钟、外设,并跳转到main()函数。

总结

  • 地址 0x0 是逻辑起始地址:CPU 通过映射机制访问 0x0,实际对应 FLASH 的物理地址 0x08000000。
  • 映射可配置:通过 BOOT 引脚或 VTOR 寄存器,可以改变 0x0 地址的映射目标。
  • 设计目的:这种机制兼顾了启动兼容性和系统灵活性,允许 STM32 支持多种启动模式(如从 FLASH、SRAM 或系统存储器启动)。

理解这一机制对 STM32 开发至关重要,特别是在处理中断向量表、IAP 升级或多应用分区时。

更多内容全在下方专栏

全网最受欢迎的嵌入式笔试专栏

笔试专栏包含全部最新的笔试必考考点,非常适合在找工作面经薄弱的同学

3000+订阅还会涨价,提前订阅提前享受,持续更新中。

专栏链接:https://www.nowcoder.com/creation/manager/columnDetail/mPZ4kk

#嵌入式笔面经分享#
全部评论

相关推荐

评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务