• Windows Subsystem for Linuxガイド 第28回 USBデバイスをWSLで使う - その2

今回は、前回の続きでusbipd-winを使い、Arduino開発環境を動かしてみる。記事中、Win32側はWindows 11 Ver.23H2、WSLはバージョン 1.2.5.0を利用した。

usbipd-winの使い方

usbipd-winでは、usbipd.exeコマンドを使い、WSL側と接続を行う。Win32側でこのコマンドを実行すれば、WSL側は指定したUSBデバイスが接続された状態になり、基本的には操作は必要ない。

なお、usbipd.exeコマンドは、本来のUSB/IPの機能を持つため、WSL関連のコマンドは、すべて「wsl」サブコマンドの後に続ける必要がある。(表01)は、usbipd.exeのWSL関連のコマンドとそのオプションを示す。usbipd-winのWSL関連のコマンドは3つ。「list」、「attach」、「detach」である。それぞれ、デバイスの一覧表示、デバイスの接続、デバイスの切断を行う。

  • ■表01

listコマンドは、attachコマンドで利用するBUSIDやVID:PID対の情報を表示する(写真01)。“-u”オプションを使うことで、デバイス名の表示をLinux側と同じにすることができる。これは、Linux用のhwdata(Linux側では前回インストールを行っている)と呼ばれるハードウェアのデータベースを使った表示で、Linuxのlsusbなどで使われているもの。そのファイル名からusbidsと呼ばれることもある。

  • 写真01: usbipd.exe wslコマンドの実行。listサブコマンドで接続可能なデバイスの一覧が得られ、先頭にあるBUSIDを使ってattachサブコマンドで接続を行う。接続したデバイスは、attached - WSLと表示される

attachコマンドは、USBデバイスをWSL側に接続する場合に用いる。このとき、USBデバイスの指定方法として「BUSID」と「VID:PID」(usbids)の2つの方法が利用できる。前者は、接続位置による区別で簡単にいうとハブ番号とポート番号の組合せである。後者は、USBデバイスが持つベンダーIDとプロダクトIDの組合せである。後者の方がデバイスを見つけやすいが、同一のUSBデバイスは、同じVIP:PIDを持つため区別ができないという欠点がある。このため、一般的には、BUSIDを使用してデバイスを指定する。

attachコマンドでは、-dオプションで、デバイスを接続するWSLディストリビューション名を指定できる。省略すると“Ubuntu”が仮定される。このため、-dオプションを使ってディストリビューションを指定した方がトラブルが少ない。

開発などでは、USBデバイスの抜き差しをすることが少なくない。こうした場合-aオプションで、再接続を自動化する。-aオプションを指定すると、usbipd.exe wsl attachコマンドは実行状態が続きプロンプトに戻らなくなる。この間、指定したデバイスが切断されても自動的に再接続処理を行う。ただし、WSL側がシャットダウンされた場合には再接続ができない。

なお、PowerShellでは、バックグラウンド演算子「&」やStart-Jobコマンドを使い、コマンドをバックグラウンド実行できる。複数のデバイスを接続し、それぞれを自動再接続させたい場合などには、usbipd.exeコマンドをバックグラウンド実行させる。


usbipd wsl attach -b "7-3" -d Ubuntu -a &

ジョブを停止する場合はStop-Jobコマンドを使う。

detachコマンドは、接続したUSBデバイスをUSB/IPから切断するときに使う。対象デバイスはBUSIDまたはVID:PIDでデバイスを指定するほか、-aオプションを使うことで、usbipd-winで接続したデバイスをすべて切断することができる。

LinuxでUSBデバイスを扱う

ここでは、具体的に開発ボードを接続して、開発環境を動かしてみる。まず、事前準備として、ユーザーがUSBシリアルポートにアクセスできるようにdialoutグループに登録しておく。これはUSBシリアルを利用する場合に必要な設定である。


sudo usermod -a -G dialout $USER

ここでは、ソニーのSpresenseを接続し、WSL側で開発環境を動作させてみる。Spresenseは、Arduino互換で動作できるため、ここではLinux版のソフトウェアを利用する。Spresense以外でもArduinoや互換ボードであれば基本的な操作は同じである。

まずは、統合開発環境であるArduino IDEをインストールする。これについては、Arduino公式サイトに説明がある。ただし、Ubuntu Ver.22.04 LTS以降の場合には、FUSEのインストールが必要である(AppImageファイルを使う場合)。IDEのインストールが終わったら、開発ボードを接続し、Win32側で「usbipd wsl attach」コマンドを実行しておく。

WSL側から接続されているデバイスを調べるには、lsusbコマンドを使う(表02)。そのほかには、sysfs(/sysディレクトリ)や/devを調べる方法もある。

  • ■表02

USBシリアルの場合、Linux側では、/dev/ttyUSB?というデバイスに割り当てられる。複数あって対応を調べたいときには、「dmesg | grep -i <ドライバ名>または"ttyUSB"」などとして、接続時のイベントメッセージを探す(写真02)。なお、SpresenseのUSBシリアルには、cp210xというドライバ名が使われている。

  • 写真02: Linux側では、lsusbコマンドで接続しているUSBデバイスの一覧を見ることができる。root hubはUSBコントローラー内部のhubで必ず表示される。2行目がusbipdで接続したデバイス。デバイスパスを探したい場合にはdmesgコマンドを使う

Arduino IDE(写真03)が起動したら、初回のみボードマネージャーでSpresense Arduino board packageをインストールし、開発ボードにファームウェアを転送する必要がある(図01)。このあたりはSpresenseの解説ページや利用する開発ボードの文書を参照してほしい。

  • 写真03: Arduino IDE Ver.2。WSLgによりLinux GUIプログラムも実行可能。

  • 図01: Spresense接続までの手順。Arduino互換ボードの手順はだいたい同じ。Arduino IDEの「設定」で、ボードマネージャーのURL(Spresenseホームページにある)を設定し、Spresenseのボードマネージャーをインストール。ボードとポートを選択できたら準備完了である

スケッチ(Arduinoのプログラム)を入力し、ツールバーの右矢印ボタン(書き込み)を押せば、コンパイルされたプログラムがデバイスに転送されるはずだ。前記、解説ページにLEDを点滅させるプログラムのスケッチがある。

エラーの場合、usbipd-win以外の問題としてUSBハブと開発ボードの接続がある。USBハブを複数経由するときなど、コマンド上はエラーがなくても電源容量などの問題で接続が正しくできないことがある。開発ボードはPCのUSBポートに直接接続するのが確実だ。

一部の開発ボードでは、ファームウェアの転送などにUSBマスストレージクラスを使うことがある。しかし、WSLのLinuxカーネルにはUSBマスストレージのデバイスドライバが組み込まれておらず、usbipd-winで接続してもWSL側でアクセスすることができない。次回は、WSLのLinuxカーネルの構成を変えて差し替え、USBマスストレージを利用する方法を解説する。

Windows Subsystem for Linuxガイド 連載バックナンバー
https://news.mynavi.jp/tag/winsubsystem/