蓝牙

一、蓝牙体系设计思想

在深入 Linux 内核的具体实现之前,我们首先需要理解蓝牙协议体系本身的设计初衷和核心骨架。蓝牙并非凭空创造,它是为了解决短距离无线互联这一特定问题而设计的,其体系结构蕴含了极其精妙的分工思想。

1、 核心设计目标

蓝牙的设计目标决定了它的分层结构:

短距离与低功耗:面向个人局域网(PAN),追求极致的能效比。

全球统一与互操作性:确保不同厂商的设备(如手机、耳机、鼠标)能无缝通信。

抗干扰与高可靠性:在拥挤的 2.4GHz ISM 频段(工业、科学和医疗频段)稳定工作。

支持多种应用场景:同时满足音频(耳机)、数据传输(文件)、控制(鼠标)等多样化需求。

2、 最经典的分层思想:Host & Controller 分离

为了实现上述目标,蓝牙规范从底层定义了最核心的物理架构分界,将整个系统划分为两大职能区域:

Controller(控制器):处理“硬实时”任务。负责物理层(射频调制解调)和链路层(时序、跳频、底层重传)这些对时间极度敏感、必须在微秒级完成的工作。它通常由专用的蓝牙芯片(MCU + 射频电路)实现,运行着闭源的固件。

Host(主机):处理“逻辑”任务。负责协议栈上层(L2CAP 数据路由、RFCOMM 串口仿真、服务发现)以及应用策略(配对、连接管理)。它通常运行在功能强大的主 CPU(如手机的 AP 或开发板的 ARM 处理器)上,由操作系统(如 Linux)来实现。

3、 关键接口:HCI(主机控制器接口)

HCI(Host Controller Interface,主机控制器接口) 是这套思想中最关键的桥梁。它定义了 Host 和 Controller 之间通信的标准数据格式与交互流程:

HCI 命令包(Host → Controller):主机下发的指令,如“开启扫描”、“发起连接”。

HCI 事件包(Controller → Host):控制器上报的异步通知,如“设备已连接”、“扫描结果返回”。

HCI 数据包(双向):传输 ACL(异步无连接)数据和 SCO(同步定向连接)语音数据。

设计精髓:通过 HCI 这一标准“普通话”,将极致的硬实时任务(Controller 侧)与复杂多变的业务逻辑(Host 侧)彻底解耦。这使得无论蓝牙芯片如何变化,只要它支持标准的 HCI 协议,上位机(Linux 主机)就能以统一的方式进行控制。

二、蓝牙分类及架构

  蓝牙技术分为基础率/增强数据率(BR/EDR)和低功耗(LE)两种技术类型。BR/EDR是经典蓝牙技术,LE是低功耗蓝牙技术。

1、蓝牙分类

  蓝牙可分为BLE模式、经典模式和双模。双模蓝牙是即支持BLE又支持经典模式。

image

 2、蓝牙硬件结构

image

 

1)主机(Host) :主机部分由核心协议层(L2CAP、SDP、SMP、ATT)和核心规范(GAP、GATT)构成;

2)控制器(Controller):此部分可分为低功耗蓝牙(Low Energy Controller)和经典蓝牙(BR/EDR Controller)两种工作模式;

3)HCI协议+接口:此部分定义了主机和控制器之间通信的协议标准(Host Controller Interface),硬件接口可以是UART/USB/SPI/SDIO等通信方式。

4、协议栈

  经典蓝牙协议栈:

image

   功耗蓝牙协议栈

image

 

三、嵌入式linux 蓝牙分层结构

