0%

MacOS配置Nordic蓝牙BLE的Vscode开发环境

本文将介绍如何在MacOS下配置Nordic蓝牙开发环境, 器材为nRF52832(开发板NRF52-DK, PCA10040)。

通常来说人们会在windows上进行蓝牙开发, 但实际上MacOS也同样可以, 并且配合vscode可比Keil舒服多了。

如果你对Makefile等工具较为熟悉, 甚至可以获得比IDE更便捷的开发体验。

安装步骤

在所有步骤开始之前,首先创建一个文件夹作为你的项目目录

我也尝试了使用conda配置GCC编译工具链, 但是目前conda上没有合适的arm gcc包, 因此还是使用Homebrew安装

1
brew install --cask gcc-arm-embedded nordic-nrf-command-line-tools 

安装过程中需要输入密码获取权限, 输入密码后等待安装完成

安装 nordic sdk

目前nordic主要在推Mesh协议栈,但是作为一个例子,我们还是使用传统的nRF5 SDK。

1
2
3
4
mkdir .nRF5_SDK && cd .nRF5_SDK
curl https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v17.x.x/nRF5_SDK_17.1.0_ddde560.zip -O
unzip nRF5_SDK_17.1.0_ddde560.zip
rm nRF5_SDK_17.1.0_ddde560.zip

在Nordic SDK中配置GCC

默认的配置文件位于 .nRF5_SDK/nRF5_SDK_17.1.0_ddde560/components/toolchain/gcc/Makefile.posix

执行 arm-none-eabi-gcc --versionwhich arm-none-eabi-gcc 检查gcc版本和安装目录

之后替换原本文件中的内容,GNU_INSTALL_ROOT和GNU_VERSION需要根据实际情况修改,GNU_PREFIX通常不需要修改

1
2
3
GNU_INSTALL_ROOT := /opt/homebrew/bin/
GNU_VERSION := 14.2.1
GNU_PREFIX := arm-none-eabi

编译demo

选择一个复杂度适中的demo进行编译

使用扩展坞连接你的开发版,然后执行如下命令

1
2
3
4
5
6
7
cd .nRF5_SDK/nRF5_SDK_17.1.0_ddde560/examples/ble_peripheral/ble_app_blinky/pca10040/s132/armgcc
# 编译
make
# 烧录协议栈
make flash_softdevice
# 烧录程序
make flash

报错处理

当使用新版GCC编译时,可能会出现以下错误

1
2
3
4
../../../../../../components/libraries/log/src/nrf_log_frontend.c: In function 'nrf_log_module_name_get':
../../../../../../components/libraries/log/src/nrf_log_frontend.c:219:29: error: array subscript 'nrf_log_module_const_data_t[0]' is partly outside array bounds of 'nrf_log_module_const_data_t[0]' [-Werror=array-bounds=]
219 | return p_module_data->p_module_name;
| ^~

传统的解决办法可以将gcc版本降级, 但是想使用新版GCC, 则需要修改Makefile文件将 -Werror=array-bounds 添加到 CFLAGS

对于我们的demo,修改.nRF5_SDK/nRF5_SDK_17.1.0_ddde560/examples/ble_peripheral/ble_app_blinky/pca10040/s132/armgcc/Makefile, 将

1
CFLAGS += -Wall -Werror

修改为

1
CFLAGS += -Wall -Werror -Wno-array-bounds

修改后便可以正常编译了

调试工具

uart工具较为常见, 本文不进行介绍, 主要介绍JLINK相关的工具

这些工具在homebrew安装nordic-nrf-command-line-tools时作为依赖已经添加到了系统中, 因此可以直接使用

RTT LOG

开启RTT Log需要修改sdk_config.h文件,将 #define NRF_LOG_ENABLED 1 修改为 #define NRF_LOG_ENABLED 1

对于这个demo, 文件位置在.nRF5_SDK/nRF5_SDK_17.1.0_ddde560/examples/ble_peripheral/ble_app_blinky/pca10040/s132/config/sdk_config.h

1
#define NRF_LOG_BACKEND_RTT_ENABLED 0

修改为

1
#define NRF_LOG_BACKEND_RTT_ENABLED 1

之后重新编译烧录编译即可开启RTT Log

查看RTT log时需要同时运行两个终端

在第一个终端中执行

1
JLinkExe -device nRF52840_xxAA -if SWD -speed 4000 -autoconnect 1

在第二个终端中执行

1
JLinkRTTClient

在和蓝牙设备互动之后便可以看到类似如下的输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SEGGER J-Link V8.12 - Real time terminal output
SEGGER J-Link (unknown) V1.0, SN=682454502
Process: JLinkExe
<info> app_timer: RTC: initialized.
<info> app: Blinky example started.
<info> app: Connected
<info> app: Received LED ON!
<info> app: Disconnected
<info> app: Connected
<info> app: Disconnected
<info> app: Connected
<info> app: Disconnected
<info> app: Connected
<info> app: Received LED ON!

通过UI配置sdk_config

有些人可能习惯于使用UI配置sdk_config, 此时需要安装Java工具, 要求Java版本为8

为了防止和系统自带的Java冲突, 此处我使用了conda安装Java, conda的使用方法此处不过多介绍

1
conda install openjdk=8

安装后执行

1
make sdk_config

即可启动UI配置工具

Vscode 代码索引

完成上述配置后,我们可以进一步配置vscode使其可以正常索引代码

在vscode中安装C/C++插件, 并配置c_cpp_properties.json文件

在项目目录下创建.vscode文件夹, 并在其中创建或编辑c_cpp_properties.json文件为以下内容

注意includePath中最后一行${workspaceFolder}/.nRF5_SDK/nRF5_SDK_17.1.0_ddde560/examples/ble_central/ble_app_blinky_c是为了让vscode能够索引到demo的代码, 对于自己的项目需要替换为对应的项目目录

如果你用到了.nRF5_SDK/nRF5_SDK_17.1.0_ddde560/external.nRF5_SDK/nRF5_SDK_17.1.0_ddde560/integration中的库, 则同样需要将这些目录添加到include Path中

此外

1
2
"/Applications/ArmGNUToolchain/14.2.rel1/arm-none-eabi/arm-none-eabi/include/**",
"/Applications/ArmGNUToolchain/14.2.rel1/arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/include/**",

这些路径是Homebrew安装的GCC的安装路径, 如果你使用的是其他版本的GCC, 则需要修改为对应的路径。

完整的c_cpp_properties.json文件如下

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
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/.nRF5_SDK/nRF5_SDK_17.1.0_ddde560/components/**",
"${workspaceFolder}/.nRF5_SDK/nRF5_SDK_17.1.0_ddde560/components/**",
".nRF5_SDK/nRF5_SDK_17.1.0_ddde560/examples/ble_central/ble_app_blinky_c/pca10040/**",
"/Applications/ArmGNUToolchain/14.2.rel1/arm-none-eabi/arm-none-eabi/include/**",
"/Applications/ArmGNUToolchain/14.2.rel1/arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/include/**",
"${workspaceFolder}/.nRF5_SDK/nRF5_SDK_17.1.0_ddde560/examples/ble_central/ble_app_blinky_c"
],
"defines": [
"NRF52840_XXAA",
"__GNUC__"
],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/opt/homebrew/bin/arm-none-eabi-gcc",
"cStandard": "c99",
"cppStandard": "c++98",
"intelliSenseMode": "macos-gcc-arm"
}
],
"version": 4
}