nRF-Connect-SDK 安装与入门
2026.7.28更新:
- 推荐安装 NCS v3.4.0 LTS.
- 重新整理安装流程,强化 nrfutil 纯命令行用法,适合 AI Agent 和服务器环境使用
2026.1.11更新:
- 官方已经支持中国大陆服务器源下载NCS
2025.10.14 更新:
- 增加了NCS v3.1.0 和 v3.1.1 在中文 Windows 系统上编码问题的解决方案
- 增加了说明,nrfutil sdk-manager v1.8.0 已经解决了SDK在Windows系统上 git 状态错误的问题
2025.7.27 更新:
- 增加了nRF Connect详细安装说明,和国内软件源
- 增加了 nrfutil 详细安装说明,以及命令行自动补全
- 新增了强制用国内服务器加速安装NCS的方法
2025.5.12 更新:
- NCS v3.0.0 支持打包下载,无需从 GitHub 拉取
- 新增 workspace 插件清理内容,解决 VS Code 弹窗问题
- 新增对 Windows 目录名长度限制的提醒
nRF Connect SDK,简称 NCS,是 Nordic 最新的 SDK 平台。该平台支持 Nordic 的四大产品线:
- 短距离 2.4G SoC 和功率放大器(PA) :Bluetooth LE, 802.15.4, 2.4G 私有协议(ESB)
- 中距离 Wi-Fi : Wi-Fi 6 收发器和SoC
- 长距离蜂窝模组 (SiP):CAT-M,CAT1-bis,CAT-NB,卫星通信(NTN)
- 电源管理芯片 :多合一 PMIC。支持 Charger,电量计, BUCK / Boost,LDO / Load Switch,Ship Mode,GPIO,Watchdog,Hard Reset
以上述硬件为基础,提供多种物联网、嵌入式、机器学习、低功耗穿戴等领域的技术方案和应用示例。
NCS 基于 Zephyr 系统。Zephyr 系统是一个开源嵌入式实时操作系统项目,由 Linux 基金会和众多厂商维护。Zephyr 系统是一个完整的 BSP,除了基本的编译环境和 RTOS 之外 ,还有很多中间件、软件库、硬件驱动、工具脚本、测试框架等等。
Zephyr 的强大特性
- 全面的内核服务
- 多线程,支持协程和基于优先级的抢占。兼容 POSIX pthreads API。
- 多种动态内存分配工具,支持固定大小或可变大小的内存块
- 支持多种信号量同步机制(信号量、互斥锁等);支持多种线程间通讯机制(消息队列、字节流等)
- CPU 电源管理和外设电源管理等低功耗机制
- 多种调度策略可选
- 高度可定制性、模块化开发
- 支持许多架构(x86, ARM, RISC-V)
- 堆栈、内核、驱动、线程间内存保护
- 允许编译时静态定义资源(线程、内存池、队列等),提高性能
- 提供具有一致性的设备驱动模型,并且支持 DeviceTree 规范
- 集成常见外部设备的驱动,如显示屏、存储器、传感器、灯带、RTC等
- 全功能网络协议栈(包括 LwM2M 和 BSD Sockets),OpenThread,BLE
- 支持 TrustZone 安全技术,按照 PSA 架构提供安全基础设施
- 集成常用软件包:LVGL, LZ4, iperf, Json Lib, TinyCBOR
- 支持多种文件系统(ext2, LittleFS, FatFS…)和简单的键值对存储系统
- 统一的配置项持久存储系统,全系统(应用层和中间件)的配置项可共享同一存储器分区
- 远程资源管理(通过串口、USB、BLE、network 管理固件升级、版本回滚、文件系统资源等)
- 强大的模块化日志框架,支持多种后端(串口、RTT、BLE、network、filesystem…)
- 为开发调试提供便利的 Shell 功能
- 跨平台开发(Windows / Linux / MacOS)
- 支持 QEMU 模拟仿真
Nordic 的 NCS 在 Zephyr 的基础上提供了更多的脚本工具、协议栈、驱动、功能库等等。
更多信息可参考:
1. 简介
必装选项:
| 序号 | 软件 | 分类 | 用途 |
|---|---|---|---|
| 1 | J-Link 驱动 | 驱动 | JLink驱动需要单独安装。安装时必须勾选 Legacy USB Driver。 |
| 2 | nRF Util | CLI 工具 | 统一 CLI 工具,包含子命令:sdk管理、烧录、DFU 等等。类似软件包管理器,支持更新。 |
| 3 | NCS Toolchain | 编译工具链 | 独立的工具链文件夹,含Git、CMake、Python、Ninja、GCC、west 等工具,与电脑上已经安装的工具环境相互独立。可以同时存在多个版本的 Toolchain。 |
| 4 | nRF Connect SDK | SDK 源码包 | SDK本体,含 Zephyr 内核、驱动、模块、协议栈等源码。可以同时存在多个版本的 SDK。 |
| 5 | nrf-udev | Linux 配置文件 | 仅 Linux 系统需要。配置USB设备权限,可识别 Nordic USB 设备。 |
对于纯命令行开发、CI/CD服务器环境、AI 辅助编程来说,以上软件已经足够实现编译、烧录和简单的调试。
此外,Nordic 还提供其他开发工具:
| 序号 | 软件 | 分类 | 用途 |
|---|---|---|---|
| 6 | VS Code + nRF Connect 插件 | IDE | 提供编译、烧录、调试的可视化界面,提供设备树可视化、SDK管理、工具链环境等。支持 VS Code Remote 在远程服务器或虚拟机/WSL上开发。 |
| 7 | nRF Connect for Desktop | 桌面工具 | Nordic 桌面工具与上位机集合,包含:开发板配置、串口助手、固件烧录、功耗测量、蜂窝抓包、射频测试等 |
| 8 | nRF Connect for Mobile | 手机 APP | iOS / Google Play 直接商店下载。Android 系统也可以从 GitHub Release APK 安装。 |
2. 安装开发工具
J-Link 驱动
J-Link 驱动的版本参考 NCS依赖(v3.4.0) 文档。打开文档后,先把文档版本对齐为你要安装的最新的正式版 NCS 版本,比如这里是 NCS v3.4.0:

然后往下翻,找到 J-Link 需要的版本:

一般来说比这个版本高也是可以的。在 SEGGER - J-Link官网 下载 J-LINK 驱动:

Linux系统直接安装:
1 | |
Windows系统安装 J-Link 驱动时,一定要带上JLink USB驱动:
1 | |
或者在安装时勾选 Legacy USB Driver:

安装完毕后,Windows 系统一定要把 J-Link 可执行文件所在目录添加到 PATH 环境变量:


注意,根据前面安装时选择 “Update existing installation” 还是 “Install a new instance”,JLink.exe 所在的目录是不一样的。设置 PATH 环境变量时要注意设置正确的位置。
验证 PATH 环境变量设置正确。能找到路径说明已经成功设置:
1 | |
1 | |
1 | |
nrfutil - CLI 工具
nrfutil 是一个命令行工具集。它可以联网安装、升级许多功能。如程序烧录、SDK管理、工具链环境、MCU Mgr 等等。此外,它也包含许多 Nordic 上位机工具的底层控制命令,如 BLE Sniffer、Cellular trace、电源管理芯片上位机等。
纯 CLI 工具可以方便服务器 CI/CD 环境编译、本地脚本开发、量产测试工具开发。在 AI 时代,也是扩展 AI Agent 能力的重要接口。
依赖项:
- J-link 驱动
- Windows 系统: C++ 运行库 Microsoft Visual C++ Redistributable

