当前位置: 首页 > news >正文

嵌入式固件升级框架详解与实战经验

嵌入式固件升级(Firmware Update)是什么?

固件升级是指在设备不拆解、不更换芯片的前提下,为了修复Bug、增加新功能或提升性能,通过软件方式更新嵌入式系统固件。
对嵌入式产品而言,固件升级机制可以保持产品生命周期期间的生命力。

单片机有三种烧录方式:

  1. ICP(In Circuit Programing)在电路编程;
    使用仿真器(如 J-Link、ST-Link)经 SWD/JTAG 接口进行编程,常用于开发调试阶段或产线烧录。
    特点是可靠、快速,但是依赖仿真器,而正版仿真器的采购成本一般也较高。
  2. ISP(In System Programing)在系统编程;
    芯片出厂前通常会自带一小段ROM Bootloader,可通过 UART/SPI/I²C 等接口与上位机交互,实现系统内烧录。
    进入方式通常需拉高或拉低特定引脚。
    特点是开发者无法修改ROM Bootloader逻辑,灵活性较差,烧录速度也比不上ICP,ISP常用于量产烧录或后期维护。
    在某些调试场景下,比如上电后立即关闭SWD,会导致无法重新烧录,芯片变砖,就需要该种方式作为最后的救命手段。调试建议:初始化中可加 1~2 秒延时,避免出现该极端场景。
  3. IAP(In applicating Programing)在应用编程;
    本文所说的固件升级主要是基于 IAP(In-Application Programming)机制的实现。通过软件在运行时实现 Flash 擦写与编程。
    程序通常分为两部分:
  • Bootloader(引导程序):负责通信、下载、校验与切换;
  • APP(应用程序):正常业务逻辑运行部分。
    要实现 IAP,开发者需先考虑以下条件是否满足:
  • 芯片是否具备通信接口(UART / SPI / I²C / BLE / Wi-Fi)
  • ROM / RAM 空间是否充足
  • ROM 是否支持在线擦写

什么时候需要固件升级功能?

如果产品功能需要频繁迭代更新或远程维护,那么就需要在设计阶段考虑固件升级,同时也要考虑硬件成本、研发成本和测试成本。
固件升级功能的使用者可分为三类:开发人员、维护人员和用户。
如果只是开发调试阶段需要更新软件,可只做仿真器烧录;如果需要长期维护产品,则应预留Bootloader;如果是联网设备,则建议考虑OTA。

常见的升级方式

image
无论哪种方式,核心流程都是一致的:
跳转 → 握手 → 下载 → 校验 → 切换/回滚

升级流程详解

以终端与PC上位机交互升级为例:

1.跳转机制
进入Bootloader有两种方式,一种是复位,每次复位先执行Bootloader;一种是从APP应用程序使用跳转指令跳转到Bootloader,这种需要设计一定的触发条件,比如通过上位机指令等。
系统启动后首先运行 Bootloader。Bootloader 决定:

  • 是否进入升级模式;
  • 还是直接跳转到 APP。
    判断方法通常有两种:
  • 超时等待:上电后在 1s 内未收到升级信号则跳转 APP;简单但影响开机速度;
  • 升级标志位:上位机设置标志位,Bootloader 检查后进入升级模式。
    推荐做法:标志位 + 校验结合,可提升升级可靠性。
    image

2.握手阶段
升级前,终端需与上位机确认状态和版本信息,例如:
上位机:准备就绪?------------------------------------------------------终端:准备就绪
终端:当前我是v1.0版本,你是什么版本?------------------------上位机:我是v1.2版本
终端:请求升级至1.2版本,固件信息?-----------------------------上位机:固件名、固件大小、校验值
这一过程称为握手(Handshake),主要目的是:

  • 确认通信正常;
  • 校验版本信息;
  • 确定升级包信息。

3.下载阶段
握手完成后开始传输固件数据。
一般为分包下载:
终端:请发送第0包固件数据------------------------上位机:第0包数据
......
终端:请发送第Z包固件数据------------------------上位机:第Z包数据
接收数据,还需要将固件数据写入flash,需要选择升级策略:
image
image

模式特点单Bank占用空间少,但失败可能“变砖”双Bank安全可靠,支持回滚,但占用Flash更大

RAM建议:至少预留 2~3 倍单包大小的缓冲区,因为要在 RAM 中缓存接收数据、进行校验和 Flash 对齐写入,若包太大或 RAM 太小会影响速度与可靠性。
若下载过程同时保存当前包序号到flash,那么当系统掉电或通信中断,可通过该包序号实现断点续传;同时,在 Bootloader 启动阶段检测该标志,可自动恢复下载流程或清除异常状态,提高升级效率。

4.校验阶段
固件接收完成后进行完整性校验。
常用校验方法有CRC或者SHA校验,对于 MCU 通信型升级(UART、SPI等),CRC足够;对于 OTA 或安全性较高场景,建议 SHA + 签名机制。。
调试建议:写入完毕后从Flash回读再校验,避免边写边算导致误差。

