STM32的存储起始地址和运行起始地址为什么一样

这是一个嵌入式系统启动过程的核心问题。对于大多数简单的、没有使用操作系统的STM32应用来说,程序在Flash中可以直接运行,因此它的存储地址(在Flash中的位置)和运行地址(被CPU读取的位置)是相同的。​​

但这背后的原理更为重要。

1. 核心概念:哈佛架构与内存映射

STM32内核(如Cortex-M系列)采用了一种修改过的哈佛架构。这意味着:

  • 程序指令(代码)和数据存放在不同的物理内存空间中。
  • 但是,这些不同的物理内存(Flash, RAM, 外设等)都被映射到同一个统一的4GB线性地址空间中。这被称为内存映射。

在STM32的内存映射中(以Cortex-M4为例):

  • Flash(用于存储代码和常量)​ 的起始地址通常是 0x0800 0000。
  • RAM(用于存放变量)​ 的起始地址通常是 0x2000 0000。

2. 启动过程:为什么从0x0800 0000开始

当STM32芯片上电或复位后,内核会做的第一件事就是从中断向量表中读取前两个值:

  1. 第一个值(地址0x0800 0000)​ :是初始栈指针(MSP)​ 的值,它会被加载到SP寄存器。
  2. 第二个值(地址0x0800 0004)​ :是复位向量,也就是复位中断服务程序的地址。内核会跳转到这个地址开始执行程序。

​关键点在于:​ ​ 这个"复位向量"指向的地址,就是你的main函数或其他初始化代码的入口。这些代码本身就存储在Flash中。因此,CPU会继续从Flash(0x0800 0000及之后的地址)中读取指令并执行。

​所以,对于存储在Flash中的代码来说:​​

  • 存储地址:代码被烧录到Flash中,比如从0x0800 0000开始存放。
  • 运行地址:CPU直接从0x0800 0000这个地址读取指令来执行。

​因此,它们的起始地址是一样的。​​

3. 什么时候会不一样?(运行地址 ≠ 存储地址)

在某些高级或复杂的应用场景中,运行地址和存储地址就会不同。最常见的情况是:​将代码从Flash拷贝到RAM中运行。​​

​为什么要这么做?​​

  1. 追求极致速度:有些RAM(如STM32F4/F7/H7的CCM RAM或TCM RAM)的访问速度比Flash快得多,尤其是当CPU主频很高时。将关键的性能敏感代码(如算法循环、中断服务程序)搬到RAM中运行可以大幅提升执行速度。
  2. 固件升级:在运行IAP(在应用编程)功能时,新的固件程序可能先被下载到Flash的另一个位置(如0x0804 0000),然后在升级时,需要将这部分代码搬运到它的正常运行地址(如0x0800 0000)并跳转过去执行。

​在这种情况下:​​

  • 存储地址:代码被烧录在Flash的某个位置(例如 0x0804 0000)。
  • 运行地址:代码在运行时,需要被搬运到RAM(例如 0x2000 0000)或Flash的另一个区域,然后CPU从新的地址(0x2000 0000)取指执行。

4. 链接器脚本的角色

无论是哪种情况,都需要一个链接器脚本​(.ld文件)来告诉链接器:

  • 不同内存区域(Flash, RAM)的起始地址和大小。
  • 代码和数据的加载地址(存储地址)。
  • 代码和数据的运行地址(虚拟地址)。

对于简单的"在Flash中运行"的情况,链接器脚本会将.text(代码)段的加载地址和运行地址都设置为Flash的地址(如0x08000000)。而对于需要"拷贝到RAM运行"的代码,链接器脚本会指定其加载地址在Flash,但运行地址在RAM。

总结

场景 存储地址(加载地址) 运行地址(虚拟地址) 原因
​常见简单应用​ Flash (0x0800 0000) Flash (0x0800 0000) Flash支持就地执行(XIP),启动流程简单直接。
​高性能优化​ Flash (0x0800 0000) RAM (0x2000 0000) RAM速度远快于Flash,用于加速关键代码。
​固件升级(IAP)​​ Flash的备份区 (0x0804 0000) Flash的主程序区 (0x0800 0000) 新固件需要从下载区搬运到执行区才能运行。

所以,​​"STM32的存储起始地址和运行起始地址一样"是默认且最常见的情况 ,因为它最简单、最直接,完全利用了Flash的就地执行​ 特性。而当你有更高级的需求(如极致性能、OTA升级)时,才会让它们变得不同。

相关推荐
新晨单片机设计44 分钟前
S023E-基于STM32单片机WIFI智能插座(温度、定时)【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·wifi智能电表
硅基手札1 小时前
SPI技术系列 08 · SPI 控制器寄存器与 IP 架构
驱动开发·stm32·单片机·嵌入式硬件·mcu·架构·计算机外设
夏虫不可与之言冰1 小时前
第三课 点亮 LED 与定时器非阻塞闪烁
c语言·c++·vscode·单片机·嵌入式硬件·物联网
Chery11402 小时前
ESP32-C3FH8X技术解析:8MB Flash低功耗Wi-Fi与Bluetooth LE物联网SoC
单片机·物联网
元器件BOM超人2 小时前
STM32F103和GD32F103怎么选?
stm32·单片机·gd32
HRTOS2 小时前
HRTOS 4.0 本轮测试与升级工作阶段性总结
经验分享·单片机·嵌入式硬件·51单片机
‎ദ്ദിᵔ.˛.ᵔ₎3 小时前
STM32 时钟树与 RCC
stm32
kkkkkkkkkk_Z3 小时前
新手自学嵌入式 | 学习日记:EPIT/GPT定时器、输入捕获与PWM、UART通信与Modbus协议
单片机·gpt·学习
笨笨饿4 小时前
#142_VS Code.map文件插件的用法
git·python·stm32·单片机·嵌入式硬件·物联网·vim
三佛科技-187366133974 小时前
HN62512是什么芯片?HN62512多规格5V/12V500mA,24V350mA芯片解析
单片机·嵌入式硬件