在官网下载可执行文件:nRF Util。

然后把 nrfutil 所在目录添加到 PATH 环境变量:


常用命令:
1 | |
如果你的环境不能联网,可以先在有网络的电脑安装子命令,然后用U盘导出到不能联网的电脑,见:nrfutil 离线安装方法。
子命令通常都支持 --help 参数,可以帮助你学习这个命令的用法。
其中,
completion子命令是用来帮助你安装命令自动补全脚本。这样以后敲 nrfutil 命令,按 Tab 键就能补全子命令,非常方便。以 powershell 为例:
1
2
3
4
5
6
7
8
9PS C:\Users\Jayant> nrfutil completion install powershell
Add the following to your $PROFILE file:
# From nrfutil completion install
# WARNING: nrfutil tab-completion may become slow because of Windows Defender
if ( Test-Path -Path ${env:USERPROFILE}\.nrfutil\share\nrfutil-completion\scripts\powershell\setup.ps1 ) {
. ${env:USERPROFILE}\.nrfutil\share\nrfutil-completion\scripts\powershell\setup.ps1
}对于 Linux 系统,执行
nrfutil completion install bash或者nrfutil completion install zsh,把输出的脚本配置复制到对应的~/.bashrc或者~/.zshrc中即可。命令结果提示我们,把命令行输出的内容粘贴到
$PROFILE文件中,也就是~\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1。安装了 VS Code 的情况下,可以这样打开此文件:
1code $PROFILE另外如果你是首次设置 Windows Powershell 脚本,需要修改注册表使其允许执行脚本:
1
2#在终端中执行
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned在那之后,重新打开终端。随意输入nrfutil的命令,只输入一半按TAB键,就可以看到自动补全候选项了:
nRF Connect For Desktop
访问下载页面:https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop

下载并安装最新版本,进入设置,打开中国大陆服务器软件源:

然后安装自己需要的软件即可,可以先安装这三个最常用的:

如果你的电脑不能联网,可以先在可以联网的电脑上安装nRF Connect for Desktop。然后导出离线文件,再导入到不能联网的电脑上。见:
VS Code + nRF Connect 插件
从官网安装:Visual Studio Code
VS Code的插件可以在VS Code插件市场搜索 nRF Connect for VS Code Extension pack 来一次性安装所有需要的插件。

如果你需要 CMake 语法高亮,可以安装 CMake - twxs插件:

注意,不要安装 CMake Tools - Microsoft,这个会一直弹窗让你选择 CMakeLists.txt 文件和编译器,在 Zephyr 中都是不需要的。如果你电脑上其他项目需要这个插件,可以单独在 NCS 的 workspace 中禁用这个插件,见后续章节。
如果你还需要远程开发,比如 SDK 安装在远程服务器或者虚拟机中的情况,可以在本机安装 Remote 插件:

如果你的电脑不能联网,需要离线安装插件。参考以下内容:
[点击展开]
先在有网络的电脑上下载VSIX离线插件文件:
注意这个插件包只是个合集。合集里的每一个插件都要单独下载VSIX,并选择平台:
然后,拷贝到不能联网的电脑上导入即可:
Linux USB 规则
对于 Linux 环境,需要安装:
1 | |
其他工具
以下工具在 toolchain 中已经打包了。但是在本机环境中直接安装,使用起来会更加方便,后续可以按需考虑安装。
3. 安装编译工具链和SDK
Zephyr 官方教程是把各种工具(python, cmake, ninja, gcc, git 等)直接安装到系统环境,再分别安装Zephyr工具链包(主要是编译器)和 SDK 源码包,设置 PATH 环境变量。一台电脑只安装一个环境。
NCS 的工具链是上述工具 + Zephyr 工具链包的合集,放在一个单独的目录内,而不是默认的全局 PATH 环境变量。因此可以实现一台电脑上安装多个版本的工具链和 SDK,并且互不影响。
方式一(推荐):从压缩包自动安装
Toolchain 和 SDK 是独立的文件夹。Toolchain 目录包含编译工具链,与电脑上本身的 PATH 软件环境不冲突;SDK 包含源码、脚本、预编译库等。
Nordic 在对象存储服务器上提供了 Toolchain 和 SDK 的压缩包,方便用户下载加速。
可以通过 nrfutil sdk-manager 或者 nRF Connect for VS Code 插件直接下载。
默认安装路径为:
- Windows:
C:\ncs - Linux:
~/ncs - macOS:
/opt/nordic/ncs/
目录结构:
1 | |
电脑上可以同时安装多个版本的 toolchain 和 SDK。toolchains/目录下是工具链,vX.Y.Z/格式的目录下是 SDK 源码。
tmp/下是解压过程中的临时文件,会自动清理干净。
downloads/下是工具链和 SDK 的原始压缩包,不会自动清理。其中,SDK 的压缩包可以拷贝到其他电脑 NCS 安装路径的 downloads/ 目录下,这样其他电脑安装时就会跳过下载,直接解压;而 toolchain 的压缩包只能分享给相同 CPU 架构的电脑中(Windows, Linux ARM64, Linux AARCH64, macOS 互不相同)。
修改默认安装路径
如果你要修改默认安装路径,则 nrfutil 和 VS Code 插件都要修改。
macOS 不能修改默认安装路径。
Windows 注意事项:
- 建议全英文路径,不能有空格;
- Windows 有路径长度限制,目录层级不能太深,建议就是
D:\ncs,E:\ncs等等;- 后续开发工程存放的磁盘必须和 NCS 在同一个磁盘。
nrfutil:
1 | |
VS Code:

下载并安装
可以用 nrfutil 安装,也可以用 VS Code 安装,二选一。
用 nrfutil 安装
1 | |
--region cn :指定中国大陆服务器。
1 | |
用 VS Code 安装
首先设置中国大陆服务器源:

首次安装界面:

非首次安装界面:

选择 nRF Connect SDK:

另外一个是裸机 SDK,仅支持 nRF54L 系列,仅支持 BLE 开发。只适合 nRF5 SDK 历史包袱较重的公司或开发者临时过渡使用。
选择要安装的版本:

【注意】
右上角 “Pre-packaged” 标记代表从 Nordic 服务器下载,速度较快。而 “GitHub” 标记表示从 GitHub拉取,速度很慢。
LTS 是长期支持(Long-Term Support)。
Nordic 承诺从 v3.4.0 开始提供 5 年保证的长期支持版本。在支持期内:
- 持续修复安全漏洞和关键 Bug。
- LTS 将只会从 Zephyr 上游代码库中拉取关键 patch,包括安全修复和新的 boards 支持。会造成应用层代码破坏性修改的feature 将被跳过。
- 用户在 LTS 内升级小版本时(v3.4.1, v3.4.2, …),无需修改应用层代码和配置方式(除非安全修复必须包含破坏性修改)。
LTS 方便客户开发需要长期维护的产品,或需要应对欧盟网络弹性法案(CRA)等合规要求的场景。
选择安装路径:
由于前面已经设置了D:\ncs安装路径,这里自动识别了正确位置,直接回车安装即可。

