嵌入式固件升级原理
嵌入式固件升级(Firmware Update)
固件升级是指,在设备不拆解,不更换芯片的前提下,为了修复Bug,增加新功能或提升性能,通过软件方式更新嵌入式系统固件.
什么是固件?
固件是指嵌入式系统中存储在非易失性存储器(如flash)中的程序.通常包括:
- Boot loader(引导程序): 负责设备的启动,检查固件完整性并决定是否进行固件升级
- App(应用程序): 设备的主要功能逻辑
- 有时候还包括:参数区,文件系统,配置数据.
固件升级可以分成3种方式:
- ICP(In Circuit Programming)在电路编程:
- 定义:使用外部编程器(如J-Link,AT-Link),通过JTAG/SWD等调试接口,直接烧写芯片Flash.
- 特点:常用于开发,调试,生产阶段.依赖专用硬件工具.
- 例子: 雅特力开发板通过AT-Link升级
- ISP(In System Programming)在系统编程:
- 定义: 通过系统已有通信接口(UART/USB/CAN),在整机状态下烧写固件.
- 特点:不需要拆机,常用于现场维护或批量升级.
- 例子: 通过串口使用特定的烧录软件进行烧录.
- IAP(In Application Programming)在应用编程:
- 定义: 通过软件在应用程序运行时实现固件升级.
- 特点: 设备在运行过程种完成升级.
- 例子:OTA升级
OTA(over the air)
定义: 通过网络(Wifi/4G/以太网)从服务器获取新固件并升级
特点: 自动化程度高,对可靠性和安全性要求最高.实现复杂.
要实现在程序运行时进行固件升级,程序通常分为两部分:
-
Bootlaoder:负责通信,下载,校验与切换.
-
App:正常业务逻辑运行部分. 要实现IAP,开发者需要先考虑以下条件是否满足:
-
芯片是否具备通信接口(UART/SPI/BLE/Wifi)
-
ROM/RAM空间是否充足
-
ROM是否支持在线擦写
固件升级流程
无论采用哪种升级方式,本质的升级流程是一致的.区别只在于,谁触发,谁传数据,谁写Flash.
- 进入升级模式
- 获取升级固件
- 固件合法性和完整性校验
- 准备Flash
- 写入新固件
- 写入后校验
- 设置升级标志
- 重启
- 新固件启动确认
进入升级模式
通过Bootloader判断,这次开机时正常运行,还是进入升级模式.
| 触发方式 | 场景 |
|---|---|
| 按键/跳线 | 产线,维修 |
| 上电检测IO | 强制下载模式 |
| 通信命令 | 串口/USB/网络 |
| 版本检测 | OTA自动升级 |
| 升级标志位 | 上次升级未完成 |
Boot loader必须能识别升级条件,且条件判断一定要简单,可靠.防止误进升级模式,从而进入死循环
升级标志没清: 每次上电都进升级模式
获取升级固件
固件的来源和升级方式有关:
| 升级方式 | 固件来源 |
|---|---|
| ICP | 编程器 |
| ISP | 串口/USB/CAN |
| IAP | Flash/SD卡 |
| OTA | 网络服务器 |
固件通常由两部分组成:
-
固件数据(bin/hex)
-
固件头(header)
- 长度
- 版本号
- CRC/Hash
- 签名信息
校验固件
这是固件升级中最重要的一步,只有确认固件的完整性和合法性才能保证固件升级的成功进行.
- 完整性校验
- CRC16/CRC32
- MD5/SHA-256
- 作用:防止传输错误/数据损坏
- 合法性校验
- 固件魔数(Magic Number):
- 存储在固件文件或存储介质特定位置的特定数值或字符序列,用来标识该固件的格式,版本,类型或有效性.
- 产品ID/芯片ID
- 固件签名(RSA/ECC)
- 作用: 防止刷错型号/非法固件
- 固件魔数(Magic Number):
在校验固件的时候
- 至少要有CRC
- 重要产品一定要有签名校验
- 校验失败->直接退出升级
CRC(Cyclic Redundancy Check)循环冗余校验. 是一种检测数据传输或存储过程中是否发生错误的校验方法. 它通过对数据进行特定的数学运算(通常是除法运算), 生成一个固定长度的校验码,并将其附加到数据中. 接收方可以使用相同的运算方式来验证接收到的数据是否与发送的数据一致.
整体流程如下:
- 数据准备: 假设你要传输的数据是一个二进制序列.
- 选择生成多项式: CRC使用一个固定的生成多项式来执行除法运算. 常用的多项式有CRC-16,CRC-32等,生成多项式的选择会影响校验码的长度和性能.
- 计算CRC值: 将数据和生成多项式进行除法运算,得到余数(即CRC值).
- 附加CRC: 将CRC值附加到数据后一起发送
- 接收方校验: 接收方使用相同的生成多项式对接收到的数据进行CRC计算,若结果为零,则表示数据没有错误,否则表示数据发生了错误
CRC校验的优点是简单,高效,可以有效检测到常见的传输错误. 但它并不能完全消除所有的错误,只是提供了一种有效的错误检测方法.
在嵌入式系统中,CRC通常用于数据通信(如串口通信,CAN总线等)和存储设备(如闪存)中,确保数据的完整性和准确性.
CRC使用的是模2除法(XOR除法).规则是:
- 不借位
- 不进位
- 相同为0
- 不同为1
MD5和SHA-256都是"哈希算法"(Hash Algorithm)
他们的作用是:
把任意长度的数据,计算成一个固定长度的指纹
MD5现在已被证明不安全. (可以构造两个不同的文件,却拥有相同的MD)
| 项目 | CRC | MD5/SHA-256 |
|---|---|---|
| 目的 | 检测随机错误 | 防止恶意篡改 |
| 是否安全 | 不安全 | 安全 |
| 是否抗攻击 | 不 | 抗攻击 |
| 计算方式 | 多项式除法 | 密码学算法 |
Flash准备(擦除&解锁)
为什么要单独一步?
Flash写入 ≠ \neq = 覆盖写
必须先擦除,再写.
这一步需要做的:
- 解锁Flash
- 擦除目标区域
- 检查擦除结果
常见的擦除方法:
- 整区擦除
- 按页擦除
- 写前擦除
- 擦除失败一定要检测
- 避免误擦除:
- boot loader区
- 参数区
- 注意Flash擦写寿命
写入新固件和校验
写入方式:
- 按页写
- 按块写
- 边接收边写
关键问题:
- 写入对齐
- 写入速度
- 写入停止(断电)
常见校验方式:
- 写完后重新算CRC然后对比
- 逐字节对比(慢,但最可靠)
失败处理:
- 标记升级失败
- 保持旧固件
- 等待重新升级
重启与新固件确认
重新启动后,程序先运行Bootloader.
bootloader跳转新固件
新固件进行自检
如果新固件启动失败
回滚至旧固件. 重新进入升级模式.
固件升级策略
单分区机制
- flash只有一个app区,升级固件时,先擦除原有的app区,然后将新固件写入dao
- 优点
- 节省空间
- 缺点:
- 升级过程中无法提供正常功能
- 在擦除和写入新固件的过程中,如果发生断电,flash里的旧固件已经被擦除,新固件没写完,设备变砖,只能靠恢复模式救回.
双分区机制(A/B分区)
-
A/B分区机制:设备的App通常分为两个分区,分别用于存储旧版固件和新固件
- 升级时,新固件会写入备用分区,然后切换启动标志,启动新固件
- 如果新固件启动失败,设备可以回滚到旧版本固件
-
升级方案设计
- 增量升级:只升级变化的部分,减少升级包大小和升级时间
- 全量升级: 每次都升级整个固件,适用于重大版本更新.
-
缺点:
- 升级过程中无法提供正常功能
- 在擦除和写入新固件的过程中,如果发生断电,flash里的旧固件已经被擦除,新固件没写完,设备变砖,只能靠恢复模式救回.
双分区机制(A/B分区)
- A/B分区机制:设备的App通常分为两个分区,分别用于存储旧版固件和新固件
- 升级时,新固件会写入备用分区,然后切换启动标志,启动新固件
- 如果新固件启动失败,设备可以回滚到旧版本固件
- 升级方案设计
- 增量升级:只升级变化的部分,减少升级包大小和升级时间
- 全量升级: 每次都升级整个固件,适用于重大版本更新.

937

被折叠的 条评论
为什么被折叠?



