3. 开发环境搭建:nRF5 SDK 与 Zephyr RTOS 环境配置、VS Code 与 Keil IDE 设置

做嵌入式开发,尤其是蓝牙多设备协同这种活儿,环境搭建往往是第一道坎。很多人觉得不就是装个软件嘛,结果一搞就是半天,最后编译还报错。我刚开始接触 nRF 系列时也踩过不少坑,今天就把这些经验掰开揉碎讲给你听。

本章核心目标:让你能在 30 分钟内跑通一个蓝牙例程的编译和下载。不管是 nRF5 SDK 还是 Zephyr RTOS,我们都要把路铺平。

3.1 工具链总览:你需要哪些“武器”

先看看我们到底要装哪些东西。别急着下载,先理清关系。

开发环境组件关系图 你的蓝牙应用代码 nRF5 SDK 或 Zephyr RTOS ARM GCC / Segger Embedded Studio / IAR VS Code / Keil MDK / SES J-Link / nRF52-DK / nRF52840-Dongle 选择 nRF5 SDK 还是 Zephyr?看你的项目复杂度。简单产品用 SDK,多设备协同推荐 Zephyr。

说白了,从上到下就是:你的代码 → 调用 SDK/RTOS 的 API → 编译器把它变成机器码 → 用 IDE 管理工程 → 最后通过调试器烧到芯片里。每一层都不可或缺。

3.2 nRF5 SDK 环境配置

nRF5 SDK 是 Nordic 官方的传统开发包。虽然现在 Zephyr 很火,但很多老项目、量产方案还是用这套。我个人习惯把 SDK 放在 C:\nRF5_SDK\ 下,路径里不要有中文和空格,否则编译会哭。

3.2.1 下载与目录结构

去 Nordic 官网下载 nRF5 SDK 17.1.0(最新稳定版)。解压后你会看到这样的结构:

nRF5_SDK_17.1.0_ddde560/
├── components/          # 核心组件:蓝牙协议栈、外设驱动、库
├── examples/            # 官方例程,我们的起点
├── external/            # 第三方库,比如 FreeRTOS、FatFS
├── integration/         # 与 RTOS 集成的文件
├── modules/             # 一些实用模块
├── nrf5x/               # 芯片头文件、链接脚本
├── sdk_config.h         # 全局配置文件,非常重要!
└── documentation/       # API 文档

嗯,这里要注意:千万不要移动或删除 components 和 examples 里的任何文件。例程的路径是写死的,挪了位置编译就找不到头文件。我曾经手贱把 ble_app_uart 拷到桌面改,结果折腾了一下午。

3.2.2 编译器选择

nRF5 SDK 支持三种编译器。我列个表,你看着选:

编译器 优点 缺点 我的建议
ARM GCC (GNU Arm Embedded Toolchain) 免费、跨平台、命令行友好 调试体验一般,需要自己配 Makefile 适合 Linux 用户或 CI 自动化
Segger Embedded Studio (SES) Nordic 官方推荐、开箱即用、调试强 Windows 独占(有 Linux 版但不好用) 新手首选,省心
Keil MDK 老牌 IDE、很多公司用、uVision 界面 收费、代码补全弱、License 管理麻烦 公司项目要求才用

我个人推荐:入门用 SES,进阶用 VS Code + ARM GCC。为什么?SES 打开例程直接编译下载,零配置。VS Code 则更灵活,适合我们后面做多设备协同的复杂调试。

3.2.3 快速验证:编译第一个例程

用 SES 打开 examples\ble_peripheral\ble_app_uart\pca10056\s140\ses\ble_app_uart_pca10056_s140.emProject。然后按 F7 编译。如果一切顺利,你会看到:

Build completed successfully.
Total time: 12.3s
Memory: Flash 0x2A3B0, RAM 0x4C00

小技巧:第一次编译会比较慢,因为要编译整个协议栈。后面改代码只会增量编译,几秒就完事。

3.3 Zephyr RTOS 环境配置

Zephyr 是 Linux 基金会下的 RTOS,Nordic 现在是主要贡献者之一。如果你要做多设备蓝牙协同,Zephyr 的蓝牙栈比 nRF5 SDK 更现代、更灵活。但配置起来也稍微复杂一点。

3.3.1 安装 west 与 SDK

Zephyr 用 west 作为项目管理工具。先装 Python 3.8+,然后:

pip install west
west init ~/zephyrproject
cd ~/zephyrproject
west update

