Stm32F103 + NuttX(一):开发环境配置与系统安装
之前文章《Stm32F103 + Stm32CubeMX(一):VSCode 开发环境配置》配置了 stm32 裸机开发的一系列环境,这篇文章试着运行 RTOS,这里选择 NuttX 而不是 FreeRTOS 这种主要是由于作者的学习路线(以后上班接触的是 NuttX 所以就跑这个了),并且 Stm32F103 + FreeRTOS 的教程网上应该非常多,也就不重复写了。
注意这里不坚持纯 Windows 做开发了,因为作者试了几天觉得还是会带来不少不必要的麻烦,因此把整体的开发、调试环境切换到了 WSL,以下内容会从零开始配置 WSL 的开发环境,因此如果前面的文章没看过,无需去看,按照本篇文章配置环境即可。
硬件型号:正点原子精英开发板(STM32F103ZET6)
开发平台:Windows 11 专业版 24H2(26100.7462)+ WSL2(2.6.3)
NuttX 版本:12.11.0(Release Date:2025-10-05)
Windows 配置
安装 WSL
这部分可以直接参考 安装 WSL | Microsoft Learn,网上的教程也很多,因此这里不详细写了。
请自行安装 Debian 发行版(目前应该是 Debian13),并更换 APT 软件源,最好再配置好网络代理
安装 VSCode
我们会使用 VSCode 的 Remote 来连接 WSL 进行类远程开发,因此请先自行安装 VSCode 并学习如何使用 Remote 插件来打开 WSL
安装 MobaXterm
后续会通过串口访问 nsh,因此需要一个串口连接工具,这里推荐 MobaXterm,可以自行安装。
官网下载页面:https://mobaxterm.mobatek.net/download-home-edition.html,两个版本都可以。
安装 usbipd-win
usbipd-win 可以将 USB 设备连接到 WSL2
github 下载页面:https://github.com/dorssel/usbipd-win/releases,下载 msi 文件安装即可。
WSL 配置
安装依赖项
sudo apt install \
bison flex gettext texinfo libncurses5-dev libncursesw5-dev xxd \
git gperf automake libtool pkg-config build-essential gperf genromfs \
libgmp-dev libmpc-dev libmpfr-dev libisl-dev binutils-dev libelf-dev \
libexpat1-dev gcc-multilib g++-multilib picocom u-boot-tools util-linux \
wget gcc-arm-none-eabi binutils-arm-none-eabi cmake ninja-build kconfig-frontends \
python-is-python3 usbutils python3-pip gdb-multiarch binutils-multiarch clangd
pip install kconfiglib --break-system-packages
将 ~/.local/bin 加入到环境变量中
echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
安装 OpenOCD
wget https://github.com/xpack-dev-tools/openocd-xpack/releases/download/v0.12.0-7/xpack-openocd-0.12.0-7-linux-x64.tar.gz
tar xf xpack-openocd-0.12.0-7-linux-x64.tar.gz
解压后将 xpack-openocd-0.12.0-7/bin 加入到环境变量中**(注意换成你的实际路径)**
echo 'export PATH=$HOME/xpack-openocd-0.12.0-7/bin:$PATH' >> ~/.bashrc
测试 STLink 连接
这是最重要的一个过程,决定了是否能顺利在 WSL 上进行烧录和调试。
- 将 ST-Link 调试器连接到电脑
- 将开发板连接 ST-Link 调试器
- 开发板接入电源上电
在 Windows 中的管理员 PowerShell 中运行
查看当前的 USB 设备
usbipd list
可以看到 STLink 设备的 BUSID 是 4-7
4-7 0483:3748 STM32 STLink Not shared
暂不清楚是否是因为之前在 Windows 上安装过 STLink 的驱动因此会显示名称。如果没有明确显示 STLink,可以通过插拔的方式来确认哪一个设备是 STLink
共享 USB 设备
usbipd bind --busid 4-7
共享后可以通过 usbipd list 再次查看,会发现 STLink 的状态变成了 Shared
附加 USB 设备
usbipd attach --wsl debian --busid 4-7
注意每次 STLink 设备插拔后,都要重新进行附加
关于更多说明可以看 连接 USB 设备 | Microsoft Learn
在 WSL 中的终端运行
查看当前的 USB 设备
lsusb
输出结果中应包含类似内容,看到产品型号 0483:3748
Bus 001 Device 002: ID 0483:3748 STMicroelectronics ST-LINK/V2
配置 udev 规则
这里主要是解决权限问题,让普通用户也可以访问到该 USB 设备。
先查看当前权限,文件路径 001/002 按照上面的 Bus 001 Device 002 进行相应修改
ls -l /dev/bus/usb/001/002
crw-rw-r-- 1 root root 189, 1 Dec 28 11:59 /dev/bus/usb/001/002
可以看到只有 root 用户或 root 组可以进行读写。
新建 udev 规则,注意将这里的 0483 和 3748 换成你实际的数字。
sudo tee /etc/udev/rules.d/49-stlink.rules >/dev/null <<'EOF'
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3748", GROUP="plugdev", MODE="0660"
EOF
重载并触发
sudo udevadm control --reload-rules
sudo udevadm trigger
重新查看权限,可以看到已经改变过来了,当前用户是处在 plugdev 组下的,因此具备了读写权限。
ls -l /dev/bus/usb/001/002
crw-rw---- 1 root plugdev 189, 1 Dec 28 12:07 /dev/bus/usb/001/002
测试连接
openocd -f interface/stlink.cfg -c "transport select swd" \
-f target/stm32f1x.cfg -c "adapter speed 480"
其中 SWD 采样频率的有效值为 950/480/240/100,如果发现连接失败的情况(比如输出 Info : clock speed 480 kHz 后就退出了)可以适当降低采样频率。
如果一切正常,应该会输出类似内容:
xPack Open On-Chip Debugger 0.12.0+dev-02228-ge5888bda3-dirty (2025-10-04-22:42)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 480 kHz
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : STLINK V2J35S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.220513
Info : clock speed 480 kHz
Info : SWD DPIDR 0x1ba01477
Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : [stm32f1x.cpu] Examination succeed
Info : [stm32f1x.cpu] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
说明 STLink 和开发板都已经正常连接上了,此时可以 Ctrl+C 退出。
安装系统
下载源码
mkdir nuttxspace
cd nuttxspace
git clone https://github.com/apache/nuttx.git nuttx
git clone https://github.com/apache/nuttx-apps apps
进行板级配置
可以先查看当前支持的配置,也可以直接在 nuttx/boards 目录下查找
cd nuttx
./tools/configure.sh -L | less
这里选用 stm3210e-eval 这个板级配置,它的 MCU 是 STM32F103ZET6,和我的硬件匹配。应用配置选择普通的 nsh,可以在终端中如下配置
cmake -B build -DBOARD_CONFIG=stm3210e-eval:nsh -GNinja
编译源码
cmake --build build
最终结果如下,得到 build/nuttx 文件
[1143/1145] Linking C executable nuttx
Memory region Used Size Region Size %age Used
flash: 92816 B 512 KB 17.70%
sram: 7140 B 64 KB 10.89%
[1145/1145] Generating System.map
烧录文件
openocd -f interface/stlink.cfg \
-c "transport select swd" \
-f target/stm32f1x.cfg -c "adapter speed 480" \
-c "init" \
-c "program build/nuttx verify reset" \
-c "shutdown"
烧录命令解释
-c "init":建立 SWD 连接/识别 CPU 等一系列初始化操作-c "program build/nuttx verify reset":把 ELF 文件写入 Flash,写完后再读取做一次校验。最后复位 MCU,开始运行。-c "shutdown:关闭 OpenOCD 本身,释放 ST-Link,关闭 gdb 端口。
烧录输出
xPack Open On-Chip Debugger 0.12.0+dev-02228-ge5888bda3-dirty (2025-10-04-22:42)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 480 kHz
Info : STLINK V2J35S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.223173
Info : clock speed 480 kHz
Info : SWD DPIDR 0x1ba01477
Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : [stm32f1x.cpu] Examination succeed
Info : [stm32f1x.cpu] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
[stm32f1x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000130 msp: 0x2000127c
** Programming Started **
Info : device id = 0x10036414
Info : flash size = 512 KiB
Warn : Adding extra erase range, 0x08016a90 .. 0x08016fff
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
shutdown command invoked
测试 nsh
使用 USB 线将板子和电脑连接,应该会自动安装驱动,设备管理器的端口中可以看到 USB-SERIAL CH340。
在 Windows 上使用 MobaXterm 进行串口连接:Session 中选择 Serial,Serial port 选择 USB-SERIAL CH340
连接后输入回车就可以看到
nsh>
这就说明系统已经启动成功了,可以随便测试一下常用命令
VSCode 工程建立
成功运行 NuttX 后,我们会想着怎么更便利地在 VSCode 做开发。首先要在 WSL 中安装几个 VSCode 插件:
- Cortex-Debug
- clangd(在 C 语言插件这块本人偏向于 clangd,选择微软自家的 C/C++ 也没什么问题)
这里建议关闭所有的 VSCode 窗口,重新打开一次 VSCode,主要是为了刷新前面设置的环境变量。
然后在项目根目录创建 .vscode 文件夹,分别创建三个配置文件
tasks.json
配置两个任务,分别为编译和烧录,然后使用将两个任务打包在一起,并设置为默认的 build,这样就可以通过 ctrl+shift+B 来快速运行。
|
|
launch.json
使用 cortex-debug 插件,创建一个启动配置,这会自动运行 openocd 并使用 gdb 连接。
启动调试的快捷键是 F5。
|
|
settings.json
主要是手动设置一下 clangd 插件的可执行文件路径,否则会一直提示下载 Windows 版本的。不知道是 Bug 还是我没配置好,反正每次在远程开发中使用 clangd 都要手动指定一下。
|
|
GDB 调试
上面配置完之后,编译与烧录是没问题的,但调试仍读不到符号,即不能在 VSCode 中进行源码调试,这需要打开 NuttX 的调试配置,默认不启用。
打开配置菜单
cmake --build build -t menuconfig
启用配置
- Build Setup -> Debug Options -> Generate Debug Symbols
分别按 q 退出和 y 保存
删除原有编译产物
cmake --build build --target clean
然后可以试试 ctrl+shift+B 进行编译和烧录。
完成后使用 F5 开始调试,发现成功在 nx_start() 处停止。
如果在调试中有问题,可以看看下文的《终极大坑》一节。
关于更多调试选项,可以自行看配置菜单。
终极大坑(无法正确复位)
问题描述
直接现象:
- 使用 GDB 调试时复位后 CPU PC 卡在 0x1ffff020 而不是 0x08000130
- 使用 MobaXterm 进行串口调试时,按复位物理按键无法继续输出,必须重新上电才能通信
间接原因:当开发板的 USB 串口和电脑连接时,板子复位会使用系统存储器启动。
根本原因:这块板子专门设计了一键下载电路,会通过串口的 DTR 和 RTS 信号,来自动配置 BOOT0 和 RST 信号,因此串口连接时会导致一些问题(这里作者也不太懂,只能说坑在这)。
解决方法
控制串口的 DTR 和 RTS 信号,在 VSCode 中安装 Serial Monitor 扩展,取消 DTR 和 RTS 的勾选,然后打开串口。有了这个插件以后 MobaXterm 其实就用不到了,之后都可以用这个插件来进行串口通信。
注意,这里是在 Windows 中的 VSCode 而不是 WSL 中,如果在 WSL 中,这里显示的串口是 /dev/ttyS0 等,因此串口调试时每次需要打开两个 VSCode 界面。
参考文档
本站不记录浏览量,但如果您觉得本内容有帮助,请点个小红心,让我知道您的喜欢。