ESP-BLE-ISO 详解:在 ESP-IDF 中使用 BLE 等时信道实现 CIS 与 BIS 流传输
2026/9/18 14:19:14 网站建设 项目流程

ESP-BLE-ISO 详解:在 ESP-IDF 中使用 BLE 等时信道实现 CIS 与 BIS 流传输

【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf

ESP-BLE-ISO 是 ESP-IDF 蓝牙子系统中专用于Bluetooth LE Isochronous Channels(LE 等时信道)的传输层组件,为上层提供创建/加入 Connected ISO Group(CIG)、创建/同步 Broadcast ISO Group(BIG)、配置 ISO 数据路径以及收发等时数据(如 LC3 音频)的完整 API,是 LE Audio 功能(esp-ble-audio组件)的底层承载。阅读本文后,你将掌握 ESP-BLE-ISO 的两种信道模型(CIS/BIS)、核心 API 与数据结构、Kconfig 配置项,并能基于仓库自带的 four 个官方示例搭建广播(BIG)与单播(CIS)的端到端等时流传输方案。

本文基于当前仓库(ESP-IDF)中的 docs/zh_CN/api-reference/bluetooth/esp-ble-iso.rst(其正文 include 自 docs/en/api-reference/bluetooth/esp-ble-iso.rst),并结合 components/bt/esp_ble_iso 组件源码、examples/bluetooth/esp_ble_iso 示例工程展开。

ESP-BLE-ISO 是什么

ESP-BLE-ISO 提供 Bluetooth LE等时信道(Isochronous Channels)的 API,支持时间同步的、面向连接(CIS)与无连接(BIS)的流传输。该实现构建在蓝牙控制器(Controller)的 ISO 支持之上,设计用于配合 esp-ble-audio 组件使用——也就是说,它是 LE Audio 协议栈的传输底座,本身不包含任何音频编解码或 profile 逻辑。

其核心组件位于 components/bt/esp_ble_iso,源码结构包括:

  • api/include/esp_ble_iso_common_api.h—— 对外公开的全部宏、类型定义与函数声明(本组件唯一的公共头文件);
  • api/esp_ble_iso_common_api.c—— 公共 API 的 C 实现,内部调用 Zephyr 风格的bt_*/bt_le_*接口;
  • host/—— 双 Host(Bluedroid 与 NimBLE)适配层、GAP/GATT/HCI/L2CAP/ISO 事件处理与 ISO 任务;
  • include/—— 移植自 Zephyr 的蓝牙头文件(zephyr/bluetooth/iso.h等),提供底层数据结构定义;
  • Kconfig.in—— 组件功能开关与内存布局等配置。

两种等时信道模型

信道类型英文全称方向前提典型用途
CISConnected Isochronous Stream双向必须先建立 ACL 连接时间同步的单播音频(LE Audio 通话/音乐)
BISBroadcast Isochronous Stream单向(Broadcaster → Synchronized Receiver)无需连接广播音频、群体收听(如助听、场馆广播)

借助这些 API,你可以:

  • 创建或加入 CIG(Connected ISO Group,连接等时组)——由 Central 侧创建、Peripheral 侧通过 ISO Server 接受;
  • 创建或同步 BIG(Broadcast ISO Group,广播等时组)——Broadcaster 创建并加密,Synchronized Receiver 通过周期广播(PA)同步并解码;
  • 设置 ISO 数据路径(Data Path)——决定等时数据走 HCI 透传还是厂商自定义路径;
  • 发送/接收等时数据(SDU)——例如承载 LC3 编码的音频帧。

更上层的 LE Audio profile 与编解码 API 见 esp-ble-audio;架构总览与集成细节见 Bluetooth LE Audio 文档,特别是 ESP-BLE-ISO 架构 一章。

⚠️预览版声明:当前 ESP-BLE-ISO API、数据结构与配置参数在后续版本中可能变更。未来版本可能在不另行通知的情况下引入破坏性改动——例如类型重命名/重组、函数签名修改、字段移除等。在依赖这些接口做产品化时需评估风险。