查看安装进度:
在 Output 标签页下,选择 nRF Connect 插件日志,即可查看安装进度和日志:

等待安装完毕。
方式二:从 GitHub 拉取或者更新
虽然 Nordic 提供了压缩包下载,但还是有必要了解 Zephyr 标准的源码管理方式。
这种方式是从 GitHub 拉取,无法受到国内镜像源加速,但可以精确切换到某个特定 commit 。确保你能稳定访问 GitHub 并拉取仓库再考虑此方式。
如果你的需求是切换到某个特定的 commit, 也可以先用前面的压缩包方式下载一个最接近的版本,再用本节介绍的方法更新过去,这样只需要差分下载。
NCS 项目结构:
NCS 项目托管在 GitHub,由多个仓库组成。其中既有 Nordic 自己的代码仓库,也有上游开源仓库的 Fork 副本。Nordic 会持续开发优化,并贡献给开源社区,同时也从开源项目获取新功能。
其中,主仓库是 sdk-nrf。主仓库的版本就是 NCS 版本。每个主仓库中会通过
west.yml文件记录其他子仓库的 GitHub 地址和版本,这样就可以用west命令一次性拉取全部仓库。此外,一些特殊的功能仓库(如 Edge AI,Apple Find-My,Garmin ANT+ 等)有自己的版本发布节奏,不会和 sdk-nrf 保持一致。这种情况下,这些仓库作为主仓库,然后 west 命令可以进一步拉取其指定版本的 sdk-nrf, sdk-zephyr 等其他仓库,这种情况下安装的就不是标准版 NCS 了,见《nRF Connect SDK Add-ons介绍与国内安装实践》。
安装工具链
SDK 可以从 Github 拉取,但工具链仍然要使用 Nordic 提供的压缩包。这里只单独安装工具链,不安装 sdk。
如果想要修改安装路径,记得先按照方式一中的步骤进行修改。
默认安装路径为:
- Windows:
C:\ncs- Linux:
~/ncs- macOS:
/opt/nordic/ncs/,不允许修改。
使用 nrfutil 的方式:
1 | |
使用 VS Code 的方式:

打开工具链环境
后续需要在 toolchain 环境中进行操作。
nrfutil 打开工具链环境
1 | |
1 | |
会弹出一个新的终端窗口,包含 toolchain 环境变量。
VS Code 打开工具链环境

默认情况下打开 toolchain 环境时,要同时指定 SDK 版本和 toolchain 版本。但是这里我们只是要安装新的 SDK,直接跳过 SDK 选择:

然后选择刚刚安装的 Toolchain 版本:

打开的工具链环境:

