2. Linux蓝牙子系统架构:BlueZ核心组件与内核蓝牙子系统

Linux蓝牙子系统采用经典的分层架构设计,从上至下依次为:用户空间协议栈(BlueZ)、内核蓝牙子系统(Bluetooth Subsystem)以及蓝牙硬件设备。本章将深入剖析这一架构的核心组件与目录结构,帮助开发者建立完整的系统视图。

Linux蓝牙子系统分层架构 用户空间 (User Space) — BlueZ协议栈 bluetoothd hciattach hcitool / gatttool 核心守护进程 UART HCI初始化 调试与BLE工具 内核空间 (Kernel Space) — Bluetooth Subsystem net/bluetooth/ (协议核心) drivers/bluetooth/ (驱动层) HCI核心、L2CAP、SMP、RFCOMM btusb、hci_uart、hci_bcm等 硬件层 (Hardware) USB蓝牙适配器 | UART蓝牙模块 (BCM/Intel/Realtek) | SDIO蓝牙 交互流程 用户空间工具 → Socket/ioctl → 内核HCI核心 → 驱动 → 硬件

2.1 BlueZ核心组件

BlueZ是Linux官方蓝牙协议栈,自Linux 2.4.6起被纳入主线内核。其用户空间组件提供了从设备管理到协议交互的完整能力。

2.1.1 bluetoothd — 核心守护进程

bluetoothd是BlueZ的主守护进程,负责管理蓝牙适配器、处理设备配对、提供D-Bus接口供上层应用调用。它实现了HCI(Host Controller Interface)层的用户空间管理逻辑。

关键职责:

  • 适配器状态管理(up/down、扫描、可发现性)
  • 设备配对与绑定(SSP、LE Secure Connections)
  • GATT服务注册与通告管理
  • 通过D-Bus暴露org.bluez接口

2.1.2 hciattach — UART HCI初始化工具

hciattach用于将UART(串口)连接的蓝牙模块初始化为HCI设备。它发送特定的初始化序列(如BCM43xx的固件加载、Intel的patches),然后将串口绑定到内核HCI UART驱动。

# 典型用法:初始化BCM43438蓝牙模块
hciattach /dev/ttyAMA0 bcm43xx 115200 flow

# 初始化Intel蓝牙模块
hciattach /dev/ttyUSB0 intel 3000000 flow

2.1.3 hcitool — HCI调试与配置工具

hcitool提供对HCI层的直接访问,常用于调试、扫描和参数配置。对于低功耗蓝牙(BLE)开发,以下命令尤为关键:

命令 功能 BLE相关参数
hcitool dev 列出本地蓝牙设备 —
hcitool lescan 低功耗扫描 —duplicate、—passive
hcitool lecc 建立LE连接 连接间隔、延迟、超时
hcitool cmd 发送原始HCI命令 OGF/OCF编码

2.1.4 gatttool — GATT协议交互工具

gatttool是BLE开发中最常用的调试工具之一,用于与BLE外设的GATT服务进行交互。它支持服务发现、特征值读写、通知/指示订阅等操作。

# 连接BLE设备并交互
gatttool -b AA:BB:CC:DD:EE:FF -I

# 在交互模式下:
connect           # 建立连接
primary           # 发现主服务
char-desc         # 发现特征描述符
char-read-hnd 0x0028  # 按句柄读取特征值
char-write-req 0x002e 0100  # 写入特征值(启用通知)

开发提示:在BLE性能调优中,gatttool的MTU协商命令(mtu 512)和连接参数更新命令(conn-update)是验证配置是否生效的快速手段。

2.2 内核蓝牙子系统目录结构

Linux内核蓝牙子系统主要分布在两个核心目录:net/bluetooth/(协议核心)和 drivers/bluetooth/(硬件驱动)。理解其目录结构是进行驱动开发和性能调优的基础。