这一步会下载整个 Zephyr 源码和所有模块,大概 1-2GB。别急,去泡杯咖啡。

然后安装 Zephyr SDK(包含编译器、调试器等):

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

注意:Windows 用户建议用 WSL2(Ubuntu 22.04)。原生 Windows 下 Zephyr 的体验一言难尽,我试过两次都放弃了。

3.3.2 环境变量设置

把下面几行加到 ~/.bashrc 或 ~/.zshrc 里:

export ZEPHYR_BASE=~/zephyrproject/zephyr
export ZEPHYR_SDK_INSTALL_DIR=~/zephyr-sdk-0.16.8
source $ZEPHYR_BASE/zephyr-env.sh

然后 source ~/.bashrc 使其生效。验证一下:

west --version
# 应该输出 west 1.2.0 或更高

3.3.3 编译第一个 Zephyr 例程

以 nRF52840 DK 为例,编译蓝牙信标例程:

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

如果看到 Flashing completed,恭喜你,环境通了。这时候用手机上的 nRF Connect 应该能搜到一个叫 "Zephyr Beacon" 的设备。

为什么推荐 Zephyr?它的蓝牙栈支持 LE Audio、Connection Subrating、多角色并发等新特性。nRF5 SDK 在这些方面已经停止更新了。

3.4 VS Code 与 Keil IDE 设置

IDE 是咱们写代码的主战场。我平时主力用 VS Code,但有些公司项目必须用 Keil。两个都讲讲。

3.4.1 VS Code 配置(推荐)

VS Code 配合插件,开发体验可以拉满。必装插件:

  • C/C++(微软官方):代码补全、跳转、调试
  • Arm Assembly:汇编语法高亮
  • Hex Editor:查看二进制文件
  • Serial Monitor:串口调试,不用再开 Putty
  • CMake Tools:Zephyr 项目必备

对于 Zephyr 项目,我习惯在 .vscode/settings.json 里加这个:

{
  "cmake.configureArgs": [
    "-DBOARD=nrf52840dk_nrf52840"
  ],
  "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
}

这样打开项目后,VS Code 会自动识别 CMakeLists.txt,代码跳转和智能提示都正常。你想想看,没有代码跳转的嵌入式开发,那不得累死?

3.4.2 Keil MDK 配置(备选)

Keil 的配置相对简单。安装好 MDK v5.38 或更高版本,然后装 nRF 设备包:

  1. 打开 Keil,点击 Pack Installer
  2. 搜索 NordicSemiconductor.nRF_DeviceFamilyPack,安装最新版
  3. 打开 nRF5 SDK 例程中的 .uvprojx 文件
  4. 在 Options for Target 里选择正确的芯片型号和调试器

避坑:Keil 的 AC6 编译器对 nRF5 SDK 支持不太好。如果编译报错,试试在 Target 设置里把编译器切回 AC5(ARM Compiler 5)。

3.5 调试器配置:J-Link 与 OpenOCD

环境搭好了,烧录和调试也得跟上。nRF52 系列板载了 J-Link OB,插上 USB 就能用。

如果你用 SES 或 Keil,调试器基本是自动识别的。用 VS Code 的话,需要装 Cortex-Debug 插件,然后在 launch.json 里配:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Attach to nRF52840",
      "type": "cortex-debug",
      "request": "attach",
      "servertype": "jlink",
      "device": "nRF52840_xxAA",
      "interface": "swd",
      "runToMain": true
    }
  ]
}

嗯,这里要注意:J-Link 驱动版本不要低于 7.84。我遇到过因为驱动太旧导致无法识别 nRF5340 的情况,折腾了半天才发现是驱动的问题。

3.6 常见问题与避坑指南

最后总结几个我经常被问到的问题:

  • 编译报错 "cannot find -lnrf_ble":检查 SDK 路径是否包含空格,或者例程路径是否被移动过。
  • Zephyr 编译巨慢:第一次编译会全量构建,后面用 west build -t menuconfig 裁剪不需要的功能,能快不少。
  • 烧录后没反应:先检查板子上的电源灯亮不亮。再确认调试器是否识别:JLinkExe 里输入 device nRF52840 然后 connect。
  • VS Code 代码跳转失效:删除 build 目录,重新 west build 生成 compile_commands.json。

重要:nRF5 SDK 和 Zephyr 不要混用!它们的蓝牙协议栈 API 完全不同。选定一个方向后,就坚持用下去。我见过有人想在 Zephyr 里调用 nRF5 SDK 的驱动,结果编译出一堆链接错误。