news 2026/6/15 13:21:45

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
嵌入式固件升级框架详解与实战经验

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

固件升级是指在设备不拆解、不更换芯片的前提下,为了修复Bug、增加新功能或提升性能,通过软件方式更新嵌入式系统固件。

对嵌入式产品而言,固件升级机制可以保持产品生命周期期间的生命力。

单片机有三种烧录方式:

ICP(In Circuit Programing)在电路编程;

使用仿真器(如 J-Link、ST-Link)经 SWD/JTAG 接口进行编程,常用于开发调试阶段或产线烧录。

特点是可靠、快速,但是依赖仿真器,而正版仿真器的采购成本一般也较高。

ISP(In System Programing)在系统编程;

芯片出厂前通常会自带一小段ROM Bootloader,可通过 UART/SPI/I²C 等接口与上位机交互,实现系统内烧录。

进入方式通常需拉高或拉低特定引脚。

特点是开发者无法修改ROM Bootloader逻辑,灵活性较差,烧录速度也比不上ICP,ISP常用于量产烧录或后期维护。

在某些调试场景下,比如上电后立即关闭SWD,会导致无法重新烧录,芯片变砖,就需要该种方式作为最后的救命手段。调试建议:初始化中可加 1~2 秒延时,避免出现该极端场景。

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运行异常(如掉电),可能导致系统不可启动,比前面提及的变砖更加严重;

总结

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 15:27:52

Android Compose 基础系列:您的第一个 Kotlin 程序

简介Kotlin 是一门现代、简洁、安全的编程语言,由 JetBrains 开发,并被 Google 作为 Android 官方首选语言。它可以与 Java 完美互操作,并支持跨平台开发,是现代 Android 开发的首选。🛠️ Kotlin 的主要用途✅ Androi…

作者头像 李华
网站建设 2026/6/15 9:50:46

BurpSuite工具HaE插件好用正则收集

0. 如何使用HaE HaE 主要由三块部分组成: Rules(规则信息管理):管理匹配特定信息的正则表达式 Config(配置信息管理):配置文件和忽略后缀名的管理 Databoard(数据集合面板):对匹配到的信息进行集中查询和管理 先说 Rules 规则信息管理,我们点击 Add ,界面如下: 通…

作者头像 李华
网站建设 2026/6/15 6:03:10

系统编程—线程的互斥与同步

线程的互斥和同步是多线程编程的核心问题,用于解决资源竞争和执行时序协调的问题,确保多线程程序的正确性、稳定性和可预测性。核心概念铺垫临界区(Critical Section):多个线程共享的资源(如全局变量、硬件…

作者头像 李华
网站建设 2026/6/15 12:39:30

解锁本地大模型推理性能:llama.cpp动态批处理实战指南

解锁本地大模型推理性能:llama.cpp动态批处理实战指南 【免费下载链接】llama.cpp Port of Facebooks LLaMA model in C/C 项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp 你是否遇到过这样的场景?当多个用户同时访问你的本地大模型…

作者头像 李华
网站建设 2026/6/15 12:39:10

【干货收藏】RAG分块策略全解析:7种方法提升大模型效果的实战指南

文章详解了RAG系统中提升效果的关键环节——分块(Chunking)策略,系统介绍了固定大小、语义、递归、文档、智能体、句子和段落七种主流分块方法,分析其优缺点与应用场景。实践建议从512 tokens搭配10-15%重叠率起步,优先采用递归和句子分块&am…

作者头像 李华
网站建设 2026/6/15 14:16:58

收藏!大模型学习别乱冲,这份进阶指南帮你少走2年弯路

在大模型学习社群和CSDN评论区,每天都能看到相似的迷茫:有人抱着《深度学习入门》啃了3个月,却连Llama模型都不会部署;有人跟风学了LoRA微调、RAG开发,换个项目场景就无从下手;更有人刷遍了免费教程&#x…

作者头像 李华