3. WSL2 連接USB裝置篇(usbipd)
詳細内容參考:微軟官網WSL教學-如何連接USB裝置、以及 基于 usbip 实现共享 usb 设备 博文。
- 需求1: Win11 build 22000 版之後,只支持 x86機器,只支持 WSL2 功能虛擬機。至於Win10請查找官網教學看可行性。
- 需求2:Lunux Kernel在 5.10.60.1 版之後。
Windows主機透過 usbipd-win 套件,可以將多種USB周邊裝置,分享給Hyper-V從機、WSL2從機、或遠端的Linux服務器、遠端OpenWRT路由器。從機只要安裝 linux-tools (網路工具)和 usbip 套件,就可以發現被宿主機分享給他的 USB設備。
usbipd/usbip 透過網路或虛擬網路IP協議,將USB設備映射給近端的Hyper-V或WSL,或遠端的客戶端linux、OpenWRT機器。舉凡UART、JLink、STLink、OpenOCD、CAN、LAN、PRINTER、Secure KEY等USB裝置都可以映射。這裏主要操作USB裝置到WSL客戶端機器的映射。
- linux 是用
usbipd -D &啓動 usbipd 服務,用usbip bind命令將自己的USB 裝置綁定到 usbipd 服務,用usbip attach連接遠端(-r ip_addr)的 USB裝置。- windows 是用
usbipd server啓動 usbipd 服務,用usbipd bind命令將自己的USB 裝置綁定到 usbipd server。- windows 額外提供
usbipd wsl attach的近端命令,不透過 usbipd server,直接將 USB 裝置提供給(-d指定的) WSL客戶端,客戶端不必再用usbipd命令連接宿主裝置。- WSL客戶端仍然可以采用遠端模式,只要知道宿主機的ip,仍可沿用
usbip attach連接宿主機/其他主機的 usbipd server所提供的USB裝置。
3.1 usbipd 安裝
- Windows主機: 到usbipd-win 項目的最新發布頁面。下載
usbipd-win_x.x.x.msi安裝 usbipd。可能需要重啓主機生效。 -
WSL2從機:Ubuntu/Debian 系統的從機可以執行下面兩條命令安裝 usbip:
sudo apt install linux-tools-5.4.0-77-generic hwdata sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/5.4.0-77-generic/usbip 20or
sudo apt install linux-tools-virtual hwdata sudo update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20
3.2 usbipd 使用
- #### 主機查看目前 usbipd/wsl 連綫:
usbipd wsl list
Pyboard 目前挂在 BUSID 2-4 上:
BUSID VID:PID DEVICE STATE
2-4 f055:9800 USB 大容量存储设备, USB 串行设备 (COM7) Not attached
2-8 2808:a658 FocalTech Fingerprint Reader Not attached
2-9 3277:0016 Integrated Camera Not attached
2-10 8087:0033 英特尔(R) 无线 Bluetooth(R) Not attached
2-13 090c:1000 USB 大容量存储设备 Not attached
- #### 把 Pyboard 連接到 WSL 從機上:
# 將裝置連接到 wsl:
usbipd wsl attach -b 2-4
再查看:
BUSID VID:PID DEVICE STATE
2-4 f055:9800 USB 大容量存储设备, USB 串行设备 (COM7) Attached - Ubuntu-20.04
2-8 2808:a658 FocalTech Fingerprint Reader Not attached
2-9 3277:0016 Integrated Camera Not attached
2-10 8087:0033 英特尔(R) 无线 Bluetooth(R) Not attached
2-13 090c:1000 USB 大容量存储设备 Not attached
看到 Pyboard 挂在Ubuntu-20.04上了。
- #### 從機查看已連接的 USB裝置:
# 查看已連接的 USB裝置:
lsusb
Pyboard 已經連接上了:
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID f055:9800 MicroPython Pyboard Virtual Comm Port in FS Mode
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
3.3 usbipd參考
其他 WSL2 從機參考:其他發行版的 usbip 客戶端包。
安裝設定完成後,主機可以以管理員身份執行 Powewrshell,下 usbipd 命令,將選定的USB裝置交付給WSL2從機。
命令用法舉例如下:
usbipd -?/usbipd wsl -?: 查看命令幫助説明 / 針對 WSL客戶端的命令幫助説明。-
usbipd wsl list: 查看Windows11主機可以提供給WSL的USB裝置,以及裝置在WSL的連接狀態。 -
usbipd wsl attach -b xx-xx: 將 BUSID為 xx-xx 的裝置連接到WSL。若添加
-a參數則此命令會 hold住,持續監視並重連裝置到WSL,直到按下Ctrl+C。若要連到非預設的WSL子系統,可用
-d WSL_NAME指定子系統。(可用wsl -l查系統有的子系統) usbipd wsl attach -i VID:PID: 將裝置類別為 VID:PID 的裝置連接到WSL。
若添加
-a參數則此命令會 hold住,持續監視並重連裝置到WSL,直到按下Ctrl+C。
若要連到非預設的WSL子系統,可用-d WSL_NAME指定子系統。(可用wsl -l查系統有的子系統)usbipd wsl detach -b xx-xx:斷開 BUSID為xx-xx 的WSL連接。-
usbipd wsl detach -i VID:PID:斷開 裝置類別為 VID:PID 的WSL連接。
3.4 WSL從機掛載驅動或安裝工具套件
通用的Linux内核有標準的USB類裝置驅動程式,如VCP(USB串口),可以直接使用。若有特殊的裝置,就要額外安裝驅動程式。有的提供了安裝程式,有的需要自行編譯。
3.4.1 VCP 驅動
VCP是標準的 USB Class,是虛擬串口硬件,Ubuntu提供通用驅動。虛擬串口一種是支持 V.25標準 Modem的類型,會被Linux枚舉成 /dev/ttyACM* 樣式的裝置,一種是普通的 UART命令類型,模擬16550 串口控制器,會被Linux枚舉成 /dev/ttyUSB*樣式的裝置。
使用橋接器的MCU需要在 screen 連接時設定baudrate,使用自帶USB VCP的MCU可以不設定。
安裝uart 工具:
sudo snap install serial-monitor --edge
測試
- CH340: ID:1a86:7523
- CP210x: ID:10c4:ea60
- PL2303: ID:067b:2303
3.4.2 CDC – ACM 裝置(ttyACM)
與VCP不同,CDC-ACM 裝置是 USB下虛擬的一套 Modem協議,雖然和 VCP一樣是序列通信,但不會有硬體流控和波特率的設定。CDC裝置會被枚舉在 /dev/ttyACM* 中。
STM32在 microPython下的 USB 被枚舉成MSC+CDC 複合設備,在管理員Powershell 下,用 usbipd.exe wsl list 可以看到其 VID:PID 是 f055:9800 。
$ usbipd.exe wsl list
BUSID VID:PID DEVICE STATE
2-4 f055:9800 USB 大容量存储设备, USB 串行设备 (COM3) Not attached
。。。
用 usbipd wsl attach -a -i f055:9800 將其連接到 WSL,並持續監視重連:
PS C:\Users\cyue1> usbipd wsl attach -a -i f055:9800
usbipd: info: Device with hardware-id 'f055:9800' found at busid '2-4'.
usbipd: info: Starting endless attach loop; press Ctrl+C to quit.
Attached
在Linux下用 lsusb查看裝置信息:
$ lsusb
。。。
Bus 001 Device 002: ID f055:9800 MicroPython Pyboard Virtual Comm Port in FS Mode
。。。
用 screen 連接STM32 的 VCP 時,可以不設定 baudrate。
3.4.3 DFU UTIL 套件
許多MCU會提供DFU(device firmware updates)模式,此模式可透過RS232界面或USB界面升級MCU的Firmware。
Ubuntu 下的 DFU工具在 apt 的 dfu-util 套件中,可以直接使用。
sudo apt install dfu-util
但 ubuntu20.04 提供的 0.9版有些老舊,目前最新的是 0.11版。建議從DFU UTIL官網直接下載最新dfu工具的執行檔包,解壓後,將linux-amd64/ 下的dfu-xxx 文件,複製到 /usr/local/bin ,以取代 apt 提供的版本。另外可參考dfu build 説明,自行編譯自己的版本。
STM32 進入DFU 模式的方法是拉高 BOOT0 pin,再 reset MCU,這時 USB 看到的STM32F407 的 VID:PID 會是 0483:df11 。
可用下面的 PowerShell 指令將 DFU模式的STM32 接到 WSL:
usbipd wsl attach -a -i 0483:df11
3.4.4 OpenOCD DEBUG工具
OpenOCD是通用的 Debugger 工具。可以連接多家的 DEBUGGER(詳情參考這裏)。Ubuntu可以直接 apt 安裝。
sudo apt install openocd
JLink也可由 OpenOCD控制。
3.4.5 JLink DEBUG工具
除了OpenOCD,對於JLink裝置,可以從 https://www.segger.com/downloads/jlink/JLink_Linux_x86_64.deb 下載 JLink。點Accept 後下載。
我當前下載到的包是 JLink_Linux_V784f_x86_64.deb,下載後在 WSL ubuntu中用 sudo dpkg -i命令安裝此安裝包:
sudo dpkg -i JLink_Linux_V784f_x86_64.deb
驗證:
Host 提供 jlink給WSL:
usbipd wsl attach -a -i 1366:0101
連接 STM32F407 開發板到 JLink,然後在WSL 執行JLinkSTM32:
$JLinkSTM32
SEGGER J-Link Unlock tool for STM32 devices
Compiled Feb 7 2023 16:54:18
(c) 2009-2015 SEGGER Microcontroller GmbH, www.segger.com
Solutions for real time microcontroller applications
This program is designed to reset the option bytes of a STM32 device to their factory settings。If read protection of the device is enabled, reset the option bytes will cause a mass erase.
Options:
[0] Exit
[1] STM32F0xxxx
[2] STM32F1xxxx
[3] STM32F2xxxx
[4] STM32F3xxxx
[5] STM32F4xxxx
。。。
Please select the correct device family: 5
Connecting to J-Link via USB...O.K.
Using SWD as target interface.
Target interface speed: 1000 kHz.
VTarget = 3.300V
連接成功。
3.4.6 STLink V2 DEBUG工具
Ubuntu下的stlink-v2需要編譯。
3.4.6.1、安裝編譯依賴
sudo apt-get install git make cmake libusb-1.0-0-dev -y
sudo apt-get install gcc build-essential -y
3.4.6.2、編譯安裝stlink工具
git clone https://github.com/stlink-org/stlink
cd stlink
cmake
make
sudo make install
3.4.6.3 stlink的 st-xxx 命令舉例:
st-flash erase
st-flash reset
st-info --probe
st-flash read out.bin 0x8000000 0x40000
st-flash write xxx.bin 0x8000000
3.5 讓 WSL2 支持 Mass Storage Class(MSC)
STM32 在 microPython 下是被枚舉成 CDC+MSC,可以直接用 隨身碟模式來修改 microPython 的文件,速度比其他的 microPython 透過 CDC虛擬串口快速而知覺了。然而,WSL2 內核不支持 MSC。
找到 https://github.com/jovton/USB-Storage-on-WSL2 的方案是編譯內核,增加 iSCSI 來透過網路連接。但對於 CDC+MSC 合成裝置,我們已經用 usbipd 把 USB 連給 WSL2,直接讓內核支持 MSC 就好了。
kernel 編譯安裝方法:
- 安裝 kernel 下載和編譯環境:
sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses5-dev git bc -y
- git clone取得 Microsoft WSL2 內核:
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
- 進入內核目錄,選擇 wsl 的config檔案,修改選項:
cd WSL2-Linux-Kernel
export KCONFIG_CONFIG=Microsoft/config-wsl
make menuconfig
修改需求:
- Device Drivers 的 USB 支持USB Mass Storage 。
- (可選) File System 的 DOS/FAT/EXFAT/NTFS 支持 FAT UTF-8 和 支持 exFAT。
- Kernel hacking 的編譯時檢查,關閉生成 BTF 訊息 (編譯報錯,省麻煩關了) 。
因為開發環境常用,我直接編進內核,不做內核模塊加載:
Device Drivers --->
[*] USB support --->
<*> USB Mass Storage
File systems --->
DOS/FAT/EXFAT/NT Filesystems --->
[*] Enable FAT UTF-8 option by default
<*> exFAT filesystem support
Kernel hacking --->
Compile-time checks and compiler options --->
[ ] Generate BTF typeinfo
- 保存配置退出後,編譯:(分工給CPUx2=40個task協同工作)
time make KCONFIG_CONFIG=Microsoft/config-wsl -j40
我的 12700H 筆記本大約花5分鐘編譯:
real 3m45.713s user 56m28.891s sys 5m22.852s
- 安裝新構建的模塊:
sudo make modules_install
似乎模塊有工具相依問題,先不管了,我要的功能都直接進 kernel 了.
arch/x86/Makefile:142: CONFIG_X86_X32 enabled but no binutils support
INSTALL /lib/modules/5.15.90.1-microsoft-standard-WSL2+/kernel/drivers/usb/storage/usb-storage.ko
INSTALL /lib/modules/5.15.90.1-microsoft-standard-WSL2+/kernel/fs/exfat/exfat.ko
DEPMOD /lib/modules/5.15.90.1-microsoft-standard-WSL2+
- 將新的內核映像bzImage 複製 Windows 主機中(cyue1 是我的 Windows帳戶,請改成你的):
cp ./arch/x86_64/boot/bzImage /mnt/c/Users/cyue1/
- 在 Windows 主機的用戶目錄下建立
.wslconfig文件。設定 wsl2 的參數。(cyue1 是我的 Windows帳戶,請改成你的)
pico /mnt/c/Users/cyue1/.wslconfig
內容如下:
[wsl2]
memory=24GB
kernel=C:\\Users\\cyue1\\bzImage
(我的筆記本有 32GB RAM,指定24GB給 wsl2 使用。內核指定為剛剛編譯好複製過來的)
參考 https://learn.microsoft.com/zh-tw/windows/wsl/wsl-config 設定wsl成為你想要的.
- 關閉 wsl ,之後再重啟,以使用新內核和設定.
sudo shutdown now
- wsl2開機後驗證。power shell 下:
usbipd wsl list
BUSID VID:PID DEVICE STATE
2-4 f055:9800 USB 大容量存储设备, USB 串行设备 (COM7) Not attached
2-8 2808:a658 FocalTech Fingerprint Reader Not attached
2-9 3277:0016 Integrated Camera Not attached
2-10 8087:0033 英特尔(R) 无线 Bluetooth(R) Not attached
- 將 microPython 裝置 (2-4) 連接到WSL上:
usbipd wsl attach -b 2-4
- wsl 中察看usb連接:
lsusb
Bus 002 Device 002: ID 090c:1000 Silicon Motion, Inc。- Taiwan (formerly Feiya Technology Corp.) Flash Drive
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID f055:9800 MicroPython Pyboard Virtual Comm Port in FS Mode
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
- wsl 中察看 /dev,看到多了
/dev/sdd和/dev/sdd1
ls /dev/sd* -ls /dev/sd*
/dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sdd1
- mount sdd1 並查看內容:
sudo mount /dev/sdd1 /mnt/d
ls /mnt/d
看到是我的 pyboard 內容:
boot.py main.py myApp.py polar.py pybcdc.inf README.txt 'System Volume Information' testVCP.py
成功灑花。
留言