# osp-upgrade-engine **Repository Path**: liudegui/osp-upgrade-engine ## Basic Information - **Project Name**: osp-upgrade-engine - **Description**: 工业级固件升级引擎,基于 newosp 基础设施,适用于 ARM-Linux 嵌入式系统 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-17 - **Last Updated**: 2026-02-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: Cpp17, 固件升级, ARM-Linux, 嵌入式, OTA ## README # osp-upgrade-engine > 面向工业嵌入式的 C++17 固件升级引擎: HSM 驱动 + 三层掉电保护 + 零堆分配 [Gitee 仓库](https://gitee.com/liudegui/osp-upgrade-engine) | [源码](https://gitee.com/liudegui/osp-upgrade-engine) | [文档](docs/design_upgrade_engine_zh.md) ## 快速开始 ### 项目简介 osp-upgrade-engine 是一个工业级 A/B 分区固件升级引擎,面向 ARM-Linux 嵌入式系统 (激光雷达、机器人、边缘计算等),专为资源受限环境 (32-256 MB RAM) 设计。 **核心特性**: - **HSM 驱动**: 8 阶段升级流程,基于 newosp `osp::StateMachine` - **零堆分配**: 全程栈/静态分配,热路径无动态内存 - **三层掉电保护**: raw 分区状态持久化 + U-Boot 冗余 env + bootcount 自动回滚 - **函数指针表 HAL**: 易于单元测试和仿真,无虚函数开销 - **x86 仿真层**: 完整升级流程可在开发机上验证 (包括掉电场景) - **编译期分发**: C++17 header-only,无外部依赖,仅依赖 newosp + mbedtls **设计对标**: | 维度 | SWUpdate / RAUC | osp-upgrade-engine | |------|-----------------|-------------------| | 运行时依赖 | D-Bus + systemd + GLib | newosp header-only (零外部依赖) | | 内存占用 | ~10-50 MB | < 73 KB | | 进程模型 | 独立 daemon | 嵌入应用进程 | | 掉电保护 | update_state 文件 | raw 分区 + U-Boot 冗余 env + bootcount | | 适用场景 | Yocto/Buildroot | 资源受限嵌入式 (32-256MB) | ## 架构概览 ### 存储布局 ``` eMMC: /dev/mmcblk0 ├── bootloader (p1) - U-Boot SPL + U-Boot (2 MB) ├── env (p2) - U-Boot 冗余环境变量 (128 KB) ├── recovery (p3) - 最小恢复系统 (32 MB) ├── rootfs_a (p4) - 主系统 A 分区 (1 GB) ├── rootfs_b (p5) - 主系统 B 分区 (1 GB) ├── config (p6) - 持久化配置 (64 MB) ├── data (p7) - 用户数据 (剩余) └── upgrade_state (p8) - 升级状态持久化 (64 KB, raw) ``` ### HSM 状态机 ``` Idle → Verifying → Writing → Switching → Rebooting → BootVerify → Rollback → Idle ``` 8 个状态,每次转换前持久化到 raw 分区,支持任意时刻掉电恢复。 ### 升级流程 (完整版) ``` 1. 应用层 StartUpgrade("/path/to/fw.osp") 2. Idle: 校验包头 (128B, CRC-32 + magic),版本/硬件兼容检查 3. Verifying: 流式计算 SHA-256,Ed25519 签名验证 4. Writing: 4KB chunk 循环读写,每 1MB 持久化进度,最后读回校验 5. Switching: U-Boot env 原子切换启动分区 6. Rebooting: 执行系统重启 7. (重启后) BootVerify: 新固件启动,应用层自检确认 8. Rollback: 掉电恢复或自检失败时回滚到旧分区 9. Idle: 升级完成,等待下次升级 ``` ## 技术亮点 ### 1. 三层掉电保护 | 层 | 机制 | 覆盖范围 | |------|------|--------| | 1 | raw 分区状态记录 + fsync | 每次状态转换前持久化 64B 记录 | | 2 | U-Boot 冗余 env + fw_setenv | 启动分区切换的原子性由 U-Boot 保证 | | 3 | bootcount 回滚机制 | bootcount > bootlimit 时自动回滚到旧分区 | ### 2. 128 字节二进制包头 ``` Offset Size Field 说明 0 4 magic[4] "OSP\x01" 4 1 header_ver 头格式版本 5 1 pkg_type 0=全量, 1=差分, 2=Bootloader 8 4 hw_compat_mask 硬件兼容性 bitmask (32 种板型) 12 4 fw_version major<<24 | minor<<16 | patch 16 4 min_version 差分升级基准版本 20 8 payload_size payload 字节数 28 32 payload_sha256 SHA-256 校验值 60 2 signature_len Ed25519 签名长度 (64B) 62 62 reserved_1 扩展预留 124 4 header_crc32 前 124 字节的 CRC-32 ``` 无需 JSON 解析器,CRC-32 快速校验,直接用 `>` 比较版本号。 ### 3. 函数指针表 HAL (零虚函数) ```cpp struct UpgradeHAL { int32_t (*open_partition)(const char*, int32_t, void*); ssize_t (*write_partition)(int32_t, const void*, uint32_t, void*); ssize_t (*read_partition)(int32_t, void*, uint32_t, void*); int32_t (*fsync_partition)(int32_t, void*); int32_t (*close_partition)(int32_t, void*); bool (*get_env)(const char*, char*, uint32_t, void*); bool (*set_env)(const char*, const char*, void*); void (*reboot_system)(void*); void* ctx; }; ``` 同一份代码可轻松切换生产环境 (POSIX HAL) 和仿真环境 (SimHAL),无虚函数开销。 ### 4. SpinOnce 轮询模式 ```cpp while (!engine.IsIdle()) { engine.SpinOnce(); // 处理 4KB chunk RunLidarPipeline(); // 其他任务不阻塞 } ``` 主循环不创建额外线程,升级在应用进程内执行。 ## 构建与使用 ### 依赖 - C++17 编译器 (gcc >= 9.0) - CMake 3.14+ - newosp (FetchContent 自动下载) - mbedtls (FetchContent 自动下载) ### 编译 ```bash mkdir build && cd build cmake .. -DOSP_GITHUB_MIRROR="https://ghfast.top/" \ -DOSP_BUILD_TESTS=ON \ -DOSP_BUILD_EXAMPLES=ON make -j$(nproc) ctest ``` **中国大陆**环境建议指定 `OSP_GITHUB_MIRROR` 以加速 FetchContent 下载 (使用 ghfast.top 或类似代理)。 ### 单元测试 ```bash ctest -V ``` 包括: - PackageHeader 解析与 CRC-32 校验 - HSM 状态转换与掉电恢复 - 分区写入与读回校验 - Ed25519 + HMAC-SHA256 签名验证 ### 仿真示例 x86 Linux 上完整升级演示: ```bash ./demo/demo_full_upgrade # 完整升级流程 ./demo/demo_power_loss # 掉电安全测试 (5 个场景) ``` ## API 设计 ### UpgradeEngine (门面类) ```cpp class UpgradeEngine { public: // 初始化 UpgradeEngine(UpgradeHAL* hal, uint32_t current_version, uint32_t local_hw_id, const uint8_t* pub_key, const char* state_dev_path) noexcept; // 升级控制 Expected StartUpgrade(const char* pkg_path) noexcept; void CancelUpgrade() noexcept; Expected ConfirmBoot() noexcept; // 轮询驱动 void SpinOnce() noexcept; // 状态查询 const char* GetStateName() const noexcept; uint8_t GetProgress() const noexcept; bool IsIdle() const noexcept; UpgradeError GetLastError() const noexcept; // 掉电恢复 void RecoverFromPersistentState() noexcept; }; ``` ### 应用层集成示例 ```cpp #include int main() { static const uint8_t kPubKey[32] = { /* Ed25519 公钥 */ }; UpgradeHAL hal = MakePosixHAL(); UpgradeEngine engine(&hal, MakeVersion(1,0,0), 3, kPubKey, "/dev/mtd5"); // 启动恢复 engine.RecoverFromPersistentState(); // 触发升级 engine.StartUpgrade("/mnt/usb/fw_v2.0.0.osp"); // 主循环驱动 while (!engine.IsIdle()) { engine.SpinOnce(); RunApplicationLogic(); } if (engine.GetLastError() != UpgradeError::kOk) { // 处理升级错误 } return 0; } ``` ## 文档 - [设计文档](docs/design_upgrade_engine_zh.md) -- 详细设计、存储布局、掉电安全、U-Boot 集成、资源预算 - [article](../embedded-cpp-articles/content/posts/blog/osp_upgrade_engine_design.md) -- 配套文章 ## 相关项目 - [newosp](https://github.com/DeguiLiu/newosp) -- C++17 header-only 嵌入式基础设施库 (HSM, Bus, Watchdog, Process) - [embedded-cpp-articles](https://gitee.com/liudegui/embedded-cpp-articles) -- 嵌入式 C++ 文章库 ## 许可证 MIT License