🔧 WSL 共享 USB 设备配置指南

在 WSL 2 中搭建 STM32 开发环境时,需要访问 J-Link 调试器和串口设备进行程序烧录和调试。本文将介绍如何使用开源项目 usbipd-win 将 Windows 上的 USB 设备共享到 WSL 2,实现完整的嵌入式开发工作流。

准备工作

在开始配置之前,请确认以下环境要求:

  • ✅ Windows 11(内部版本 22000 或更高)或 Windows 10(需应用商店版 WSL)
  • ✅ x64 或 ARM64 处理器(x86 架构暂不支持)
  • ✅ WSL 2 已安装并更新到最新版本
  • ✅ Linux 内核版本 5.10.60.1 或更高

检查系统版本

检查 Windows 版本:按 Win + R,输入 winver 查看版本号

检查 Linux 内核版本

1
2
# 在 WSL 中执行
uname -a

更新 WSL 内核

1
2
# 在 PowerShell 中执行
wsl --update

💡 提示:Windows 10 用户可通过 Microsoft 应用商店安装最新版 WSL,无需手动编译内核。

第一步:安装 usbipd-win

WSL 不提供原生 USB 设备连接支持,需要通过 usbipd-win 项目实现设备共享。

方法一:使用 MSI 安装包

  1. 访问 usbipd-win 发布页面
  2. 下载最新版本的 .msi 安装文件
  3. 运行安装程序完成安装

方法二:使用 winget 安装

1
2
# 推荐使用交互式安装,避免自动重启
winget install --interactive --exact dorssel.usbipd-win

安装内容说明

安装完成后将包含以下组件:

  • usbipd 服务:后台服务(显示名称:USBIP 设备主机)
  • usbipd 命令行工具:已自动添加到系统 PATH
  • 防火墙规则:允许本地子网连接到服务

第二步:共享 USB 设备

查看可用设备

管理员权限打开 PowerShell,列出所有连接的 USB 设备:

1
usbipd list

记录需要共享设备的 BUSID(如 4-4)。

绑定设备

使用 bind 命令将设备设置为可共享状态(需要管理员权限):

1
2
# 将 4-4 替换为实际的 BUSID
usbipd bind --busid 4-4

执行后再次运行 usbipd list 确认设备状态已变为 Shared

第三步:连接设备到 WSL

⚠️ 重要:在执行以下操作前,请确保 WSL 命令行窗口保持打开状态,以维持 WSL 2 虚拟机运行。

附加设备到 WSL

1
2
# 将设备附加到 WSL(不需要管理员权限)
usbipd attach --wsl --busid 4-4

注意事项

  1. USB 设备连接到 WSL 后,Windows 将无法访问该设备
  2. 所有 WSL 2 分发版都可以使用已连接的设备
  3. 设备保持连接状态直到手动分离或物理断开

验证设备连接

在 WSL 终端中执行:

1
2
# 列出已连接的 USB 设备
lsusb

应能看到刚刚附加的设备信息。

第四步:断开设备连接

使用完毕后,可通过以下方式断开设备:

方法一:物理断开 USB 设备

方法二:使用命令分离

1
2
# 在 PowerShell 中执行
usbipd detach --busid 4-4

常见问题

设备权限问题

如果在 WSL 中无法以非 root 用户访问设备,需要配置 udev 规则:

1
2
3
4
5
6
7
8
9
# 创建 udev 规则文件
sudo nano /etc/udev/rules.d/99-usb-device.rules

# 添加规则(根据实际设备调整)
SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", ATTR{idProduct}=="xxxx", MODE="0666"

# 重新加载规则
sudo udevadm control --reload-rules
sudo udevadm trigger

内核版本过低

如果内核版本低于 5.10.60.1,执行以下命令更新:

1
2
3
4
5
# 关闭所有 WSL 实例
wsl --shutdown

# 更新 WSL
wsl --update

设备无法识别

  1. 确认设备已正确绑定(状态为 Shared
  2. 检查 WSL 虚拟机是否正在运行
  3. 尝试重新启动 usbipd 服务:
1
2
3
# 在管理员 PowerShell 中执行
net stop usbipd
net start usbipd

STM32 开发场景配置

查找 J-Link 设备

1
2
3
4
5
# 列出设备,找到 J-Link 的 BUSID
usbipd list
# 示例输出:
# BUSID VID:PID DEVICE STATE
# 2-3 1366:0101 J-Link driver Not shared

绑定并连接 J-Link

1
2
3
4
5
# 绑定设备(管理员权限)
usbipd bind --busid 2-3

# 附加到 WSL
usbipd attach --wsl --busid 2-3

在 WSL 中验证

1
2
3
4
5
6
7
# 检查设备
lsusb | grep -i jlink
# 应显示:Bus 001 Device 002: ID 1366:0101 SEGGER J-Link

# 测试 J-Link 连接
JLinkExe
# 输入 connect 命令测试连接

串口设备配置

查找串口设备

1
2
3
4
# 在设备管理器中查看 COM 口号(如 COM3)
# 然后在 PowerShell 中查找对应的 USB 设备
usbipd list
# 找到 USB Serial Converter 或 CH340/CP2102 等设备

连接串口设备

1
2
3
4
5
# 绑定串口设备
usbipd bind --busid 3-2

# 附加到 WSL
usbipd attach --wsl --busid 3-2

在 WSL 中使用串口

1
2
3
4
5
6
7
8
9
10
# 查看串口设备
ls /dev/ttyUSB* /dev/ttyACM*
# 通常显示为 /dev/ttyUSB0 或 /dev/ttyACM0

# 设置串口权限
sudo chmod 666 /dev/ttyUSB0

# 使用 minicom 进行串口调试
sudo apt install minicom
minicom -D /dev/ttyUSB0 -b 115200

配置 udev 规则(推荐)

为避免每次都需要手动设置权限,可配置 udev 规则:

1
2
# 创建 J-Link 规则
sudo nano /etc/udev/rules.d/99-jlink.rules

添加以下内容:

1
2
3
4
5
6
7
8
# J-Link 调试器
SUBSYSTEM=="usb", ATTR{idVendor}=="1366", ATTR{idProduct}=="0101", MODE="0666", GROUP="plugdev"

# USB 串口设备(CH340)
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE="0666", GROUP="dialout"

# USB 串口设备(CP2102)
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE="0666", GROUP="dialout"

重新加载规则:

1
2
3
4
5
sudo udevadm control --reload-rules
sudo udevadm trigger

# 将当前用户添加到相关组
sudo usermod -a -G plugdev,dialout $USER

开发工作流建议

保持设备连接

开发过程中建议保持 WSL 窗口打开,避免虚拟机休眠导致设备断开。可以使用 tmuxscreen 保持会话:

1
2
3
4
5
# 安装 tmux
sudo apt install tmux

# 创建持久会话
tmux new -s dev

自动化连接脚本

创建 PowerShell 脚本简化设备连接流程:

1
2
3
4
5
6
7
8
# connect-stm32-devices.ps1
# 连接 J-Link
usbipd attach --wsl --busid 2-3

# 连接串口
usbipd attach --wsl --busid 3-2

Write-Host "STM32 开发设备已连接到 WSL" -ForegroundColor Green

适用场景

  • STM32 开发:使用 J-Link/ST-Link 进行程序烧录和调试
  • 串口调试:通过 USB 转串口模块进行日志输出和命令交互
  • 嵌入式开发:Arduino、ESP32 等开发板刷写
  • 硬件调试:逻辑分析仪、示波器等 USB 设备访问