一、蓝牙子系统概述:蓝牙技术演进、内核蓝牙架构全景、核心协议栈分层

各位好,我是你们的Linux内核蓝牙子系统讲师。今天咱们来聊聊蓝牙子系统这个模块。说实话,我最早接触蓝牙还是在做功能机驱动的年代,那时候蓝牙还只是个“耳机专属”的短距通信技术。一晃这么多年过去,蓝牙已经成了物联网、车载、可穿戴设备里不可或缺的一环。

嗯,咱们这门课的目标很明确——让你彻底搞懂Linux内核里的蓝牙子系统是怎么工作的。今天这第一讲,我们先搭个框架,把蓝牙技术的演进、内核里的架构全景、以及核心协议栈的分层结构讲清楚。

1.1 蓝牙技术演进:从1.0到5.4,我踩过的坑

蓝牙技术从1999年推出1.0版本到现在,已经走过了二十多年。我个人习惯把它的演进分成三个阶段:

  • 经典蓝牙时代(1.0-3.0):主打音频传输、文件传输。速率从1Mbps到3Mbps。我记得当年做蓝牙耳机驱动时,配对流程那叫一个痛苦——每次都要手动输入PIN码,用户体验极差。
  • 低功耗蓝牙(BLE)时代(4.0-4.2):2010年推出的BLE彻底改变了游戏规则。功耗降到经典蓝牙的十分之一,支持广播、扫描、连接。我在项目中遇到过一个问题:BLE设备在密集部署场景下,广播冲突导致扫描不到设备。后来通过调整广播间隔和信道选择算法才解决。
  • 高速与Mesh时代(5.0-5.4):5.0引入了2Mbps PHY、长距离编码、广播扩展。5.4新增了带响应的周期性广播(PAwR)和加密广播数据(EAD)。说白了,现在的蓝牙已经不只是传音频了,它正在成为物联网的“毛细血管”。

避坑指南:我曾经在BLE 5.0的早期芯片上踩过一个坑——长距离模式(Coded PHY)虽然能传400米,但数据速率只有125kbps。如果你做的是需要高速传输的应用,千万别盲目开长距离模式。

1.2 内核蓝牙架构全景:一张图看懂所有模块

Linux内核的蓝牙子系统,说白了就是一套从硬件到用户空间的完整软件栈。我习惯把它分成三层:

层次 模块 职责
用户空间 BlueZ工具集(bluetoothctl、hciconfig等) 提供命令行管理接口
内核空间 蓝牙核心层(Bluetooth Core) 协议栈实现、设备管理、连接管理
硬件层 蓝牙控制器(UART/USB/SDIO接口) 物理层、基带、链路控制

你想想看,当你在手机上打开蓝牙,点击“扫描设备”时,背后发生了什么?

  1. 用户空间的bluetoothctl发送HCI命令到内核
  2. 内核蓝牙核心层将命令封装成HCI帧
  3. 通过UART/USB驱动发送给蓝牙芯片
  4. 蓝牙芯片执行扫描,返回事件
  5. 内核解析事件,上报给用户空间

嗯,这里要注意:内核里的蓝牙核心层并不是一个单独的驱动,而是一组协同工作的模块。我把它拆解成下面几个关键组件:

  • HCI核心(hci_core.c):管理蓝牙适配器、连接、设备列表。这是整个蓝牙子系统的“大脑”。
  • L2CAP层(l2cap_core.c):提供协议复用、分段重组、流量控制。说白了就是给上层协议提供“管道”。
  • SCO/eSCO层(sco.c):处理同步面向连接通道,主要用于语音传输。
  • RFCOMM层(rfcomm/):模拟串口通信,经典蓝牙的“串口替代方案”。
  • BNEP层(bnep/):桥接以太网,用于蓝牙网络共享。
  • HIDP层(hidp/):处理蓝牙人机交互设备(键盘、鼠标)。
  • MGMT接口(mgmt.c):用户空间与内核的现代控制接口,替代了古老的HCI socket。

个人经验:我建议初学者先从HCI核心层入手。因为所有蓝牙操作最终都会落到HCI命令/事件上。你只要理解了HCI,就等于抓住了蓝牙子系统的“七寸”。

1.3 核心协议栈分层:从物理层到应用层

蓝牙协议栈的分层,其实和OSI七层模型有点像,但更精简。我把它分成四层:

1.3.1 物理层(PHY)

负责无线信号的调制解调。经典蓝牙使用GFSK调制,BLE使用2GFSK。5.0之后支持2Mbps PHY和Coded PHY。说白了,这一层就是“怎么把0和1变成无线电波”。

1.3.2 链路层(Link Layer)

负责设备发现、连接建立、数据包传输。BLE的链路层有5种状态:待机、广播、扫描、发起、连接。我记得在调试BLE连接参数时,如果连接间隔设置得太小,功耗会飙升;设置得太大,又会导致延迟过高。这是个典型的“鱼和熊掌”问题。

1.3.3 主机控制器接口(HCI)

这是内核蓝牙子系统的核心。HCI定义了主机(CPU)和控制器(蓝牙芯片)之间的通信协议。它支持两种传输方式:

  • HCI命令:主机发给控制器,比如“开始扫描”、“建立连接”
  • HCI事件:控制器发给主机,比如“扫描到设备”、“连接断开”

你可以在内核源码的include/net/bluetooth/hci.h里看到所有HCI命令和事件的定义。我经常说,HCI就是蓝牙的“汇编语言”——虽然底层,但最直接。

1.3.4 主机协议层(Host Protocols)

这一层包括L2CAP、RFCOMM、BNEP、HIDP等。它们运行在主机上,负责提供各种应用服务。举个例子:

// L2CAP连接请求示例(伪代码)
struct l2cap_conn_req req;
req.psm = cpu_to_le16(0x1001); // RFCOMM的PSM
req.scid = cpu_to_le16(0x0040); // 本地通道ID
hci_send_cmd(hdev, HCI_OP_L2CAP_CONN_REQ, sizeof(req), &req);

这段代码展示了如何通过HCI发送L2CAP连接请求。PSM(协议服务复用器)是L2CAP层用来区分上层协议的标识符。RFCOMM的PSM是0x1001,HIDP的PSM是0x0011。

注意:我曾经在项目中遇到一个bug——L2CAP的MTU协商失败导致蓝牙键盘无法连接。原因是键盘端声明的MTU是48字节,但主机端默认MTU是672字节,双方没有协商成功。后来我在内核配置里强制设置了L2CAP的默认MTU为48才解决。所以,做蓝牙开发时,MTU协商一定要仔细检查。

1.4 总结:这一章你该记住什么?

好了,第一讲的内容就到这里。我帮你梳理一下重点:

  • 蓝牙技术从经典蓝牙到BLE再到5.x,核心变化是低功耗和高速
  • 内核蓝牙架构分三层:用户空间(BlueZ)、内核空间(蓝牙核心层)、硬件层(蓝牙控制器)
  • 协议栈分四层:PHY、Link Layer、HCI、Host Protocols
  • HCI是内核蓝牙子系统的核心,所有操作最终都落到HCI命令/事件

下一讲,我们会深入HCI核心层的源码,看看蓝牙适配器是怎么初始化的。到时候我会带你看hci_register_dev()这个函数的实现细节。嗯,那才是真正“硬核”的内容。

各位,咱们下节课见。