双存储区技术是 STM32 微控制器实现 “即时固件更新” 的核心,通过将片上 Flash 划分为两个独立区域,让系统在运行当前固件的同时,完成新固件的接收与写入,更新后无需额外操作即可切换生效。该方案完美解决传统单存储区升级 “停机时间长”“掉电变砖” 的痛点,适用于工业控制、物联网等对连续性要求高的场景。本文基于 AN4767 应用笔记,详解双存储区固件更新的核心原理、实现流程与关键技术,结合 X-CUBE-DBFU 扩展包提供可落地的实操指南。
资料获取:双存储区 STM32 微控制器的即时固件更新
1. 核心原理:双存储区的架构与优势
1.1 双存储区定义与硬件支持
STM32 的双存储区是将用户 Flash 划分为两个半独立区域(Bank1 为主区、Bank2 为副区),两者地址空间独立但可通过寄存器动态映射。
- 支持型号:STM32L0 系列 Cat5、STM32L4 系列入门款 / USB OTG 款、STM32G4 系列 Cat.3 等,其他带双区 Flash 的 STM32 可参考适配。
- 存储特性:两个区域支持并行读写,写入副区时主区可正常运行代码,实现 “边运行边更新”。
1.2 核心优势
- 无停机更新:更新过程不中断当前业务,仅切换存储区时需微秒级复位,几乎不影响系统连续性。
- 高可靠性:新固件先写入副区并验证,验证通过再切换,避免升级中掉电导致设备瘫痪。
- 灵活扩展:双区可复用同一固件(升级场景),或存储不同功能程序(双工作模式),也可用于数据备份与记录。
2. 软件架构:三大核心组件协同设计
双存储区更新的软件架构需包含 “Bootloader + 双区固件 + 向量表重定位”,三者协同实现安全更新与无缝切换。
2.1 Bootloader:更新流程的控制核心
Bootloader 是上电后首先运行的代码,负责存储区管理与更新决策,核心功能如下:
- 启动判断:读取选项字节的 BFB2 标志,决定从主区或副区启动。
- 更新触发:通过串口、CAN、USB 等接口接收更新指令(如上位机发送的升级命令)。
- 固件管理:接收新固件数据,写入副区并执行校验(CRC、数字签名等)。
- 切换控制:校验通过后,配置存储区映射寄存器,下次启动自动切换至新固件区。
2.2 双区固件:统一二进制设计
与传统 IAP 升级不同,双存储区更新的主、副区可复用同一二进制固件,核心设计要求:
- 地址无关性:固件代码不依赖固定存储地址,通过链接脚本配置地址重映射。
- 数据隔离:易失性数据需避免跨区依赖,确保切换后数据完整性。
- 统一入口:两个区域的固件起始地址需配置为相同映射地址(如 0x08000000),通过存储区切换实现无缝跳转。
2.3 向量表重定位:中断正常响应的关键
Cortex-M 内核的中断向量表默认位于存储区起始地址,切换存储区后需重新定位向量表,避免中断异常:
- 重定位方案:将向量表复制到系统 RAM(L0 系列需 192B,L4 系列需 288B),更新 SCB->VTOR 寄存器指向 RAM 中的向量表地址。
- 操作时机:存储区切换前完成向量表复制与 VTOR 配置,确保中断处理不中断。
3. 完整更新流程:从触发到生效的五步走
基于 AN4767 与 X-CUBE-DBFU 扩展包,双存储区更新的标准流程如下,以串口传输新固件为例:
步骤 1:触发更新模式
- 上位机通过串口发送升级指令(如特定协议帧),主区固件接收后通知 Bootloader。
- 主区固件保存当前业务状态,跳转至 Bootloader 的更新流程。
步骤 2:接收新固件数据
步骤 3:写入副存储区
- Bootloader 解锁 Flash 副区,按扇区擦除原有数据(STM32 Flash 擦除单位为扇区)。
- 调用 HAL 库 Flash 编程 API(如
HAL_FLASH_Program),将接收的固件数据逐段写入副区。 - 关键操作:写入前需清除 Flash 错误标志,写入后验证数据一致性,避免编程错误。
步骤 4:固件验证与切换配置
- 完整性校验:计算副区固件的 CRC 值或验证数字签名,确认固件未损坏或篡改。
- 安全性可选:若需加密保护,可通过 STM32 内置 AES 加速器对固件解密后写入,防止 IP 泄露。
- 切换配置:设置选项字节的 BFB2 标志,或修改 SYSCFG 寄存器的存储区映射位(L0 的 UFB 标志、L4 的 FB_MODE 标志)。
步骤 5:重启生效
- Bootloader 触发系统软复位,复位后 ROM CODE 读取 BFB2 标志,自动从副区(新固件)启动。
- 新固件运行后,完成向量表重定位,恢复业务状态,更新流程结束。
4. 关键配置与注意事项
4.1 核心寄存器与选项字节配置
- BFB2 标志:位于选项字节,置 1 时复位后优先从副区启动,是自动存储区选择的核心开关。
- SYSCFG 寄存器:手动切换存储区时,通过修改 UFB(L0)或 FB_MODE(L4)位,动态更改存储区映射。
- VTOR 寄存器:中断向量表偏移寄存器,需配置为 RAM 地址(如 0x20000000),确保中断响应正确。
4.2 常见问题与避坑指南
- 链接错误 “Undefined symbol __use_two_region_memory”:需确认启动文件支持双区域内存模型,或在链接脚本中手动定义该符号。
- 切换后中断失效:未完成向量表重定位,需确保 VTOR 配置与向量表 RAM 地址一致,且地址对齐到 128 字节边界。
- 副区写入失败:Flash 未解锁或扇区未擦除,需先调用
HAL_FLASH_Unlock(),再执行擦除操作。 - 掉电风险:更新过程中需添加掉电检测,掉电时记录进度,上电后可恢复更新。
4.3 安全性增强方案
- 固件加密:使用 AES 硬件加速器对固件加密,Bootloader 解密后写入 Flash,防止固件被窃取。
- 身份认证:添加数字签名验证,仅允许通过认证的固件写入,避免恶意固件注入。
- 写保护:对 Bootloader 区域设置 Flash 写保护,防止其被篡改导致更新功能失效。
双存储区 STM32 的即时固件更新,核心是通过 “双区并行读写 + Bootloader 控制 + 向量表重定位”,实现无停机、高可靠的固件升级。其关键在于:
- 合理规划 Flash 分区,确保主副区独立且地址映射正确;
- 设计健壮的 Bootloader,覆盖固件接收、校验、切换全流程;
- 重视向量表重定位与安全性设计,避免中断异常与固件泄露。
该方案基于 AN4767 应用笔记与 X-CUBE-DBFU 扩展包,可直接适配 STM32L0/L4/G4 等系列,是工业级设备固件迭代的优选方案。
450