蓝牙OTA升级怎么实现
蓝牙 BLE 设备通过手机 App 做固件 OTA 升级怎么实现?讲清芯片原厂方案和自定义方案怎么选、升级协议的几条指令、分包大小与 MTU、逐包确认和窗口确认、升级速度估算、断点续传、手机息屏切后台和多平台日志,附 BMS 项目 926 包升级的经验。

本文目录
只有蓝牙的设备,固件升级只能靠手机:App 下载固件,再通过蓝牙一包一包写进设备。听起来简单,但实际做下来,问题集中在三个地方:太慢、中途断了、失败了不知道停在哪。
我们做过几个蓝牙 OTA:BMS 云平台的 App 和小程序都能蓝牙直连电池升级,航标灯器单独做了蓝牙升级 App。这篇讲蓝牙 OTA 的实现细节。整体流程(分区、包头、校验、回滚)请先看 固件OTA升级全流程。
原厂方案还是自定义方案
很多蓝牙芯片厂商提供现成的 OTA 方案,比如 Nordic 的 DFU,其他原厂也有各自的 OTA 服务和配套 SDK。
- 原厂方案:设备侧有现成的 Bootloader 和服务,App 侧有 SDK,省事、可靠
- 自定义方案:用自己的升级协议,通过普通的读写特征值传输,灵活,适合蓝牙模组透传给 MCU 的结构
判断方法:如果被升级的就是蓝牙芯片本身,优先用原厂方案;如果蓝牙只是模组、真正要升级的是后面的主控 MCU,一般只能走自定义方案,因为原厂方案升级的是蓝牙芯片,不是你的 MCU。
自定义升级协议的几条指令
最少需要这几条:
1. 开始升级 App → 设备 包头信息:型号、版本、固件长度、CRC
设备 → App 是否接受;如果接受,告诉 App 每包大小、从哪个偏移开始(支持续传)
2. 数据包 App → 设备 偏移 / 序号 + 数据
设备 → App 确认,带下一包期望的偏移
3. 结束升级 App → 设备 发送完毕
设备 → App 整包校验结果
4. 执行切换 App → 设备 重启进入新固件(或设备校验通过后自动重启)
5. 查询状态 App → 设备 当前是否在升级、已接收多少升级相关的指令最好和普通业务指令分开(单独一对特征值或单独的命令字段),避免升级时设备上报的普通数据和升级确认混在一起。GATT 规划可以参考 蓝牙设备GATT服务和通讯协议怎么设计。
每包多大
每包的数据量受 MTU 限制,默认 MTU 下只有 20 字节,协商后可以大很多。但包不是越大越好:
- 包越大,单包出错重传的代价越大
- 设备侧接收缓冲区和写 Flash 的速度也是上限
- 不同手机实际协商出的 MTU 不一样
比较稳的做法是:连接后先协商 MTU,再由设备在"开始升级"的应答里告诉 App 本次用多大的包。我们在 BMS 项目里用的是 64 字节一包,一个约 59KB 的固件共 926 包。
逐包确认还是窗口确认
- 逐包确认:每发一包等设备回确认再发下一包。最稳,但慢,每包都要等一个往返
- 窗口确认:用 Write Without Response 连续发 N 包,设备每收到 N 包或者每写完一个 Flash 扇区回一次确认,确认里带下一包期望的偏移
窗口确认能快很多,但设备侧要有足够缓冲区,并且要处理丢包:设备发现序号不连续时,在确认里要求 App 从缺失的那包重发。
BMS 项目采用的是逐包确认。实测中遇到过设备迟迟不回通知的情况,App 会先记录超时快照,再换一种写入方式重试。
速度怎么估
粗略估算:
升级耗时 ≈ 包数 × 单包往返时间 + 擦写 Flash 时间
926 包 × 每包等待一次连接事件往返 → 几十秒到几分钟不等影响最大的是连接间隔。升级开始前设备可以请求缩短连接间隔,升级完再恢复。如果升级要好几分钟,App 界面一定要有进度条和预计剩余时间,否则用户会以为卡死了。
断点续传
蓝牙升级中断太常见了:用户走远了、手机来电、App 被切到后台。设备侧要记录已经成功写入的偏移,重新连接、再次发"开始升级"时,设备在应答里告诉 App 从哪里继续。App 侧也要保存升级任务,下次打开能提示"继续上次的升级"。
手机息屏和切后台
- iOS:App 切到后台后,蓝牙操作会受限制,长时间升级可能被中断
- Android:不同厂商的系统省电策略不一样,有的会在息屏后限制后台 App
- 微信小程序:切到后台后蓝牙通讯可能被挂起
所以升级时要提示用户保持 App 在前台、不要锁屏,同时一定要支持续传。
每个平台都要有升级日志
升级失败时,"升级失败"四个字没法排查。BMS 项目里,iOS、Android 和微信小程序各留一份升级日志,记录每个阶段、每一包的发送和确认、超时和重试。失败时能看到停在哪个阶段、哪一包,固件工程师才好定位是设备没收到、写 Flash 失败还是校验没过。
升级完成的判定
最后一包发完不算完成。设备重启后,App 重新连接、读取固件版本号,等于目标版本才算成功。很多设备重启后蓝牙地址或广播内容会变(尤其是进出 Bootloader 时),App 要能重新找到这台设备。
现场升级工具
除了给终端用户的 App,很多厂家还需要给售后和现场人员的升级工具。我们给航标灯器厂商单独做了一个蓝牙升级 App,现场选择固件后分包升级并显示进度,参考 航标灯器蓝牙调试与升级 App。
常见问题
小程序能做蓝牙 OTA 吗?
能。BMS 项目的 App 和微信小程序都能蓝牙直连电池做 OTA。小程序要注意切后台的问题和不同手机的兼容性。
升级时设备还能正常工作吗?
双区方案下,传输阶段旧固件照常运行,只在最后切换时重启。单区方案升级期间设备停在 Bootloader,不能正常工作。
一次能同时升级多台吗?
可以,但受手机同时连接数限制,速度也会变慢。批量升级通常逐台进行,或者给产线用专门的升级工具。
你们能做蓝牙 OTA 的 App 端吗?
可以,参考 OTA 升级平台开发 和 蓝牙 App 开发服务,或者把设备情况 发给我们。