🙆

WSL2からホストマシンのUSBデバイスを使えるようにする

2024/05/07に公開

はじめに

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を開いて下記のコマンドを入力してインストール

    PowerShell
    winget install --interactive --exact dorssel.usbipd-win
    
  • 今回のターゲットとなるデバイス
    • FT2232D
      FT2232Dですが、USB-シリアル変換モジュールと呼ばれるもので、PCとマイコンとでUART通信したり、信号のレベル変換をすることでRS232C規格の機器とも通信できます。
      また、MPSSEというモードに切り替えて使う事で、GPIOやI2C,SPIが普通のPCでも使えるようになります。
      これを、Windows上で動くWSL2でも使えるようにするのが目的です。
      実際のデバイスマネージャ上では下記のように表示されています。

WSL2側(Ubuntu)のUSBデバイスを確認

まず、USBデバイス一覧を確認します。

WSL2(Ubuntu)
$ 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
    
    今回の対象となるデバイスが表示されています
    2-3    0403:6010  Dual RS232 (Interface 0), Dual RS232 (Interface 1)            Not shared
    
    STATEが[Not shared]になっているので、まだWSL2では使えません。
    使える様にするためには
    1. デバイスのバインド
    2. デバイスのアタッチ
    を実行する必要があります。

デバイスのバインド

PowerShell
> usbipd bind --busid 2-3

ここで指定するbusidとは、デバイスリストを表示した際の[BUSID]列に表示されている物を指します。
再度、デバイスリストを確認してみます。

PowerShell
> 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では使用できないので、次にバインドします。

デバイスのアタッチ

PowerShell
> usbipd attach --wsl --busid 2-3

再度、デバイスリストを確認します。

PowerShell
> 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側のデバイスリストを確認します

WSL2(Ubuntu)
$ 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