wsl2 ubuntu 访问 USB 设备

注意:如下 usbipd 命令需要在 以管理员身份运行 的 powershell 中执行

usbipd: USB/IP open-source project

本文主要内容

本文主要介绍了如何在 Windows 10/11 系统中,通过 WSL 2(Windows Subsystem for Linux 2)的 Ubuntu 环境,使用 usbipd-win 项目访问 USB 转串口设备。同时,还探讨了普通用户进程访问设备时可能遇到的权限问题及其解决方案。

前提条件

  • 运行 Windows 11(内部版本 22000 或更高版本)。Windows 10 也支持,但需要一些额外步骤。
  • 已安装并设置为最新版本的 WSL。
  • 已安装并设置为 WSL 2 的 Linux 发行版。

大致流程

windows admin usbipd bind device -> windows admin usbipd attach device -> wsl2 ubuntu 操作 USB 设备 -> windows admin usbipd detach device -> windows admin usbipd unbind device

下载安装必要工具

windows 端工具

下载 usbipd-win

重新以管理员身份打开一个 [[windows terminal]]

wsl2 ubuntu 安装 usbutils

sudo apt install usbutils

确认设备的 USBID

确定 usb 设备BUS-ID (通过对比是否插入设备两种情况下 usbipd.exe list 命令的结果)

例如:

不插设备执行结果

$ usbipd.exe list  
Connected:  
BUSID VID:PID DEVICE STATE  
1-1 30c9:0096 HP 5MP Camera, HP IR Camera, Camera DFU Device Not shared  
1-10 8087:0033 英特尔(R) 无线 Bluetooth(R) Not shared  
  
Persisted:  
GUID DEVICE  
  
usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.

插入设备后执行结果

$ usbipd.exe list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-1    30c9:0096  HP 5MP Camera, HP IR Camera, Camera DFU Device                Not shared
1-3    1a86:7523  USB-SERIAL CH340 (COM4)                                       Not shared

Persisted:
GUID                                  DEVICE

usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.

找到对应设备:1-3 就是我们需要的 BUSID

1-3    1a86:7523  USB-SERIAL CH340 (COM4)                                       Not shared

bind 设备

$ usbipd bind --force -b 1-3


$ usbipd.exe list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-1    30c9:0096  HP 5MP Camera, HP IR Camera, Camera DFU Device                Not shared
1-3    1a86:7523  USB-SERIAL CH340 (COM4)                                       Shared (forced)
1-10   8087:0033  英特尔(R) 无线 Bluetooth(R)                                   Not shared

Persisted:
GUID                                  DEVICE

usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.

attach 设备

$ usbipd attach -w --busid 1-3
usbipd: info: Using WSL distribution 'Ubuntu-24.04' to attach; the device will be available in all WSL 2 distributions.
usbipd: info: Detected networking mode 'nat'.
usbipd: info: Using IP address 172.20.16.1 to reach the host.
WSL wsl: �hKm0R localhost �NtM�n
                                �FO*g\��P0R WSL0NAT !j_
                                                       N�v WSL
WSL N/ec localhost �Nt0
WSL
WSL


$ usbipd.exe list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-1    30c9:0096  HP 5MP Camera, HP IR Camera, Camera DFU Device                Not shared
1-3    1a86:7523  USB-SERIAL CH340 (COM8)                                       Attached
1-10   8087:0033  英特尔(R) 无线 Bluetooth(R)                                   Not shared

Persisted:
GUID                                  DEVICE

usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.

wsl2 ubuntu

## windows attach 设备之前
$ sudo lsusb                                                                       Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

## windows attach 设备之后
$ sudo lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 1a86:7523 QinHeng Electronics CH340 serial converter
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
$ ls -lah /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Jun 19 14:37 /dev/ttyUSB0

测试打开 /dev/ttyUSB0

#include <iostream>
#include <fcntl.h>      // open()
#include <unistd.h>     // close()
#include <errno.h>      // errno
#include <string.h>     // strerror()

int main() {
    const char* device = "/dev/ttyUSB0";

    // O_RDWR: 读写模式
    // O_NOCTTY: 不让这个设备成为控制终端
    // O_NONBLOCK: 非阻塞模式打开
    int fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);

    if (fd == -1) {
        std::cerr << "Failed to open " << device << ": "
                  << strerror(errno) << " (errno: " << errno << ")" << std::endl;
        return 1;
    }

    std::cout << "Successfully opened " << device << " with fd = " << fd << std::endl;

    // 后续可以添加串口配置代码(termios 等)

    close(fd);
    return 0;
}
g++ -o open_ttyUSB open_ttyUSB.cpp
$ ./open_ttyUSB
Successfully opened /dev/ttyUSB0 with fd = 3

为什么能够成功:因为当前用户默认已经属于 dialout 组

$ groups luyang
luyang : luyang adm dialout cdrom floppy sudo audio dip video plugdev users netdev docker

权限问题导致打开 /dev/ttyUSB 设备失败

在依次裸机直接安装 ubuntu 系统,默认用户不属于 dialout 组,会出现设备打开失败的情况。解决方案分三种

方法 1:临时修改权限

可以使用 chmod 命令临时修改 /dev/ttyUSB0 的权限,使其对所有用户可读写:

sudo chmod 666 /dev/ttyUSB0

这种方法简单快捷,但重启系统后权限会恢复默认,需要重新设置。

方法 2:将用户添加到 dialout 组

/dev/ttyUSB0 设备通常属于 dialout 组。将普通用户添加到该组后,用户即可访问该设备:

sudo usermod -aG dialout $USER

添加用户到组后,需要注销并重新登录,或者重启系统,使更改生效。

方法 3:使用 udev 规则永久设置权限

通过创建 udev 规则,可以永久设置 /dev/ttyUSB0 的权限。步骤如下: 创建规则文件:

sudo nano /etc/udev/rules.d/70-ttyusb.rules

在文件中添加以下内容:

KERNEL=="ttyUSB[0-9]*", MODE="0666"

或者,根据设备的供应商 ID 和产品 ID 指定规则:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE="0666"

使用 lsusb 命令查看设备的供应商 ID 和产品 ID。如下:1a86:7523

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 1a86:7523 QinHeng Electronics CH340 serial converter
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

保存文件后,重新加载 udev 规则:

sudo udevadm control --reload-rules
sudo udevadm trigger

然后重新插入 USB 设备。

detach 设备

$ usbipd.exe list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-1    30c9:0096  HP 5MP Camera, HP IR Camera, Camera DFU Device                Not shared
1-3    1a86:7523  USB-SERIAL CH340 (COM8)                                       Attached
1-10   8087:0033  英特尔(R) 无线 Bluetooth(R)                                   Not shared

Persisted:
GUID                                  DEVICE

usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.
$ usbipd detach --busid 1-3

$ usbipd.exe list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-1    30c9:0096  HP 5MP Camera, HP IR Camera, Camera DFU Device                Not shared
1-3    1a86:7523  USB-SERIAL CH340 (COM8)                                       Shared (forced)
1-10   8087:0033  英特尔(R) 无线 Bluetooth(R)                                   Not shared

Persisted:
GUID                                  DEVICE

usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.

unbind 设备

$ usbipd unbind -b 1-3

$ usbipd.exe list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-1    30c9:0096  HP 5MP Camera, HP IR Camera, Camera DFU Device                Not shared
1-3    1a86:7523  USB-SERIAL CH340 (COM8)                                       Not shared
1-10   8087:0033  英特尔(R) 无线 Bluetooth(R)                                   Not shared

Persisted:
GUID                                  DEVICE

usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required.