蓝牙驱动移植适配与DMA优化工程案例 - 第1节

1.1 蓝牙协议栈概述:经典蓝牙与低功耗蓝牙架构对比

蓝牙无线通信技术自 1994 年诞生以来,已演化为两大核心分支:经典蓝牙(BR/EDR)与低功耗蓝牙(BLE)。两者在协议栈架构、功耗模型、数据传输模式及应用场景上存在显著差异。理解这些差异是进行蓝牙驱动移植与 DMA 优化的前提。

1.1.1 经典蓝牙(BR/EDR)协议栈架构

经典蓝牙(Basic Rate / Enhanced Data Rate)面向持续连接、中等速率的数据流场景,如音频耳机、文件传输。其协议栈采用分层紧耦合设计,核心层次如下:

层次 功能描述 典型协议/组件
应用层 用户直接交互的蓝牙服务 HFP、A2DP、AVRCP、SPP
主机协议栈 逻辑链路控制、服务发现、安全管理 L2CAP、SDP、RFCOMM、GAP
HCI 层 主机与控制器之间的命令/事件/数据接口 HCI 命令、事件、ACL 数据
链路层/基带 物理连接建立、跳频、数据包调度 Link Manager、Baseband
射频层 2.4GHz 模拟收发、调制解调 BR/EDR RF
关键特征:经典蓝牙使用 79 个信道(1 MHz 间隔),跳频速率 1600 hops/s,支持 SCO/eSCO 同步语音链路,适合实时音频流。

1.1.2 低功耗蓝牙(BLE)协议栈架构

BLE(Bluetooth Low Energy)从 Bluetooth 4.0 开始引入,专为低功耗、低延迟、小数据包的物联网场景设计。其协议栈采用分层松耦合,核心层次如下:

层次 功能描述 典型协议/组件
应用层 GATT 配置文件、服务/特征值定义 GATT、GAP 角色
主机协议栈 属性协议、安全管理、逻辑链路控制 ATT、SMP、L2CAP
HCI 层 主机与控制器之间的标准化接口 HCI 命令/事件/数据
链路层 广播、扫描、连接、数据信道管理 Link Layer (LL)
物理层 2.4GHz 收发、GFSK 调制 BLE PHY
BLE 核心优势:使用 40 个信道(2 MHz 间隔),其中 3 个广播信道、37 个数据信道。广播时无需建立连接即可发送数据,峰值电流仅 15 mA 左右,待机功耗可低至 1 µA 以下。

1.1.3 经典蓝牙 vs BLE 架构对比

对比维度 经典蓝牙 (BR/EDR) 低功耗蓝牙 (BLE)
信道数量 79 个 (1 MHz) 40 个 (2 MHz)
跳频速率 1600 hops/s 自适应跳频,连接后固定
数据速率 1-3 Mbps (EDR) 1 Mbps (LE 1M), 2 Mbps (LE 2M)
功耗模型 持续连接,中等功耗 短时突发,极低功耗
拓扑结构 微微网 (Piconet) 广播/连接,支持 Mesh
典型应用 音频流、文件传输 传感器、信标、可穿戴
主机协议栈复杂度 高 (RFCOMM, SDP, AVDTP) 低 (ATT, GATT)
驱动移植注意:经典蓝牙与 BLE 的 HCI 命令集、事件格式、数据包类型完全不同。在 Linux 内核中,hci_uart 驱动需要根据芯片类型(如 CSR、Broadcom、TI CC256x)分别配置 HCI 传输层(H4、H5、BCSP 等),不可混用。

1.1.4 蓝牙协议栈分层架构总览(SVG)

下图展示了经典蓝牙与 BLE 协议栈的完整分层结构,以及 HCI 接口在主机与控制器之间的桥梁位置:

蓝牙协议栈分层架构对比图 蓝牙协议栈分层架构对比 经典蓝牙 (BR/EDR) 应用层 (HFP, A2DP, SPP) 主机协议栈 (L2CAP, SDP, RFCOMM) HCI 接口层 链路管理层 (LM / Baseband) 射频层 (BR/EDR RF) 低功耗蓝牙 (BLE) 应用层 (GATT, GAP) 主机协议栈 (ATT, SMP, L2CAP) HCI 接口层 链路层 (Link Layer) 物理层 (BLE PHY) HCI 传输层 UART / USB SDIO / SPI 3-Wire (H5) HCI 接口是主机(Host)与控制器(Controller)之间的标准化通信桥梁 驱动移植的核心工作集中在 HCI 传输层适配与 DMA 数据通道优化 图例 经典蓝牙主机层 BLE 主机层 HCI 接口层 经典蓝牙链路层 BLE 链路层 射频/物理层