+============================================================================+
|                              [用户空间]                                      |
|  +----------------------------------------------------------------------+  |
|  |  蓝牙应用 (App)                                                       |  |
|  |  例如: PulseAudio, bluetoothctl, 自定义BLE扫描程序                    |  |
|  +-----------------------------+----------------------------------------+  |
|                                |                                            |
|         (控制/策略)            | (数据流)                                   |
|         通讯: D-Bus            | 通讯: Socket 系统调用                      |
|          (dbus-send)          |      (socket AF_BLUETOOTH)                |
|                                |                                            |
|                                v                                            |
|  +----------------------------------------------------------------------+  |
|  |  BlueZ 用户态服务 (bluetoothd)                                       |  |
|  |  - 管理配对/连接策略                                                  |  |
|  |  - 解析 GATT 服务 (BLE)                                              |  |
|  |  - 加载 Profile 插件 (A2DP/HFP)                                      |  |
|  +-----------------------------+----------------------------------------+  |
|                                |                                            |
|                (控制通道)       | 注意: 业务数据(音频/文件)不过bluetoothd   |
|                通讯: Netlink   | 应用通过Socket直接与内核交互               |
|                (管理Socket)    |                                            |
+================================+============================================+
|                                |  <------ 系统调用(Socket/ioctl) 边界 -----> |
+================================+============================================+
|                              [内核空间]                                      |
|  +----------------------------------------------------------------------+  |
|  |  蓝牙协议层 (net/bluetooth)                                           |  |
|  |  - HCI (主机控制器接口) 核心调度器                                     |  |
|  |  - L2CAP (数据分片/重组/通道复用)                                     |  |
|  |  - RFCOMM (串口仿真) / SCO (音频同步)                                 |  |
|  +-----------------------------+----------------------------------------+  |
|                                |                                            |
|                 (上下行数据/事件) 通讯: 内核内部函数调用 + sk_buff          |
|                                |  (驱动注册 struct hci_ops 回调)            |
|                                |  上行: hci_recv_frame()                    |
|                                |  下行: ops->send_frame()                   |
|                                v                                            |
|  +----------------------------------------------------------------------+  |
|  |  蓝牙驱动层 (drivers/bluetooth)                                       |  |
|  |  - USB驱动 (btusb.c): 处理URB(USB请求块)                             |  |
|  |  - UART驱动 (hci_uart.c): 处理TTY线路规程(Line Discipline)           |  |
|  +-----------------------------+----------------------------------------+  |
|                                |                                            |
|              (物理总线帧)      | 通讯: USB批量/中断传输 / UART物理波形      |
|              (HCI 帧格式)     |  (带流控 RTS/CTS)                          |
|                                v                                            |
+================================+============================================+
|                              [硬件层]                                        |
|  +----------------------------------------------------------------------+  |
|  |  蓝牙芯片 (如 RTL8852BS)                                              |  |
|  |  - 物理层(PHY): 2.4GHz 射频调制解调                                   |  |
|  |  - 链路层(LL): MCU 运行 rtl8852bs_fw, 管理时隙/跳频/重传             |  |
|  +----------------------------------------------------------------------+  |
+============================================================================+

四、各个层的主要功能

1、 硬件层

  硬件层即蓝牙芯片,它里面主要是物理层和链路层,通过HCI标准协议与主控通讯。物理层主要功能是完成电磁信号和数字信号的转换。链路层功能主要有蓝牙芯片内部的mcu完成,作用是保证数据传输的正确性。有数据校验,重传,跳频同步等功能。可以把它当做一个黑盒子,主控用HCI指令与它交互即可。

2、 蓝牙驱动层

  蓝牙驱动层在linux中的drivers/bluetooth中,这里有各个厂家的蓝牙驱动代码。下对接蓝牙芯片,上对接协议层,把协议层的sk_buff数据用usb或uart发送给蓝牙芯片。这部分程序通常有蓝牙厂家提供,虽然蓝牙芯片与主控用标准的HCI协议通信,这个协议主要是规定双方的通讯格式,通信逻辑一般有厂家自己定义。例如用uart时什么时候波特率该用多少,重传机制,固件下载流程等这些有厂家自定义。这一层是屏蔽了与底层芯片的通讯细则,向上提供标准数据。蓝牙驱动移植主要也是在这一层,其它层是标准的东西。

3、 蓝牙协议层

  蓝牙协议层 (net/bluetooth) 是内核中的“数据路由总调度室”。主要实现L2CAP 和 ATT 的核心部分。它不负责物理搬运(驱动层),也不关心用户意图(BlueZ),核心职责是解析 HCI 数据包,并根据包类型(事件/ACL/SCO)进行精确分发,同时完成 L2CAP 层面的数据分片与重组。

  1. 数据路由与分发(HCI 层的“总交换机”)
  当驱动层通过 hci_recv_frame() 把数据包丢给协议层时,协议层做的第一件事就是看一眼这个包的“头部类型”,然后立刻拆分为三条完全不同的路径:

事件包(Event Packet):比如“连接完成”、“设备断连”。协议层把这些事件解析后,通过 Netlink(管理 Socket)上报给用户态的 bluetoothd,告诉它状态变了。

ACL 数据包(异步无连接数据):这是传输文件、音频、蓝牙鼠标移动轨迹的主力通道。协议层会剥离 HCI 头,提取出里面的 L2CAP(逻辑链路控制与适配协议) 数据,然后交给下一级处理。

SCO 数据包(同步定向连接):这是通话语音的专用高速通道。协议层看到这个类型,绝不走 L2CAP 的复杂逻辑,直接通过专用的 SCO Socket 接口旁路给用户态的音频服务(如 PulseAudio),确保通话不卡顿(极低延迟)。

  2. L2CAP 层的“拆快递与合包裹”功能
  你发送的音频数据可能很大(如 1KB),但蓝牙空口每次只能传几十个字节。协议层在这里完成 “分片(Segmentation)与重组(Reassembly)”:

