STM32F1 存储与 IAP 核心要点

📅 2026/7/9 9:15:19 👁️ 阅读次数 📝 编程学习
STM32F1 存储与 IAP 核心要点

STM32F1 存储与 IAP 核心要点速查

1. Flash 与 SRAM 的地址关系

在 STM32F1 的 4GB 统一地址空间中,Flash 和 SRAM 位于完全不重叠的地址段:

存储介质物理地址范围 (以 F103C8T6 为例)作用类比
Flash0x0800 00000x0801 FFFF硬盘 (存代码、常量)
SRAM0x2000 00000x2000 4FFF内存 (存变量、堆栈)

重要映射:0x0000 0000

  • CPU 上电后从0x0000 0000取向量表。
  • 通过 BOOT 引脚可将Flash / System Memory / SRAM之一映射到0x0000 0000
  • 最常见:从 Flash 启动 →0x0800 00000x0000 0000指向同一物理单元

对工程师的直接意义

  • 写链接脚本时:ROM起始 →0x0800 0000RAM起始 →0x2000 0000
  • 调试时看地址:0x08xxxxxx→ Flash(代码),0x20xxxxxx→ SRAM(变量)。

2. 程序在 SRAM 中运行 ⇒ 会占用“运行内存”吗?

结论:不会。这是一个常见的概念误解。

  • 运行内存通常指存放变量的 SRAM 空间。
  • 代码放到 SRAM 中执行,是占用代码存储区,与变量区是两片不同的区域。
  • 对于简单的 IAP 升级应用:
    • 代码区(SRAM 的一部分)存放 Bootloader 指令
    • 变量区(SRAM 的另一部分)存放堆栈/变量
    • 两者互不挤占

✅ 真正占用变量区的是:全局变量、静态变量、堆、栈,不是代码本身。


3. SRAM 中运行 vs Flash 中运行:谁更卡?

性能对比表

对比项在 Flash 中运行(常规)在 SRAM 中运行(IAP 临时)
访问速度有等待周期 (Flash 接口)零等待 (直接总线访问)
执行效率较慢更快
是否可同时擦写 Flash❌ 不可(有总线冲突)✅ 可(CPU 在 SRAM 跑,擦写 Flash)
掉电后代码保留✅ 保留❌ 立即丢失
工程风险高(易变砖)

结论

  • 不会更卡,反而更快
  • 但绝对不要将 SRAM 运行作为常态,仅适用于IAP 升级这个极短的窗口期

4. IAP 中:SRAM 里的程序究竟什么时候写 Flash?如何释放 SRAM?

标准“金蝉脱壳”流程

阶段动作说明
1. 加载到 SRAM将 Bootloader 或升级程序加载到 SRAM 并运行通常由一小段启动代码完成
2. 接收新固件通过 UART/USB/SPI 等接收固件数据暂存在 SRAM 缓冲区(可分批)
3. 写入 Flash立即边收边写到 Flash在 SRAM 中运行的代码主动擦写 Flash
4. 跳转关闭中断 → 重设向量表 → 跳转到 Flash 入口PC 指针指向0x0800 xxxx
5. 释放 SRAMFlash 中的新 App 启动后,重新初始化变量区原 Bootloader 占用的 SRAM 空间被自然覆盖,无需手动释放

关键结论

  • 写入 Flash 的时机一边接收一边写,或收完后立刻写,绝不拖延。
  • SRAM 会被长期占用吗不会
    • 跳转到 Flash 中的 App 后,App 的启动代码会重新设置堆栈和变量区。
    • 原 Bootloader 占用的 SRAM 区域 = 不再被任何代码引用 ⇒自动成为空闲内存

5. 工程落地建议(针对 STM32F1)

由于 STM32F1 的 SRAM 通常只有20–64 KB,推荐采用更稳定、更省 SRAM的方案:

✅ 推荐方案:Bootloader 与 App 均放在 Flash 中

区域地址范围(示例)大小
Bootloader0x0800 00000x0800 3FFF16 KB
App0x0800 4000– 芯片 Flash 末尾剩余空间
SRAM0x2000 00000x2000 4FFF全留给 App 变量

升级流程(不需要把 Bootloader 搬到 SRAM)

  1. Bootloader 在 Flash 中运行。
  2. 接收新固件(可放在 SRAM 里的小缓冲区,或逐包处理)。
  3. 直接擦写 Flash 中的 App 区域。
  4. 校验后跳转。

缺点:擦写 Flash 时 CPU 会有短暂停顿(Flash 总线忙)。
优点:极简、可靠、基本不占 SRAM。


6. 常见误区与避坑指南

误区真相
“在 SRAM 中跑代码会占满变量区”❌ 代码区和变量区是不同地址段,相互独立。
“SRAM 中跑程序会更卡”❌ 反而更快(零等待)。
“IAP 升级一定要全程序放到 SRAM”⚠️ 不是必要,且 SRAM 小容易失败,推荐 Flash 内 Bootloader。
“跳转后 SRAM 会被一直占用”❌ 新 App 启动后,原 Bootloader 代码区会被自然回收。
“Flash 中运行的程序不能擦写 Flash”✅ 可以,但会互相等待(用时间长、影响响应)。此时 SRAM 运行的优势才明显。

7. 一句话总结(给忙人)

  • Flash 与 SRAM地址独立,一个存代码,一个存变量。
  • SRAM 中跑代码更快,但不安全,只用于 IAP 临时擦写 Flash。
  • IAP 时边收边写 Flash,写完后跳转,SRAM自动释放
  • 工程上推荐Bootloader + App 全部放在 Flash,简单可靠,不占 SRAM。