5.切换与回滚
校验成功后,Bootloader将更新固件有效标志位,并在下次重启时跳转到新APP。
启动失败(如CRC错误或启动异常)时,若支持回滚机制(Rollback)则自动回退到上个版本,否则就滞留在Bootloader,等待下一次升级开始:
关于Bootloader和APP之间相互跳转,有几个注意事项:
跳转时应先关闭中断、重设堆栈指针(MSP)、并跳转至 APP 的 Reset_Handler,否则可能导致启动异常。

typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;void IAP_JumpToApplication(void)
{__disable_irq();                                  //关闭中断JumpAddress = *(__IO uint32_t*) (APP_ADDRESS + 4);//获取Reset_Handler指针JumpToApplication = (pFunction) JumpAddress;__set_MSP(*(__IO uint32_t*) APP_ADDRESS);         //从设堆栈指针JumpToApplication();                              //跳转
}

在Bootloader中会用到某些外设,如看门狗、UART、定时器等,跳转到APP后,这些外设可能还会继续工作,进而影响产品功耗或者外设配置冲突,建议在跳转前可增加反初始化。

安全性设计要求

在OTA场景,固件升级必须考虑安全问题:

  • 签名验证,要确保固件来源可信
  • 加密传输,避免固件在空中被截获
  • 版本防降级,防止回刷旧固件,利用旧固件版本漏洞攻击
  • 校验完整性,防止传输过程损坏、错漏

扩展

嵌入式产品由于资源限制和应用场景不同,有时候不会固定Bootloader+APP、单双Bank这些选择。会有许多变种设计,咱们在此适当展开说说。

1.单Bank+差分升级
image

上位机不直接发送整包固件,而是发送旧版本与新版本的差异数据,设备端根据当前固件内容和补丁生成新固件。
该方案的Flash 占用居于单bank和双bank之间,带宽和功耗最低,升级速度最快,但实现复杂度也是最高的。
优点:

  • Flash 占用居于单Bank和双Bank之间(多出一块Patch区);
  • 带宽占用最低,适合 BLE / LoRa / NB-IoT 等低速物联网设备;
  • 升级速度快、功耗低;
    缺点:
  • 实现复杂度高,需保证差分算法与旧固件一致;
  • 无法像双Bank支持回滚;
  • 如果掉电或Patch损坏仍有变砖风险。

2.双bootloader
image

前面我们使用bootloader给APP升级,那要是bootloader也需要升级呢?
在一些高可靠性或多阶段升级场景中,会使用两个 Bootloader:主Bootloader 和 子Bootloader。
正常情况下,主Bootloader 负责设备启动与APP升级,当主Bootloader需要升级或者被破坏时,子Bootloader进行接管。
优点:

  • 解决“Bootloader自身无法自升级”的问题;
  • 增加了安全性,避免主Bootloader损坏后系统无法启动问题;
    缺点:
  • 增加Flash占用(双Bootloader本身需要空间);
  • 启动流程、跳转流程更加复杂,调试门槛高;

3.RAM运行bootloader

这种方式同样也可以解决bootloader的问题。
把Bootloader 加载到 RAM 中运行,从而可以自由擦写整个 Flash(包括自身所在区域)。
优点:

  • 允许完全自由地重写Flash布局(包括Bootloader区);
  • Flash利用率高,可实现Bootloader自升级而不需双Bootloader设计,适合Flash紧张的系统;
    缺点:
  • RAM 需足够大以容纳Bootloader;
  • 一旦RAM运行异常(如掉电),可能导致系统不可启动,比前面提及的变砖更加严重;

总结

嵌入式固件升级是一个看似简单,但实现难度较大的功能,对可靠性、安全性、成本控制、性能、系统架构设计都有着严格的要求。

http://www.hskmm.com/?act=detail&tid=26723

相关文章:

  • 2025 年家用电梯最新推荐排行榜:精选技术领先、服务优质的实力品牌,助您精准选购
  • helm 模板的基础使用
  • 20251008J赛合订本
  • [计算机组成] 计算机字体文件及其运行原理
  • 后量子密码技术延迟随数据量增加而降低
  • 2025 南昌装修公司最新推荐榜单:权威解析本土标杆与新锐品牌,助力品质家装决策南昌装修设计 / 南昌装修设计师公司推荐
  • 1000th post Problem 1
  • 下行经济周期,就应该做只能在下行周期里做的事情
  • 题解:AT_agc065_d [AGC065D] Not Intersect
  • uniapp滚动导航 - unique
  • 滚动导航 - unique
  • windows剪切板工具
  • P1545 [USACO04DEC] Dividing the Path G 题解
  • 视频采集程序
  • java作业2
  • 关于PPT的课后作业
  • RK 系列 GPU 驱动检查方法
  • 咕乡
  • Linux随记(十八) - 详解
  • week2课后作业
  • Java 语言程序设计(第二讲 方法)动手动脑与课后实验问题整理文档 - 20243867孙堃2405
  • 算法第一章
  • mac打开app提示文件损坏解决方案
  • QBXT2025S刷题 Day7题
  • 无需重新训练即可更新语音识别词汇
  • 深入解析:vscode中无法使用npm node
  • 第一次算法作业
  • AI元人文:新的评价与启示
  • Ai元人文:岐金兰回应
  • Why is English commonly used in scientific literature?