MCU OTA 服务

更新时间:2025-06-17 03:44:49下载pdf

OTA(Over the air)即空中下载技术,通过网络远程为设备更新软件程序。

蓝牙 Mesh 标准协议(通用对接固件 key:keyen8gu,版本为 v0.2 以上)接入支持 MCU OTA 功能。

首先将需要升级的固件文件通过 涂鸦开发者平台 上传至涂鸦服务器,配置好升级操作。蓝牙模组收到云端推送后会根据以下协议将文件进行分包传输,最终 MCU 接收升级文件并写入本地闪存,实现固件的升级。详细的平台操作,请参考 固件升级选择固件版本

升级流程

模组MCUOTA 升级请求(0xDA)OTA 升级请求回复(0xDA)回复结果是否允许升级不允许或超时未回复,结束失败,不进行以下流程OTA 升级文件信息(0xDB)OTA升级文件信息回复(0xDB)回复结果是正常升级,其他回复或超时未回复,结束失败,不进行以下流程OTA 升级文件偏移(0xDC)OTA 升级文件偏移回复(0xDC)接收设备端的偏移量,超时未回复结束失败,不进行以下流程群升偏移量固定 0,可忽略回复OTA 升级数据(0xDD)OTA 升级数据回复(0xDD)回复结果是成功他回复或超时未回复,结束失败不进行以下流程,群升忽略回复loop[固件整体传输完成?]OTA 升级校验(0xDE)OTA 升级校验回复(0xDE)回复结果是成功其他回复或超时未回复,结束失败,不进行以下流程OTA 升级结束(0xDF)模组发送结束结果是否成功若结果成功,MCU 等待 500 ms 重启,否则不重启OTA 升级结束回复(0xDF)模组MCU

指令列表

命令字 命令说明
0xD8 模组主动获取 MCU 当前版本号
0xD9 MCU 主动上报当前版本号
0xDA MCU OTA 升级请求
0xDB MCU OTA 升级文件信息
0xDC MCU OTA 升级文件偏移
0xDD MCU OTA 升级数据传输
0xDE MCU OTA 升级校验
0xDF MCU OTA 升级结束

指令设计

获取 MCU 版本号(CMD-0xD8)

模组发送

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xD8
4
5
2 数据长度 0x00
0x00
6 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

MCU 返回

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xD8
4
5
2 数据长度 0x00
0x08
6-13 8 Data 见下表
14 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

Data 格式

1-3 4-6 7-8
MCU-soft-version MCU-hard-version Len
  • MCU-soft-version:MCU 当前固件软件版本号,例如 0x010000 代表版本号为 1.0.0
  • MCU-hard-version:MCU 当前固件硬件版本号(PCBA 版本号),例如 0x010000 代表版本号为 1.0.0
  • Len:此长度为 OTA 升级数据(0xDD)中数据包最大长度,MCU 根据自身资源情况,通过此接口设定后续升级数据包最大长度。
  • MCU 可以协商的升级数据长度(Len)的长度范围为 64 字节到 194 字节,超出范围模组将会将长度定到默认 194 字节。
  • CMD-0xD8:蓝牙模组每次启动后在第一次发送心跳收到回复后,发送一次主动查询 MCU 版本号命令。

MCU 主动发送当前版本号(CMD-0xD9)

MCU 发送

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xD9
4
5
2 数据长度 0x00
0x08
6-13 8 Data 见下表
14 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

Data 格式

1-3 4-6 7-8
MCU-soft-version MCU-hard-version Len
  • MCU-soft-version:MCU 当前固件软件版本号,例如 0x010000 代表版本号为 1.0.0
  • MCU-hard-version:MCU 当前固件硬件版本号(PCBA 版本号),例如 0x010000 代表版本号为 1.0.0
  • Len:此长度为 OTA 升级数据(0xDD)中数据包最大长度,MCU 根据自身资源情况,通过此接口设定后续升级数据包最大长度。
  • MCU 可以协商的升级数据长度(Len)的长度范围为 64 字节到 194 字节,超出范围模组将会将长度定到默认 194 字节。
  • CMD-0xD9:MCU 在每次启动时(串口初始化完成后)主动发送一次当前的版本号到模组。如果没有收到响应,需要重新发送,重试机制根据自身情况决定。此要求是为了确保模组能及时拿到包的版本号并上报。

模组返回

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xD9
4
5
2 数据长度 0x00
0x08
6 1 State
  • 0x00:成功
  • 0x01:失败
7 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

OTA 升级请求(CMD-0xDA)

模组发送

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDA
4
5
2 数据长度 0x00
0x00
6 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

MCU 返回

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDA
4
5
2 数据长度 0x00
0x04
6-9 4 Data 见下表
10 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

Data 格式

1 4-6
State version
  • State
    • 0x00:允许升级
    • 0x01:拒绝升级
  • version:当前固件版本号,例如 0x010002 代表版本号为 1.0.2

OTA 升级文件信息(CMD-0xDB)

描述 MCU 升级文件的信息,MCU 可以对升级信息进行对比。

模组发送

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDB
4
5
2 数据长度 0x00
0x23
6-40 35 Data 见下表
41 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

Data 格式

