STM32F1 存储与 IAP 核心要点
STM32F1 存储与 IAP 核心要点速查
1. Flash 与 SRAM 的地址关系
在 STM32F1 的 4GB 统一地址空间中,Flash 和 SRAM 位于完全不重叠的地址段:
| 存储介质 | 物理地址范围 (以 F103C8T6 为例) | 作用类比 |
|---|---|---|
| Flash | 0x0800 0000–0x0801 FFFF | 硬盘 (存代码、常量) |
| SRAM | 0x2000 0000–0x2000 4FFF | 内存 (存变量、堆栈) |
重要映射:0x0000 0000
- CPU 上电后从
0x0000 0000取向量表。 - 通过 BOOT 引脚可将Flash / System Memory / SRAM之一映射到
0x0000 0000。 - 最常见:从 Flash 启动 →
0x0800 0000与0x0000 0000指向同一物理单元。
对工程师的直接意义
- 写链接脚本时:
ROM起始 →0x0800 0000,RAM起始 →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. 释放 SRAM | Flash 中的新 App 启动后,重新初始化变量区 | 原 Bootloader 占用的 SRAM 空间被自然覆盖,无需手动释放 |
关键结论
- 写入 Flash 的时机:一边接收一边写,或收完后立刻写,绝不拖延。
- SRAM 会被长期占用吗:不会。
- 跳转到 Flash 中的 App 后,App 的启动代码会重新设置堆栈和变量区。
- 原 Bootloader 占用的 SRAM 区域 = 不再被任何代码引用 ⇒自动成为空闲内存。
5. 工程落地建议(针对 STM32F1)
由于 STM32F1 的 SRAM 通常只有20–64 KB,推荐采用更稳定、更省 SRAM的方案:
✅ 推荐方案:Bootloader 与 App 均放在 Flash 中
| 区域 | 地址范围(示例) | 大小 |
|---|---|---|
| Bootloader | 0x0800 0000–0x0800 3FFF | 16 KB |
| App | 0x0800 4000– 芯片 Flash 末尾 | 剩余空间 |
| SRAM | 0x2000 0000–0x2000 4FFF | 全留给 App 变量 |
升级流程(不需要把 Bootloader 搬到 SRAM)
- Bootloader 在 Flash 中运行。
- 接收新固件(可放在 SRAM 里的小缓冲区,或逐包处理)。
- 直接擦写 Flash 中的 App 区域。
- 校验后跳转。
缺点:擦写 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。
