第4章 链路层(LL)核心机制:状态机与空中接口

链路层,说白了就是BLE协议栈的“心脏”。

我刚开始接触BLE时,总觉得这层就是个状态机来回跳,没什么大不了的。直到有一次调试一个连接断连问题,折腾了整整三天,最后发现是链路层状态切换的时序没卡对。嗯,从那以后我再也不敢小看它了。

4.1 链路层状态机——五个核心状态

BLE 5.0的链路层定义了5种状态:待机(Standby)广播(Advertising)扫描(Scanning)发起(Initiating)连接(Connection)

你想想看,一个蓝牙设备在任意时刻,只能处于其中一种状态。状态之间怎么跳?有严格的规定。

状态转换规则(核心要点):

  • Standby → 任何状态都可以进入Standby
  • Advertising → 只能从Standby进入
  • Scanning → 只能从Standby进入
  • Initiating → 只能从Standby进入
  • Connection → 从Advertising或Initiating进入

我个人习惯把Standby比作“待机室”。所有设备一开始都在这儿待着,想干活了,就跳出去。干完活,再回来。

4.2 广播状态(Advertising)——设备在“喊话”

广播状态,说白了就是设备在不停地喊:“我在这儿!我叫XX!我能干这些事!”

BLE 5.0支持两种广播模式:

  • 可连接广播(Connectable):允许其他设备发起连接
  • 不可连接广播(Non-connectable):只发数据,不接受连接

我在项目中遇到过一个问题:某个传感器设备广播间隔设得太短,导致功耗飙升。后来我把广播间隔从20ms调到100ms,电池续航直接翻倍。嗯,这里要注意——广播间隔不是越小越好。

避坑指南:

我曾经在调试时发现,广播包里的AD Type填错了,导致手机扫描不到设备。检查一下你的广播数据结构,尤其是AD Type字段,别踩这个坑。

4.3 扫描状态(Scanning)——设备在“监听”

扫描状态,就是设备竖起耳朵听广播。

BLE 5.0定义了两种扫描方式:

  • 被动扫描(Passive Scanning):只听,不回复
  • 主动扫描(Active Scanning):听到广播后,发送扫描请求,获取更多信息

你想想看,主动扫描会多一次交互,功耗自然更高。但有时候不得不这么做——比如你想知道设备的具体名字,广播包里放不下,就得靠扫描请求去拿。

4.4 发起状态(Initiating)——建立连接的“敲门砖”

发起状态,是连接建立前的最后一步。

设备从Standby进入Initiating状态后,会监听特定设备的广播。一旦收到,立刻发送连接请求。这个过程非常快,通常在几个毫秒内完成。

我记得有一次调试,连接总是建立失败。查了半天,发现是发起设备的连接参数设置得太激进——连接间隔设成了7.5ms,但远端设备根本处理不过来。后来我把连接间隔放宽到15ms,问题就解决了。

注意事项:

连接参数不是随便设的。连接间隔(Connection Interval)建议范围是7.5ms到4s。设得太短,设备容易掉线;设得太长,响应延迟大。我一般建议从30ms起步调试。

4.5 连接状态(Connection)——真正的“对话”开始

连接建立后,设备进入连接状态。这时候,双方按照固定的时间间隔交换数据。

连接状态有两个角色:

  • 主设备(Master):控制连接时序,决定何时发送数据
  • 从设备(Slave):跟随主设备的节奏,在指定时间窗口内回复

说白了,主设备是“老板”,从设备是“员工”。老板说“现在开会”,员工就得回应。

4.6 空中接口协议——数据怎么在空中飞

BLE的空中接口,用的是跳频技术。BLE 5.0在40个信道(37个数据信道+3个广播信道)之间跳来跳去。

为什么会这样?为了抗干扰。Wi-Fi和蓝牙共用2.4GHz频段,如果不跳频,两个设备撞在一起就完蛋了。

我建议你记住这个表格:

信道类型 信道编号 用途
广播信道 37、38、39 广播、扫描、发起连接
数据信道 0-36 连接后的数据传输

4.7 数据包结构——BLE的“语言”

BLE的数据包,结构很清晰。我拆开给你看:

| 前导码(1字节) | 访问地址(4字节) | PDU(2-257字节) | CRC(3字节) |

每个字段的作用:

  • 前导码:用于接收端同步时钟,固定为0xAA或0x55
  • 访问地址:连接后用于区分不同连接的标识
  • PDU:真正的数据内容,包含头部和有效载荷
  • CRC:校验数据完整性

我个人习惯在调试时,先看CRC对不对。如果CRC错了,后面的数据就不用看了——肯定是丢包或者干扰。

调试小技巧:

我曾经用逻辑分析仪抓包,发现某个设备的访问地址总是0x8E89BED6。后来查手册才知道,这是广播包的固定访问地址。嗯,记住这个值,调试时很有用。

4.8 实际项目中的链路层调试经验

最后,分享几个我踩过的坑:

  1. 广播超时:BLE 5.0规定,广播状态不能无限持续。如果60秒内没有连接请求,设备会自动回到Standby。我遇到过产品在展台上“死机”,就是因为广播超时了。
  2. 扫描窗口设置:扫描窗口设得太小,容易漏掉广播包。我一般建议扫描窗口至少设为广播间隔的1.5倍。
  3. 连接事件长度:连接后,每个连接事件里能传多少数据?这取决于连接间隔和物理层速率。BLE 5.0支持2Mbps,但实际吞吐量通常只有1.2Mbps左右。

好了,链路层的核心机制就讲到这里。下一章我们会深入数据通道的细节,看看数据到底是怎么在连接中流动的。

记住一句话:链路层是BLE的基石。搞懂了它,你就掌握了BLE协议栈的半壁江山。