第三章:固件版本管理
版本管理这事儿,说白了就是给固件一个「身份证」。我见过太多团队,版本号乱写,升级出问题都不知道回退到哪个版本。今天咱们就把这块聊透。
3.1 版本号规范:别让数字骗了你
版本号不是随便写的。它要能传递信息。我个人习惯用三段式:主版本.次版本.修订号。
| 字段 | 含义 | 举例 |
|---|---|---|
| 主版本 | 重大架构变更,不兼容升级 | 2.0.0 → 3.0.0 |
| 次版本 | 新增功能,向下兼容 | 2.1.0 → 2.2.0 |
| 修订号 | Bug修复,小改动 | 2.1.0 → 2.1.1 |
我在项目中遇到过一件事:某次紧急修复,有人直接把版本号从 1.3.2 改成了 1.3.3,结果发现改错了,又改成 1.3.4。你想想看,现场运维的人看到版本号跳来跳去,根本不知道哪个才是对的。
另外,我还会在版本号后面加一个「构建号」。比如 2.1.0.20250315,这样一眼就能看出是 2025 年 3 月 15 日构建的。嗯,这个细节在排查问题时特别有用。
3.2 版本发布策略:别一股脑全推出去
发布固件,最忌讳的就是「全量推送」。你想想看,万一有 bug,所有 POS 机都变砖了,那画面太美我不敢看。
我常用的策略是灰度发布。说白了,就是先让一小部分设备升级,观察没问题了,再逐步扩大范围。
// 灰度发布流程示例
1. 内部测试(5台设备)
2. 小范围公测(50台设备)
3. 区域推送(500台设备)
4. 全量推送(所有设备)
每个阶段至少观察 24 小时。我曾经因为着急,跳过小范围公测,结果某个型号的屏幕驱动不兼容,导致 200 台 POS 机花屏。从那以后,我再也不敢跳步骤了。
还有一个细节:版本冻结。在发布前一周,代码库要冻结,只允许修 Bug,不允许加新功能。这个规矩我吃过亏才立下的——有一次发布前三天还在加功能,结果测试没覆盖到,上线就崩了。
3.3 版本回退机制:给自己留条后路
回退机制,说白了就是「后悔药」。但后悔药也得提前备好,不能临时抱佛脚。
我设计的回退机制分三层:
- 应用层回退:固件本身保留两个版本(当前版本 + 上一个版本)。升级失败时,自动回退到上一个版本。
- Bootloader 层回退:如果应用层完全损坏,Bootloader 还能从备份区加载固件。
- 远程回退:通过后台下发指令,强制设备回退到指定版本。
// 回退逻辑伪代码
if (新固件启动失败) {
if (备份固件存在) {
加载备份固件;
标记回退事件;
} else {
进入恢复模式;
等待远程指令;
}
}
这里有个坑:回退不能无限次。我曾经见过一台设备来回回退 10 次,最后 Flash 都写坏了。所以我会限制回退次数,比如最多回退 3 次,之后必须人工介入。
嗯,还有一个容易被忽略的点:回退后的数据兼容性。比如新版本改了数据库结构,回退到旧版本后,旧版本读不了新数据怎么办?我的做法是:回退时,把数据也回退到上一个版本的格式。如果做不到,至少保证设备能正常启动,数据丢失总比设备变砖强。
最后说一句:版本管理不是技术问题,是管理问题。你定好规矩,团队执行到位,才能避免「版本地狱」。我个人习惯把版本号、发布策略、回退机制写进团队的《固件开发规范》里,新人来了先读这个,能少踩很多坑。