4. 版本构建与打包流程

本章重点:掌握从构建触发到固件签名、形成正式交付件的完整 SOP,理解不同触发方式下的编译环境隔离要求,以及输出物清单的规范性。

4.1 适用场景

  • 固件开发完成后,需要将源码编译为可烧录/可升级的正式版本。
  • 需要区分开发版、测试版、正式发布版的构建策略。
  • 涉及多个硬件平台(如不同 MCU/SoC)或固件变体(如基础版、Pro 版)。
  • 必须进行签名校验以确保固件完整性与来源可信。

4.2 前置条件

  1. 源码已提交至受控仓库:主干/特性分支通过代码评审,且无阻塞性问题。
  2. 编译环境已标准化:使用 Docker 容器或专用构建机,环境配置通过配置文件(如 build.env)管理。
  3. 签名密钥对已就绪:私钥存储在离线安全模块或 HSM 中;公钥预先烧录至设备安全区。
  4. 版本号规则已定义:遵循语义化版本 MAJOR.MINOR.PATCH-BUILDMETA,如 2.1.0-beta.20240315。
  5. CI/CD 管道已配置:至少包含编译、静态检查、单元测试、打包、签名等阶段。

4.3 操作步骤

  1. 触发构建:根据触发条件自动或手动启动构建流水线。
    • 代码推送至 release/* 或 master 分支时自动触发。
    • 定时构建(如每晚 2:00)用于生成 nightly 版本。
    • 手工触发并指定版本号与目标平台。
  2. 准备编译环境:CI/CD agent 拉取对应平台的基础镜像(如 gcc-arm-none-eabi:12.2),安装依赖工具链及 SDK。
  3. 执行编译构建:运行构建脚本,生成目标固件二进制(.bin / .hex / .elf)。
    # CMake 构建示例
    cmake -B build -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -DTARGET=stm32h743
    cmake --build build --target firmware_bin
  4. 生成版本元数据:自动写入版本号、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"
  5. 固件签名:使用私钥对固件哈希进行签名,附加公钥证书或签名区。
    # 使用 OpenSSL 签名 (ECDSA)
    openssl dgst -sha256 -sign private_key.pem -out firmware.bin.sig firmware.bin
  6. 打包输出物:将签名的固件、校验文件、版本说明、烧录脚本等组装为发行包。
  7. 归档与发布:上传至制品仓库(Nexus / Artifactory),同时将正式版同步至 OTA 服务器。
关键提醒:签名步骤必须在隔离环境中运行,私钥不得离开 HSM 或专用签名服务器。签名工具的输出应与固件文件一同打包。
版本构建与打包流程 ① 构建触发 ② 环境准备 ③ 编译构建 ④ 元数据生成 ⑤ 固件签名 ⑥ 打包 & 输出 ⑦ 归档 / 发布 输出物清单 签名固件 + 校验文件 + 版本说明 烧录脚本 + OTA 元数据 JSON

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 验收标准

  1. 构建流水线返回 0(无错误),且所有单元测试通过。
  2. 固定区签名校验通过:openssl dgst -sha256 -verify public_key.pem -signature firmware.bin.sig firmware.bin 返回 Verified OK。
  3. 输出物清单 100% 匹配制品仓库中的文件列表,且校验和一致。
  4. 版本元数据(版本号、commit SHA)与仓库 Tag 或 CI 构建号准确对应。
  5. 打包后的 OTA 升级包大小不超过设备 flash 分区限制,且格式(如 raw / compressed / encrypted)符合设计规范。