OTA
OTA(空中升级)技术是指通过蓝牙传输,对 RTL8752H 系列设备中的 Flash 存储的 image 和 data 进行空中升级的一种技术。OTA 技术提供了一种高效且便捷的方式,使设备可以远程接收和安装更新,而无需物理连接或手动干预。SDK 通过无线方式支持 OTA 功能,使其能够兼容运行 Android 和 iOS 系统的设备。具体来说,SDK 利用 GATT(通用属性规范)协议进行蓝牙数据传输,以确保更新过程的稳定性和可靠性。此外,OTA 更新不仅可以提高设备的性能和功能,还能修复已知的漏洞和安全问题,从而提升用户体验和设备的安全性。

OTA 示意图
方案介绍
OTA 方案根据 Flash布局 排布的不同,可以分为以下两种:
- 支持 Bank 切换OTA Bank0 和 OTA Bank1 将作为彼此的备份固件存储区。在固件更新期间,这两个存储区可以相互切换使用,从而确保在固件更新失败时能够回滚到之前的备份固件,保证系统的稳定性和安全性。
- 不支持 Bank 切换OTA Bank1 不需要分配空间,OTA TMP 区需要分配,且大小必须不小于 OTA Bank0 最大的 image 大小,相对节约 Flash 空间。 OTA 传输完成,Boot Loader 会将 OTA TMP 区数据搬到 OTA Bank0 指定 image 区域,再重启生效,所以相对增加了 OTA 升级完成的重启时间。
备注
支持 Bank 切换方案需要维护两个 Bank 对应地址的 image,Realtek 默认发布的 image 只支持运行在 Bank0,如果需要运行在 Bank1,需要联系 Realtek 获取。
在不支持 Bank 切换方案中还支持压缩 OTA 方案,在升级时使用 LZMA 压缩算法将 image 压缩再传输到 OTA TMP 区,压缩率大约为 70% ,可以解决 Flash 空间不足的问题。该方案默认不开启,需要联系 Realtek 获取定制 ROM Patch 支持。
流程说明
OTA 升级流程如下,从图中可以更清晰地理解 OTA 更新的整体流程和各个模块的交互关系。其中手机是 Controller,SoC 是 Target。在 OTA 开始之前,Controller 与 Target 建立连接。随后,Controller 获取 Target 信息判断是否允许升级。

