前言

本文记录在 Linux/WSL 环境下,为 ESP32-P4-Function-EV-Board 搭建 Apache NuttX 编译环境,并构建、烧录 usbconsole 示例的完整过程。

usbconsole 配置会使用 ESP32-P4 的 USB Serial/JTAG 外设作为 NuttX 控制台。对于 ESP32-P4-Function-EV-Board v1.5.2,开发板连接到 PC 后通常表现为 USB Serial/JTAG 设备,烧录和串口控制台都可以通过同一个 USB 口完成。

本文使用的环境:

  • 系统:Ubuntu on WSL2
  • 开发板:ESP32-P4-Function-EV-Board
  • NuttX 配置:esp32p4-function-ev-board:usbconsole
  • 工具链:xPack riscv-none-elf-gcc 14.2.0
  • 烧录工具:esptool 5.3.1

目录规划

创建一个工作目录:

mkdir -p ~/esp32p4-nuttx
cd ~/esp32p4-nuttx

NuttX 推荐源码目录结构是 nuttxapps 并列:

esp32p4-nuttx/
├── apps
├── nuttx
└── toolchains

获取 NuttX 源码

cd ~/esp32p4-nuttx
git clone --depth 1 https://github.com/apache/nuttx.git nuttx
git clone --depth 1 https://github.com/apache/nuttx-apps.git apps

确认 ESP32-P4-Function-EV-Board 的 usbconsole 配置存在:

cd ~/esp32p4-nuttx/nuttx
ls boards/risc-v/esp32p4/esp32p4-function-ev-board/configs/usbconsole

安装 RISC-V 工具链

ESP32-P4 是 RISC-V 架构。这里使用 NuttX 文档推荐的 xPack RISC-V GCC:

cd ~/esp32p4-nuttx
mkdir -p toolchains/downloads toolchains/riscv-none-elf-gcc

curl -L \
  -o toolchains/downloads/xpack-riscv-none-elf-gcc-14.2.0-3-linux-x64.tar.gz \
  https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-3/xpack-riscv-none-elf-gcc-14.2.0-3-linux-x64.tar.gz

tar -C toolchains/riscv-none-elf-gcc \
  --strip-components 1 \
  -xzf toolchains/downloads/xpack-riscv-none-elf-gcc-14.2.0-3-linux-x64.tar.gz

验证工具链:

~/esp32p4-nuttx/toolchains/riscv-none-elf-gcc/bin/riscv-none-elf-gcc --version

正常输出类似:

riscv-none-elf-gcc (xPack GNU RISC-V Embedded GCC x86_64) 14.2.0

准备 Python 和 esptool

NuttX 生成 ESP32-P4 镜像时需要 esptool.py

python3 -m pip install --user --upgrade pip setuptools wheel
python3 -m pip install --user esptool

验证:

~/.local/bin/esptool.py version

如果系统环境使用了 SOCKS 代理,但 Python 没有安装 SOCKS 支持,可能会遇到:

Missing dependencies for SOCKS support

这种情况下可以临时清除代理变量后安装:

env -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY -u all_proxy \
  python3 -m pip install --user esptool

配置 PATH

为了避免误用系统里较旧的 riscv64-unknown-elf-* 工具链,建议显式设置 PATH:

export PATH=$HOME/esp32p4-nuttx/local-bin:$HOME/.local/bin:$HOME/esp32p4-nuttx/toolchains/riscv-none-elf-gcc/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

确认工具链路径:

which riscv-none-elf-gcc riscv-none-elf-ld
riscv-none-elf-gcc --version

输出路径应该指向:

/home/<user>/esp32p4-nuttx/toolchains/riscv-none-elf-gcc/bin/...

如果链接时出现下面的错误,通常就是工具链 PATH 错了:

riscv64-unknown-elf-ld: Invalid or unknown z ISA extension: 'zifencei'

修正 PATH 后,可以清理并重新编译:

make clean
make -j$(nproc)

处理 kconfig-tweak

部分 Linux 环境没有安装 kconfig-frontends,执行 configure.sh 时可能报错:

kconfig-tweak: command not found

如果系统可以安装依赖,可以安装 kconfig 工具。若是在普通 WSL 用户环境中,也可以准备一个本地 kconfig-tweak 兼容脚本放到:

~/esp32p4-nuttx/local-bin/kconfig-tweak

然后保证 local-bin 在 PATH 前面。这个脚本只需要支持 NuttX 配置流程中用到的 --file--enable--disable--undefine 等基础操作即可。

配置 usbconsole

进入 NuttX 源码目录:

cd ~/esp32p4-nuttx/nuttx

选择 ESP32-P4-Function-EV-Board 的 usbconsole 配置:

./tools/configure.sh esp32p4-function-ev-board:usbconsole

补全默认配置:

make olddefconfig

可以检查关键配置项:

grep -E "CONFIG_ARCH_BOARD|CONFIG_ESPRESSIF_USBSERIAL|CONFIG_SYSTEM_NSH|CONFIG_EXAMPLES_HELLO" .config

关键项应包含:

