WSL2からホストマシンのUSBデバイスを使えるようにする
はじめに
WSL2上で開発をする場合、ホスト側であるWindowsに接続されたUSBデバイスに直接アクセスする事ができないため、USBに接続されたデバイスを用いた開発が出来ませんが、USB/IPというUSBデバイスをIP上で使えるようにした仕組みがあり、今回はそのUSB/IPを利用してWSL2でUSBデバイスを使ってみたいと思います。
前提条件
- ホストOSがWindows10/11かつ、x64版であること(x86/ARM版は非対応)
- WSL2がインストールされ何れかのLinuxディストリビューションがインストールされていること
ホスト側(Windows側)のセットアップ
- usbipd-winパッケージのインストール
ホスト側のWindowsでUSB/IPを利用するためにusbipd-winパッケージをインストールします。
以下のリンクからmsi形式のインストーラーも準備されていますが、PowerShellでの操作が多いので、wingetを利用したインストールの方が手間が少なくておすすめです。-
msiインストーラーからインストールする方法
usbipd-winダウンロードページ
ダウンロードページから最新のmsiインストーラーをダウンロードして実行する。 -
PowerShellからwingetでインストールする方法
PowerShellを開いて下記のコマンドを入力してインストール
PowerShellwinget install --interactive --exact dorssel.usbipd-win
-
- 今回のターゲットとなるデバイス
- FT2232D
FT2232Dですが、USB-シリアル変換モジュールと呼ばれるもので、PCとマイコンとでUART通信したり、信号のレベル変換をすることでRS232C規格の機器とも通信できます。
また、MPSSEというモードに切り替えて使う事で、GPIOやI2C,SPIが普通のPCでも使えるようになります。
これを、Windows上で動くWSL2でも使えるようにするのが目的です。
実際のデバイスマネージャ上では下記のように表示されています。
- FT2232D
WSL2側(Ubuntu)のUSBデバイスを確認
まず、USBデバイス一覧を確認します。
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
現状ではホスト側からアタッチされていないので、デバイス一覧が見えない事が分かります。
ホスト側(Windows)からWSL2側へデバイスをアタッチする
- ホスト側(Windows)のUSB/IPのデバイスリストを表示PowerShell
> usbipd list Connected: BUSID VID:PID DEVICE STATE 2-3 0403:6010 Dual RS232 (Interface 0), Dual RS232 (Interface 1) Not shared 2-6 27c6:6094 Goodix Moc Fingerprint Not shared 2-10 8087:0033 インテル(R) ワイヤレス Bluetooth(R) Not shared
STATEが[Not shared]になっているので、まだWSL2では使えません。2-3 0403:6010 Dual RS232 (Interface 0), Dual RS232 (Interface 1) Not shared
使える様にするためには
1. デバイスのバインド
2. デバイスのアタッチ
を実行する必要があります。
デバイスのバインド
> usbipd bind --busid 2-3
ここで指定するbusidとは、デバイスリストを表示した際の[BUSID]列に表示されている物を指します。
再度、デバイスリストを確認してみます。
> usbipd list
Connected:
BUSID VID:PID DEVICE STATE
2-3 0403:6010 Dual RS232 (Interface 0), Dual RS232 (Interface 1) Shared
2-6 27c6:6094 Goodix Moc Fingerprint Not shared
2-10 8087:0033 インテル(R) ワイヤレス Bluetooth(R) Not shared
対象のデバイスの[STATE]がNot sharedからSharedになりました。
これだけではWSL2では使用できないので、次にバインドします。
デバイスのアタッチ
> usbipd attach --wsl --busid 2-3
再度、デバイスリストを確認します。
> usbipd list
Connected:
BUSID VID:PID DEVICE STATE
2-3 0403:6010 Dual RS232 (Interface 0), Dual RS232 (Interface 1) Attached
2-6 27c6:6094 Goodix Moc Fingerprint Not shared
2-10 8087:0033 インテル(R) ワイヤレス Bluetooth(R) Not shared
対象のデバイスの[STATE]がAttachedになりました。
最後に、WSL2側のデバイスリストを確認します
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 0403:6010 Future Technology Devices International, Ltd FT2232C/D/H Dual UART/FIFO IC
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
ちゃんとWSL2側でデバイスが認識されていますね!
Bus 001 Device 002: ID 0403:6010 Future Technology Devices International, Ltd FT2232C/D/H Dual UART/FIFO IC
まとめ
WSL2はWindows上で動くため、USBデバイスなどを直接利用する事ができませんでしたが、USB/IPという仕組みを利用する事でWSL2上でも物理デバイスを使った開発が行えるようになります。
USB/IPと書かれている通り、IPのペイロードにUSBのメッセージをカプセリングすることで、IP経由でUSBを使えるようにしたものなので、IPネットワーク上の別の機器からUSBデバイスを操作する事も可能になります。
RaspberryPiや小型のボックスPCに接続されたUSBデバイスを、少し離れた場所にあるLAN接続されたPCから利用することもできそうです。
また、次回以降はFT2232DなどのUSBで使えるGPIO/I2C/SPIの使い方について記事を書いていこうと思います。
Discussion