OTA 升级流程
传输协议
OTA 升级根据传输协议不同分为静默升级和普通升级。
静默升级
升级 image 的过程中,设备原来的功能可以正常使用,升级完成后,只需很短的重启时间,程序自动切换到新的功能。
普通升级
OTA 功能稳定,但升级过程需要将设备切换到 DFU mode,设备原有的功能无法使用,需要等待升级完成。
备注
上述两种升级方式都会使用到 OTA Service 和 DFU Service。
OTA Service:用于获取设备信息或进入 DFU mode。
DFU Service:用于执行升级过程。
OTA Service
OTA Service 的 UUID 及 Characteristics 如下:
{0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFF, 0xD0, 0x00, 0x00}
特征名称 |
要求 |
UUID |
属性 |
格式 |
值 |
介绍 |
---|---|---|---|---|---|---|
OTA CMD |
Mandatory |
0xFFD1 |
Write Without Response |
Uint8 |
1 |
允许设备进入 DFU mode 的控制端点 |
Device Mac |
Mandatory |
0xFFD2 |
Read |
Uint8*6 |
XX:XX:XX:XX:XX:XX |
读取设备的蓝牙地址用于和 DFU mode 中的蓝牙地址进行比较 |
Device Info |
Mandatory |
0xFFF1 |
Read |
读取设备的固件基本信息 |
||
Image Counter |
Optional |
0xFFF2 |
Write Response |
Uint8 |
0xNN |
告知设备接下来有多少个 image 文件需要写入 |
Image Version |
Mandatory |
0xFFE0~FFEF |
Read |
Uint32*N |
0xNNNNNNNN |
读取设备的 image 版本 |
字节 |
值 |
|
---|---|---|
Byte0 |
ic_type |
|
Byte1 |
spec version |
|
Byte2 |
secure version |
|
Byte3 |
Bit0: buffer check |
0: 不支持buffer check |
1: 支持buffer check |
||
Bit1: AES |
0: 关闭AES |
|
1: 开启AES |
||
Bit2: encryption mode |
0: 加密前16字节 |
|
1: 加密 16*N 字节 |
||
Bit3: copy image |
0: 不支持copy image |
|
1: 支持copy image |
||
Bit4: multi image |
0: 一次更新单个image |
|
1: 一次更新多个image |
||
Bit5: handshake |
0: 不支持handshake |
|
1: 支持handshake |
||
Bit6: compress mode |
0: 不支持ota image compressed |
|
1: 支持ota image compressed |
||
Byte4~5 |
max buffer size |
|
Byte6 |
temp bank size (unit: 4KB) |
|
Byte7 |
reserved |
|
Byte8~11 |
Indications for each image version. Each indication uses 2 bits. |
00: image不存在 |
01: image位于bank0, OTA需要升级bank1 image |
||
10: image位于bank1, OTA需要升级bank0 image |
||
11: image是单独的,OTA需要单独升级image |
||
Byte12~13 |
ctrl header offset |
ctrl header在 image header 中的偏移 |
Byte14~15 |
compressed ctrl header offset |
compressed ctrl header 在 image header 中的偏移 |
DFU Service
DFU Service 的 uuid 和 Characteristics 如下:
{0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x62, 0x00, 0x00}
Data Characteristic:接受 image 的数据通道,属性 write no response。
Control Point Characteristic:接受控制指令的通道,属性 write/notification。
DFU Service 支持的所有 control point 如下表:
Opcode值 |
程序 |
要求 |
属性 |
参数说明 |
响应参数 |
---|---|---|---|---|---|
0x01 |
Start DFU |
Mandatory |
Write |
crc16(UINT16) ic_type(UINT8) secure_version(UINT8) ctrl_flag.value(UINT16) image_id(UINT16) payload_len(UINT32) start_dfu_mode(UINT8) |
None |
0x02 |
Receive FW Image Information |
Mandatory |
Write |
image_id(UINT16) cur_offset(UINT32) |
None |
0x03 |
Validate FW |
Mandatory |
Write |
image_id(UINT16) |
None |
0x04 |
Activate Image and Reset |
Mandatory |
Write |
None |
None |
0x05 |
Reset System |
Mandatory |
Write |
None |
None |
0x06 |
Report Received Image Information |
Mandatory |
Write |
image_id(UINT16) |
origin_image_version(UINT32) cur_offset(UINT32) |
0x07 |
Connection Parameter Update |
Mandatory |
Write |
connIntervalMin(UINT16) connIntervalMax(UINT16) connLatency(UINT16) supervisionTimeout(UINT16) |
None |
0x09 |
Buffer Check Enable |
Mandatory |
Write |
image_id(UINT16) |
Max buffer size(UINT16) Mtu size(UINT16) |
0x0A |
Buffer Check Size & CRC |
Mandatory |
Write |
mBufferSize(UINT16) mCRC(UINT16) |
Next send offset(UINT32) |
0x0B |
IC Type |
Optional |
Write |
None |
ic_type(UINT8) |
备注
在收到 image control header 后,会将 image control header 中的 not_ready 临时写成 1 再写入 flash 中。当 image 传输完成,并且 image 完整性校验成功后,修改备份区 image 中的 not_ready 为 0,标识备份区 image 有效。这样设计是当 OTA 传输中断时,BootLoader 很容易识别这个 image 是否是 ready 状态。
在数据传输过程中,如果采用 AES 加密,每 16 字节的数据都会进行加密,最后小于 16 字节的部分将不进行加密,直接发送。接收端在收到数据后,需要首先对加密部分进行解密。
如果启用 buffer check,当收满 buffer check size 后,再写入 flash。
OTA 协议流程
OTA 升级时会通过 OTA Service 和 DFU Service 将待升级的 image 传输到升级区域,传输完成后会进行重启由 Bootloader 完成激活流程。
传输流程

