AED设备OTA升级流程设计

5 阅读6分钟

AED设备OTA升级流程设计(云端管理系统)

系统架构说明
本系统由 门户(Portal)CODEC 两个微服务组成。

  • CODEC 使用私有协议通过 TCP(基于 Netty)与 AED 设备通信;
  • CODEC 接收到设备信息后,将其封装为 JSON 格式,通过 MQTT 中间件发送给 Portal;
  • Portal 负责固件管理、状态存储、用户交互及与对象存储(如阿里云 OSS)的对接。

OTA 升级核心要求

  • 每台设备可能包含多个固件文件,且必须按指定顺序升级;
  • 所有固件分片必须由 设备端主动发起拉取请求
  • 设备在拉取分片或完成安装后,必须立即反馈结果给 CODEC;
  • 支持 4G 物联网弱网环境,需具备断点续传、CRC 校验、错峰请求等能力;
  • CODEC 不直接访问对象存储(如阿里云 OSS),所有固件分片由 Portal 代理获取

一、数据模型设计

1. 固件元信息(FirmwareMeta)

字段说明
firmwareId固件唯一ID
deviceModel适配的设备型号
hardwareVersion适配的硬件版本
fileOrder升级顺序(从1开始)
fileName文件名(如 boot.bin
fileVersion文件版本号
fileSize文件总大小(字节)
crc32整个文件的 CRC32 校验值
totalChunks总分片数
chunkSize单个分片大小(建议 4KB)

管理员上传固件包时,Portal 解析并持久化上述信息,并将原始文件上传至阿里云 OSS。

2. 设备升级状态(DeviceUpgradeState)

字段说明
deviceId设备唯一标识
currentFileOrder当前正在处理的文件序号(初始为0)
targetFileName当前目标文件名
downloadedChunks已成功下载的分片索引列表(如 [0,1,2]
status状态:IDLE / WAITING_META / DOWNLOADING / VERIFYING / UPGRADING / SUCCESS / FAILED

二、OTA 升级完整流程(按文件粒度)

阶段 1:设备上报 + 服务端匹配升级包(触发)

  1. 设备上电,与 CODEC 建立 TCP 连接。
  2. 设备主动上报自身文件信息列表,包括:
    • deviceModel
    • hardwareVersion
    • 当前各文件的 fileNamefileVersionfileIndex
  3. CODEC 接收并解析设备上报数据
  4. CODEC 向 Portal 发起内部请求(HTTP/gRPC),携带设备信息:
    {
      "deviceId": "AED-12345",
      "deviceModel": "AED-X200",
      "hwVersion": "V1.2",
      "currentFiles": [
        { "name": "boot.bin", "version": "1.0.0" },
        { "name": "app.bin", "version": "2.1.3" }
      ]
    }
    
  5. Portal 查询固件库
    • 根据 deviceModel + hwVersion 匹配预定义的升级策略;
    • 比对 currentFiles,确定是否有新版本可升级;
    • 若有,按 fileOrder 顺序选出下一个待升级文件
  6. Portal 返回该文件的 meta 信息给 CODEC(仅返回一个文件)。
  7. CODEC 通过私有 TCP 协议将 meta 下发给设备
  8. 设备收到 meta 后
    • 缓存目标文件信息(fileName, totalChunks, crc32 等);
    • 启动错峰定时器(例如随机延迟 5~30 分钟,避免集中请求);
    • 立即向 CODEC 上报 OTA_META_ACK,确认接收。

✅ 此时设备进入“等待拉取”状态,但不立即请求分片。


阶段 2:设备主动拉取分片(循环)

设备在错峰时间到达后,开始逐片拉取。

  1. 设备向 CODEC 发送分片请求
    { "cmd": "req_chunk", "fileOrder": 1, "chunkIndex": 5 }
    
  2. CODEC 收到请求后
    • 向 Portal 发起内部 API 请求,携带 deviceIdfileOrderchunkIndex
    • Portal 接收请求后,从阿里云 OSS 读取对应的固件文件分片
    • Portal 将该分片的字节数组返回给 CODEC;
    • CODEC 通过 TCP 私有协议将分片数据下发给设备:
      { "cmd": "chunk_data", "fileOrder": 1, "chunkIndex": 5, "data": "base64...", "isLast": false }
      
  3. 设备收到分片后
    • 本地暂存;
    • 立即向 CODEC 上报接收结果
      { "cmd": "ack_chunk", "fileOrder": 1, "chunkIndex": 5, "success": true }
      
    • 若校验失败(如长度错误、超时),上报 success: false
  4. CODEC 收到 ACK 后
    • 更新设备状态,记录已成功接收的 chunk;
    • 若所有 chunks 已收齐,通知设备进入校验阶段。

⚠️ 关键原则

  • 所有分片请求均由设备发起;
  • 每次拉取后必须立即反馈,便于服务端追踪进度;
  • CODEC 不直接访问 OSS,所有分片由 Portal 代理获取,确保权限集中、安全可控;
  • 失败时设备可指数退避重试,服务端不主动重推。

阶段 3:文件校验、安装与结果上报

  1. 设备收齐所有分片后
    • 拼接完整文件;
    • 计算 CRC32,与 meta 中的 crc32 比对;
    • 若一致,执行安装(可能需重启);
    • 安装完成后,立即向 CODEC 上报升级结果
      { "cmd": "upgrade_result", "fileOrder": 1, "result": "SUCCESS" }
      
  2. CODEC 收到结果后
    • SUCCESS
      • 更新设备 currentFileOrder += 1
      • 若存在下一个文件(fileOrder + 1),则 重复阶段 1(向 Portal 查询下一个文件 meta);
      • 若无后续文件,标记设备 OTA 成功。
    • FAILED
      • 记录失败原因;
      • 终止后续文件升级(因顺序依赖);
      • 可触发告警通知管理员。

三、关键机制保障

机制说明
设备主动拉取所有 req_chunk 由设备发起,适应 4G 弱网(设备在信号好时拉取)
实时反馈闭环每个 chunk 和每个文件安装后必须上报结果,服务端才能推进状态
顺序控制必须完成 fileOrder = N 才能开始 N+1
断点续传设备记录已下载 chunks,只请求缺失部分
幂等性重复请求同一 chunk 应返回相同数据
错峰请求避免大量设备同时拉取造成网络拥塞
CRC 校验确保固件完整性,防止弱网传输损坏
存储访问隔离CODEC 无权直连 OSS,所有文件访问经 Portal 代理,提升安全性

四、异常处理策略

场景处理方式
设备离线CODEC 缓存 meta,待设备重连后重新下发
分片请求失败设备自动重试(带退避),服务端不干预
CRC 校验失败丢弃文件,上报失败,可人工介入或自动重试整个文件
升级卡住(超时)Portal 设置全局超时(如 72 小时),自动标记失败并告警
网络中断设备下次上线时继续未完成的升级(基于 downloadedChunks 状态)
Portal-OSS 访问异常CODEC 收到 Portal 错误响应后,向设备返回错误码,设备可重试

五、通信消息示例(简化)

// 设备上报当前文件
{ "cmd": "report_files", "model": "AED-X200", "hwVer": "V1.2", "files": [...] }

// CODEC 向 Portal 查询升级包
→ POST /api/v1/ota/check-upgrade { deviceId, model, hwVer, files }

// Portal 返回 meta{ "fileOrder": 1, "fileName": "boot.bin", "totalChunks": 100, "crc32": "a1b2c3d4" }

// CODEC 下发 meta 到设备
{ "cmd": "ota_meta", "fileOrder": 1, "fileName": "boot.bin", "totalChunks": 100, "crc32": "a1b2c3d4" }

// 设备 ACK meta
{ "cmd": "ota_meta_ack", "fileOrder": 1, "success": true }

// 设备请求分片
{ "cmd": "req_chunk", "fileOrder": 1, "chunkIndex": 5 }

// CODEC → Portal 请求分片
→ GET /api/v1/ota/chunk?fileOrder=1&chunkIndex=5

// Portal 从 OSS 获取后返回分片[binary data or base64]

// CODEC 返回分片给设备
{ "cmd": "chunk_data", "fileOrder": 1, "chunkIndex": 5, "data": "...", "isLast": false }

// 设备 ACK 分片
{ "cmd": "ack_chunk", "fileOrder": 1, "chunkIndex": 5, "success": true }

// 设备上报文件升级结果
{ "cmd": "upgrade_result", "fileOrder": 1, "result": "SUCCESS" }

六、总结

本设计严格遵循以下原则:

  • 设备驱动:升级由设备上电上报触发;
  • 服务端响应式:Portal 仅在被查询时返回 meta 或分片;
  • 设备主动拉取:所有分片由设备发起请求;
  • 实时反馈闭环:每一步操作均有 ACK 机制;
  • 顺序与完整性保障:多文件按序升级,CRC 校验确保安全;
  • 弱网友好:错峰、断点续传、重试机制支持 4G 物联网场景;
  • 安全架构:CODEC 不直连 OSS,所有文件访问由 Portal 代理,权限集中管理。

该方案可安全、可靠、可扩展地支撑 AED 设备的远程固件升级需求。