从源码理解组件架构

在深入 API 之前,先了解 ESP-BLE-ISO 在仓库中的底层运行模型,这对理解回调时机与线程安全至关重要(详见 ble-audio-architecture-iso.rst)。

单一 ISO 任务与全局锁

  • ISO 任务(iso_task:所有位于 Host 栈之上的处理都在这个单一 FreeRTOS 任务中执行。外部通过bt_le_iso_task_post()向它投递工作,投递队列分为三级优先队列(Critical/Normal/Floodable),按优先级严格调度。Critical 级(深 32,满则丢弃最新)承载等时收/发数据路径,保证突发 GAP 上报不会阻塞音频数据;Normal 级(深 64,满则阻塞)承载定时器、GAP 生命周期、GATT 与 ISO HCI 事件;Floodable 级(深 32,满则丢弃最新)承载扩展广播、周期广播与 BIGInfo 上报等大流量尽力而为事件。
  • ISO 锁(bt_le_host_lock:一把全局递归互斥锁,序列化应用线程直接调用公共 API、NimBLE 同步回调与 ISO 任务处理程序对共享状态(连接表、PA sync 表、GATT 订阅表、ISO 簿记)的访问。获取超时会主动abort(),防止带锁竞争。
  • _safe后缀约定:内部操作成对出现——核心函数假定锁已持有,_safe包装函数先加锁再调用核心函数。公共入口与 ISO 任务外的调用方一律使用_safe变体。

对应用开发者的启示:所有注册的回调(GAP 事件、ISO connected/recv/sent 等)基本都在 ISO 任务上执行,该任务栈仅4 KB,回调内应避免深层调用链与大栈上缓冲,也不要在回调里阻塞等待。

双 Host 适配

组件同时支持 Bluedroid 与 NimBLE 两种 Host,由 Kconfig 在构建期选择(见下文)。bt_前缀符号是 Host 无关接口,定义在host/commonbt_le_bluedroid_*/bt_le_nimble_*是适配层实现,每次构建只编译其一。这一点在示例工程的main/bluedroid/main/nimble/双份适配文件中体现得很直观(例如 big_broadcaster 的 adv.c 与 nimble 版本)。

ESP-BLE-ISO Common API 详解

ESP-BLE-ISO 的公共 API 全部集中在 esp_ble_iso_common_api.h,划分为:宏定义(BIS 索引与数据路径宏、控制器延迟与间隔上下限)、CIG/BIG 参数与结构体ISO Server 与信道操作数据路径设置BIG 创建/同步/终止GAP 事件类型ISO 通用初始化。对应的实现见 esp_ble_iso_common_api.c,其中大部分函数是对 Zephyr 接口的_safe封装,并做了参数校验(ESP_ERR_INVALID_ARG/ESP_ERR_NOT_FOUND/ESP_FAIL等错误码映射)。

常用宏:常量与上下限

组件把控制器/Host 相关的等时参数边界暴露为一组ESP_BLE_ISO_*宏(定义在 esp_ble_iso_common_api.h),供应用在编译期引用,避免硬编码越界。分类如下:

类别含义
BIS 索引ESP_BLE_ISO_BIS_INDEX_BIT(x)把 1 起始的 BIS 索引转成位域(要同步 BIS 0x01 与 0x02 用BIT(0)\|BIT(1));另有ESP_BLE_ISO_BIS_INDEX_MIN/MAX
数据路径ESP_BLE_ISO_DATA_PATH_VS_ID_MIN/MAX厂商自定义数据路径 ID 范围
时序参数ESP_BLE_ISO_CONTROLLER_DELAY_MIN/MAX(μs)、ESP_BLE_ISO_SDU_INTERVAL_MIN/MAX(μs)、ESP_BLE_ISO_ISO_INTERVAL_MIN/MAX(N×1.25 ms)、ESP_BLE_ISO_LATENCY_MIN/MAX(ms)、ESP_BLE_ISO_SYNC_TIMEOUT_MIN/MAX(N×10 ms)等时时序各参数合法范围
打包/帧格式ESP_BLE_ISO_PACKING_SEQUENTIAL/INTERLEAVEDESP_BLE_ISO_FRAMING_UNFRAMED/FRAMED组内多信道的打包方式与是否成帧
尺寸ESP_BLE_ISO_MIN_SDU/MAX_SDUESP_BLE_ISO_CONNECTED_PDU_MIN/BROADCAST_PDU_MIN/PDU_MAXESP_BLE_ISO_BN_MIN/MAXESP_BLE_ISO_FT_MIN/MAXESP_BLE_ISO_NSE_MIN/MAXESP_BLE_ISO_MAX_GROUP_ISO_COUNTSDU/PDU/突发数/刷新超时/子事件数等边界
重传与加密ESP_BLE_ISO_CONNECTED_RTN_MIN/MAXESP_BLE_ISO_BROADCAST_RTN_MIN/MAXESP_BLE_ISO_BROADCAST_CODE_SIZE(16 字节)重传次数与广播码长度
数据路径方向ESP_BLE_ISO_DATA_PATH_DIR_INPUT(Host→Controller,音频输入)、ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT(Controller→Host,音频输出)setup_data_path 的方向参数
编码格式ESP_BLE_ISO_CODING_FORMAT_TRANSPARENTESP_BLE_ISO_CODING_FORMAT_LC3ESP_BLE_ISO_DATA_PATH_HCI透明编码 / LC3 编码 / 数据路径走 HCI
收包状态ESP_BLE_ISO_FLAGS_VALID/ERROR/LOST/TS接收元数据中包的合法性、错误、丢失与时间戳有效位
PHYESP_BLE_ISO_PHY_1M/2M/CODED物理层速率
时钟精度ESP_BLE_ISO_SCA_UNKNOWN/251_500/.../0_20Peripheral 睡眠时钟精度(Sleep Clock Accuracy)
安全等级ESP_BLE_ISO_SECURITY_NONE/NO_MITM/MITM对应 BT Security Level 1/2/3
GAP 事件ESP_BLE_ISO_GAP_EVENT_EXT_SCAN_RECV/PA_SYNC/PA_SYNC_PAST/PA_SYNC_LOST/ACL_CONNECT/ACL_DISCONNECT/SECURITY_CHANGE/BIGINFO_RECVISO 内部使用的应用层 GAP 事件

核心结构体

所有公开类型都是对 Zephyr 结构体的 typedef(见 esp_ble_iso_common_api.h),字段语义以 zephyr/bluetooth/iso.h 为准。常用的有:

  • esp_ble_iso_chan_t(信道)ops(回调)、qos(收发 QoS)、iso(连接引用)、state。见 iso.h#L204-L216。
  • esp_ble_iso_chan_io_qos_t(IO QoS)sdu(SDU 大小)、phy(PHY,不能是 NONE)、rtn(重传次数)、max_pduburst_number。见 iso.h#L218-L256。
  • esp_ble_iso_chan_qos_t(信道 QoS)rx/tx指向 IO QoS,置 NULL 即禁用对应方向的数据路径(如纯发送端把rx设为 NULL);num_subevents为每个 CIS/BIS 事件的最大子事件数。见 iso.h#L258-L286。
  • esp_ble_iso_chan_path_t(数据路径)pid(HCI 或厂商路径)、format(编码格式)、cid/vid(厂商编解码 ID)、delay(控制器延迟,μs)、cc_len/cc(编解码配置 LTV 数据)。见 iso.h#L288-L321。
  • esp_ble_iso_cig_param_t(CIG 参数)cis_channels/num_cisc_to_p_interval/p_to_c_interval(双向 SDU 间隔)、c_to_p_latency/p_to_c_latencysca(取所有 Peripheral 中最差睡眠时钟精度,未知则用SCA_UNKNOWN)、packingframingc_to_p_ft/p_to_c_ftiso_interval。见 iso.h#L378-L473。
  • esp_ble_iso_big_create_param_t(BIG 创建参数)bis_channels/num_bisinterval(SDU 间隔 μs)、latencypackingframingencryptionbcode(16 字节广播码,字符串不足 16 字节时剩余字节填 0)、irc/pto/iso_interval(高级参数)。见 iso.h#L487-L572。
  • esp_ble_iso_big_sync_param_t(BIG 同步参数)bis_channels/num_bisbis_bitfield(用ESP_BLE_ISO_BIS_INDEX_BIT组装)、mse(最大子事件数,可让控制器自选)、sync_timeoutencryptionbcode。见 iso.h#L574-L631。
  • esp_ble_iso_chan_ops_t(信道回调)connecteddisconnected(携带 BT_HCI_ERR_* reason)、alloc_bufrecv(携带esp_ble_iso_recv_info_t元数据)、sent(携带 user_data)。见 iso.h#L678-L749。
  • esp_ble_iso_server_t(ISO Server)accept回调,Peripheral 侧在收到新 CIS 请求时被调用,应用在此决定是否接受并交出信道对象。见 iso.h#L771-L784。
  • esp_ble_iso_accept_info_t:包含请求授权的 ACL 连接、Central 侧的cig_idcis_id。见 iso.h#L751-L769。
  • esp_ble_iso_recv_info_t:接收元数据——ts(时间戳,仅当 flags 含ESP_BLE_ISO_FLAGS_TS时有效)、seq_numflags(VALID/ERROR/LOST/TS 位域)。见 iso.h#L347-L361。
  • esp_ble_iso_biginfo_t:BIGInfo 上报内容——广播地址/SID、BIS 数量、子事件数、ISO 间隔、突发数、预传输偏移、重复次数、最大 PDU/SDU、PHY、framing、加密标志。见 iso.h#L633-L676。
  • esp_ble_iso_ext_adv_info_t:BIG 关联的扩展广播信息(adv_handle、地址类型、地址、sid),为 ESP 扩展类型,见 esp_ble_iso_common_api.h#L288-L293。

公共函数一览

函数作用关键实现点(esp_ble_iso_common_api.c)
esp_ble_iso_data_parse()解析 LTV 编码数据,逐元素回调校验ltv/func非空;元素格式[len][type][value...];回调返回 false 即中止解析并返回ESP_FAIL,见 L11-L54
esp_ble_iso_server_register()/unregister()注册/注销 ISO Server(仅 Peripheral)CONFIG_BT_ISO_PERIPHERAL门控
esp_ble_iso_cig_create()/reconfigure()/terminate()创建/重配/终止 CIG(仅 Central)CONFIG_BT_ISO_CENTRAL门控,最终调用bt_iso_cig_*_safe
esp_ble_iso_chan_connect()建立 CIS(仅 Central)参数为 NULL 或 count 为 0 返回ESP_ERR_INVALID_ARG;按conn_handle查找 ACL 连接,找不到返回ESP_ERR_NOT_FOUND,找到则把acl填入每个connect_param后调用bt_iso_chan_connect,见 L122-L153
esp_ble_iso_chan_disconnect()断开 ISO 信道CONFIG_BT_ISO_UNICAST门控
esp_ble_iso_setup_data_path()/remove_data_path()设置/移除信道数据路径校验方向必须是 INPUT/OUTPUT(valid_dir);CIS 需在connected回调中调用;广播信道仅 INPUT、同步接收仅 OUTPUT
esp_ble_iso_big_register_cb()注册广播源回调CONFIG_BT_ISO_BROADCAST门控
esp_ble_iso_big_ext_adv_add()/delete()为 BIG 添加/删除扩展广播(仅 Broadcaster)基于adv_handle调用bt_le_ext_adv_new_safe/delete_safe
esp_ble_iso_big_create()创建 BIG(仅 Broadcaster)adv_handle查找扩展广播对象,找不到返回ESP_ERR_NOT_FOUND
esp_ble_iso_big_sync()同步 BIG(仅 Synchronized Receiver)sync_handle查 PA sync,找不到返回ESP_ERR_NOT_FOUND
esp_ble_iso_big_terminate()终止 BIG同时清除关联数据路径
esp_ble_iso_chan_get_info()查询信道信息
esp_ble_iso_chan_get_tx_sync()/send()/send_ts()获取 TX 同步信息、发送 SDU(可带时间戳)send内部构造net_buf后调用bt_iso_chan_send_safesdusdu_len必须同时非空/为空,否则ESP_ERR_INVALID_ARG,见 L352-L399
esp_ble_iso_gap_app_post_event()投递应用层 GAP 事件(仅 NimBLE 需要)直接转发bt_le_gap_app_post_event
esp_ble_iso_common_init()ISO 通用初始化注册gap_cb后调用bt_le_host_init();失败时回滚注销,见 L407-L435
esp_ble_iso_bluedroid_get_gattc_if()获取 Bluedroid 引擎内部 GATTC 接口句柄传给esp_ble_gattc_aux_open()使 ACL 事件路由回引擎;GATTC 未注册完成时返回ESP_GATT_IF_NONE(0xFF),见 L437-L442

数据路径的生命周期(重要细节)

关于esp_ble_iso_remove_data_path(),头文件注释 给出了与蓝牙核心规范 6.0 对齐的规则:

  • CIS(Peripheral 侧):CIS 断开后数据路径由控制器自动删除,Peripheral 无需(也无法)手动移除;
  • CIS(Central 侧):断开后数据路径仍有效,Central 若不打算再使用该 CIS,应在断开时主动调用esp_ble_iso_remove_data_path();CIG 被esp_ble_iso_cig_terminate()终止时,Central 创建的全部数据路径随之清除;
  • BIG(Synchronized Receiver 侧):BIG sync 丢失或终止时由控制器删除数据路径,无需手动处理;
  • BIG(Broadcaster 侧):BIG 被esp_ble_iso_big_terminate()终止时全部数据路径随之清除。

esp_ble_iso_setup_data_path()必须在信道已关联 BIS/CIS 句柄之后调用——也就是在esp_ble_iso_chan_ops_t.connected()回调中调用(见 头文件说明)。

Kconfig 配置:功能开关与资源预算

ESP-BLE-ISO 的所有功能开关定义在 components/bt/esp_ble_iso/Kconfig.in,由CONFIG_BT_ISO_*前缀控制:

配置项说明
BT_ISO总开关,自动被 UNICAST/BROADCAST 选中;自动选择对应 Host 的 ISO 支持
BT_ISO_TX/BT_ISO_RX等时发送 / 接收能力
BT_ISO_UNICAST单播等时(CIS)支持,隐式开启 TX+RX
BT_ISO_PERIPHERALCIS Peripheral 角色支持
BT_ISO_CENTRALCIS Central 角色支持
BT_ISO_BROADCAST广播等时(BIS)支持
BT_ISO_BROADCASTERBroadcaster 角色支持(隐式开启 TX)
BT_ISO_SYNC_RECEIVERSynchronized Receiver 角色支持(隐式开启 RX)
BT_ISO_MAX_CHAN最大同时 ISO 信道数,默认 1,范围 1–64
BT_ISO_MAX_CIG最大 CIG 数(Bluedroid 下 1–2,默认 1;NimBLE 下取BT_NIMBLE_ISO_CIG
BT_ISO_MAX_BIG最大 BIG 数(Bluedroid 下 1–2,默认 1;NimBLE 下取BT_NIMBLE_ISO_BIG),一个 BIG 同一时刻只能用于发送或接收
BT_ISO_TEST_PARAMSISO 测试参数支持(默认 Bluedroid 开启),允许 Host 设置通常由控制器控制的参数
BT_ISO_BSS_SEG_EXTERNAL_MEMORY把组件.bss段放入外部 SPIRAM(需SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
BT_ISO_HEAP_EXTERNAL_MEMORY控制面堆分配走 SPIRAM;实时数据路径(TX/RX SDU 缓冲)仍留在内部 DRAM
BT_ISO_DISPATCH_MONITORISO 任务回调分发延迟监控(默认关),配合BT_ISO_DISPATCH_THRESHOLD_US(默认 2000 μs)与BT_ISO_DISPATCH_DUMP_PERIOD_S(默认 10 s)使用
BT_ISO_NO_LOG/BT_ISO_LOG_LEVEL关闭 ISO 调试日志或设置日志级别(同时影响 esp_ble_audio 的LEA_*日志)

以官方示例 big_broadcaster/sdkconfig.defaults 为例,一个典型的 BIS 广播端最小配置是:

CONFIG_BT_ENABLED=y CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_CONTROLLER_ENABLED=y CONFIG_BT_BLE_ENABLED=y CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y CONFIG_BT_BLE_FEAT_ISO_EN=y CONFIG_BT_ISO_BROADCASTER=y CONFIG_BT_ISO_MAX_CHAN=2

如需在 PSRAM 目标上释放内部 RAM,可打开SPIRAM并启用BT_ISO_BSS_SEG_EXTERNAL_MEMORY/BT_ISO_HEAP_EXTERNAL_MEMORY(见该文件 L21-L26 注释)。

官方示例:从广播到单播的完整链路

官方提供了四个配对示例(examples/bluetooth/esp_ble_iso),支持 ESP32-H4 / ESP32-S31 等带 BLE 5.2 ISO 能力的芯片,构建时通过 Kconfig 在 NimBLE 与 Bluedroid 之间二选一:

示例角色演示内容
big_broadcasterBroadcaster创建 BIG 并通过 BIS 发送等时数据
big_receiverSynchronized Receiver同步 BIG 并从 BIS 接收等时数据
cis_centralCIS Central创建 CIG/CIS 并发送等时数据
cis_peripheralCIS Peripheral接受 CIS 并接收等时数据

这四个示例共享common_components/下的example_init(BLE 初始化)与example_utils(TX 调度器、RX 统计等工具),方便直接对照学习。

BIG 广播链路:big_broadcaster ↔ big_receiver

big_broadcaster(核心逻辑见 main/main.c)的流程是:

  1. 初始化 NVS(存放 PHY 校准数据)→bluetooth_init()app_host_init()esp_ble_iso_common_init()
  2. 为 2 个 BIS 信道各初始化一个软件 TX 调度器(注释明确说明esp_timer精度不够,必须用调度器保证 10 ms 节拍);
  3. 配置并启动扩展广播 + 周期广播(handle 0,非连接、非可扫描,主信道 1M / 次信道 2M);
  4. esp_ble_iso_big_ext_adv_add()把广播句柄绑定到 BIG,再用esp_ble_iso_big_create()下发 HCILE Create BIG:2 个 BIS、加密开启、广播码"1234"(最多 16 字节,不足部分补 0);
  5. 每个 BIS 就绪后,connected回调安装 HCI 输入数据路径(ESP_BLE_ISO_DATA_PATH_DIR_INPUT+ 透明编码);
  6. 两个 BIS 全部连接后,调度器每 10 ms 触发一次esp_ble_iso_chan_send(),发送 120 字节哑元 SDU(内容为序号字节值),seq_num自增;
  7. 全部 BIS 断开时停止调度器并清空 BIG 句柄。

关键参数(硬编码于 main.c):BIG_SDU_INTERVAL_US = 10000BIG_LATENCY_MS = 10BIG_PHY = ESP_BLE_ISO_PHY_2MBIG_RTN = 2BIG_PACKING = 0(sequential)、BIG_FRAMING = 0(unframed)、BIS_ISO_CHAN_COUNT = 2BIS_SDU_SIZE = 120BIG_ENCRYPTION = true

big_receiver(核心逻辑见 main/main.c)走的是"扫描发现 → PA 同步 → BIGInfo → BIG Create Sync"的经典链路:

  1. esp_ble_iso_common_init()注册gap_cb,处理四类 GAP 事件:EXT_SCAN_RECVPA_SYNCPA_SYNC_LOSTBIGINFO_RECV
  2. EXT_SCAN_RECV中先用esp_ble_iso_data_parse()解析广播数据里的完整设备名,匹配"BIG Broadcaster"后调用pa_sync_create()建立 PA sync;
  3. PA_SYNC成功后停止扩展扫描(后续 BIGInfo 会经由 PA 信道到达);
  4. BIGINFO_RECV中组装esp_ble_iso_big_sync_param_tbis_bitfield = BIT_MASK(2)mse = event->biginfo_recv.nsesync_timeout = 100(100×10 ms = 1 s)、encryptionbcode取自 BIGInfo/本地配置,然后调用esp_ble_iso_big_sync()
  5. 每个 BIS 就绪后connected回调安装输出数据路径(ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT),recv回调统计收到的 SDU 并打印[BIS #N] Connected
  6. PA_SYNC_LOST时复位状态并重启扫描,自动重连。

接收端断开原因注释值得注意:0x08(CONN_TIMEOUT,广播方消失/超出范围,常见)与0x3D(TERM_DUE_TO_MIC_FAIL,加密 BIG 下广播方在超时窗口内重启导致旧会话密钥失效,低概率),两者都是正常现象,接收方会重新发现。

编译烧录(默认 Bluedroid Host,目标 ESP32-H4):

idf.py set-target esp32h4 idf.py -p PORT flash monitor

使用 NimBLE Host(叠加sdkconfig.defaults.nimble):

idf.py set-target esp32h4 idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.defaults.esp32h4;sdkconfig.defaults.nimble" -p PORT flash monitor

ESP32-S31 目标替换对应的 chip overlay(sdkconfig.defaults.esp32s31)即可。串口监视器用Ctrl-]退出。

预期日志(标签BIG_BRD):

I (xxx) BIG_BRD: Advertising started (handle 0) I (xxx) BIG_BRD: [BIS #0] Connected I (xxx) BIG_BRD: Waiting for remaining BIS channels (1/2) I (xxx) BIG_BRD: [BIS #1] Connected I (xxx) BIG_BRD: All 2 BIS channels connected, starting TX I (xxx) BIG_BRD: [BIS #0] TX: <N> packets I (xxx) BIG_BRD: [BIS #1] TX: <N> packets I (xxx) BIG_BRD: [BIS #0] Disconnected, reason 0x<rr> I (xxx) BIG_BRD: All BIS channels disconnected, TX stopped

CIS 单播链路:cis_central ↔ cis_peripheral

cis_central(核心逻辑见 main/main.c)演示 Central 主动建链:

  1. 扫描发现"CIS Peripheral"后建立 ACL 连接(EXT_SCAN_RECVconn_create),随后触发ACL_CONNECT
  2. 按安全等级(ESP_BLE_ISO_SECURITY_NO_MITM,即 L2 加密)发起配对,SECURITY_CHANGE成功后进入建链流程;
  3. create_cig_and_cis()填充esp_ble_iso_cig_param_t(双向间隔 10 ms、双向延迟 10 ms、sca = ESP_BLE_ISO_SCA_UNKNOWN、sequential packing、unframed),先esp_ble_iso_cig_create(),再esp_ble_iso_chan_connect()下发LE Create CIS
  4. CIS 就绪后connected回调安装输入数据路径并启动 10 ms TX 调度器,循环esp_ble_iso_chan_send()发送 120 字节哑元数据;
  5. 断开处理中演示了 Central 侧必须显式移除数据路径的规范要求(对比 Peripheral 由控制器自动删除,见 main.c 注释)。

cis_peripheral(核心逻辑见 main/main.c)演示被动接受 CIS:

  1. 注册esp_ble_iso_server_t.accept回调);收到新 CIS 请求时检查信道是否空闲,空闲则交出iso_chan,否则返回-ENOMEM拒绝(见 L80-L97);
  2. 通过esp_ble_iso_server_register()注册 Server;
  3. ACL_CONNECT后等待 Central 的 CIS 建立请求,connected回调安装输出数据路径(ESP_BLE_ISO_DATA_PATH_DIR_OUTPUT),recv回调统计并打印收到的 SDU;
  4. ACL_DISCONNECT时重新开始扩展广播,等待下一次连接。

收发数据路径与元数据语义

无论 CIS 还是 BIS,等时数据的收发都围绕SDU(Service Data Unit)展开:

  • 发送esp_ble_iso_chan_send(chan, sdu, sdu_len, seq_num)或带时间戳的esp_ble_iso_chan_send_ts(chan, sdu, sdu_len, seq_num, ts)seq_num由应用维护并自增,供接收端按序重组与丢包检测。sent回调在控制器标记 SDU 完成时触发(何时标记由控制器实现决定,可能是在入队、空中发出或刷新之后),因此不能sent回调作为真正的发送完成时刻。
  • 接收recv(chan, info, data, len)中,esp_ble_iso_recv_info_t提供三个关键元数据:
    • seq_num——SDU 首个分片的包序号;
    • flags——ESP_BLE_ISO_FLAGS_VALID(有效)/ERROR(CRC 失败或 SDU 不完整,可能含错)/LOST(丢包)/TS(时间戳有效);
    • ts——ISO 时间戳,仅当flagsTS位时才有效,是音频渲染对齐(音画同步、多设备同步)的基础。
  • TX 同步信息:Central/Broadcaster 可通过esp_ble_iso_chan_get_tx_sync()获取esp_ble_iso_tx_info_t(CIG/BIG anchor 点时间ts、时间偏移offset、包序号),用于精确规划发送时隙。

硬件约束提示:BIG/CIG 的调度由控制器基于 ISO anchor 点驱动,应用层的 10 ms 发送节拍必须由高精度软件调度器承担(示例中封装为example_iso_tx_scheduler_t),仓库示例注释明确指出现有esp_timer精度不足以直接驱动等时发送。

典型错误处理与调试建议

  • 参数校验:公共 API 对 NULL 指针、非法方向(setup_data_pathdir不是 INPUT/OUTPUT)、chan_sendsdu/sdu_len不一致等场景返回ESP_ERR_INVALID_ARG;找不到 ACL/PA sync/扩展广播对象时返回ESP_ERR_NOT_FOUND;底层 Zephyr 接口失败统一映射为ESP_FAIL
  • CIS 断开后 Central 的数据路径残留:必须按规范在断开回调中显式esp_ble_iso_remove_data_path(),否则复用同一 CIS 时控制器会返回 Command Disallowed(示例 cis_central 有完整注释)。
  • 加密广播失步0x3D(MIC 校验失败)通常意味着广播方以新会话密钥重启而接收方尚未超时,属正常现象,接收方会走PA_SYNC_LOST重发现流程。
  • 调试工具CONFIG_BT_ISO_DISPATCH_MONITOR用于定位在 ISO 任务上耗时过长的回调(默认 2000 μs 阈值);CONFIG_BT_ISO_NO_LOG可裁剪日志以节省 rodata;CONFIG_BT_DEBUG_ISO_DATA可开启所有 ISO 收发数据的调试日志。
  • 内存规划CONFIG_BT_ISO_MAX_CHANBT_ISO_MAX_CIGBT_ISO_MAX_BIG决定 Host 侧资源;大并发信道或大量 SDU 缓冲时,可借助BT_ISO_BSS_SEG_EXTERNAL_MEMORY/BT_ISO_HEAP_EXTERNAL_MEMORY将控制面搬入 SPIRAM,但实时数据路径(TX/RX SDU 缓冲)始终保留在内部 DRAM。

小结

ESP-BLE-ISO 把 BLE 等时信道的复杂性(CIG/BIG 生命周期、数据路径、双 Host 适配、任务调度与线程安全)封装为一套简洁的esp_ble_iso_*API。上手路径很清晰:先用big_broadcaster+big_receiver验证广播链路,再用cis_central+cis_peripheral验证单播链路,然后以 esp_ble_iso_common_api.h 为索引、以 Kconfig.in 为资源预算表,替换哑元数据为真实 LC3 音频流,即可过渡到上层 esp-ble-audio 的完整 LE Audio 应用。由于当前为预览版本,请留意后续版本中的 API 变更公告。

【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询