OTA 蓝牙传输流程
激活流程
组合升级
在将 image 数据写入 OTA TMP 区时,会去计算 OTA TMP 区剩余空间能否放得下下一个需要写入的 image 文件,如果可以放下则继续将下一个 image 文件写入 OTA TMP 区,当放不下时会先重启将 OTA TMP 区数据搬到 OTA Bank0 区域,拷贝激活生效之后,再升级其他文件。
非组合升级
当打包待升级文件中包含 Patch、APP 或者 APP DATA,需要一个文件升级验证成功,重启拷贝激活生效之后,再升级下一个文件。
当打包待升级文件中包含 OTA Header file、Patch、APP 或者 APP DATA,需要一个文件传输验证成功,再传输验证下一个文件。等所有文件都传输验证成功后,才能进行重启,否则本次升级无效。原因是切换 Bank 方案,需要 Bank 区所有文件都一起生效,才能正常运行。
工具指南
以下是 OTA 升级过程中所需工具。
工具 |
说明 |
路径 |
---|---|---|
生成 |
|
|
打包 OTA 文件 |
|
|
APP Data Tool |
生成可被打包的 APP Data 文件 |
|
User Data Tool |
生成可被打包的 User Data 文件 |
|
备注
Flash Map Generate Tool 以及 MP Pack Tool 的使用将按照是否支持 Bank 切换分两种方案进行介绍。
支持 Bank 切换
支持 Bank 切换方案 Flash 布局示例如下:
flash 总大小为 1MB 的示例布局 |
大小(字节) |
起始地址 |
---|---|---|
Reserved |
4K |
0x00800000 |
OEM Header |
4K |
0x00801000 |
OTA Bank0 |
344K |
0x00802000 |
|
4K |
0x00802000 |
|
4K |
0x0080A000 |
|
28K |
0x00803000 |
|
28K |
0x0080B000 |
|
144K |
0x00812000 |
|
132K |
0x00836000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
4K |
0x00857000 |
OTA Bank1 |
344K |
0x00858000 |
|
4K |
0x00858000 |
|
4K |
0x00860000 |
|
28K |
0x00859000 |
|
28K |
0x00861000 |
|
144K |
0x00868000 |
|
132K |
0x0088C000 |
|
0K |
0x008AD000 |
|
0K |
0x008AD000 |
|
0K |
0x008AD000 |
|
0K |
0x008AD000 |
|
0K |
0x008AD000 |
|
4K |
0x008AD000 |
FTL |
16K |
0x008AE000 |
OTA TMP |
0K |
0x008B2000 |
user data1 |
0K |
0x008B2000 |
user data2 |
0K |
0x008B2000 |
备注
Flash 布局需要根据用户实际 image 和 data 的大小进行合理划分。
操作步骤:
使用 Flash Map Generate Tool 生成
flash map.ini
、flash_map.h
、Bank0 OTA Header file
和Bank1 OTA Header file
。Flash Size 选择合适的大小。
Support OTA Switch 选择 Enable。
设置两级 flash layout。
点击 Confirm 完成 flash layout 设置。
Version 处修改 OTA Header file 版本。
点击 Confirm 生成
flash_map.h
,flash map.ini
,Bank0 OTA Header file
和Bank1 OTA Header file
。
设置 Flash 布局并生成 OTA Header —— 支持 Bank 切换
备注
打包用的 OTA Header 版本号要比原来运行的高,这样 OTA 升级完新 Bank 才能正常生效。
将
flash map.ini
文件拷贝到工程文件上级目录下,编译链接生成app_MP_sdk#####+version+MD5.bin
的文件供打包使用。编译 APP 文件
备注
支持 Bank 切换的方案需要编译 OTA Bank0 和 OTA Bank1 的 APP image。
Realtek 发布的 SDK 中,demo APP 工程默认编译的是 OTA Bank0 的 APP image。编译 OTA Bank1 的 APP image 需要将工程文件上级目录下
mem_config.h
中的 #define APP_BANK 修改为 1,具体代码如下:
/** @brief set app bank to support OTA: 1 is ota bank1, 0 is ota bank0 */ #define APP_BANK 1
获取 OTA Bank1 的 ROM Patch,BT Stack Patch,Secure Boot Loader 和 Upperstack image。
备注
SDK 中发布的 ROM Patch,BT Stack Patch,Secure Boot Loader 和 Upperstack image 默认运行在 OTA Bank0,如果选用支持 Bank 切换方案,请咨询 Realtek 对应发布运行在 OTA Bank1 的 ROM Patch,BT Stack Patch,Secure Boot Loader 和 Upperstack image。
生成打包文件,默认在软件同目录下生成
ImgPacketFile-xxxxxx.bin
,此文件为升级用的打包文件。选择 ForOTA 选项。
加载生成的
flash map.ini
。点击 Browse 加载所有 OTA Bank0 和 Bank1 image。
点击 Confirm 生成打包文件。
打包文件 — 支持 Bank 切换
备注
Bank 内 Flash 布局中定义的内容都需要进行打包,缺一不可。
建议 Bank0 和 Bank1 一起打包。
不支持 Bank 切换
不支持 Bank 切换方案 Flash 布局示例如下:
flash总大小为 512KB 的示例布局 |
大小 (字节) |
起始地址 |
---|---|---|
Reserved |
4K |
0x00800000 |
OEM Header |
4K |
0x00801000 |
OTA Bank0 |
344K |
0x00802000 |
|
4K |
0x00802000 |
|
4K |
0x0080A000 |
|
28K |
0x00803000 |
|
28K |
0x0080B000 |
|
144K |
0x00812000 |
|
132K |
0x00836000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
4K |
0x00857000 |
OTA Bank1(等于0) |
0K |
0x00858000 |
FTL |
16K |
0x00858000 |
OTA TMP |
144K |
0x0085C000 |
user data1 |
0K |
0x00880000 |
user data2 |
0K |
0x00880000 |
备注
此处没有分配 APP data,Flash 布局需要根据用户实际 image 和 data 的大小进行合理划分。
操作步骤:
使用 Flash Map Generate Tool 生成
flash map.ini
、flash_map.h
和Bank0 OTA Header file
。Flash Size 选择合适的大小。
Support OTA Switch 选择 Disable。
设置两级 flash layout。
点击 Confirm 完成 flash layout 设置。
Version 处修改 OTA Header file 版本。
点击 Confirm 生成
flash_map.h
、flash map.ini
和Bank0 OTA Header file
。
设置 Flash 布局并生成 OTA Header — 不支持 Bank 切换
备注
此处生成的
flash map.ini
需要和 SoC 内部使用的flash map.ini
保持一致。将
flash_map.h
复制到工程文件上级目录下,编译链接生成app_MP_sdk#####+version+MD5.bin
的文件供打包使用。备注
不支持 Bank 切换的方案 只需要编译 OTA Bank0 的 image ,配置见工程文件上级目录下的
mem_config.h
中的 #define APP_BANK ,具体代码如下:/* @brief set app bank to support OTA: 1 is ota bank1, 0 is ota bank0 */ #define APP_BANK 0
生成打包文件,默认在软件同目录下生成
ImgPacketFile-xxxxxx.bin
,此文件为升级用的打包文件。选择 ForOTA 选项。
加载生成的
flash map.ini
。点击 Browse 加载 OTA Bank0 image。
点击 Confirm 生成打包文件。
打包文件 —— 不支持 Bank 切换
备注
Bank0 OTA Header file 在不支持 Bank 切换方案时不允许打包。
如果只需要更新 Patch Image 或者 APP Image ,可只打包其中一个。
APP Data 升级
APP Data Tool 是将原始 APP Data 的 bin 文件转换成可通过 MP Tool 烧录到 Flash 中的 APP Data 类型的 image 。
APP Data Tool 处理后,会在原始的 APP data 前面添加一个 512 bytes MP header 和 1024 bytes image header ,分别用于 MP Tool 烧录和 Bootloader 校验。假设原始的 APP Data 的 bin 文件的大小是 120KB ,最后烧录到 flash 中将是 1024 bytes image header 加上 120KB 的 APP data payload 。
接下来以 APP Data1 为例进行说明, 具体路径如下:

