从零实现BLE协议栈(6-3)实验:06_phy_data_channel
6-3 动手实验:编译运行 06_phy_data_channel
本篇是第 6 章的配套实验,将 6-1 和 6-2 中讲解的 LL Data PDU 与 L2CAP 分片重组完整跑通。
一、概述
06_phy_data_channel 在 Demo 05 的稳定连接基础上,增加了数据通道功能:
- LL Data PDU 解析:识别 LLID=01(Start/Complete)和 LLID=10(Continue)片段
- L2CAP 重组:多个 LL PDU 片段拼接为完整的 L2CAP Basic Frame
- Echo 回传:将收到的 L2CAP 数据原样分片回传给对端(验证双向数据通路)
- TX 队列:最多 4 个待发送片段,每连接事件发一个
通过本实验,你将验证 LL→L2CAP 的分层解析以及 BLE 4.0 默认 27 字节 MTU 下的分片过程。
二、编译与烧录
west build -b nrf52dk/nrf52832 .\write-BLE-stack-from-scratch\06_phy_data_channel\ -p
west flash
编译产物:
Memory region Used Size Region Size %age Used
FLASH: 99672 B 512 KB 19.01%
RAM: 19648 B 64 KB 29.98%
RAM 增加约 640B(L2CAP 重组缓冲区 + TX 队列)。
三、运行测试
测试 1:基础连接(bumble_connect.py)
.\write-BLE-stack-from-scratch\tools\venv\Scripts\python.exe `
.\write-BLE-stack-from-scratch\tools\bumble_connect.py `
--transport usb:2FE3:000B `
--target 66:55:44:33:22:11 `
--duration 15
Bumble 侧:连接稳定保持 15 秒。bumble_connect.py 只做 LL 控制过程(Version/Feature Exchange),不发送 L2CAP 数据,echo 计数为 0。
测试 2:L2CAP Echo(bumble_l2cap_echo.py)
# 单 PDU echo (16 字节 payload, 适合单个 LL PDU)
.\write-BLE-stack-from-scratch\tools\venv\Scripts\python.exe `
.\write-BLE-stack-from-scratch\tools\bumble_l2cap_echo.py `
--transport usb:2FE3:000B `
--target 66:55:44:33:22:11 `
--count 5 --size 16
[SEND] #0 | 16B | head=00000000a0a1a2a3
[ECHO] #0 OK | 16B | latency=32.0ms | recv=1/1
[SEND] #1 | 16B | head=01000000a0a1a2a3
[ECHO] #1 OK | 16B | latency=47.0ms | recv=2/2
...
L2CAP ECHO TEST REPORT
Sent : 5
Received : 5
Match (OK) : 5
Success rate : 100.0%
Latency (ms) : avg=42.0 min=32.0 max=47.0
# 多分片 echo (40 字节 payload → L2CAP 44 字节 → 2 个 LL PDU)
.\write-BLE-stack-from-scratch\tools\venv\Scripts\python.exe `
.\write-BLE-stack-from-scratch\tools\bumble_l2cap_echo.py `
--transport usb:2FE3:000B `
--target 66:55:44:33:22:11 `
--count 3 --size 40
[SEND] #0 | 40B | head=00000000a0a1a2a3
[ECHO] #0 OK | 40B | latency=140.0ms | recv=1/1
...
LL fragments : 2 per frame (MTU=27)
Sent : 3
Received : 3
Success rate : 100.0%
Latency (ms) : avg=156.0 min=140.0 max=188.0
多分片延迟更高(~150ms vs ~42ms),因为 2 个 LL PDU 需要分别在不同连接事件中传输(每事件 50ms)。
四、串口日志
连接事件循环(bumble_connect.py)
[CONN] #1 ch=11 OK | ww=5 | rx=1/1 l2cap_rx=0 tx=0
[CONN] #2 ch=22 OK | ww=5 | rx=2/2 l2cap_rx=0 tx=0
[CONN] #3 ch=33 OK | ww=5 | rx=3/3 l2cap_rx=0 tx=0
...
[CONN] #300 ch=14 OK | ww=5 | rx=297/300 l2cap_rx=0 tx=0
L2CAP Echo 日志(bumble_l2cap_echo.py)
[CONN] #1 ch=15 OK | ww=5 | rx=1/1 l2cap_rx=0 tx=0
[CONN] #2 ch=30 OK | ww=5 | rx=2/2 l2cap_rx=0 tx=0
...
[L2CAP] RX #1: CID=0x0040 len=16 → echo 1 frags
[L2CAP] RX #2: CID=0x0040 len=16 → echo 1 frags
[L2CAP] RX #3: CID=0x0040 len=16 → echo 1 frags
连接总结(echo 测试)
========== Connection Summary ==========
Total events: 152
RX OK: 149
RX timeout: 3
RX CRC error: 0
L2CAP RX: 3
L2CAP TX echo: 3
Anchor updates: 149
Max consec miss: 1
日志解读
- bumble_connect.py 测试:
l2cap_rx=0 tx=0,因为 LL Feature/Version Exchange 走 LLID=Control(0x03),不经过 L2CAP - bumble_l2cap_echo.py 测试:
L2CAP RX: 3, TX echo: 3,3 帧全部正确接收并 echo 回传 - 延迟日志打印:
[L2CAP] RX #N: ...出现在连接事件之间(而非事件内部),避免阻塞 SW TIFS - RX OK: 149/152 = 98%:连接稳定性与 Demo 05 一致
五、关键概念图
LL Data PDU 格式
┌──────────┬──────┬───────────────────────────────────┐
│ Header │ Len │ Payload (最多 27 字节, BLE 4.0) │
│ (2 bytes)│ │ │
├──────────┼──────┤ │
│ LLID(2b) │ │ [L2CAP Header(4B)] [L2CAP Data] │
│ 01 = Start/Complete │
│ 10 = Continue fragment │
│ 11 = LL Control PDU │
└──────────┴──────┴───────────────────────────────────┘
L2CAP 重组流程
LL PDU #1 (LLID=01, Start) LL PDU #2 (LLID=10, Continue)
┌────────────────────────────┐ ┌────────────────────────────┐
│ L2CAP Hdr │ Data Part 1 │ │ Data Part 2 (续) │
│ Len=40 │ (23 bytes) │ │ (17 bytes) │
│ CID=0x0004│ │ │ │
└────────────────────────────┘ └────────────────────────────┘
│ │
└──────── 拼接到 reassembly buffer ─────────┘
│
┌───────▼────────┐
│ 完整 L2CAP Frame│
│ 40 字节 payload │
│ CID = ATT │
└───────┬────────┘
│ echo
┌───────▼────────┐
│ 分片为 2 个 │
│ LL Data PDUs │
│ 放入 TX Queue │
└────────────────┘
Echo 数据流
Master (Bumble) Slave (nRF52)
│ │
│── LL Data PDU (LLID=01) ──────→ │ reassemble
│── LL Data PDU (LLID=10) ──────→ │ → complete L2CAP frame
│ │ ↓ echo
│←── LL Data PDU (LLID=01) ────── │ segment
│←── LL Data PDU (LLID=10) ────── │
│ │
本系列教程同款硬件:👇
芯片: nRF 52832 开发板
工具: nRF 52840 BLE Dongle 蓝牙嗅探器
工具: 逻辑分析仪
工具: BPA low energy 蓝牙分析仪
本文版权归作者:ixbwer所有,转载请注明原文链接:https://www.cnblogs.com/ixbwer/p/19810104,否则保留追究法律责任的权利。

浙公网安备 33010602011771号