8 字节 3 字节 16 字节 4 字节 4 字节
产品 PID 版本号(目前不适用) 文件 MD5(目前不适用) 文件长度 CRC32
  • 产品 PID:MCU 的 PID。
  • 版本号:将升级的文件版本,例如,0x010001 代表版本号为 1.0.2(目前不适用)。
  • 文件 MD5:升级固件的 MD5 值(目前不适用)。
  • 文件长度:升级固件的总长度,单位为字节。
  • CRC32:升级固件的 CRC32。

MCU 返回

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDB
4
5
2 数据长度 0x00
0x19
6-30 25 Data 见下表
11 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

Data 格式

8 字节 3 字节 16 字节 4 字节
State 已存储文件长度 已存储文件 CRC32 已存储文件 MD5(目前不适用)
  • State:
    • 0x00:正常升级
    • 0x01:产品 PID 不一致
    • 0x02:保留
    • 0x03:文件大小超过范围
    • 其他:保留
  • 已存储文件长度:代表上次升级意外中断,MCU 已经升级的部分文件长度。
  • 已存储文件 CRC32:代表上次升级意外中断,MCU 已经升级的部分文件计算的 CRC32。
  • MCU 端若做支持断电续传功能,此时应返回自身已存储的文件信息(已存储文件长度和已存储文件 CRC32)。App 或网关收到信息后,根据设备返回的已存储文件长度,计算新文件对应长度的 CRC32,然后与设备返回的 CRC32 进行比较。如果两者吻合,那么在下一次文件起始传输请求中,将起始传输偏移量修改为该长度值。如果不吻合,文件起始传输偏移量将设置为 0,表示从头开始传输。
  • MCU 端若做不支持断电续传功能,此时将返回自身已存储的文件信息(已存储文件长度和已存储文件 CRC32)参数全部置为 0 回复。

若使用网关升级并在网关升选择的是群升操作,那么不支持断电续传功能,无论 MCU 端回复的已存储的文件信息是上次升级的偏移量还是 0,都会从偏移量 0 开始传输。

OTA 升级文件偏移(CMD-0xDC)

下发文件起始传输偏移量,并比较 MCU 返回的偏移量。如果它们匹配,表示文件传输可以从该偏移量处继续。如果不匹配,将重新开始传输整个文件。

模组发送

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDC
4
5
2 数据长度 0x00
0x04
6-9 4 Offset 文件起始传输偏移量,四字节
10 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

Offset:手机或者网关根据 0xDB 设备回复的已存储长度和 CRC32 匹配的偏移量。

MCU 返回

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDC
4
5
2 数据长度 0x00
0x04
6-9 4 Offset MCU 要求的起始传输文件偏移量
10 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

Offset:设备本地维护的升级偏移量。

  • 下发文件起始传输偏移量,并比较 MCU 返回的偏移量。如果它们匹配,表示文件传输可以从该偏移量处继续。如果不匹配,将重新开始传输整个文件。
  • 如果选择的是群升,升级偏移量固定为 0

OTA 升级数据(CMD-0xDD)

模组发送

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDD
4
5
2 数据长度 Len 长度高 8 位
长度低 8 位
6 - 6+Len-1 Len Data 见下表
6+Len 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

Data 格式

4 字节 2 字节 2 字节 n 字节
数据偏移 当前包数据长度 n 当前包数据 CRC16 当前包数据
  • 数据偏移:单升级数据的偏移量。
  • 当前数据包长度:单升级数据包的最大长度(0xd80xd9 指令中设置的 Len)。
  • 当前包数据 CRC16:单升级数据包的 CRC16。
  • 当前包数据:升级数据。

MCU 返回

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDD
4
5
2 数据长度 0x00
0x01
6 1 State
  • 0x00:成功
  • 0x01:数据偏移异常
  • 0x02 :长度不一致
  • 0x03:CRC 检验失败
11 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余
  • 群升时 MCU 回此条命令,模组会忽略,模组平均间隔 200 ms 下发一次数据,不依赖回复后下发下一条数据。
  • MCU 端 Flash 写入必须支持非连续偏移写入,不满足不支持批量升级。

OTA 升级校验(CMD-0xDE)

模组发送

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDE
4
5
2 数据长度 0x00
0x00
6 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

MCU 返回

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDE
4
5
2 数据长度 0x00
0x01
6 1 State
  • 0x00:成功
  • 0x01:CRC32 不一致
  • 0x02:长度不一致
7 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

OTA 升级结束(CMD-0xDF)

模组发送

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDF
4
5
2 数据长度 0x00
0x01
6 1 State 升级的结果通知:
  • 0x00:成功
  • 其他:失败
7 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余

MCU返回

序号 长度(字节) 字段 说明
0
1
2 帧头 0x55
0xAA
2 1 版本号 0x00
3 1 命令字(CMD) 0xDF
4
5
2 数据长度 0x00
0x01
6 1 State 返回的状态值:
  • 0x00:成功
  • 0x01:失败
7 1 CRC8 从帧头开始按字节求和,得出的结果对 256 求余
  • MCU 在收到模组发送的结束指令后,根据比较信息回复对应 State。回复模组后如果模组通知的结果是成功,MCU 等待 500 ms 后重启运行升级固件代码。否则不重启。
  • 支持 MCU 升级的产品开发时,波特率要使用 115200。由于升级期间通过串口交互数据和数据 Flash 写入,小波特率可能会引起升级期间的超时逻辑导致升级失败。