1.2 HCI 接口定义与驱动适配要点

1.2.1 HCI 接口的角色与分层

HCI(Host Controller Interface)是蓝牙协议栈中主机(Host)与控制器(Controller)之间的标准化通信接口。在 Linux 内核中,HCI 层由 bluetooth 子系统统一管理,驱动开发者主要关注 HCI 传输层的适配。

HCI 接口定义了三种基本数据包类型:

  • 命令包(Command Packet):主机下发至控制器,用于配置、扫描、连接等操作。
  • 事件包(Event Packet):控制器上报至主机,用于响应命令、通知状态变化。
  • 数据包(Data Packet):分为 ACL(异步无连接)和 SCO(同步面向连接)两种,承载用户数据。

1.2.2 HCI 传输层标准

传输层标准 物理接口 典型速率 Linux 驱动 适用场景
H4 (UART) UART (TX/RX/CTS/RTS) 115200 bps - 4 Mbps hci_uart + h4 协议 嵌入式设备、低成本模块
H5 (3-Wire) UART (TX/RX 无流控) 115200 bps - 921600 bps hci_uart + h5 协议 无硬件流控的 UART 场景
BCSP UART (BlueCore 串行协议) 115200 bps - 3 Mbps hci_uart + bcsp 协议 CSR 芯片专用
USB USB 全速/高速 12 Mbps - 480 Mbps btusb PC、开发板 USB 蓝牙适配器
SDIO SDIO 1-bit/4-bit 25 MB/s - 100 MB/s btintel, btsdio WiFi+蓝牙组合芯片 (如 Intel 8260)
驱动移植核心任务:在 Linux 内核中注册一个新的 HCI 传输驱动,实现 struct hci_uart_proto 或 struct h4_recv_buf 回调,完成数据包的封装/解封装、流控管理、以及 DMA 缓冲区的分配与回收。

1.2.3 HCI 数据包格式(SVG)

下图展示了 HCI 数据包在 UART 传输层上的封装格式,以及主机与控制器之间的交互流程:

HCI 数据包格式与传输流程 HCI 数据包格式与 UART 传输流程 主机 (Host) 控制器 (Controller) HCI 传输层 (UART / USB) HCI UART 数据包封装格式 包类型 命令/事件/数据载荷 校验和 包类型字节 (1 Byte): 0x01 = 命令包 0x02 = ACL 数据包 0x03 = SCO 数据包 0x04 = 事件包 典型交互流程 主机下发命令包 控制器回复事件包 ACL 数据双向传输 驱动适配关键点 • 正确解析包类型字节 • 管理 DMA 接收缓冲区 • 处理流控与超时重传

1.2.4 Linux 内核 HCI 驱动注册示例

在 Linux 内核中,HCI UART 驱动的注册通过 hci_uart_register_proto() 完成。以下是一个简化的 H4 协议注册示例:

/* hci_h4.c - H4 UART 协议驱动片段 */
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_uart.h>

static struct hci_uart_proto h4_proto = {
    .id       = HCI_UART_H4,
    .name     = "H4",
    .open     = h4_open,
    .close    = h4_close,
    .recv     = h4_recv,
    .enqueue  = h4_enqueue,
    .dequeue  = h4_dequeue,
    .flush    = h4_flush,
};

int __init h4_init(void)
{
    int err;
    err = hci_uart_register_proto(&h4_proto);
    if (err < 0)
        pr_err("H4 protocol registration failed\n");
    return err;
}

void __exit h4_exit(void)
{
    hci_uart_unregister_proto(&h4_proto);
}

module_init(h4_init);
module_exit(h4_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Bluetooth H4 UART protocol driver");
DMA 优化切入点:在 h4_recv() 回调中,数据从 UART FIFO 搬运到内核缓冲区时,应使用 dma_alloc_coherent() 分配 DMA 安全的接收缓冲区,避免 CPU 逐字节拷贝。后续章节将详细讲解 DMA 环形缓冲区的设计与实现。

1.3 本章小结

  • 经典蓝牙(BR/EDR)与低功耗蓝牙(BLE)在协议栈层次、信道数量、功耗模型上存在本质差异,驱动移植时需分别适配不同的 HCI 命令集。
  • HCI 接口是主机与控制器之间的标准化桥梁,支持 UART、USB、SDIO 等多种物理传输层。
  • Linux 内核中,HCI 传输驱动通过 struct hci_uart_proto 注册,核心回调包括 recv、enqueue、dequeue。
  • DMA 优化应从 HCI 数据接收路径入手,使用一致性 DMA 缓冲区减少 CPU 干预,提升吞吐量。