APP Data1
文件说明:
SampleAppData1.bin
是原始的 APP Data 的 bin 文件。SampleImageAppData1_MP_0.0.0.1-b9dff8aa815059047f6844497d328342.bin
是由 Tool 生成的用于烧录的 APP Data1 的 bin 文件。
打开
run.bat
,将以下所有 SampleAppData1 部分替换成需要处理的 APP Data 的 bin 文件名。run.bat
备注
注意最后一行中的必须是
xxx_MP.bin
,后缀“_MP”不可更改。运行
run.bat
,将会额外生成 3 个文件:SampleImageAppData1.bin
:在原始的 APP Data 的 bin 文件上添加了 1024 bytes image header 的 bin 文件。SampleImageAppData1_MP.bin
:在SampleImageAppData1.bin
文件上再添加了 512 bytes MP Header 的 bin 文件。SampleImageAppData1_MP_0.0.0.1-b9dff8aa815059047f6844497d328342.bin
:在xxx_MP.bin
的基础上计算了 MD5 的校验值。
备注
注意只有同时带有 _MP 和 MD5 校验的 bin 文件才可以最后用于烧录和 OTA。
User Data 升级
User Data 主要用来存放不会影响到系统功能的数据。User Data 的升级策略与其他 image 不同。对于其他 image,会先将其传输到 OTA TMP 区域,而 User Data 则直接传输到其对应的 Flash 地址上。
下面以 1M byte 的 Flash 为例,介绍 User Data 升级。Flash 布局示例如下:
Flash 总大小为 1MB 的示例布局 |
大小(字节) |
起始地址 |
---|---|---|
Reserved |
4K |
0x00800000 |
OEM Header |
4K |
0x00801000 |
OTA Bank0 |
344K |
0x00802000 |
|
4K |
0x00802000 |
|
4K |
0x0080A000 |
|
28K |
0x00803000 |
|
28K |
0x0080B000 |
|
144K |
0x00812000 |
|
136K |
0x00836000 |
|
0K |
0x00858000 |
|
0K |
0x00858000 |
|
0K |
0x00858000 |
|
0K |
0x00858000 |
|
0K |
0x00858000 |
|
4K |
0x00858000 |
OTA Bank1(等于0) |
0K |
0x00859000 |
FTL |
16K |
0x00859000 |
OTA TMP |
144K |
0x0085D000 |
user data1 |
32K |
0x00881000 |
user data2 |
32K |
0x00889000 |
操作步骤:
使用 Flash Map Generate Tool 生成
flash map.ini
、flash_map.h
和Bank0 OTA Header file
。设置 Flash 布局并生成 OTA Header —— User Data 升级
备注
此处生成的
flash map.ini
需要和 SoC 内部使用的flash map.ini
保持一致。双击
RTL8752H-SDK-Vx.x.x\tool\Gadgets\UserData
中的脚本生成可支持打包的 User Data 文件。生成打包文件,默认在软件同目录下生成
ImgPacketFile-xxxxxx.bin
,此文件为升级用的打包文件。选择 ForOTA 选项。
加载生成的
flash map.ini
。点击 Browse 加载 User Data image。
点击 Confirm 生成打包文件。
打包文件 —— User Data 升级
备注
如果只需要更新某一个 User Data,可只打包其中一个。
允许将 User Data 和其他 image 一起打包升级。