物联网设备的BLE无线固件更新技术实现:从原理到实践
2026-04-10 09:10:03作者:庞队千Virginia
一、技术原理:低功耗通信与OTA机制解析
1.1 BLE通信协议基础
蓝牙低功耗(BLE)技术采用客户端-服务器(Client-Server)架构,通过服务(Service)和特征(Characteristic)实现数据交互。在ESP32 BLE OTA场景中,设备作为GATT服务器(GATT Server)广播特定服务,智能手机作为客户端(GATT Client)连接并传输固件数据。BLE协议栈分为物理层、链路层、L2CAP层、ATT层和GATT层,其中ATT层定义了属性的读写操作规范,GATT层则组织服务和特征的层次结构。
1.2 OTA更新核心原理
OTA(Over-The-Air)更新通过无线方式将新固件传输到设备并完成升级。ESP32的OTA机制基于双分区设计:设备包含两个应用分区(ota_0和ota_1),当前运行分区(如ota_0)接收新固件并写入备用分区(ota_1),验证通过后切换启动分区。这种设计确保升级失败时可回退到原固件,提高系统可靠性。
1.3 数据传输流程
图1:BLE OTA数据传输流程
- 发现阶段:设备广播包含OTA服务UUID的广告包,客户端扫描并识别目标设备
- 连接阶段:客户端发起连接,协商MTU(最大传输单元)大小
- 控制阶段:通过控制特征传递升级指令(开始/结束升级)
- 数据传输阶段:通过数据特征分段发送固件数据
- 验证重启阶段:完成数据传输后验证固件完整性,重启设备切换到新固件
二、核心组件:功能模块交互与实现
2.1 BLE服务与特征设计
项目定义了符合Silicon Labs规范的OTA服务和特征,关键代码实现如下:
// [main/gatts_table_creat_demo.c] 定义OTA服务UUID
static uint8_t service_uuid[16] = {
0xf0, 0x19, 0x21, 0xb4, 0x47, 0x8f, 0xa4, 0xbf,
0xa1, 0x4f, 0x63, 0xfd, 0xee, 0xd6, 0x14, 0x1d // 服务UUID: 1D14D6EE-FD63-4FA1-BFA4-8F47B42119F0
};
// 定义OTA控制特征UUID(必须支持写操作)
static uint8_t char_ota_control_uuid[16] = {
0x63, 0x60, 0x32, 0xe0, 0x37, 0x5e, 0xa4, 0x88,
0x53, 0x4e, 0x6d, 0xfb, 0x64, 0x35, 0xbf, 0xf7 // 控制特征UUID: F7BF3564-FB6D-4E53-88A4-5E37E0326063
};
// 定义OTA数据特征UUID(支持写操作和无响应写)
static uint8_t char_ota_data_uuid[16] = {
0x53, 0xa1, 0x81, 0x1f, 0x58, 0x2c, 0xd0, 0xa5,
0x45, 0x40, 0xfc, 0x34, 0xf3, 0x27, 0x42, 0x98 // 数据特征UUID: 984227F3-34FC-4045-A5D0-2C581F81A153
};
2.2 固件接收与Flash写入模块
设备通过esp_ota_write函数将接收到的固件数据写入Flash,关键实现如下:
// [main/gatts_table_creat_demo.c] OTA数据处理
if (heart_rate_handle_table[IDX_CHAR_VAL_B] == param->write.handle) {
uint16_t length = param->write.len;
err = esp_ota_write(update_handle, (const void *)param->write.value, length);
if (err != ESP_OK) {
esp_ota_abort(update_handle); // 写入失败时终止OTA
}
}
2.3 分区表配置
项目使用partitions.csv定义OTA所需分区结构:
| 名称 | 类型 | 子类型 | 偏移量 | 大小 | 标志 |
|---|---|---|---|---|---|
| nvs | data | nvs | 0x9000 | 0x6000 | |
| otadata | data | ota | 0xf000 | 0x2000 | |
| phy_init | data | phy | 0x11000 | 0x1000 | |
| ota_0 | app | ota_0 | 0x12000 | 0x1C0000 | |
| ota_1 | app | ota_1 | 0x1D2000 | 0x1C0000 |
三、实施步骤:从环境搭建到升级验证
3.1 开发环境准备与校验
环境要求:
- ESP-IDF v4.4
- ESP32-C3开发板
- Silicon Labs EFR Connect应用
环境校验命令:
# 克隆项目仓库
git clone https://gitcode.com/gh_mirrors/es/esp32-ota-ble
cd esp32-ota-ble
# 验证ESP-IDF环境
idf.py --version # 预期输出:ESP-IDF v4.4.x
# 检查设备连接
ls /dev/ttyUSB* # 预期输出:列出连接的USB串口设备
3.2 固件编译与烧录
编译命令:
# 设置目标芯片
idf.py set-target esp32c3
# 配置项目(默认配置已包含OTA所需参数)
idf.py menuconfig # 可验证"Component config" > "ESP32C3-specific" > "Support for external SPIRAM"等选项
# 编译项目
idf.py build # 预期输出:生成build/esp32-ota-ble.bin文件
烧录命令:
# 烧录固件和分区表
idf.py -p /dev/ttyUSB0 flash # 预期输出:"Leaving... Hard resetting via RTS pin..."
3.3 OTA升级流程
步骤1:启动设备与连接
- 设备上电后自动广播BLE信号(名称:OTA-BLE)
- 打开EFR Connect应用,扫描并连接到"OTA-BLE"设备
步骤2:触发OTA更新
- 在应用中找到OTA服务(UUID: 1D14D6EE-FD63-4FA1-BFA4-8F47B42119F0)
- 向控制特征(UUID: F7BF3564-FB6D-4E53-88A4-5E37E0326063)写入0x00,触发设备擦除Flash分区
步骤3:传输固件
- 选择编译生成的.bin文件(需重命名为.gbl后缀)
- 应用自动通过数据特征(UUID: 984227F3-34FC-4045-A5D0-2C581F81A153)发送固件数据
- 设备接收数据并写入Flash:
// [main/gatts_table_creat_demo.c] 开始OTA流程
if(0x00 == value) {
update_partition = esp_ota_get_next_update_partition(NULL);
err = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &update_handle);
}
步骤4:完成升级
- 固件传输完成后,应用向控制特征写入0x03
- 设备验证固件并重启:
// [main/gatts_table_creat_demo.c] 完成OTA并重启
err = esp_ota_end(update_handle);
err = esp_ota_set_boot_partition(update_partition);
esp_restart();
3.4 常见误区与正确做法
| 常见误区 | 正确做法 |
|---|---|
| 使用默认MTU大小(23字节) | 通过esp_ble_gatt_set_local_mtu(500)增大MTU,减少传输包数 |
| 未验证固件完整性 | 实现CRC校验或加密签名验证,防止恶意固件 |
| 升级过程中断电 | 实现断点续传,记录已传输数据偏移量 |
四、进阶优化:功能扩展与应用场景
4.1 安全性增强
固件签名验证:通过ESP32的安全启动功能,仅允许运行经过签名的固件。修改sdkconfig启用安全启动:
CONFIG_SECURE_BOOT_ENABLE=y
CONFIG_SECURE_SIGNED_APPS=y
4.2 断点续传实现
在控制特征中增加"恢复传输"指令(如0x02),设备记录已接收数据长度,客户端从断点继续传输:
// 伪代码:断点续传逻辑
case 0x02: // 恢复传输指令
send_current_offset(update_handle); // 发送已接收字节数
break;
4.3 扩展应用场景
场景1:电池供电设备
- 优化:降低广播频率(adv_int_min=0x80, adv_int_max=0x100),减少功耗
- 实现:修改
adv_params结构体中的广播间隔参数
场景2:多设备批量升级
- 方案:实现"主从模式",一个主设备接收固件后广播给多个从设备
- 关键:使用BLE广播包传输固件元数据,主从设备间建立Mesh网络
场景3:跨厂商兼容
- 适配:除EFR Connect外,支持nRF Connect等通用BLE工具
- 方法:增加标准OTA服务UUID(0000FFE0-0000-1000-8000-00805F9B34FB)
五、技术选型决策树
是否需要无线升级?
├─ 是 → 选择通信方式:
│ ├─ 有WiFi环境 → WiFi OTA(传输速度快)
│ └─ 低功耗需求 → BLE OTA(本文方案)
└─ 否 → 串口升级
BLE OTA适用场景:
- 电池供电设备
- 短距离(<10米)升级
- 对功耗敏感的物联网节点
六、扩展学习资源
- ESP-IDF OTA官方文档:docs/en/api-reference/system/ota.rst
- BLE服务开发指南:components/bt/host/bluedroid/doc/gatt_server.md
- 分区表配置说明:docs/en/api-reference/storage/partition_table.md
登录后查看全文
热门项目推荐
相关项目推荐
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0446
源启盛夏_AtomGit暑期开发者成长计划「源启盛夏」暑期校园开发者成长计划旨在激活校园开源力量,通过积分激励、认证扶持、资源倾斜等形式,引导高校组织和开发者完成「入驻 — 建项目 — 做贡献 — 获认证 — 得资源」的完整闭环。无论你是想带领社团入驻平台的组织者,还是希望用代码贡献证明自己的开发者,都能在这里找到属于你的成长路径。Markdown00
jiuwenswarmJiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。Python0765
Hy3Hy3 是由腾讯混元团队研发的快慢思考融合的混合专家模型,总参数量 295B,激活参数 21B,MTP 层参数 3.8B。4 月底发布 Hy3 Preview 后,我们在 50 多个业务中获得了广泛的反馈,修复了各种体验问题,进一步提升了后训练的质量和规模。今天,我们发布 Hy3。它展现出显著强于同尺寸并比肩旗舰(参数规模往往是 Hy3 的 2~5 倍)开源模型的智能水平,显著提升了在各类产品和生产力任务中的实用价值。Python00
AscendNPU-IRAscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优C++0311
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
项目优选
收起
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
494
515
deepin linux kernel
C
32
16
Ascend Extension for PyTorch
Python
800
1.14 K
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
781
1.57 K
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
965
2.28 K
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
C
845
6.18 K
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.21 K
1.24 K
AtomGit CLI (ag cli),AtomGit 命令行工具,参考 GitHub CLI (gh) 开发。
目前 atomgit-cli 项目已在 AtomCode 的 Coding Plan 项目列表中
Go
40
24
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
644
281
暂无描述
Markdown
827
5.48 K