WSL2 下搭建 ESP32-C3 Zephyr 开发环境

背景

Zephyr 是一个面向资源受限设备的小型实时操作系统(RTOS),支持 500+ 开发板,包括乐鑫的 ESP32 系列。ESP32-C3 是乐鑫的 RISC-V 单核 Wi-Fi/BLE SoC(160MHz,4MB Flash),开发板用的是 Seeed XIAO ESP32C3。

Zephyr 官方对 Ubuntu 支持最好,下面以 Ubuntu(WSL2)为例。

前置条件

  • Windows 10/11,已安装 WSL2(wsl --install),发行版建议 Ubuntu 22.04/24.04
  • 一个 ESP32-C3 开发板(本文用 Seeed XIAO ESP32C3)
  • 管理员权限的 PowerShell(后面 usbipd 需要)

1. 安装环境依赖工具

参考官方指导:Zephyr Getting Started

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
sudo apt update
sudo apt upgrade

sudo apt install --no-install-recommends git cmake ninja-build gperf \
  ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \
  xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1

# 验证版本
cmake --version
python3 --version
dtc --version

2. 安装 west 与 Zephyr 源码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
python3 -m venv ~/zephyrproject/.venv
source ~/zephyrproject/.venv/bin/activate

pip install west

west init -m https://github.com/zephyrproject-rtos/zephyr ~/zephyrproject
cd ~/zephyrproject
west update

west packages pip --install
west zephyr-export

west update 会拉取 Zephyr 主仓库和所有模块(hal、mcuboot 等),网络不好时容易卡,可以挂代理或换国内镜像加速。

3. 安装 Zephyr SDK

1
2
cd ~/zephyrproject/zephyr
west sdk install

4. 共享 USB 设备到 WSL2

WSL2 是虚拟机,默认访问不到宿主机 USB 设备,需要借助微软官方的 usbipd-win 做 USB/IP 直通。

4.1 安装 usbipd-win

1
winget install usbipd

4.2 命令行绑定并连接

管理员 PowerShell 中执行:

1
2
3
4
5
6
7
8
# 列出 USB 设备,找到 ESP32-C3 对应的 BUSID
usbipd list

# 绑定(只需做一次,绑定后设备对 WSL 可见)
usbipd bind --busid=<BUSID>

# 连接到当前 WSL 发行版
usbipd attach --wsl --busid=<BUSID>

之后在 WSL 里用 lsusb 验证,能看到 303a:1001(Espressif USB JTAG/serial debug unit)就说明直通成功:

1
2
3
4
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 004: ID 303a:1001 Espressif USB JTAG/serial debug unit
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

4.3 图形界面方案:wsl-dashboard(可选)

不想敲命令行的话,可以装 wsl-dashboard,在它的 UI 里直接绑定和连接 USB 设备,适合偶尔用一下的场景。

4.4 串口权限(dialout 组)

设备直通后,/dev/ttyACM0 默认属于 dialout 组,普通用户没有读写权限:

1
2
$ ls -l /dev/ttyACM*
crw-rw---- 1 root dialout 166, 0 Sep  1 16:15 /dev/ttyACM0

把自己加进 dialout 组,然后重启 WSLwsl --shutdown 后重开)生效:

1
sudo usermod -aG dialout $USER

5. 编译 hello_world

用 sysbuild 方式编译(会自动带上 mcuboot 二级引导):

1
2
cd ~/zephyrproject/zephyr
west build -p always -b xiao_esp32c3 --sysbuild samples/hello_world

关键输出:CMake 会先构建 mcuboot,再构建 hello_world,最后生成 ESP32-C3 镜像:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
-- Board: xiao_esp32c3, qualifiers: esp32c3
-- Zephyr version: 4.4.99
-- Found toolchain: zephyr 1.0.1 (/home/xx/zephyr-sdk-1.0.1)
...
[239/239] Linking C executable zephyr/zephyr.elf
Memory region         Used Size  Region Size  %age Used
     mcuboot_hdr:          32 B         32 B    100.00%
        metadata:          80 B         96 B     83.33%
           FLASH:      134116 B    4194176 B      3.20%
...
esptool v5.3.1
Successfully created ESP32-C3 image.

6. 烧录

1
west flash

west 会自动选择 /dev/ttyACM0,走 USB-Serial/JTAG 直连烧录(921600bps):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
-- west flash: using runner esp32
Detecting chip type... ESP32-C3
Auto-selected /dev/ttyACM0 for esp32c3
Chip type:          ESP32-C3 (QFN32) (revision v0.3)
Features:           Wi-Fi, BT 5 (LE), Single Core, 160MHz, Embedded Flash 4MB (XMC)
Crystal frequency:  40MHz
USB mode:           USB-Serial/JTAG
...
Wrote 32576 bytes at 0x00000000 in 0.4 seconds   # mcuboot
Wrote 134284 bytes at 0x00020000 in 0.7 seconds   # hello_world
Hash of data verified.
Hard resetting via RTS pin...

7. 串口监视

1
west espressif monitor

启动后能看到完整启动日志和 Hello World 输出:

1
2
3
4
5
6
7
8
--- idf_monitor on /dev/ttyACM0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ESP-ROM:esp32c3-api1-20210207
...
I (soc_init): MCUboot 2nd stage bootloader
I (boot): Loading image 0 - slot 0 from flash, area id: 2
*** Booting Zephyr OS build v4.4.0-13771-gb9df9f46ae46 ***
Hello World! xiao_esp32c3/esp32c3

看到 Hello World! xiao_esp32c3/esp32c3 就说明环境全部打通了。

常见问题

  1. WSL 里 lsusb 看不到 ESP32-C3 确认在管理员 PowerShell 里执行过 usbipd bind --busid=<BUSID>,且 usbipd attach --wsl --busid=<BUSID> 成功。Windows 重启或 WSL 重启后,attach 会失效,需要重新 attach(bind 一次即可)。

  2. /dev/ttyACM0 权限不足

    1
    
    could not open port /dev/ttyACM0: Permission denied
    

    加入 dialout 组并重启 WSL:sudo usermod -aG dialout $USER

参考