# 概述

[English]

蓝牙® 无线技术是一种短距离通信标准，具备高可靠性、低功耗和低成本等特点。主要分为两种类型：

- 经典蓝牙: 优化用于连续的高吞吐量数据流，适用于音频传输等应用。

- 低功耗蓝牙 (Bluetooth LE): 针对低功耗间歇性数据传输设计，适合用于传感器和可穿戴设备等。

ESP32 支持双模蓝牙，即同时支持经典蓝牙和低功耗蓝牙。

# 蓝牙协议栈

蓝牙协议栈是一种分层通信架构，定义了蓝牙设备如何发现彼此、建立连接、交换数据，并确保通信安全可靠。如图 蓝牙核心系统架构（来源：蓝牙核心规范） 所示，协议栈主要分为控制器（Controller）和主机（Host）两大部分，两者通过 HCI 接口进行通信。

蓝牙核心系统架构（来源：蓝牙核心规范）

控制器

控制器负责硬件层面的操作和底层链路控制，包含：

- PHY (物理层): 处理 2.4 GHz ISM 频段的蓝牙信号收发。

- 基带 (Baseband): 管理底层时序和控制功能，包括跳频、数据包格式化和纠错。

- 链路控制器 (Link Controller): 处理设备连接/断开的链路状态机、流控和重传机制。

- 链路管理器 (Link Manager): 管理链路设置、身份验证、加密和功率控制。

- 设备管理器 (Device Manager): 管理设备状态，处理寻呼/查询流程，存储安全密钥。

主机

主机实现应用交互所需的高层协议，包含：

- L2CAP (逻辑链路控制与适配协议): 处理数据分段、重组和复用。

- SMP (安全管理协议): 管理身份验证、加密和安全配对。

- GAP (通用访问规范): 管理设备发现、连接建立，并定义蓝牙设备的角色和模式。

- ATT/GATT (属性协议/通用属性规范): 通过服务和特征实现基于属性的数据交换，主要用于低功耗蓝牙。

- SDP (服务发现协议): 允许设备广播和发现可用服务，主要用于经典蓝牙。

蓝牙主机和控制器可以集成在同一设备上，也可以在不同设备上实现。ESP32 可以支持上述两种方式，下图 ESP32 蓝牙主机与控制器的关系结构图 展示了典型的应用结构：

ESP32 蓝牙主机与控制器的关系结构图

- 场景 1（ESP-IDF 默认设置）

  使用 Bluedroid 作为蓝牙主机，通过 VHCI（软件实现的虚拟 HCI）实现主机与控制器之间的通信。Bluedroid 和控制器运行在同一设备上（即 ESP32 芯片），无需外部主机设备。

- 场景 2（仅控制器模式）

  ESP32 仅作为蓝牙控制器。外部主机设备（如运行 BlueZ 的 Linux PC 或运行 Bluedroid 的 Android 设备）负责蓝牙操作。

- 场景 3（测试/认证）

  类似于场景 2，但用于蓝牙认证机构（BQB）控制器测试或认证。ESP32 芯片通过 UART 连接到测试工具。

# 蓝牙运行环境

ESP-IDF 蓝牙协议栈运行在 FreeRTOS 环境中，蓝牙任务根据功能和优先级进行分配。由于实时性要求，控制器任务具有最高优先级（部分跨核通信 IPC 任务除外）。

ESP32 的运行环境为双核 FreeRTOS，控制器任务的优先级最高，仅次于用于双核 CPU 之间通信的 IPC 任务。默认的蓝牙主机 Bluedroid 包含三个任务：BTC、BTU 和 HCI。

# Bluedroid

ESP-Bluedroid 是基于 Android 蓝牙协议栈 Bluedroid 的修改版， 支持经典蓝牙和低功耗蓝牙。由两层组成：

- 蓝牙上层 (BTU): 实现核心协议（L2CAP、GATT、SMP 等）。

- 蓝牙传输控制器层 (BTC): 提供应用层 API， 并管理配置文件。

使用场景: 推荐用于同时需要经典蓝牙和蓝牙低能耗的应用。

## 操作系统适配

Bluedroid 通过适配系统相关功能与 FreeRTOS 集成：

- Timer (Alarm): FreeRTOS 的 Timer 封装成 Alarm，⽤于启动定时器，触发某些特定任务。

- Task (Thread): FreeRTOS 的 Task 取代 POSIX Thread，并使用 FreeRTOS 的 Queue 来触发任务的运行（唤醒）。

- Future Await/Ready (Semaphore): `xSemaphoreTake` 封装成 `future_await`，`xSemphoreGive` 封装成 `future_ready`。 `future_await` 和 `future_ready` 不能在同一任务中调用。

- Allocator (malloc/free): 标准库中的 `malloc/free` 被封装为 `Allocator`，用于分配 (malloc) 或释放 (free) 内存。

## Bluedroid 目录结构

ESP-IDF 目录 component/bt/host/bluedroid 包含如下子文件夹：

    ├── api
    ├── bta
    ├── btc
    ├── common/include/common
    ├── config
    ├── device
    ├── external/sbc
    ├── hci
    ├── main
    ├── stack
    └── Kconfig.in

子文件夹的具体说明见下表:

ESP-IDF component/bt/host/bluedroid 目录描述
子文件夹 | 说明
--- | ---
api | API 目录，所有的 API（除 Controller 相关）都在此目录下。
bta | 蓝牙适配层，适配一些主机底层协议的接口。
btc | 蓝牙控制层，控制主机上层协议（包括规范）以及杂项的处理。
common | 协议栈的通用头文件。
config | 为协议栈配置一些参数。
device | 与控制器设备控制相关的，如控制器基本设置的 HCI CMD 流程等。
external | 与蓝⽛⾃身⽆关，但⼜要使⽤的代码，如 SBC codec 软件程序等。
hci | HCI 层协议。
main | 主程序⽬录（主要为启动、关闭流程）。
stack | 主机底层协议栈（GAP/ ATT/ GATT/ SDP/ SMP 等）。
Kconfig.in | Menuconfig 文件。

此文档对您有帮助吗？

- 反馈已收到，谢谢！
- 如果您有其他意见，欢迎填写乐鑫文档反馈表。

- 我们重视您的反馈。
- 您可以填写乐鑫文档反馈表告诉我们如何改进该文档。