内核蓝牙子系统目录结构 net/bluetooth/ (协议核心) hci_core.c — HCI核心层 l2cap_core.c — L2CAP协议 smp.c — 安全管理协议 hci_conn.c — 连接管理 mgmt.c — 管理接口 sco.c / rfcomm.c — 音频/串口 其他:hci_event.c, hci_sock.c, a2mp.c drivers/bluetooth/ (硬件驱动) btusb.c — USB蓝牙驱动 hci_uart.c — UART HCI驱动 hci_bcm.c — Broadcom专用 hci_intel.c — Intel专用 hci_ldisc.c — 线路规程 btintel.c / btbcm.c — 固件 其他:hci_qca.c, hci_mrvl.c, virtio_bt.c HCI接口

2.2.1 net/bluetooth/ — 协议核心层

该目录实现了蓝牙协议栈的核心逻辑,与硬件无关。关键文件及其职责如下:

文件 核心功能 BLE调优关注点
hci_core.c HCI命令/事件处理、设备初始化 HCI命令超时、事件队列深度
l2cap_core.c L2CAP分段重组、信道管理 MTU协商、FLOW CONTROL模式
smp.c LE安全配对、密钥分发 配对延迟、密钥大小(128bit)
hci_conn.c 连接建立、参数更新 连接间隔、延迟、监督超时
mgmt.c 用户空间管理接口(通过Socket) MGMT命令响应延迟

2.2.2 drivers/bluetooth/ — 硬件驱动层

该目录包含各类蓝牙硬件控制器的驱动实现。对于嵌入式开发,以下驱动最为常见:

  • btusb.c:通用USB蓝牙适配器驱动,支持大多数USB dongle。
  • hci_uart.c:UART HCI驱动框架,支持H4/H5/BCSP协议。
  • hci_bcm.c:Broadcom(博通)蓝牙芯片专用驱动,常见于树莓派、RTL8723等模块。
  • hci_intel.c:Intel蓝牙芯片驱动,常见于x86平台。
  • hci_ldisc.c:线路规程层,负责将UART数据流转换为HCI数据包。

性能调优注意:在嵌入式平台使用UART蓝牙时,hci_uart.c中的HCI流控配置(CTS/RTS)和DMA支持直接影响吞吐量。若未启用硬件流控,BLE数据吞吐量可能下降50%以上。

2.3 用户空间与内核空间的交互机制

BlueZ用户空间组件通过以下方式与内核蓝牙子系统通信:

  1. Bluetooth Socket (AF_BLUETOOTH):用户空间通过创建AF_BLUETOOTH类型的socket与内核交互,用于HCI命令、L2CAP数据、RFCOMM连接等。
  2. ioctl系统调用:hciattach等工具通过HCIDEVUP、HCIDEVDOWN等ioctl控制HCI设备状态。
  3. D-Bus接口:bluetoothd通过D-Bus与上层应用通信,但底层仍通过Socket与内核交互。
  4. Sysfs属性:部分蓝牙参数(如地址、类型)通过/sys/class/bluetooth/暴露。
// 示例:通过AF_BLUETOOTH socket发送HCI命令(伪代码)
int sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
struct sockaddr_hci addr = { .hci_family = AF_BLUETOOTH, .hci_dev = 0, .hci_channel = HCI_CHANNEL_USER };
bind(sk, (struct sockaddr *)&addr, sizeof(addr));

// 构造HCI命令:LE Set Scan Parameters (OGF=0x08, OCF=0x000B)
unsigned char cmd[5] = { 0x01, 0x0B, 0x20, 0x02, 0x00 };
write(sk, cmd, sizeof(cmd));

架构总结:Linux蓝牙子系统采用“用户空间策略 + 内核空间机制”的设计哲学。bluetoothd负责高层策略(配对策略、服务发现),内核负责低层机制(数据包收发、连接维护)。这种分离使得驱动开发者只需关注drivers/bluetooth/中的硬件适配,而协议细节由net/bluetooth/统一处理。