BLE广播从零起步,如何实现疑问?

摘要:Hello World:BLE 广播 前提知识 阅读本文需要具备以下基础: 1-1 的 TASKEVENT 模型:本文的所有硬件操作(启动晶振、触发发送、等待完成)都基于往 TASK 寄存器写 1 触发动作、读 EVENT 寄存器确认完成
Hello World:BLE 广播 前提知识 阅读本文需要具备以下基础: 1-1 的 TASK/EVENT 模型:本文的所有硬件操作(启动晶振、触发发送、等待完成)都基于往 TASK 寄存器写 1 触发动作、读 EVENT 寄存器确认完成的模式 1-1 的 SHORTS 机制:本文的 send_on_channel() 直接使用 READY→START 和 END→DISABLE 两条硬件捷径驱动发送,不理解 SHORTS 就无法理解为什么 CPU 只需要写一个寄存器就能完成整个发送流程 HEX 与二进制表示:需要读懂字节级的数据结构和位域定义 不需要提前了解 BLE 广播规范的细节——本文会从头解释每一个字段的含义和设计原因。 一、空气中发生了什么 在手机上打开 nRF Connect App 点击扫描。屏幕上会跳出一列设备,每条记录后面跟着一个随时间变动的 RSSI 值(如 -52 dBm)。这个数字反映的是接收信号强度:距离越近数字越大,越远越小。 这些设备之所以能被扫到,是因为它们在持续地向四周广播数据包,大约每 100 ms 发一次(广播间隔可以在 20 ms 到 10.24 s 之间配置)。BLE 规范为了对抗 2.4 GHz 频段的拥堵,把广播固定在三个信道上轮流发送,而不是随机选一个频率乱发: Channel 37 — 2402 MHz:紧贴 Wi-Fi 信道 1 的左侧边缘 Channel 38 — 2426 MHz:Wi-Fi 信道 1 与信道 6 之间的空隙 Channel 39 — 2480 MHz:Wi-Fi 信道 11/13 的右侧边缘 这三个位置经过精心选择,尽可能地绕开最常用的 Wi-Fi 信道。每次广播事件,设备依次在 37、38、39 上各发一帧,遭遇干扰时对方至少能在另外两个频道收到信号。 二、广播包的结构 物理层看到的空中数据只是一串比特流。BLE 规范规定了这串比特流在逻辑上的分层结构。一个完整的空中帧由硬件自动补全的首尾字段和软件负责填写的 PDU 组成: Preamble(前同步码) 是固定序列 0xAA,让接收端的时钟恢复电路锁定比特率,由 RADIO 硬件自动发送。 Access Address(接入地址) 是 BLE 广播信道的"通行密码",固定值 0x8E89BED6。所有 BLE 设备在广播信道上都用同一个接入地址,这样手机的射频芯片才知道哪段信号是 BLE 包而不是其他 2.4 GHz 设备的干扰。 PDU(协议数据单元) 分为两层: Header 占 2 字节,包含 PDU 类型(4 bit)、发送方地址类型(1 bit)、接收方地址类型(1 bit)和 Payload 长度(8 bit)等 Payload 以 6 字节的设备 MAC 地址(AdvA)开头,后面跟最多 31 字节的广播数据(AdvData) CRC 是 24 位循环冗余校验,由 RADIO 硬件在发送最后一字节后自动计算并附加。接收端也由硬件自动核验,结果反映在 RADIO->CRCSTATUS 寄存器中。 三、在内存中构建 PDU 理解了逻辑结构之后,我们来看软件如何把数据写进内存,再交给 RADIO 的 DMA 引擎。 3.1 AdvData 数组 我们的广播数据包含两个 AD 结构体:一个 Flags,一个设备名称。 static const uint8_t adv_data[] = { /* AD 结构体 1:Flags */ 0x02, /* Length = 2:Type 1B + Value 1B */ 0x01, /* Type = 0x01:Flags */ 0x06, /* Value:LE General Discoverable | BR/EDR Not Supported */ /* AD 结构体 2:Complete Local Name */ 0x0A, /* Length = 10:Type 1B + 9 字符名称 */ 0x09, /* Type = 0x09:Complete Local Name */ 'Z', 'e', 'p', 'h', 'y', 'r', 'R', 'a', 'w' }; Flags 占 3 字节(Length + Type + Value),名称占 11 字节(Length + Type + 9 字符),共 14 字节。 3.2 组装完整 PDU Zephyr BLE Controller 源码提供了 struct pdu_adv 来精确映射广播 PDU 的内存布局。
阅读全文