下发(发送):把上层发来的大块数据,切分成符合底层 HCI 传输限制的小块,并给每个小块编上序号。

上行(接收):把从驱动收到的零散小包,根据序号重新拼接成完整的大包,再交给上层应用。如果发现中间丢了一块,协议层会立即通过 L2CAP 的流控机制,向对端发起“重传请求”(这个重传是在协议层发起的,比芯片内部的物理层 ARQ 更靠上)。

  3. 多协议的“红绿灯”分流(RFCOMM / BNEP)
蓝牙上层应用极其复杂,协议层需要根据数据内容决定把这包数据送给谁:

RFCOMM(串口仿真):如果数据是用来传输文件的(OBEX)或者连接蓝牙串口调试器的,协议层会把这些数据伪装成串口数据,交给对应的 TTY 设备或 Socket。

BNEP(网络封装协议):如果是蓝牙共享网络(PAN)的数据,协议层会把数据剥离蓝牙头,然后直接灌进 Linux 内核的网络协议栈(TCP/IP)。这样一来,你通过蓝牙上网时,手机发的 IP 包就能被 Linux 当成普通的网卡数据来处理。

  4. 连接状态机的基础管理(不是策略,是状态)
注意,协议层只负责维护 “连接还在不在”,而不负责“要不要连”。

它会维护一个内核内部的连接哈希表,记录当前 hci0 上每个连接的句柄(Handle)、加密状态、链路质量(RSSI)。

当驱动上报“硬件断开”事件时,协议层会立刻清理内核中的 Socket 队列,并向用户态(bluetoothd)发送“连接已死亡”的强制通知,防止上层应用死等。

4、 bluez 用户态蓝牙服务层

  主要实现蓝牙协议的GATT 和 GAP。

 

五、蓝牙初始化

  例如rtl8852bs蓝牙初始化用rtk_hciattach -n -s 115200 ttyS2 rtk_h5 &命令初始化 。rtk_hciattach直接通过/dev/tttyS2串口与蓝牙芯片交互。初始化前需要将蓝牙固件rtl8852bs_fw和配置文件rtl8852bs_config放到设备端。rtl8852bs_fw其实是个蓝牙muc的程序。

  rtk_hciattach初始化流程为:

  1、低速握手与协商

  2、芯片信号探测

  3、读取配置文件和固件

  4、下载固件

  5、切换到高速模式,此时串口波特率通常从 115200bps 切换到 1.5Mbps 或 3Mbps,以支持高速数据传输。此时蓝牙芯片已经能正常运行。

  6、通过系统调用 —— ioctl(TIOCSETD, N_HCI)(将串口线路规程设置为 N_HCI)。内核中的 drivers/bluetooth/hci_uart.c 驱动被激活了。这个内核驱动会接管这个串口设备(ttyS2),并向 net/bluetooth 协议栈注册一个名为 hci0 的新设备。这时候通过hciconfig -a 就能看到一个蓝牙设备了。

六、linux 蓝牙工具

 1. hciconfig(控制与配置工具)

  它实际上是一个在用户层发送hci命令的工具,它与内核协议层通过通过 AF_BLUETOOTH 原始套接字 (Raw Socket)交互。例如:

  hciconfig hci0 up 

  它通过 AF_BLUETOOTH 原始套接字,将 HCI 命令(如 HCI_OP_RESET)直接下发。内核协议层的 HCI 核心收到后,立刻回调驱动层的 .send_frame 将命令发给芯片。

2. hcidump(监听与抓包工具)

  内核协议层的 HCI 核心内置了一个 HCI_MONITOR(监控子模块)。
每当芯片有数据上报(或主机有数据下发),内核协议层在将 sk_buff 转发给下一层的同时,会多复制一份(零拷贝或引用计数增加),通过特定的 监控通道(HCI_CHANNEL_MONITOR) 发送给用户态。
hcidump 进程通过监听这个监控通道的 Netlink Socket,就能实时看到所有裸 HCI 数据包(包括时间戳、方向(发送/接收))。

3、hcitool (扫描与连接)

  它也是用户层的hci命令工具,与hciconfig有分工,hciconfig主要是配置蓝牙芯片,hcitool主要是对外连接等。

4、bluetoothctl

  该工具是更现代的蓝牙调试工具,它要依赖bluetoothd,通过dbus与bluetoothd交互。

 

posted @ 2026-07-22 17:59  YYFaGe  阅读(16)  评论(0)    收藏  举报