ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ESP IoT Solution BLE L2CAP CoC Central 示例详解:NimBLE 面向连接通道的主动扫描与数据传输

ESP IoT Solution BLE L2CAP CoC Central 示例详解:NimBLE 面向连接通道的主动扫描与数据传输 ESP IoT Solution BLE L2CAP CoC Central 示例详解NimBLE 面向连接通道的主动扫描与数据传输【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution导读本篇文章围绕 esp-iot-solution 仓库中的 BLE L2CAP CoC Central 示例examples/bluetooth/ble_l2cap_coc/l2cap_coc_central展开讲解如何基于ble_conn_mgr连接管理组件实现一个完整的 BLE Central 角色程序执行被动扫描并打印扫描结果、按配置的设备名称自动匹配并连接外围设备、建立 L2CAP Connection-Oriented ChannelCoC通道并在通道上周期性发送数据。读完本文你将掌握 L2CAP CoC 在 ESP32 系列芯片上的核心概念、工程配置方法、源码调用链以及它与同目录 Peripheral 示例的配对调试方式。一、背景为什么需要 L2CAP CoC传统 BLE 应用主要依靠 GATTGeneric Attribute Profile传输数据每次读写都伴随着 attribute 操作开销且面向大数据块传输时并不高效。L2CAP Connection-Oriented ChannelCoC是 Bluetooth 4.2 引入的 L2CAP 增强特性它允许在 LE 链路上建立面向连接的逻辑通道以流式方式传输 SDUService Data Unit吞吐量和数据封装开销都优于 GATT 的 notification/indication 方案非常适合音频流、批量数据下发、自定义协议承载等场景。在 ESP-IDF 的 NimBLE 协议栈中L2CAP CoC 由CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM等配置控制。本示例将 CoC 的创建、连接、收发统一封装进 ble_conn_mgr 组件上层应用只需关注业务回调无需直接面对 NimBLE 的底层 API。二、示例功能概览根据 l2cap_coc_central/README.md该 Central 示例的核心行为为被动扫描执行 BLE passive scan打印每个扫描结果的地址、类型、RSSI 与广播数据按名称匹配解析广播数据中的设备名称与配置项Peer Device Name默认BLE_L2CAP_COC_PERIPH比对命中后停止扫描并发起连接建立 CoC 通道连接建立并完成服务发现后以配置的 PSM默认0x00EF向对端发起 L2CAP CoC 连接周期性发送数据通道建立成功后独立发送任务每 2 秒向对端发送一次满长度 SDU 数据接收与重注册收到对端数据后打印接收日志并通过recv_ready重新提供接收缓冲维持双向通信。三、支持的芯片与硬件要求README 的目标芯片支持矩阵如下Supported TargetsESP32ESP32-C3ESP32-C2ESP32-S3ESP32-H2硬件准备一块搭载 ESP32 / ESP32-C3 / ESP32-C2 / ESP32-S3 / ESP32-H2 SoC 的开发板一根用于供电与烧录的 USB 线。由于本示例是 Central 角色实际联调时还需要另一块开发板运行同目录下的 l2cap_coc_peripheral 示例充当外设。四、工程结构与关键文件示例位于 examples/bluetooth/ble_l2cap_coc/l2cap_coc_central其目录结构如下l2cap_coc_central/ ├── main/ │ ├── CMakeLists.txt # 组件构建描述依赖 bt 与 nvs_flash │ ├── Kconfig.projbuild # Example Configuration 菜单设备名、PSM 等 │ ├── app_main.c # 示例全部业务逻辑 │ └── idf_component.yml # 组件依赖声明 ├── CMakeLists.txt ├── README.md └── sdkconfig.defaults # 默认 sdkconfig 片段NimBLE/CoC 相关开关关键依赖关系idf_component.ymldependencies: idf: 4.3 ble_conn_mgr: version: ~1.* override_path: ../../../../../components/bluetooth/ble_conn_mgr示例直接复用仓库内的 ble_conn_mgr 组件通过override_path指向本地路径该组件同时支持 Bluedroid 与 NimBLE 双协议栈src/esp_bluedroid.c、src/esp_nimble.c本示例基于 NimBLE。五、核心代码调用链解析5.1 入口初始化流程app_main.c 中的app_main依次完成esp_ble_conn_config_t config { .device_name CONFIG_EXAMPLE_BLE_DEVICE_NAME, .broadcast_data CONFIG_EXAMPLE_BLE_SUB_ADV, }; // 1. 初始化 NVS nvs_flash_init(); // 2. 创建默认事件循环并注册 BLE 连接管理事件处理器 esp_event_loop_create_default(); esp_event_handler_register(BLE_CONN_MGR_EVENTS, ESP_EVENT_ANY_ID, app_ble_conn_event_handler, NULL); // 3. 初始化 BLE 连接管理器 esp_ble_conn_init(config); // 4. 初始化 L2CAP CoC 内存池关键 esp_ble_conn_l2cap_coc_mem_init(); // 5. 注册扫描回调 esp_ble_conn_register_scan_callback(app_ble_conn_scan_cb, NULL); // 6. 启动连接管理器 esp_ble_conn_start();其中esp_ble_conn_l2cap_coc_mem_init()是 CoC 功能可用的前提它负责为 CoC 通道分配内存池如果启动失败示例会依次调用esp_ble_conn_l2cap_coc_mem_release()、esp_ble_conn_deinit()回滚初始化并报错退出。对应 API 声明见 esp_ble_conn_mgr.h。5.2 扫描回调按名称匹配并触发连接扫描回调app_ble_conn_scan_cb实现了被动扫描 → 解析广播数据 → 匹配设备名 → 停止扫描并连接的完整逻辑static bool app_ble_conn_scan_cb(const esp_ble_conn_scan_result_t *result, void *arg) { // 打印扫描结果地址、地址类型、RSSI、广播数据长度 ESP_LOGI(TAG, scan result: addr BLE_CONN_MGR_ADDR_STR type%u rssi%d adv_len%u, ...); ESP_LOG_BUFFER_HEX(TAG, result-adv_data, result-adv_data_len); // 优先解析 Complete Local Name失败再尝试 Shortened Local Name if (esp_ble_conn_parse_adv_data(..., ESP_BLE_CONN_ADV_TYPE_NAME_COMPLETE, ...) ! ESP_OK) { if (esp_ble_conn_parse_adv_data(..., ESP_BLE_CONN_ADV_TYPE_NAME_SHORT, ...) ! ESP_OK) { return false; } } // 与 CONFIG_EXAMPLE_PEER_NAME 比对 if (strcmp(peer_name, CONFIG_EXAMPLE_PEER_NAME) 0) { s_target_found true; esp_ble_conn_scan_stop(); // 停止扫描 return true; // 返回 true 触发连接 } return false; }关键点根据 esp_ble_conn_register_scan_callback 的注释当回调返回true时连接管理器会自动对该对端发起连接且同一时间只允许一个外连尝试若已有连接尝试在进行中后续扫描结果会被跳过。esp_ble_conn_parse_adv_data用于从原始广播数据中按 AD type 提取字段如ESP_BLE_CONN_ADV_TYPE_NAME_COMPLETE表示完整名称。5.3 连接事件驱动服务发现后建立 CoC 通道通用事件处理器app_ble_conn_event_handler监听BLE_CONN_MGR_EVENTS事件ESP_BLE_CONN_EVENT_CONNECTED通过esp_ble_conn_get_conn_handle()与esp_ble_conn_get_peer_addr()获取连接句柄和对端地址并打印ESP_BLE_CONN_EVENT_DISC_COMPLETE服务发现完成后发起 CoC 连接这是关键时序点——必须等 GATT 服务发现结束后再建立 CoC 通道esp_err_t rc esp_ble_conn_l2cap_coc_connect(s_conn_handle, L2CAP_COC_PSM, L2CAP_COC_MTU, L2CAP_COC_MTU, app_ble_conn_l2cap_coc_event_handler, NULL);对应 API 签名esp_ble_conn_mgr.hesp_err_t esp_ble_conn_l2cap_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, uint16_t sdu_size, esp_ble_conn_l2cap_coc_event_cb_t cb, void *cb_arg);参数含义conn_handle为已建立的 LE 链路句柄psm为对端监听的 Protocol/Service MultiplexerLE 下有效范围 0x0001–0x00FFmtu为本端使用的最大 SDU 大小23–512 字节sdu_size为首个 SDU 的接收缓冲区大小23–65535 字节API 注释明确指出应用通常应将其设置为期望的对端 CoC MTU。示例中将 MTU 与 SDU 大小都设置为CONFIG_BLE_CONN_MGR_L2CAP_COC_MTU。ESP_BLE_CONN_EVENT_DISCONNECTED清空连接句柄并复位s_target_found使程序可再次进入扫描匹配流程。5.4 CoC 通道事件处理L2CAP CoC 专用回调app_ble_conn_l2cap_coc_event_handler处理四类事件事件类型含义示例处理ESP_BLE_CONN_L2CAP_COC_EVENT_CONNECTEDCoC 通道建立打印通道信息创建发送任务ESP_BLE_CONN_L2CAP_COC_EVENT_DISCONNECTED通道断开清空通道句柄删除发送任务ESP_BLE_CONN_L2CAP_COC_EVENT_DATA_RECEIVED收到对端 SDU打印接收日志重新注册接收缓冲ESP_BLE_CONN_L2CAP_COC_EVENT_TX_UNSTALLED发送阻塞解除打印状态供发送逻辑重试在CONNECTED分支中示例调用esp_ble_conn_l2cap_coc_get_chan_info()获取通道详情并打印esp_ble_conn_l2cap_coc_chan_info_t chan_info {0}; esp_ble_conn_l2cap_coc_get_chan_info(event-connect.chan, chan_info); // 打印 psm / scid / dcid / our_mps / our_mtu / peer_mps / peer_mtu s_peer_sdu_size chan_info.peer_coc_mtu; // 以对端 CoC MTU 作为发送长度这里s_peer_sdu_size chan_info.peer_coc_mtu非常关键发送方以对端的 CoC MTU 作为 SDU 长度保证单帧即可完整传输而不被分片。DATA_RECEIVED分支中有一段重要的使用约束注释原文event-receive.sdu.data buffer is managed internally and will be freed immediately after this callback returns. Do not save the pointer for later use. If asynchronous processing is needed, copy the data before returning.即接收数据缓冲区由组件内部管理回调返回后立即释放不能保存指针后续使用如需异步处理必须先拷贝。随后示例调用esp_ble_conn_l2cap_coc_recv_ready(event-receive.chan, L2CAP_COC_MTU)为下一个 SDU 重新提供接收缓冲——这是 NimBLE CoC 流控下的标准做法不调用则无法继续接收。5.5 周期发送任务通道建立成功后创建l2cap_coc_send_task栈 4096 字节、优先级 10每 2 秒发送一次static void app_ble_conn_l2cap_coc_test_send(esp_ble_conn_l2cap_coc_chan_t *chan) { uint8_t *payload (uint8_t *)malloc(s_peer_sdu_size); for (uint16_t i 0; i s_peer_sdu_size; i) { payload[i] (uint8_t)(i 0xFF); // 填充 0x00,0x01,... 便于对端校验 } esp_ble_conn_l2cap_coc_sdu_t sdu { .data payload, .len s_peer_sdu_size, }; esp_err_t rc esp_ble_conn_l2cap_coc_send(*chan, sdu); if (rc ! ESP_OK) { ESP_LOGW(TAG, L2CAP CoC send failed: %s, esp_err_to_name(rc)); } free(payload); }esp_ble_conn_l2cap_coc_send()的流控语义esp_ble_conn_mgr.h数据缓冲区不归协议栈所有函数返回后即可释放示例正是这样做的若通道处于 stalled 状态缓冲区满返回ESP_ERR_NOT_FINISHED调用方应等待ESP_BLE_CONN_L2CAP_COC_EVENT_TX_UNSTALLED事件后重试若内存池耗尽返回ESP_ERR_NO_MEM应稍后重试。六、工程配置详解6.1 设置目标芯片编译前必须先设置正确的芯片目标idf.py set-target chip_name其中chip_name可为esp32、esp32c3、esp32c2、esp32s3、esp32h2之一需与开发板对应。6.2 menuconfig 配置运行idf.py menuconfig打开配置菜单。Example Configuration 菜单定义于 Kconfig.projbuild配置项默认值说明Device nameBLE_L2CAP_COC_CENT本设备广播/被识别使用的设备名Subsequent advertisement dataSUB_ADV后续广播数据内容Peer Device NameBLE_L2CAP_COC_PERIPH要连接的外设名称须与外设端广告名称一致L2CAP CoC PSM0x00EF面向连接通道的协议/服务复用器值PSM 的有效范围为0x0001–0x00FFKconfig 中同时给出了分段说明0x0001 – 0x007F蓝牙 SIG 定义的固定服务0x0080 – 0x00FF动态自定义服务本示例的 0x00EF 落在此段。要求 Central 与 Peripheral 两端必须使用相同的 PSM 值否则无法建立通道。Component Config 菜单README 明确要求的两项Component config → Bluetooth → NimBLE Options → L2CAP → Maximum number of connection oriented channels设为大于 0的值本示例sdkconfig.defaults中为 1否则 NimBLE 协议栈根本不支持 CoCComponent config → Bluetooth → NimBLE Options → Memory Settings → MSYS_1 Block Size设为512以支持最大 SDU 传输。6.3 sdkconfig.defaults 中的默认开关sdkconfig.defaults 在编译前就固定了关键选项CONFIG_BT_ENABLEDy # 启用蓝牙 CONFIG_BTDM_CTRL_MODE_BLE_ONLYy # 控制器仅 BLE 模式 CONFIG_BT_NIMBLE_ENABLEDy # 使用 NimBLE 主机协议栈 CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM1 # 最大面向连接通道数 0 CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT30 # MSYS_1 内存块数量 CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE512 # MSYS_1 块大小 512 字节 CONFIG_BLE_CONN_MGR_ROLE_CENTRALy # 连接管理器角色Central其中CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM与 README 中Maximum number of connection oriented channels 大于 0的菜单要求一一对应CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE512对应MSYS_1 Block Size 设为 512。CONFIG_BLE_CONN_MGR_ROLE_CENTRAL对应 ble_conn_mgr/Kconfig 中的角色选择Peripheral / Central / Both默认 Peripheral。6.4 连接管理器的相关配置ble_conn_mgr/Kconfig 中还定义了与 CoC 相关的系统级参数BLE_CONN_MGR_L2CAP_COC_MTUL2CAP CoC SDU MTU范围 23–512默认 512用于 L2CAP CoC 内存池的默认 SDU 大小——正是示例中L2CAP_COC_MTU宏的来源BLE_CONN_MGR_MAX_CONNECTIONS连接管理器管理的最大 BLE 链路数默认 2不能超过底层协议栈的配置BLE_CONN_MGR_WAIT_DURATION等待完成时长10–31默认 31设置足够大以避免重传。七、编译、烧录与运行在l2cap_coc_central目录下执行idf.py -p PORT flash monitor该命令会依次完成构建、烧录并打开串口监视器退出监视器按Ctrl-]。建议与 l2cap_coc_peripheral 示例配对使用外设端启动广播广告名称默认BLE_L2CAP_COC_PERIPHCentral 端运行后即可在串口日志中观察到扫描结果逐条打印地址、RSSI、广播数据十六进制命中BLE_L2CAP_COC_PERIPH后打印Matched peer name: ...并停止扫描GATT 服务发现完成后打印Service discovery complete, connect L2CAP CoCCoC 通道建立后打印通道信息psm/scid/dcid/our_mps/our_mtu/peer_mps/peer_mtu每 2 秒出现一条[--TX--]L2CAP CoC data sent (N bytes)同时外设端可见对应[--RX--]接收日志。八、与 Peripheral 示例的对称设计同目录的 l2cap_coc_peripheral 扮演仅广播的广告者角色启动广播后等待 Central 连接连接建立后通过esp_ble_conn_l2cap_coc_create_server()创建 CoC 服务端PSM 默认同样为0x00EF范围 0x0001–0x00FF要求与 Central 一致并处理通道事件。两端在配置上需要对齐PSM 必须相同外设广告名称必须等于 Central 的Peer Device Name均需开启Maximum number of connection oriented channels 0并将MSYS_1 Block Size设为 512。esp_ble_conn_l2cap_coc_create_server()的接口说明esp_ble_conn_mgr.h指出服务端回调上下文对该 PSM 是持久化的会在多个入站连接间复用直到 L2CAP CoC 内存池被释放而客户端回调上下文在连接失败CONNECTED事件携带非零 status或DISCONNECTED后会被自动释放。九、常见问题与注意事项发送失败ESP_ERR_NOT_FINISHED通道处于 stalled 状态说明发送缓冲已满或对端未及时recv_ready。正确做法是等待ESP_BLE_CONN_L2CAP_COC_EVENT_TX_UNSTALLED事件后重试而不是盲目重发。发送失败ESP_ERR_NO_MEMCoC 内存池耗尽可稍后重试或检查是否有未完成的操作占用缓冲。接收回调中的数据指针不可保存DATA_RECEIVED事件的 SDU 缓冲在回调返回后被释放异步处理必须拷贝。每次接收后必须调用esp_ble_conn_l2cap_coc_recv_ready()否则无法继续接收后续 SDU。PSM 与 MTU 范围LE 下 PSM 限定 0x0001–0x00FFSDU MTU 限定 23–512 字节见 esp_ble_conn_mgr.h 中各 API 的参数注释越界会返回ESP_ERR_INVALID_ARG。扫描回调触发连接是单实例的同一时间只允许一个外连尝试连接完成或失败前后续匹配结果会被忽略esp_ble_conn_mgr.h。结语通过本文的讲解可以看到ble_conn_mgr组件把 NimBLE 中较为繁琐的 L2CAP CoC 通道管理抽象为初始化内存池 → 发起连接/创建服务 → 事件回调 → 发送/接收四个步骤Central 与 Peripheral 示例则为开发者提供了可直接复用的完整模板。基于 l2cap_coc_central 的代码骨架你可以快速改造出支持自定义协议、批量数据传输乃至音频流传输的 BLE 应用。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表