尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ESP32 BLE 扩展广播 1 KiB 大载荷示例深度解析:基于 esp-iot-solution 的 ble_ext_adv 广播端实现

ESP32 BLE 扩展广播 1 KiB 大载荷示例深度解析:基于 esp-iot-solution 的 ble_ext_adv 广播端实现 ESP32 BLE 扩展广播 1 KiB 大载荷示例深度解析基于 esp-iot-solution 的 ble_ext_adv 广播端实现【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution导读本文围绕 esp-iot-solution 仓库中的 ble_ext_adv 示例 展开它是配套 ble_ext_scan 扫描端 的广播端Advertiser演示如何在 ESP32 系列芯片上基于 BLE 5.0 扩展广播Extended Advertising一次发送1000 字节1 KiB的非连接、不可扫描广播 PDU并在 primary 1M / secondary 2M PHY 上以 Advertising SID 2 对外广播。读完本文你将掌握扩展广播与传统广播的差异、1 KiB 广播载荷的合法 AD 结构构造方法、ble_conn_mgr 组件广播参数的完整配置、FNV-1a 校验链路以及如何配合扫描端完成端到端验证。背景为什么需要扩展广播传统 BLE 广播Legacy Advertising的广播数据AdvData加上扫描响应ScanRsp合计最多31 字节只能承载设备名、少量服务 UUID 等短数据。BLE 5.0 引入的扩展广播将单次广播 PDU 的载荷上限提升到1650 字节可被控制器分片为多个 AUX 扩展广播事件发送并支持在 primary 1M / Coded PHY 上发送指针AdvA AUX 指针实际数据走 secondary 2M / Coded PHY吞吐更高、更省电通过 Advertising SID 区分同一设备上的多个广播集Advertising Set非连接、不可扫描、匿名等多种事件属性组合。本示例正是利用这一能力将 1000 字节载荷一次性装进扩展广播。README 中明确指出这不是周期性广播Periodic Advertising若需要周期广播/同步演示应使用仓库内的 ble_periodic_adv 与 ble_periodic_sync 示例。示例概览广播端 扫描端配对ble_ext_adv与ble_ext_scan构成一对演示角色示例目录职责广播端ble_ext_adv构造 1000 字节广播载荷以 SID2、primary 1M / secondary 2M PHY 广播扫描端ble_ext_scan在 1M / 2M / Coded PHY 上被动扫描按 SID2 重组分片并校验 1000 字节载荷与 FNV-1a两个示例共享同一份载荷构造与哈希函数ext_adv.h因此扫描端可以用预先计算的期望值校验收到的载荷广播端打印的 FNV-1a 与扫描端打印的 FNV-1a 必须一致这是验证链路的唯一判据。支持芯片与构建运行README 给出了本示例的支持目标Supported TargetsESP32-C3ESP32-C2ESP32-S3ESP32-C6ESP32-H2这些芯片均支持 BLE 5.0 扩展广播对应 ble_conn_mgr 中SOC_BLE_50_SUPPORTED能力。构建、烧录、监视的步骤与仓库内其他 ESP-IDF 示例一致idf.py set-target chip_name idf.py build flash monitor示例通过 idf_component.yml 以本地 override 方式依赖ble_conn_mgr组件版本~1.*路径指向components/bluetooth/ble_conn_mgr无需额外联网拉取dependencies: idf: 4.3 ble_conn_mgr: version: ~1.* override_path: ../../../../../components/bluetooth/ble_conn_mgr广播端实现深入解析1. 1 KiB 广播载荷的合法 AD 结构传统广播载荷按Length | Type | Data的 AD Structure 组织扩展广播同样遵循该规则。核心难点在于要构造出恰好 1000 字节且结构合法的载荷。ext_adv.h 中的ext_adv_1k_demo_fill()给出了可复用的构造方法其布局为段LengthTypeData说明Flags20x010x06LE General Discoverable BR/EDR Not Supported完整设备名1 strlen(name)0x09ESP_EXT_ADV_1K与 GAP 设备名一致12 字节制造商数据≤2550xFF公司 ID0xE5 0x02即 0x02E5Espressif 填充模式循环填充直至剩余空间不足填充逻辑的关键细节每条制造商数据 TLV 的长度字段L取min(rem-1, 255)确保不超过 255 字节的 AD 结构上限当剩余空间不足 3 字节时直接以0x00补齐到 1000 字节空 Type 段在接收端会被安全忽略数据区以(pos j) ^ j的确定性模式填充使扫描端可以做逐字节比对而非仅比对哈希。#define EXT_ADV_1K_TOTAL 1000 #define EXT_ADV_DEMO_NAME ESP_EXT_ADV_1K设备名常量同时被用作广播端的 GAP 设备名见 app_main.c 中的esp_ble_conn_config_t配置实现“载荷内嵌名称”与“广播设备名”统一。2. FNV-1a 校验值ext_adv.h 同时提供 FNV-1a 哈希实现用于端到端完整性校验static inline uint32_t ext_adv_1k_demo_fnv1a(const uint8_t *p, size_t n) { uint32_t h 2166136261u; /* FNV-1a 偏移基值 */ for (size_t i 0; i n; i) { h ^ p[i]; h * 16777619u; /* FNV 素数 */ } return h; }广播端在启动时先填充缓冲区、计算 FNV-1a 并打印Extended ADV payload: 1000 bytes, primary 1M / secondary 2M, non-conn non-scan AUX, FNV-1a0x...扫描端同样基于同一填充函数计算期望 FNV-1a重组完毕后打印Target ESP_EXT_ADV_1K found: ... FNV-1a0x... (compare with advertiser log)两行日志的哈希值一致即表示整条链路构造 → 广播 → 分片 → 重组正确无误。3. 广播配置与启动流程app_main.c 的完整流程为构造载荷并打印 FNV-1a调用ext_adv_1k_demo_fill()ext_adv_1k_demo_fnv1a()初始化配置esp_ble_conn_config_t中设置device_name、broadcast_data NA、extended_adv_data与extended_adv_len 1000NVS 初始化处理ESP_ERR_NVS_NO_FREE_PAGES/ESP_ERR_NVS_NEW_VERSION_FOUND后重试组件初始化esp_ble_conn_init(config)设置扩展广播参数esp_ble_conn_adv_params_set(adv)启动广播esp_ble_conn_start()失败则依次esp_ble_conn_stop()、esp_ble_conn_deinit()兜底。其中扩展广播参数是本节的核心逐字段解析如下字段定义与注释来自 esp_ble_conn_mgr.hesp_ble_conn_adv_params_t adv {0}; adv.adv_handle 0; /* 广播集句柄0x00-0xEF */ adv.own_addr_type ESP_BLE_CONN_ADDR_RANDOM; /* 使用随机地址 */ adv.primary_phy ESP_BLE_CONN_PHY_1M; /* 主信道 PHY1M */ adv.secondary_phy ESP_BLE_CONN_PHY_2M; /* 次信道 PHY2M承载实际数据 */ adv.sid 2; /* Advertising SID扫描端按此过滤 */ adv.itvl_min 0x140; /* 主广播间隔下限0.625ms 为单位 200ms */ adv.itvl_max 0x140; /* 上限0 使用栈默认值 */ adv.adv_event_properties 0; /* 非连接、不可扫描 */ adv.tx_power 127; /* 127 使用协议栈默认发射功率 */ ESP_ERROR_CHECK(esp_ble_conn_adv_params_set(adv));关键参数含义adv_event_properties与 HCILE Set Extended Advertising Parameters的Advertising_Event_Properties对齐的 16 位位图BIT0connectable、BIT1scannable、BIT2directed、BIT3high-duty directed、BIT4legacy_pdu、BIT5anonymous、BIT6include_tx_power、BIT7scan_req_notif。本例置 0表示纯广播、不可连接、不可扫描itvl_min/itvl_max单位 0.625ms合法范围 0x0020-0x4000。0x140 × 0.625ms 200mstx_power127 表示由协议栈选择默认发射功率sid广播集标识0-15扫描端必须匹配此值才接收。代码注释同时揭示了 NimBLE 的一个约束app_main.cNimBLE rejects connectablescannable when legacy_pdu0 (see ble_gap_ext_adv_params_validate).即非 legacy PDU 的扩展广播不允许同时设置 connectable scannable否则 NimBLE 返回BLE_HS_EINVAL。这是将adv_event_properties置 0 的根本原因。4. 底层参数映射在 esp_nimble.c 中可以看到扩展广播数据的落地逻辑初始化时若配置了extended_adv_data组件会将其拷贝进内部缓冲区长度取MIN(config-extended_adv_len, CONFIG_BT_NIMBLE_EXT_ADV_MAX_SIZE)——即最终广播载荷受 NimBLE 编译期最大扩展广播尺寸约束默认 1650 字节1000 字节完全在其能力范围内。而adv_event_properties在启动广播时被映射为扩展广播能力位图esp_nimble.cev_props非零时直接使用否则回退到ext_adv_cap字段兼容旧配置因此应用层应优先使用adv_event_properties表达事件属性。sdkconfig 关键配置ble_ext_adv/sdkconfig.defaults 是本示例正确运行的开关组合CONFIG_BT_ENABLEDy CONFIG_BT_NIMBLE_ENABLEDy CONFIG_BT_NIMBLE_EXT_ADVy CONFIG_BLE_CONN_MGR_ROLE_PERIPHERALy CONFIG_BLE_CONN_MGR_EXTENDED_ADVy CONFIG_BLE_CONN_MGR_EXTENDED_ADV_CAP0 CONFIG_BLE_CONN_MGR_PERIODIC_ADVn对照 ble_conn_mgr 的 Kconfig这些选项的语义如下配置项说明CONFIG_BLE_CONN_MGR_EXTENDED_ADV使能扩展广播依赖SOC_BLE_50_SUPPORTED并自动开启BT_NIMBLE_EXT_ADVCONFIG_BLE_CONN_MGR_EXTENDED_ADV_CAP扩展广播能力位图0-255BIT0connectable、BIT1scannable、BIT2directed、BIT3high-duty directed、BIT4legacy、BIT5anonymous、BIT6include TX power、BIT7scan req notif。置 0 表示纯非连接广播与代码中adv_event_properties 0一致CONFIG_BLE_CONN_MGR_PERIODIC_ADV周期性广播开关本示例专注扩展广播、明确关闭值得一提的是组件还提供BLE_CONN_MGR_SCAN_RESULT_ADV_MAX_LEN范围 31-1650默认 31决定每个扩展扫描报告分片拷贝到esp_ble_conn_scan_result_t.adv_data的最大字节数直接影响扫描端 RAM 占用见 Kconfig。扫描端的分片重组原理扩展广播数据可能跨多个 HCI 事件分片到达扫描端 ble_ext_scan/main/app_main.c 展示了标准的分片重组范式按广播身份过滤仅接收sid 2且ext_data_status ! LEGACY的报告按身份键分组以(addr, addr_type, sid)作为重组上下文reasm_same()判断是否同一条流不同则reasm_begin()重新开始顺序拼接分片把每个adv_data_len字节追加到重组缓冲区溢出则复位状态机判定BLE_GAP_EXT_ADV_DATA_STATUS_TRUNCATED被控制器截断或COMPLETE但长度 ≠ 1000 字节时均判定失败并复位只有COMPLETE且恰好 1000 字节才进入比对载荷校验先与期望模式memcmp逐字节比对再打印 FNV-1a并额外输出载荷首 64 字节与末 64 字节供人工核对。扫描参数方面ble_ext_scan/main/app_main.cpassive true被动扫描不发送扫描请求、filter_duplicates false关闭重复过滤避免丢掉分片、scan_phys覆盖 1M 与 Coded 两个主扫描 PHY。注意 HCI 扩展扫描不支持 2M 作为扫描 PHYscan_phys的 2M 位会被协议栈忽略见 esp_ble_conn_mgr.h 注释。每个分片到达时打印EXT scan fragment: prim_phy... sec_phy... sid... status... len... off... rssi...可借此观察实际分片数量与 PHY 使用情况。端到端验证方法按 README 的操作指引完成验证在一块支持板上烧录ble_ext_adv广播端在另一块板上烧录ble_ext_scan扫描端确保两者处于无线通信距离内对比两台设备的串口日志中FNV-1a行的哈希值必须完全一致广播端应打印Extended ADV payload: 1000 bytes ... FNV-1a0x...扫描端应打印Target ESP_EXT_ADV_1K found: 1000 bytes ... FNV-1a0x... (compare with advertiser log)。若哈希不一致可通过扫描端打印的首/末 64 字节十六进制与广播端载荷模式人工比对定位问题也可检查是否存在Truncated report/Complete status but assembled N bytes警告后者通常意味着信号干扰或距离过远导致分片丢失。与周期广播的区别README 特别强调本示例不是周期性广播。两者的本质区别在于扩展广播本示例由扫描端通过被动扫描发现广播数据跟随广播事件发送而周期性广播需要先建立周期同步Periodic Sync数据按固定周期独立于广播事件发送吞吐和时序可控性更强但接收端必须持有同步关系。若需在扩展广播基础上叠加周期广播/同步请参考仓库内的 ble_periodic_adv 与 ble_periodic_sync 示例以及 ble_conn_mgr 组件的ESP_BLE_CONN_EVENT_PERIODIC_REPORT/ESP_BLE_CONN_EVENT_PERIODIC_SYNC事件见 esp_ble_conn_mgr.h。延伸阅读组件总览与更多示例components/bluetooth/ble_conn_mgr/README.md、ble_conn_mgr Kconfig扩展广播/扫描/周期广播完整 APIesp_ble_conn_mgr.h底层 NimBLE 适配实现esp_nimble.c本示例周边配对ble_ext_scan、ble_periodic_adv、ble_periodic_sync【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表