第一章:Zephyr与BLE概览

各位同学,欢迎来到《Zephyr低功耗蓝牙协议栈开发与调试实战》的第一课。

说实话,我刚开始接触嵌入式无线开发那会儿,最头疼的就是协议栈。一堆分层、一堆术语,光看文档就能把人绕晕。但后来我发现,只要把整体框架理清楚,后面学起来就顺多了。今天我们就从Zephyr RTOS和BLE协议栈的宏观视角开始,把地基打牢。

1.1 Zephyr RTOS简介

Zephyr RTOS,说白了就是一个为资源受限设备设计的实时操作系统。它不像Linux那么重,但也不是裸机那种“裸奔”状态。它有自己的调度器、内存管理、设备驱动模型,还有——我们今天的主角——BLE协议栈。

我个人习惯把Zephyr比作一个“乐高积木盒”。你需要什么功能,就通过Kconfig配置把它拼进来。比如你要用BLE,就打开CONFIG_BT;要用HCI,就打开CONFIG_BT_HCI。这种模块化设计,让Zephyr在IoT领域特别吃香。

小提示: 如果你之前用过FreeRTOS或RT-Thread,会发现Zephyr的配置方式更接近Linux内核——全是Kconfig和设备树。刚开始可能不习惯,但用熟了你会爱上这种“一切皆可配置”的感觉。

1.2 BLE协议栈架构

BLE协议栈分三层:Controller、Host、Application。嗯,这里要注意,这三层不是物理上的三个芯片,而是逻辑上的划分。

层级 职责 典型模块
Controller 负责射频收发、链路控制 LL(链路层)、PHY(物理层)
Host 负责协议封装、服务发现、数据交互 GAP、GATT、L2CAP、SM
Application 用户业务逻辑 你的回调函数、服务定义

为什么这么分?你想想看,Controller处理的是最底层的时序和射频,对实时性要求极高;Host处理的是逻辑和协议,可以跑在相对慢一点的CPU上。这种分层设计,让开发变得清晰——你写应用层代码时,根本不用管射频怎么调频、怎么跳频。

避坑指南: 我曾经在项目中遇到一个问题:应用层发数据包,但设备就是连不上。查了两天,最后发现是Controller层的LL(链路层)参数没配好。所以记住:分层虽好,但调试时要从底层往上查。

1.3 Zephyr BLE子系统

Zephyr把BLE协议栈拆成了几个关键子系统。我挑四个最常用的给你讲讲:

1.3.1 BT_HCI(主机控制器接口)

HCI是Host和Controller之间的“翻译官”。它定义了命令、事件、数据包的格式。在Zephyr中,HCI可以走UART、USB、SPI,甚至可以是内部API调用(即所谓的“HCI over Zephyr”)。

我记得第一次调HCI时,用bt_hci_cmd_send_sync()发了一个LE Set Scan Parameters命令,结果等了半天没响应。后来发现是HCI的buffer没配够。嗯,这个坑后面我们会专门讲。

1.3.2 BT_LL(链路层)

LL是BLE的“心脏”。它负责连接建立、数据重传、加密、跳频。在Zephyr中,LL通常跑在Controller侧,对开发者来说几乎是透明的。但如果你要做低功耗优化,LL的参数(比如连接间隔、延迟)就是关键。

1.3.3 BT_GAP(通用访问规范)

GAP定义了设备如何发现、如何连接、如何广播。说白了,就是“你是谁?我能连你吗?”这一套社交礼仪。

Zephyr里GAP的API很直观:bt_le_adv_start()开始广播,bt_le_scan_start()开始扫描。我建议你刚开始时,先跑通一个最简单的广播+扫描示例,感受一下GAP的工作流程。

1.3.4 BT_GATT(通用属性规范)

GATT是BLE应用层最常用的协议。它定义了“属性”(Attribute)和“服务”(Service)的概念。比如一个温度传感器,它有一个温度服务,服务里有一个温度特征值,特征值里存着温度数据。

在Zephyr中,定义GATT服务通常用BT_GATT_SERVICE_DEFINE宏。你想想看,写几行宏就能定义一个完整的BLE服务,是不是很爽?

重点: GATT是应用开发的核心。你后面写的所有BLE应用,几乎都是在跟GATT打交道。所以这一块一定要吃透。

1.4 开发环境搭建

好了,理论讲完了,咱们来点实际的。搭建Zephyr开发环境,我总结了三步走:

1.4.1 安装west

West是Zephyr的元构建工具。它负责拉取源码、管理模块、执行构建。安装很简单:

pip install west

然后初始化工作区:

west init ~/zephyrproject
cd ~/zephyrproject
west update

这一步会下载Zephyr内核、BLE协议栈、以及所有依赖的模块。我第一次跑west update时,等了快十分钟,还以为卡死了。其实它是在拉Git子模块,耐心等就好。

1.4.2 配置toolchain

Zephyr支持多种工具链。我个人习惯用Zephyr SDK,因为它包含了所有必要的交叉编译器、调试器、以及QEMU模拟器。

west sdk install

如果你用的是ARM Cortex-M系列(比如nRF52840、STM32WB),那Zephyr SDK里的arm-zephyr-eabi-gcc就是你的主力编译器。

注意: 不要用系统自带的gcc去编译Zephyr!交叉编译必须用Zephyr SDK或你手动配置的ARM工具链。我曾经图省事用了系统gcc,结果链接阶段报了一堆莫名其妙的错误。

1.4.3 选择board

Zephyr支持上百种开发板。你可以在boards/目录下找到所有支持的板子。比如nRF52840 DK:

west build -b nrf52840dk_nrf52840 samples/bluetooth/beacon

这条命令会编译一个BLE信标示例。如果你没有硬件,也可以用QEMU模拟:

west build -b qemu_cortex_m3 samples/bluetooth/beacon

嗯,这里要注意:QEMU模拟的BLE功能有限,很多HCI命令不支持。所以有条件的话,还是建议用真实板子调试。

小结

这一章我们走马观花地看了Zephyr和BLE的全貌。你知道了Zephyr是一个模块化的RTOS,BLE协议栈分Controller、Host、Application三层,Zephyr的BLE子系统包括HCI、LL、GAP、GATT,以及怎么搭建开发环境。

下一章,我们会深入BLE的广播与扫描,手把手教你写一个能发广播包的设备。到时候你会发现,今天这些概念全都能用上。

好,今天就到这儿。有问题欢迎交流。

课后练习: 试着用west创建一个新的BLE应用,并修改广播数据包的内容。比如把你的名字作为广播名发出去。