第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 实际项目中的链路层调试经验
最后,分享几个我踩过的坑:
- 广播超时:BLE 5.0规定,广播状态不能无限持续。如果60秒内没有连接请求,设备会自动回到Standby。我遇到过产品在展台上“死机”,就是因为广播超时了。
- 扫描窗口设置:扫描窗口设得太小,容易漏掉广播包。我一般建议扫描窗口至少设为广播间隔的1.5倍。
- 连接事件长度:连接后,每个连接事件里能传多少数据?这取决于连接间隔和物理层速率。BLE 5.0支持2Mbps,但实际吞吐量通常只有1.2Mbps左右。
好了,链路层的核心机制就讲到这里。下一章我们会深入数据通道的细节,看看数据到底是怎么在连接中流动的。
记住一句话:链路层是BLE的基石。搞懂了它,你就掌握了BLE协议栈的半壁江山。