CONFIG_ARCH_BOARD="esp32p4-function-ev-board"
CONFIG_ESPRESSIF_USBSERIAL=y
CONFIG_SYSTEM_NSH=y
CONFIG_EXAMPLES_HELLO=y

编译 NuttX

执行:

make -j$(nproc)

第一次编译会自动拉取 Espressif HAL:

Cloning Espressif HAL for 3rd Party Platforms

编译成功后会生成:

nuttx
nuttx.hex
nuttx.bin
nuttx.map

可以查看产物:

ls -lh nuttx nuttx.bin nuttx.hex nuttx.map

示例输出:

-rwxr-xr-x 1 test test 378K nuttx
-rw-r--r-- 1 test test 221K nuttx.bin
-rw-r--r-- 1 test test 390K nuttx.hex
-rw-r--r-- 1 test test 1.4M nuttx.map

WSL2 下连接 ESP32-P4 USB 设备

如果是在原生 Linux 下,开发板通常会直接出现为 /dev/ttyACM0

如果是在 WSL2 下,Windows 中看到的是 COM4,直接使用 /dev/ttyS4 可能会遇到:

Could not configure port: (5, 'Input/output error')

这种情况下推荐使用 usbipd-win 将 USB 设备直通到 WSL。

Windows 安装 usbipd-win

在 Windows PowerShell 中执行:

winget install --interactive --exact dorssel.usbipd-win

安装后重新打开 PowerShell。

查看 USB 设备:

usbipd list

ESP32-P4 设备类似:

BUSID  VID:PID    DEVICE
2-1    303a:1001  USB 串行设备 (COM4), USB JTAG/serial debug unit

使用管理员 PowerShell 绑定并挂载到 WSL:

usbipd bind --busid 2-1
usbipd attach --wsl --busid 2-1

WSL 中确认设备

回到 WSL:

lsusb

应能看到:

303a:1001 Espressif USB JTAG/serial debug unit

加载 CDC ACM 驱动:

sudo modprobe cdc_acm

检查串口节点:

ls -l /dev/ttyACM*

如果出现 /dev/ttyACM0,但权限不足,可以临时修改权限:

sudo chmod 666 /dev/ttyACM0

烧录

进入 NuttX 目录:

cd ~/esp32p4-nuttx/nuttx

烧录:

make flash ESPTOOL_PORT=/dev/ttyACM0 ESPTOOL_BINDIR=./

成功日志类似:

Connected to ESP32-P4 on /dev/ttyACM0:
Chip type:          ESP32-P4 (revision v3.2)
Features:           Dual Core + LP Core, 400MHz
USB mode:           USB-Serial/JTAG

Stub flasher running.
Changing baud rate to 921600...
Changed.

Configuring flash size...
Wrote 225352 bytes (...) at 0x00002000 ...
Hash of data verified.

Hard resetting via RTS pin...

看到 Hash of data verified 就说明固件已经成功写入。

打开 NuttX 控制台

烧录后可以通过同一个 /dev/ttyACM0 访问 NuttX 控制台:

python3 -m serial.tools.miniterm /dev/ttyACM0 115200

或者使用 picocom

picocom -b 115200 /dev/ttyACM0

进入控制台后可以运行:

nsh> help
nsh> hello

hello 示例来自 CONFIG_EXAMPLES_HELLO=y

常见问题

1. make 找不到

如果设置 PATH 时误换行,可能导致系统路径丢失:

make: command not found

恢复 PATH:

export PATH=$HOME/esp32p4-nuttx/local-bin:$HOME/.local/bin:$HOME/esp32p4-nuttx/toolchains/riscv-none-elf-gcc/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

2. 误用了旧 RISC-V 工具链

错误表现:

riscv64-unknown-elf-ld: Invalid or unknown z ISA extension: 'zifencei'

检查:

which riscv-none-elf-gcc riscv-none-elf-ld

确保指向 xPack 工具链目录。

3. /dev/ttyS4 权限被拒绝

错误:

Permission denied: '/dev/ttyS4'

可以加入串口组:

sudo usermod -aG dialout $USER

然后在 Windows PowerShell 中执行:

wsl --shutdown

重新打开 WSL 后生效。

不过对于 WSL2,更推荐使用 usbipd-win,让设备在 WSL 内显示为 /dev/ttyACM0

4. /dev/ttyACM0 不存在

确认 USB 是否 attach 到 WSL:

lsusb
dmesg | tail -80

加载驱动:

sudo modprobe cdc_acm

如果仍然没有 /dev/ttyACM0,可以在 Windows 侧确认:

usbipd list

设备状态应为 attached。

总结

整个流程可以概括为:

  1. 克隆 nuttxnuttx-apps
  2. 安装 xPack riscv-none-elf-gcc
  3. 安装 esptool
  4. 配置 esp32p4-function-ev-board:usbconsole
  5. 执行 make -j$(nproc) 生成 nuttx.bin
  6. WSL2 下用 usbipd-win 将 ESP32-P4 USB Serial/JTAG 设备挂载到 WSL。
  7. 使用 /dev/ttyACM0 执行 make flash

最终烧录成功后,usbconsole 就可以通过 USB Serial/JTAG 口进入 NuttX NSH 控制台。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