验证工具链环境
查询 git 命令的路径:
1 | |
1 | |
1 | |
可以发现默认使用的 git 命令是 toolchain 文件夹内的实例,而不是系统默认软件安装路径里的。
从 GitHub 安装 NCS
预期的目录结构:
1 | |
新安装SDK:
1 | |
- 这一步包含一次
git clone,并且会创建.west/配置文件夹。在 Windows 资源管理器内,.开头的都是隐藏文件夹。- 这一步如果下载失败想重新下载,需要把创建的 v3.4.0 文件夹下的所有内容删除干净,尤其是
.west/隐藏文件夹。然后再次执行前面的west init ...即可
主仓库 nrf 拉取成功后,继续安装其他仓库,会自动同步到 nrf/west.yml中记录的版本:
1 | |
由于国内网络的原因,这一步也经常失败,但是没关系,
west update本质上是多次git fetch,支持断点续传。如果失败了,就重复west update就行了。不需要像west init失败一样删除干净重新下载。可以用个脚本循环执行,直到
west update无报错。
1 | |
这个操作的目的是把 SDK 的安装位置注册到操作系统:
- Linux/macOS:写入
~/.cmake/packages/Zephyr- Windows:写入注册表
HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\Zephyr这样,后续开发独立工程(Freestanding Application,源码在 SDK 外部)时,工程 CMakeLists.txt 里的
find_package(Zephyr)才能找到 SDK 位置。电脑上安装多个 SDK 时,这些注册是独立的条目,不会互相冲突。
切换SDK版本(更新或回退)
按照以下步骤操作:
-
进入 NCS 下的 nrf 仓库
1
cd nrf -
确保 SDK 中的 git 仓库状态均为 clean
1
2# 此命令可查看当前git仓库的状态
git status但是 NCS 中的仓库很多。也可以用 VS Code 打开整个 NCS,用 git 界面图形化查看是否每个仓库均为 clean。
一般来说,开发者不要随便改动 SDK 中的代码和配置,否则在切换版本的时候可能出问题。
-
检查 manifest 有无新版本
NCS 中,nrf 为主仓库,nrf 的版本即为整个SDK的版本1
2
3# 查看nrf仓库下有多少版本
git fetch
git tag # 按键盘上下键翻阅,按q退出 -
切换到自己想要的版本
1
2
3
4
5# 检出想要的主仓库nrf版本
git checkout v3.4.0
# 更新nrf之外的整个NCS仓库
west update
当使用 nRF Connect SDK Add-ons 时,也是类似的步骤。只不过主仓库不再是
sdk-nrf,而是对应的 Add-ons 仓库。
中文 Windows 环境修复编码问题修复
仅中文 Windows 系统 用户需考虑此问题,英文 Windows 系统或 Linux/macOS 无需考虑
在较老的 NCS 版本中(低于 v3.2.x),部分 Python 脚本在读取文件的时候会用操作系统默认语言读取,导致 python 用 gbk 来读取 utf-8 的配置文件,进而导致编译失败。需要修改SDK脚本使其强制使用 utf-8。
[点击展开]
NCS v3.1.0/v3.1.1修复
问题:pm_static.yml 无法写中文注释
v3.1.1\nrf\scripts\partition_manager.py 需修改三处
① 第683行:
1 | |
改为:
1 | |
② 第911行:
1 | |
改为
1 | |
③ 第985行:
1 | |
改为
1 | |
问题:部分 Matter 例程无法编译
需修改2处
① 在 v3.1.1\modules\lib\matter\scripts\codegen_paths.py 第 80 行:
1 | |
改为:
1 | |
② 在v3.1.1\modules\lib\matter\scripts\codegen.py 第 119 行:
1 | |
改为
1 | |
v3.1.x报错示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56-- Configuring done
-- Generating done
-- Build files have been written to: D:/Project/peripheral_uart_dfu_1/build/peripheral_uart_dfu_1
-- Found partition manager static configuration : D:/Project/peripheral_uart_dfu_1/pm_static.yml
Traceback (most recent call last):
File "D:\ncs\v3.1.1\nrf\scripts\partition_manager.py", line 1054, in <module>
main()
File "D:\ncs\v3.1.1\nrf\scripts\partition_manager.py", line 1024, in main
static_config = load_static_configuration(args, pm_config) if args.static_config else dict()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\ncs\v3.1.1\nrf\scripts\partition_manager.py", line 985, in load_static_configuration
static_config = yaml.safe_load(args.static_config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\ncs\toolchains\c1a76fddb2\opt\bin\Lib\site-packages\yaml\__init__.py", line 125, in safe_load
return load(stream, SafeLoader)
^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\ncs\toolchains\c1a76fddb2\opt\bin\Lib\site-packages\yaml\__init__.py", line 79, in load
loader = Loader(stream)
^^^^^^^^^^^^^^
File "D:\ncs\toolchains\c1a76fddb2\opt\bin\Lib\site-packages\yaml\loader.py", line 34, in __init__
Reader.__init__(self, stream)
File "D:\ncs\toolchains\c1a76fddb2\opt\bin\Lib\site-packages\yaml\reader.py", line 85, in __init__
self.determine_encoding()
File "D:\ncs\toolchains\c1a76fddb2\opt\bin\Lib\site-packages\yaml\reader.py", line 124, in determine_encoding
self.update_raw()
File "D:\ncs\toolchains\c1a76fddb2\opt\bin\Lib\site-packages\yaml\reader.py", line 178, in update_raw
data = self.stream.read(size)
^^^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 8: illegal multibyte sequence
CMake Error at D:/ncs/v3.1.1/nrf/cmake/sysbuild/partition_manager.cmake:179 (message):
Partition Manager failed, aborting. Command:
D:/ncs/toolchains/c1a76fddb2/opt/bin/python.exe;D:/ncs/v3.1.1/nrf/scripts/partition_manager.py;--input-files;D:/Project/peripheral_uart_dfu_1/build/peripheral_uart_dfu_1/modules/nrf/subsys/partition
_manager/pm.yml.settings;D:/Project/peripheral_uart_dfu_1/build/peripheral_uart_dfu_1/modules/nrf/subsys/partition_manager/pm.yml.bootconf;D:/Project/peripheral_uart_dfu_1/build/mcuboot/zephyr/include
/generated/pm.yml;D:/Project/peripheral_uart_dfu_1/build/mcuboot/modules/nrf/subsys/partition_manager//generated/pm.yml;D:/Project/peripheral_uart_dfu_1/build/mcuboot/modules/nrf/subsys/partition_manager/pm.yml.bootconf;D:/Project/peripheral_uart_dfu_1/build/peripheral_uart_dfu_1/zephyr/include/genera
ted/pm.yml;--regions;sram_primary;otp;bootconf;flash_primary;--output-partitions;D:/Project/peripheral_uart_dfu_1/build/partitions.yml;--output-regions;D:/Project/peripheral_uart_dfu_1/build/regions.y
ml;--static-config;D:/Project/peripheral_uart_dfu_1/pm_static.yml;--sram_primary-size;0x2f000;--sram_primary-base-address;0x20000000;--sram_primary-placement-strategy;complex;--sram_primary-dynamic-pa
rtition;sram_primary;--otp-size;1276;--otp-base-address;0xffd500;--otp-placement-strategy;start_to_end;--bootconf-size;4;--bootconf-base-address;0xffd080;--bootconf-placement-strategy;start_to_end;--f
lash_primary-size;0x165000;--flash_primary-base-address;0x0;--flash_primary-placement-strategy;complex;--flash_primary-device;rram_controller;--flash_primary-default-driver-kconfig;CONFIG_SOC_FLASH_NR
F_RRAM
Call Stack (most recent call first):
D:/ncs/v3.1.1/nrf/cmake/sysbuild/partition_manager.cmake:636 (partition_manager)
D:/ncs/v3.1.1/nrf/sysbuild/CMakeLists.txt:825 (include)
cmake/modules/sysbuild_extensions.cmake:598 (nrf_POST_CMAKE)
cmake/modules/sysbuild_extensions.cmake:598 (cmake_language)
cmake/modules/sysbuild_images.cmake:46 (sysbuild_module_call)
cmake/modules/sysbuild_default.cmake:21 (include)
D:/ncs/v3.1.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:75 (include)
D:/ncs/v3.1.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
D:/ncs/v3.1.1/zephyr/share/sysbuild-package/cmake/SysbuildConfig.cmake:8 (include)
template/CMakeLists.txt:10 (find_package)
-- Configuring incomplete, errors occurred!
See also "D:/Project/peripheral_uart_dfu_1/build/CMakeFiles/CMakeOutput.log".
?[91mFATAL ERROR: command exited with status 1: 'D:\ncs\toolchains\c1a76fddb2\opt\bin\cmake.EXE' -DWEST_PYTHON=D:/ncs/toolchains/c1a76fddb2/opt/bin/python.exe '-Bd:\Project\peripheral_uart_dfu_1\build
' -GNinja -DBOARD=nrf54l15dk/nrf54l15/cpuapp '-SD:\ncs\v3.1.1\zephyr\share\sysbuild' '-DAPP_DIR:PATH=d:\Project\peripheral_uart_dfu_1'
NCS v2.9.0/v2.9.1/v2.9.2修复
需要修改v2.9.0\zephyr\scripts\list_boards.py。否则无法编译。
1 | |
改为
1 | |
v2.9.x 报错示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25CMake Error at C:/ncs/v2.9.0/zephyr/cmake/modules/boards.cmake:196 (message):
Error finding board: nrf52840dk
Error message: Traceback (most recent call last):
File "C:\ncs\v2.9.0\zephyr\scripts\list_boards.py", line 469, in <module>
dump_v2_boards(args)
File "C:\ncs\v2.9.0\zephyr\scripts\list_boards.py", line 416, in dump_v2_boards
boards = find_v2_boards(args)
^^^^^^^^^^^^^^^^^^^^
File "C:\ncs\v2.9.0\zephyr\scripts\list_boards.py", line 341, in find_v2_boards
b, e = load_v2_boards(args.board, board_yml, systems)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\ncs\v2.9.0\zephyr\scripts\list_boards.py", line 230, in load_v2_boards
b = yaml.load(f.read(), Loader=SafeLoader)
^^^^^^^^
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa2 in position 46:
illegal multibyte sequence
Call Stack (most recent call first):
cmake/modules/sysbuild_default.cmake:15 (include)
C:/ncs/v2.9.0/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:75 (include)
C:/ncs/v2.9.0/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
C:/ncs/v2.9.0/zephyr/share/sysbuild-packag
Windows 环境错误 git 状态清理
【注意】2025.10.14开始,nrfutil sdk-manager v1.8.0 已经修复了此问题。如果你是用最新的 nrfutil 安装的 NCS,应该不会遇到此问题。
解决方案是 nrfutil 会在 SDK 解压安装时,自动把所有 .git 记录修改,直接增加了
core.filemode = false
[点击展开]
2025.10.14 之前,nrfutil 压缩包自动安装(Pre-packaged)方式有个bug。由于 SDK 是在 Linux 环境下打包好的,在 Windows 下解压,会出现部分文件的权限从 755 强制转换为644,导致 git 状态不是 clean,有大量文件被视为修改:


经过实测,必须在每个 git 子仓库都忽略文件权限的变化。
打开 nRF Connect 命令行:

进入SDK根目录,执行以下内容:
1 | |
这是给 NCS 的每个代码仓库,以及每个仓库的子仓库都递归执行 git config core.filemode false,从而忽略文件的变化。
处理完毕后,Git 状态变干净了:

4. 打开并浏览例程
从VS Code 的一个全新窗口,选择打开文件夹:

打开整个SDK目录,这样做是为了看代码跳转时,SDK中的代码也能跳转到:

然后在VS Code中再打开一个例程:

NCS中所有例程的位置:
1
2
3
4
5
6
7
8NCS
|-- nrf
| |-- applications/ # Nordic 商业级例程
| |-- samples/ # Nordic 外设、蓝牙、LTE等例程
| |-- tests/ # 组件 API 测试例程
`-- zephyr
|-- samples # Zephyr Kernel、各类板子、各类传感器芯片例程
`-- tests # 组件 API 测试例程
zephyr/samples/中有RTOS的组件例程、Zephyr支持的各类厂商的板卡例程、各类传感器的例程等,其中也有蓝牙例程。
zephyr/tests/中有全部的API测试例程。
nrf仓库的目录结构仿造zephyr仓库,也有samples/和tests/目录。samples/中有Nordic提供的软件库例程、Zephyr未收录的例程(如 nRF9160的LTE)等。
我们选择 v3.4.0\nrf\samples\bluetooth\peripheral_uart

编译例程的方式,参考后续章节。
注意 Windows 有最大路径名长度限制。对于一些依赖路径比较深的工程,再叠加上 build 目录下还有源码层级结构,会编译失败。有 2 种解决方法:
- 参考下一章节“以例程为模板创建新工程”,并把工程放到更浅的路径。
- 在编译时,用
-d参数指定 build 目录到更浅的层级。例如:
1west build -b nrf54l15dk/nrf54l15/cpuapp -d D:\ncs\build nrf/samples/bluetooth/peripheral_uart工程路径是
nrf/samples/bluetooth/peripheral_uart,build 路径是D:\ncs\build。
5. 以例程为模板创建新工程
上一节讲解了如何打开一个例程。
如果我们只是打开例程,例程的文件夹还是在 NCS 仓库内部,受到 NCS 的 git 仓库的管理。如果想自己用 git 管理自己项目的版本,就需要创建新工程。
NCS 支持把例程当作模板,复制到 NCS 外部,并创建新工程。这种独立在 SDK 外部的工程在 Zephyr 中叫做 freestanding 工程。
新建工程还有一个用处:Windows上有目录名长度限制。在一些路径比较深的例程里进行编译时,会出现长度不足导致编译系统报错找不到某个SDK文件的情况。因此,把例程作为模板拷贝到比较浅的目录中进行开发,可以避免此问题。
Linux,MacOS 则没有这个问题。
5.1. 创建新工程
NCS支持以例程作为模板,复制并创建新的工程。这也是Nordic非常推荐的方式。
首先在VS Code中打开一个新窗口

在 VS Code 中,选择左侧 nRF Connect for VS Code 插件,进入 Welcome 页面。然后点击 Create a new application 创建新工程。

选择要使用的 SDK 版本:

选择 “Copy a sample”

选择自己想要拷贝的例程,支持文字搜索:

这里选择nrf/samples/bluetooth/peripheral_uart
这里的例程列表,和第 4 节中提到的目录结构是一致的。同时也和NCS官网的例程说明文档是保持一致的,下图位置打开官网文档:
Nordic商业级应用:https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/applications.html
Nordic例程:https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples.html
Zephyr例程:https://docs.nordicsemi.com/bundle/ncs-latest/page/zephyr/samples/index.html
此外,还有一些模块的例程不会出现在这个界面,但是可供参考:
${NCS}/modules/hal/nordic/nrfx/samples/src/: NRFX外设驱动库例程。如果用户不想用、或者Zephyr没有提供某些外设的标准驱动,则可以使用NRFX驱动,其用法和老的nRF5 SDK基本一致。${NCS}/zephyr/tests:zephyr所有的API的测试用例。如果你不知道某个Zephyr API怎么用,可以从这里面找。
选择自己新建工程的位置,注意:Windows上,freestanding 工程必须和 SDK 在同一个磁盘:

然后就可以打开新的工程。
5.2. 添加 Workspace
独立工程已经可以编译了,但是编译完看代码时,按 Ctrl + 鼠标左键 跳转的代码在 SDK 内部,无法直接跳过去。这里需要把 SDK 和当前工程添加到同一个 VS Code Workspace 中。
选择添加文件夹到 Workspace

直接把整个NCS和当前工程添加到同一个Workspace中:

保存当前workspace:

下次打开时,只需双击 .code-workspace 文件,就能直接打开整个 workspace

最后记得修改.gitignore文件,这样你和其他人协助开发时这些文件就各自使用自己电脑上的配置,不会互相干扰:

5.3. 清理 Workspace 插件
可能你的 VS Code 里还安装了其他厂商的插件,或者一些 VS Code 推荐安装的插件。开发NCS时,某些插件会不断弹窗报错,非常烦人。
这时你可以用 VS Code 的 workspace 功能来局部关闭这个插件。
目前版本 NCS 的插件包只需要这六个插件:


因此你在 workspace 里可以关掉其他不必要的插件。举例来说,微软的 “CMake Tools” 插件会一直弹窗询问 CMake 根目录文件在哪里:

我们不需要它来帮助解析 CMake 。直接在插件页面单独关掉它:

如此一来,只在当前 workspace,这个插件就被关闭了。同理,其他插件也可以这样关闭,你不再会受到这些插件打扰。同时,在其他 workspace,不影响你继续正常使用那些插件。
6. 编译工程
6.1. nRF Connect for VS Code 编译
创建一个编译目标(Build Target)
所谓编译目标就是在同一套代码下,可能根据不同的配置项(Debug / Release,不同的优化级别, 不同的工作模式等等),编译出不同的可执行文件。一个项目下可以创建多个编译目标。
编译过程中的所有中间产物,和最终的固件都存放在这个编译目标的目录下。

选择 Toolchain 和 SDK 版本
在 build 界面设置 Toolchain 和 SDK 版本:

选择 Board Target

创建Build时,需要选择自己使用的板子,Zephyr自带许多厂商的开发板配置。
上图中,Board target 下拉框是用来选板子的,下方还有几个过滤器,来过滤可选的板子:
-
Compatible boards:本例程适配的板子,是经过验证的。如果选择这些板子,不需要任何修改就可以烧录进去使用
-
Nordic SoC:使用了 Nordic SoC 的板子,不一定是 Nordic 开发板
-
Nordic Kits:Nordic 出品的官方开发板
-
All boards:Zephyr 中所有的板子
黄色感叹号(⚠️)表示这个板子对应的 SoC 支持 TrustZone 硬件隔离,而我们选择了不使用。普通的应用就这样选没问题。
简单介绍安全隔离特性:
SoC 的外设和核心寄存器地址空间被分为两个部分,安全空间和非安全空间(ns)。如下图深蓝色为非安全空间可访问的资源(不包含关键资源),浅蓝色为只有安全空间可访问的资源(包含关键资源)。部分外设可以通过两个空间访问,地址不同。
如果你的 board target 是
cpuapp这种,应用程序就是直接跑在安全空间; board target 是cpuapp/ns这种,应用程序就运行在非安全空间。如果应用程序直接跑在安全空间,就和普通的单片机开发架构类似,应用程序可以访问所有寄存器和 NVM 地址。简单的传感器采集、BLE 透传等应用直接使用安全空间开发,最简单,是非常合理的选择。
如果应用程序跑在非安全空间,就需要一个单独的安全固件(Trusted Firmware-M, TF-M)跑在安全空间,负责保管非对称加密的私钥等信息,并提供 Root of Trust, Secure Boot, Secure Storage 等服务。即使你的非安全空间应用程序被漏洞攻破(通过内存踩踏等方式),ARM TrustZone 硬件隔离机制能保证秘密信息不被获取。因为非安全空间无法单纯靠地址获取到安全空间的信息,这是硬件架构保证的。
Board target 实际是为固件编译服务的,它包含固件编译所需的硬件信息。因此前面是板子名称,后面是 SoC 和 CPU名称,以及地址空间名称。
Zephyr Board target 配置的命名规则:
举例:
nrf52840dk/nrf52840,是说这个 target 是为 nRF52840DK 这块开发板上的 nrf52840 这颗 SoC 创建的。nrf9160dk/nrf9160和nrf9160dk/nrf52840,都是 nRF9160DK 这块开发板的配置。但是这块开发板上有两颗 SoC,一颗是9160 SiP,另一颗是nrf52840。所以有两个配置可选,分别是为这两颗 SoC 编译固件。nrf5340dk/nrf5340/cpuapp和nrf5340dk/nrf5340/cpunet,都是 nRF5340DK 这块板子的配置,并且这块板子上只有 nRF5340 这一颗SoC。但是 nRF5340 是一颗双核 SoC,所以,可以有两种配置来区分两个 CPU 核。这两个 CPU 核的固件是分开运行的,因此编译时也是分别编译的。nrf54l15dk/nrf54l15/cpuapp和nrf54l15dk/nrf54l15/cpuapp/ns。前面已经介绍过,表示同一板子、同一 SoC、同一 CPU,但是选择是否使用TrustZone 技术。当你选择/ns版本时,Zephyr 会自动启用 TF-M 作为安全空间固件。nrf54l15dk/nrf54l10/cpuapp。nRF54L15 / L10 / L05 是 pin to pin 封装,基本只有存储容量的区别,但是 Nordic 只出了 nRF54L15 的开发板。选择这个选项在编译固件时,会保留开发板上的引脚分配,但是 SoC 会按照 54L10 的资源进行分配,方便开发者用开发板评估 L10 和 L05。更详细的信息可参考:《理解Zephyr编译与配置系统》。
如果你想针对不同 Board target 编写 CMake 规则脚本,有以下变量可以获取代表当前编译的信息:
1
2
3
4
5
6
7
8
9
10
11
12
13># Board name, like "nrf54l15dk"
>${BOARD}
># Board qualifiers, like "/nrf54l15/cpuapp"
>${BOARD_QUALIFIERS}
># board target name, like "nrf54l15dk/nrf54l15/cpuapp"
>${BOARD}${BOARD_QUALIFIERS}
># 下划线形式,常用于匹配配置文件
># 例如 ${NORMALIZED_BOARD_TARGET}.conf
># 对应 nrf54l15dk_nrf54l15_cpuapp.conf
>${NORMALIZED_BOARD_TARGET}
配置文件
各种配置文件、追加配置文件,具体可参考《理解Zephyr编译与配置系统》:

编译选项
可以设置Build目录,优化等级等等。Sysbuild可参考《理解Zephyr编译与配置系统》,NCS v2.7.0 引入,v2.8.0 起默认启用。

6.2. 命令行编译
命令行编译常用于服务器 CI/CD 环境、脚本、AI 辅助编程。在使用命令行编译之前,一定要确保已经进入了工具链环境。
工具链环境
前面章节已经介绍了如何“打开工具链环境”。其中,VS Code 中的命令行环境,已经设置好全部的环境变量了,无需额外操作。不过,这都是让人来继续后面的操作。
这种另开的终端对于脚本或者 AI Agent 使用起来不方便。我们还是希望在当前命令行环境中直接设置环境变量。
并且,nrfutil 的方式只会设置 Toolchain 相关环境变量(PATH),还缺少 ZEPHYR_BASE 环境变量。
有时如果你发现
west help展示的命令列表里面没有west build,west flash等扩展命令,就是因为缺少ZEPHYR_BASE变量,找不到 west 工作区。工作区类型:
- Zephyr Workspace:例如 v3.4.0 目录。顶层有一个
.west/目录,里面记录了ZEPHYR_BASE的相对路径。当你直接在 v3.4.0 内的任意子目录内执行west命令时,都能自动识别。- freestanding:如果你当前目录在 West 工作区外部,必须手动指定
ZEPHYR_BASE环境变量。
最方便的做法是直接导出一个环境变量设置脚本,然后直接在当前终端设置新的环境变量。
参考以下命令:
1 | |
1 | |
1 | |
参考 AI Skills 提示词:nrf-connect-skills-ZH_CN/zephyr-build/SKILL.md at master · Jayant-Tang/nrf-connect-skills-ZH_CN
验证:
1 | |
有west命令能执行,说明 Toolchain 的PATH设置成功;west topdir有输出,说明 SDK 的ZEPHYR_BASE设置成功。
【单条命令】
如果你只是想执行1条命令,可以用:
1nrfutil sdk-manager toolchain launch --ncs-version=<version> -- <command>例如:
1nrfutil sdk-manager toolchain launch --ncs-version=v3.4.0 -- west help这个会启动单独进程来执行命令。不过这个也是没有
ZEPHYR_BASE环境变量的,可以用--chdir直接跳到 SDK 内部来规避 freestanding 的情况。
1
2
3nrfutil sdk-manager toolchain launch --ncs-version=<version> \
--chdir <ncs-install-dir> -- \
west build -b <board_target> -d <abs-build-dir> <abs-app-dir>
编译命令
| 目的 | 命令(当前终端完成环境初始化后直接执行) |
|---|---|
| 新建或重配构建 | west build -b <board_target> -d <selected-build-dir> <app-dir> |
| 复用已选 build 目录 | west build -d <selected-build-dir> |
| pristine 构建 | west build -p always -b <board_target> -d <selected-build-dir> <app-dir> |
| 显式启用 sysbuild | west build -b <board_target> -d <selected-build-dir> <app-dir> --sysbuild |
| 显式禁用 sysbuild | west build -b <board_target> -d <selected-build-dir> <app-dir> --no-sysbuild |
| 交互式 Kconfig | west build -t menuconfig -d <selected-build-dir> |
| 内存占用报告 | west build -t ram_report -d <selected-build-dir> / rom_report |
| 列出开发板 | west boards |
其中,<app-dir>可以省略,省略的话就是当前目录./。
编译命令示例:
1 | |
更多用法:
1 | |
6.3. 编译结果
在 VS Code 中,按Ctrl + ~,可以呼出终端。编译完毕后可以看到结果。

如果后续要再次编译这个target,可以在APPLICATIONS栏选中自己要构建的工程和target。然后在ACTIONS栏通过build按钮进行项目的构建。
按Build旁的圆圈箭头按钮,可以全部重新编译(pristine 构建)。
编译时,如果你选中build/上下文,会编译全部固件,如果有 bootloader 的话也会一起编译。
如果只选中 build/peripheral_uart上下文,则只会编译这个application 固件。
这个上下文选择非常重要。 Kconfig配置、设备树、烧录按钮等都受到这个上下文选择的影响。

6.4. 编译输出文件
一个工程可能有多个固件,这里以 Matter 窗帘举例。有 Bootloader 和 application。
这里选中哪个子工程,看的就是哪个子工程的输出。如window_covering就是application子工程。然后下方output files就可以看到输出文件。

其中比较重要的:
.config是所有配置项合并后的最终配置列表。当你想确认某个配置是否真的打开/关闭了,可以查看这个文件zephyr.dts是所有设备树文件合并后的最终设备树。当你想确认某个节点最终配置是什么,可以查看这个文件merged.hex:application + bootloader的合并固件。zephyr.elf:单独application的固件,并含有调试信息。在它同一目录下,有zephyr.hex是纯固件。
6.5. 内核一览

目前Core overview可以看到初始化级别和已经使能的中断。
Initialization levels
Zephyr系统中,在main函数之前,会有5个级别的初始化等级。在这些不同的初始化等级时,会执行不同的函数,例如各种外设驱动的初始化、内核服务的初始化等。在这里可以看到这些函数的执行顺序,以及它们被定义的位置。
Enabled Interrupts
可以看到哪些硬件中断被打开了。

7. 连接设备
只需通过一根 USB 线连接,左上角电源开关打开:

“VDD CURRENT MEASURE” 是 SoC VDD 供电通路,可以测量电流。不测量时,要接好跳线帽。
USB 旁边的 “DEBUGGER” 芯片是 Interface MCU,除了充当 J-Link 之外,还作为 UART 转 USB 虚拟串口、电子开关主控。
Interface MCU 可以用 nRF Connect for Desktop 中的 Board Configurator 上位机来配置:


通过控制电子开关,Interface MCU 可以管理 SoC 的 GPIO 是否连接到对应的虚拟串口、LED、SWD、外部 QSPI Flash 等等。本例程保持默认即可。
nRF54 系列开发板还能精确调节供电电压,这是由板载的 nPM1300 PMIC 实现的。
这个 PMIC 只被 Interface MCU 控制,因此不能用来开发。
然后就可以在 VS Code 中识别到设备了:

或者用 nrfutil 查看设备:
1 | |
最新的开发板一般有两个虚拟串口。通常 Vcom 1 对应的是例程默认串口,用于日志、透传或者shell;Vcom 0 通常不使用,或者用于其他功能(DFU、Modem Trace、TF-M Log、网络核的 Log)。
这两个 vcom 连接的是 SoC 上固定的引脚,而不是对应
&uart20这样的外设。只不过&uart20的 Devicetree 默认引脚连接在 Interface MCU 的 vcom 1 而已。引脚都是可以修改的。
老版本 DK:

以 nRF52840DK 为例,中间最大的带有贴纸的芯片是Interface MCU,左侧为 J-Link USB口,此接口可以用来给整块板供电。
需确保左下角电源开关打开。左侧中间位置的开关置于 VDD 挡位,右上角开关置于 DEFAULT 挡位(如上图)。
对于一些有多颗 MCU 的开发板,注意要使用拨码开关选择自己要调试的MCU,例如 nRF9160DK 可选择 9160 和 52840:

8. 烧录固件
连接并成功识别到Jlink后,可以通过ACTIONS栏中的Flash按钮触发烧录动作:

也可以通过命令行进行烧录:
1 | |
有时可能会要求全片擦除,可能的原因:
- 当前固件包含 UICR ,可以认为是一块特殊的 flash 区域,存储了客户自己的加密密钥、引脚配置等信息。要求必须全片擦除才能烧写。
这种情况下只能全片擦除然后再烧录,点击Flash右边的按钮:
或者使用命令行方式:
1west flash --force --erase此外,有时可能会要求 recover,可能的原因:
- 之前的固件启用了 Flash 写保护,尤其是带 mcuboot 的项目,通常会开启 FPROTEDCT 保护 mcuboot 区域。
- 之前的固件开启了调试接口保护
需要 recover 这颗芯片来解除保护,才能写入新固件。
注意,recover 也会擦除全部固件和 UICR。
通常,VS Code 右下角会有弹窗来问你是否要 recover。
也可以用命令行来 recover
1>nrfutil device recover如果是 nRF5340 这种双核芯片,那么网络核要先 recover
1
2>nrfutil device recover --core Network
nrfutil device recover --core Application
9. 运行并测试
连接的设备,可以看到主控芯片、串口以及RTT。

这里的串口是 SoC 上真实的物理串口,在开发板上通过 PCB 走线连接到 J-Link,然后 J-Link 把这个串口映射为 USB 虚拟串口。老款开发板可能只有 1 个 VCOM。
9.1. 连接串口
可以在 VS Code 中连接,一般 VCOM1 对应的是例程默认串口:

也可以用 nRF Connect for VS Code 的串口终端:


VS Code 里的串口终端默认是 Shell 模式,类似 PuTTY。按下键盘的按键就立即发送出去一个字符,不会显示自己发出了什么。便于在这个串口上运行 uart shell。
在操作 uart shell 时你能看到输入的命令,是因为 shell 回显了你输入的字符。
nRF Connect for Desktop 里的串口助手两种模式都支持(如上图)。如果是 Line 模式,需要在上面输入要发送的内容,然后按 “Send” 按钮才会发送。
按下板子上的 Reset 按钮,就能看到串口启动 banner:

9.2. 连接RTT
RTT 是 Segger 提供的日志调试手段,全称 Real-Time Transfer。SoC 将日志打印到内部缓存中,然后利用 J-Link的高速通道,把日志显示到电脑上。这个方法不需要占用串口外设,而且速度极快,对 CPU 运行影响小。
大多数例程的默认日志输出是串口。但本例程是蓝牙串口透传,串口需要传输用户数据,因此本例程已经把日志的输出配置成 RTT 了,无需再额外修改配置。
要查看RTT日志输出的相关配置,打开工程根目录下的
prj.conf文件:
可以看到:
1
2
3
4
5CONFIG_LOG=y # 启用日志系统
CONFIG_USE_SEGGER_RTT=y # 启用RTT驱动
CONFIG_LOG_BACKEND_RTT=y # 日志后端选用RTT
CONFIG_LOG_BACKEND_UART=n # 日志后端不选用串口
CONFIG_LOG_PRINTK=n # PRINTK不从LOG输出(而是从console输出)
如下图再连接RTT:

选中应用核(Application):

能看到日志从 RTT 输出:

9.3. 测试 peripheral_uart 例程
一般来说,需要两块开发板,一块烧 peripheral_uart,一块烧 central_uart。两块开发板上电后会自动连接 BLE。从一个开发板串口输入的数据,会自动从另一个开发板输出。
但是这里我们只有一块开发板,那么 BLE Central 我们就用手机。iOS 应用商店可以下载 nRF Connect,安卓可以在谷歌商店下载,或者直接去Github下载APK。
由于苹果权限控制,iOS 版本的 App 是看不到 MAC 地址的。
通过BLE连接设备
以 iOS 为例,在 nRF Connect APP中,先 scan 搜索附近蓝牙。scan 按钮一开始是三角形,点击开始扫描后,变成方形。
扫到设备后,再连接:

开发板接收数据


可以在串口看到数据:

开发板发送数据
Central 和 Peripheral 是 GAP 层的概念。在 GATT层,BLE 协议是 Client-Server 架构。本例程是 BLE Peripheral,同时也是 GATT Server,只能被 Client 读写上面的 GATT 特征(Characteristic)。默认情况下,Server 不能主动发消息到 Client。除非 Client 使能了 Notify 的功能,Server 才能 Notify 到 Client。相关资料,大家可以搜索 CCCD(Client Characteristic Configuration Descriptor),这里不赘述。现在我们需要点亮 TX 属性的 CCCD,使能 Notify 功能:

然后在串口中通过键盘输入内容:hello + 回车。屏幕上不会显示东西,但是按键会发送出去。
VS Code 里的串口终端默认是 Shell 模式,按下键盘的按键就立即发送出去一个字符,不会在屏幕上显示自己发出了什么。
这里之所以要加回车,是因为例程代码是靠回车解析数据包的。在串口回调函数的状态机内,检测到回车,才会把串口数据打包从蓝牙发出。
可以在手机上看到开发板发过来的数据:

至此,我们完成了在 nRF54L15DK 上的peripheral_uart例程的编译、烧录与运行测试。
10. 阅读代码、跳转与搜索
工程中的函数与变量、Kconfig 配置、设备树都是可以Ctrl+鼠标左键点击跳转到定义的。为了能够确保跳转和搜索到 SDK 内部的代码,记得按照前面第 5.2 小节的方法,把 NCS 和当前工程添加到同一个 Workspace 中。
当一个工程编译完毕后,就可以在nRF插件中进行浏览了:

Source File 中是所有参与编译的源码,Zephyr 并不是把所有源码都添加,而是根据 Kconfig 选项,通过 CMake 条件添加源码。其中 Application 中的是当前工程中的源码;SDK 中的是NCS中参与编译的源码。Generated 中的是工具链自动生成的一些代码(中断向量表、Kconfig 转换成宏等等)。
由于我们前面已经把 SDK 放进了 VS Code workspace,所以也可以直接搜索代码:

点击上面的搜索按钮后,会自动跳转到 VS Code 搜索界面,并且已经自动填充好文件搜索范围:

这个功能在Windows上不好用,因为搜索范围过滤条件太多时,Windows 会无法处理,并且非常慢
在浏览和搜索的过程中,时刻注意自己选中的工程上下文是整个工程的 Build Target 还是子工程的 Build Target

以免影响后续的编译情况。
11. NCS Add-Ons
nRF Connect SDK (NCS) Add-ons 是一个公开可用的补充组件索引,旨在扩展 nRF Connect SDK 的功能。
功能与内容:Add-ons 提供了 SDK 标准包之外的多种功能,包括蜂窝应用程序(如Asset Tracker、Serial Modem)、驱动程序、库、协议实现(如 Amazon Sidewalk、Zigbee、ANT+)以及特定技术的完整 SDK。
独立性:Add-ons 有独立的发布周期,这使得新库可以更灵活地更新,而无需等待 NCS 主版本的发布。
可以参考:nRF Connect SDK Add-ons介绍与国内安装实践

12. Nordic AI 辅助编程
TechDocs 和 DevZone 网站右下角都有 Ask AI 按钮:

AI 训练了所有的 Nordic 官网资料,以及 DevZone 论坛中的帖子。可以用中文问他:


不过,网站访问有时候比较慢。即使你有代理,又可能遇到反爬虫保护,体验不是很流畅。
可以考虑让自己的 AI Agent 接入 Nordic MCP 知识库,这样用起来比较方便。参考:在AI辅助编程中接入Nordic知识库——Nordic MCP实战
13. 官方资料
Nordic TechDocs 资料中心
目前最新的资料中心,可以通过技术或产品系列进行分类,查找想要的资料。芯片数据手册(Specification)、开发板说明都可以在这里查看。

NCS 官网
https://nrfconnectdocs.nordicsemi.com/

进入官网,首先看到右上角可以选择文档的版本,需要与SDK的版本对应。
然后可以看到中间的一排标签页:
-
nRF Connect SDK: 对应的是NCS中的
nrf文件夹。是 Nordic 在 Zephyr 系统上扩展的库、驱动和例程的文档。里面大多数是一些Nordic独有的技术和解决方案。 -
Zephyr Project:对应的是NCS中的
zephyr文件夹。是 Zephyr官方文档 的一个镜像,包含Zephyr RTOS内核服务、操作系统API、各种驱动、协议支持以及它们的例程文档。一些比较通用的功能的如日志、Flash存储、线程间通信等功能的文档都在这里面。 -
nrfxlib:对应的是NCS中的
nrfxlib文件夹。里面是与 RTOS 无关的库,大多是 Nordic 产品的闭源二进制库。 -
MCUboot:MCUboot是一个开源的第三方安全 bootloader,支持很多系统和平台,Zephyr只是其中之一。支持 OTA 的例程基本都是使用 MCUboot
-
Trusted Firmware-M:前面介绍了 TrustZone 技术。TF-M 就是微控制器上的安全空间固件实现。当你编译时选择
/ns的 board target,Zephyr 会自动把 TF-M 作为其中一个子镜像添加进来,成为 Application 的一部分。 -
Matter:Matter是智能家居的新标准,目的是打破厂商之间的壁垒,实现生态融合。
-
Kconfig:Zephyr 系统中有大量的 Kconfig 配置,Nordic 扩展的库、驱动中也有大量 Kconfig 配置。如果你不知道一个 Kconfig 配置是干什么的,可以在这个页面进行搜索。
Kconfig 也可以直接在 SDK 中搜索。比如,如果要搜索
CONFIG_BT_PERIPHERAL是什么意思,可以搜索config BT_PERIPHERAL,并过滤Kconfig*,勾选大小写匹配和完整匹配:
总之,NCS官网里面有大量的技术细节,在运行一个例程之前,一定要参照网站中该例程的说明进行操作。
Nordic 旧版资料中心 (Info Center)
此网站已于2024.6.18 被 TechDocs 替代
如果要查询老的 nRF5 SDK 资料,看:https://docs.nordicsemi.com/bundle/sdk_nrf5_v17.1.0/page/index.html
Nordic官网
一些商业新闻和产品介绍。但是最重要的是一些工具软件、开发板原理图/PCB/BOM之类,需要在这里下载。
例如:
- nRF54L15DK 硬件资料(原理图、PCB、BOM):https://www.nordicsemi.com/Products/Development-hardware/nRF54L15-DK/Hardware-files?lang=en#infotabs
DevZone开发者论坛
https://devzone.nordicsemi.com/
有问题可以在上面搜索,也可以用英文提问。每天都有原厂support team查看问题并回复。Nordic注册客户,还可以提交private ticket,解决一些与代码、板子有关的问题,也可以审核PCB。
Nordic DevAcademy官方课程
https://academy.nordicsemi.com/
类似于慕课的网站,目前有NCS,BLE、Wi-Fi、Cellular 等课程。有视频结合题目,适合英文好的读者去学习,是非常适合入门的课程。
14. 其他推荐阅读
NCS 基础:
NCS 应用:















