4. 版本构建与打包流程
本章重点:掌握从构建触发到固件签名、形成正式交付件的完整 SOP,理解不同触发方式下的编译环境隔离要求,以及输出物清单的规范性。
4.1 适用场景
- 固件开发完成后,需要将源码编译为可烧录/可升级的正式版本。
- 需要区分开发版、测试版、正式发布版的构建策略。
- 涉及多个硬件平台(如不同 MCU/SoC)或固件变体(如基础版、Pro 版)。
- 必须进行签名校验以确保固件完整性与来源可信。
4.2 前置条件
- 源码已提交至受控仓库:主干/特性分支通过代码评审,且无阻塞性问题。
- 编译环境已标准化:使用 Docker 容器或专用构建机,环境配置通过配置文件(如
build.env)管理。 - 签名密钥对已就绪:私钥存储在离线安全模块或 HSM 中;公钥预先烧录至设备安全区。
- 版本号规则已定义:遵循语义化版本
MAJOR.MINOR.PATCH-BUILDMETA,如2.1.0-beta.20240315。 - CI/CD 管道已配置:至少包含编译、静态检查、单元测试、打包、签名等阶段。
4.3 操作步骤
- 触发构建:根据触发条件自动或手动启动构建流水线。
- 代码推送至
release/*或master分支时自动触发。 - 定时构建(如每晚 2:00)用于生成 nightly 版本。
- 手工触发并指定版本号与目标平台。
- 代码推送至
- 准备编译环境:CI/CD agent 拉取对应平台的基础镜像(如
gcc-arm-none-eabi:12.2),安装依赖工具链及 SDK。 - 执行编译构建:运行构建脚本,生成目标固件二进制(.bin / .hex / .elf)。
# CMake 构建示例 cmake -B build -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -DTARGET=stm32h743 cmake --build build --target firmware_bin - 生成版本元数据:自动写入版本号、Git commit SHA、构建时间、平台标识符等。
// version.h 自动生成内容 #define FIRMWARE_VERSION "2.1.0-build.78" #define GIT_COMMIT "a1b2c3d4e5f6..." #define BUILD_DATE "2025-03-15T14:30:00Z" - 固件签名:使用私钥对固件哈希进行签名,附加公钥证书或签名区。
# 使用 OpenSSL 签名 (ECDSA) openssl dgst -sha256 -sign private_key.pem -out firmware.bin.sig firmware.bin - 打包输出物:将签名的固件、校验文件、版本说明、烧录脚本等组装为发行包。
- 归档与发布:上传至制品仓库(Nexus / Artifactory),同时将正式版同步至 OTA 服务器。
关键提醒:签名步骤必须在隔离环境中运行,私钥不得离开 HSM 或专用签名服务器。签名工具的输出应与固件文件一同打包。
4.4 输入与输出物
| 类别 | 输入物 | 输出物 |
|---|---|---|
| 代码 | Git 源码仓库(特定分支或 Tag) | 签名的固件二进制(.bin / .hex) |
| 配置 | 构建配置文件(CMakeLists.txt, .env) | 版本元数据文件(version.json) |
| 密钥 | 签名私钥(HSM 或离线安全存储) | 签名文件(.sig) |
| 工具 | 工具链镜像、编译依赖、签名工具 | 校验和文件(SHA256 或 CRC32) |
| 文档 | 版本变更日志(CHANGELOG.md) | 发行说明(Release Notes / README) |
4.5 责任边界
| 角色 | 职责 |
|---|---|
| 开发工程师 | 保证源码可构建、通过单元测试;提交规范的 changelog。 |
| 构建工程师 | 维护 CI/CD 管道与编译环境;处理构建失败异常;生成构建报告。 |
| 安全管理员 | 管理签名密钥生命周期;审计签名日志;确保私钥不泄露。 |
| 版本经理 | 审批版本发布;确认输出物完整性;更新 OTA 服务器清单。 |
4.6 记录材料
- 构建日志:保留详细的编译输出(如 Jenkins 控制台日志),至少保存 90 天。
- 签名日志:每次签名记录时间、操作人、固件哈希、签名算法。
- 制品清单:每个构建产物编号对应的输出物 MD5/SHA256 清单。
- 版本发布记录:版本号与 Git commit 对照表,用于追溯。
4.7 异常处理
常见异常及处置预案:
| 异常现象 | 可能原因 | 处理措施 |
|---|---|---|
| 编译失败 | 依赖版本冲突、编译器差异、源码错误 | 回退至上一次成功构建的镜像环境,锁定依赖版本;通知开发修复。 |
| 签名失败 | 私钥不可用、HSM 连接超时、签名服务繁忙 | 检查 HSM 状态;尝试重试 3 次,仍失败则转人工签名(离线流程)。 |
| 输出物不完整 | 打包脚本漏配、归档未成功 | 根据制品清单自检,缺少项通过脚本补充,重新触发打包步骤。 |
| 版本号冲突 | 手动重复构建未更新版本号 | 强制版本号由 CI 基于时间戳自动生成,禁止人工指定已有版本。 |
4.8 验收标准
- 构建流水线返回 0(无错误),且所有单元测试通过。
- 固定区签名校验通过:
openssl dgst -sha256 -verify public_key.pem -signature firmware.bin.sig firmware.bin返回 Verified OK。 - 输出物清单 100% 匹配制品仓库中的文件列表,且校验和一致。
- 版本元数据(版本号、commit SHA)与仓库 Tag 或 CI 构建号准确对应。
- 打包后的 OTA 升级包大小不超过设备 flash 分区限制,且格式(如 raw / compressed / encrypted)符合设计规范。