2. 开发环境搭建:搭建基于Zephyr/FreeRTOS的蓝牙协议栈开发环境

好,咱们直接进入正题。开发环境搭建这事儿,说难不难,说简单吧,我第一次搞的时候也折腾了两天。你想想看,工具链、SDK、编译器版本,哪个对不上都白搭。我个人习惯是把环境分成三块:操作系统基础、RTOS内核、蓝牙协议栈。一块一块来,别急。

2.1 操作系统与工具链准备

我建议你用Ubuntu 20.04 LTS或22.04 LTS。为什么?因为Zephyr官方支持最好,踩坑最少。Windows也能搞,但说实话,我在Windows上编译Zephyr时遇到过路径长度问题,折腾了一下午。后来干脆装了个WSL2,省心。

先装基础依赖:

sudo apt update
sudo apt install --no-install-recommends git cmake ninja-build gperf \
  ccache dfu-util device-tree-compiler wget \
  python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \
  make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1

嗯,这里要注意。Python版本必须3.8以上。我有个同事用Python 3.6硬编,结果west工具死活装不上。后来发现是pip版本太老。所以建议你先检查一下:

python3 --version
pip3 --version

2.2 Zephyr RTOS 环境搭建

Zephyr的搭建流程,说白了就是三步:装west工具、下载SDK、初始化workspace。

第一步:安装west

pip3 install --user west
echo 'export PATH=~/.local/bin:"$PATH"' >> ~/.bashrc
source ~/.bashrc

我曾经遇到过west命令找不到的情况。后来发现是~/.local/bin没加到PATH里。你如果也遇到,记得检查一下。

第二步:下载Zephyr源码

west init ~/zephyrproject
cd ~/zephyrproject
west update

这一步会下载所有模块,包括蓝牙协议栈的源码。网络不好的话,可能要等十几分钟。我建议用代理或者换个时间段。

第三步:安装Zephyr SDK

cd ~
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_linux-x86_64.tar.xz
tar xf zephyr-sdk-0.16.1_linux-x86_64.tar.xz
cd zephyr-sdk-0.16.1
./setup.sh

SDK版本我推荐0.16.1。为什么?因为我在0.15.x上遇到过GCC链接错误,升级到0.16.1就解决了。你如果要用其他版本,记得看官方Release Notes。

小技巧: 如果你只是做蓝牙音频开发,不需要装全部SDK。运行 ./setup.sh -h 可以只选你需要的架构。比如Nordic nRF52系列,选arm即可。

2.3 FreeRTOS 环境搭建(备选方案)

有些项目必须用FreeRTOS,比如客户指定了某款MCU。那也没问题,我同样支持。

FreeRTOS的蓝牙协议栈,我推荐用FreeRTOS+BLE或者ESP-IDF(如果用的是乐鑫芯片)。搭建步骤相对简单:

git clone https://github.com/FreeRTOS/FreeRTOS.git
cd FreeRTOS
git submodule update --init --recursive

然后你需要下载对应的蓝牙协议栈。比如用Nordic的nRF5 SDK:

wget https://www.nordicsemi.com/-/media/Software-and-other-downloads/SDKs/nRF5/nRF5_SDK_17.1.0_ddde560.zip
unzip nRF5_SDK_17.1.0_ddde560.zip

我个人觉得,FreeRTOS的搭建比Zephyr简单,但后续移植工作量更大。因为FreeRTOS本身不提供统一的蓝牙抽象层,你得自己对接HCI。嗯,这个后面章节会细讲。

2.4 蓝牙协议栈配置要点

环境搭好了,怎么确认蓝牙协议栈能正常工作?我一般用两个方法:

  1. 编译示例工程:Zephyr自带一个samples/bluetooth/hci_uart,编译通过就说明环境没问题。
  2. 运行HCI测试:用hcitool或btmon抓一下蓝牙数据包,看看能不能扫描到设备。

编译示例的命令:

cd ~/zephyrproject
west build -b nrf52840dk_nrf52840 samples/bluetooth/hci_uart
west flash

如果编译报错,八成是工具链路径没配好。检查一下:

echo $ZEPHYR_BASE
echo $ZEPHYR_SDK_INSTALL_DIR

这两个环境变量必须指向正确路径。我曾经因为换了终端窗口忘记source环境变量,浪费了半小时。

避坑指南: 我曾经在Ubuntu 24.04上尝试搭建Zephyr 3.2环境,结果cmake版本太高,不兼容。后来降级到cmake 3.20才解决。建议你装完环境后,先跑一下官方自带的hello_world示例,确认一切正常再往下走。

2.5 开发板与调试工具

硬件方面,我推荐几块板子:

开发板 蓝牙芯片 适合场景
nRF52840 DK nRF52840 助听器原型验证,资源丰富
nRF5340 DK nRF5340 双核架构,适合复杂音频处理
ESP32-DevKitC ESP32 成本敏感方案,FreeRTOS生态

调试工具我习惯用J-LinkOzone。为什么?因为J-Link的RTT功能可以实时打印蓝牙协议栈的日志,对排查连接断开、配对失败这类问题特别有用。

另外,nRF Connect这个桌面工具也推荐装上。它可以抓取蓝牙HCI日志,分析音频流的时序。我在调试LC3编码器时,就是靠它发现了一个packet间隔不对的问题。

2.6 验证环境是否就绪

最后,跑一个完整的蓝牙音频示例来验证。Zephyr 3.4以上版本自带samples/bluetooth/audio,里面有broadcast source和sink的示例。

west build -b nrf52840dk_nrf52840 samples/bluetooth/audio/broadcast_source
west flash

烧录后,用手机上的nRF Connect App扫描,应该能看到一个名为"Zephyr Broadcast"的设备。如果能看到,恭喜你,环境搭建成功了!

如果看不到,别慌。先检查串口日志,看看蓝牙协议栈初始化有没有报错。我遇到过几次是因为天线没接好,或者板子的DCDC配置不对。嗯,这些细节后面章节会专门讲。

核心要点: 开发环境搭建不是一次性的工作。随着项目推进,你可能需要添加新的工具链、更新SDK版本。我的建议是:每次改动环境后,都跑一遍示例工程做回归测试。别等到移植到一半才发现工具链有问题,那才叫欲哭无泪。

好,环境搭好了,下一章我们开始真正进入蓝牙音频协议栈的移植。到时候会讲怎么把LC3编码器集成进去,那可是助听器音频流的核心。