WSLでUSBを使った時のメモ(バージョン 2.5.7.0)
WSLのバージョンが2.5.7.0でカーネルバージョンが6.6.87.1-1になってカーネルの再ビルドしなくても 色々なUSBデバイスが使えるようになったので試してみた時のメモ。
usbipd-winのgithubからダウンロード(使用したのは5.10)
インストールはファイルをダウンロードして実行するだけ。
WindowsTerminarが開いている場合は一旦すべて閉じる(PATHの変更を有効にするため)
systemdを有効にするため、/etc/wsl.conf
に以下の設定を追加。
[boot]
systemd=true
ネットワーク経由でUSBデバイスを共有することを可能にするため、仮想USBホストコントローラインタフェース(vhci-hcd)をインストール (ドライバの組み込み)。
/etc/modules-load.d/usb.conf
(ファイル名は何でも可)を以下の内容で作成し、WSLの再起動。
vhci-hcd
[!TIP] お試しで1回だけ読み込むなら以下。この場合は再起動不要(というか再起動したら消える)。
sudo modprobe vhci-hcd
lsusb
とか使いたいので、インストール。
sudo apt install usbutils
設定を有効にするため、仮想マシンを再起動する。
開いているすべての仮想マシンを閉じた後、Windwos側で wsl --shutdown
を実行し、
wsl -l -v
ですべて仮想マシンのSTATEがStopped
になっていることを確認し仮想マシンを再度実行。
systemctl
起動していればサービス一覧が表示される。
起動していなければ以下のようなメッセージが表示される。
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: ホストが落ちています
lsmod
表示の中にvhci_hcd
があることを確認。
なければ組み込みの設定を確認。
今回は エレコムの UCAM-DLA200HBK を使用。
かなり古いカメラなのでもう売ってないけど…
UVC仕様のカメラなら基本的に同じはず。
今回はカメラなので、自身にvideoグループを追加
(要 再ログイン、シャットダウンは不要)
sudo gpasswd -a $USER video
表示ツールは何でもいいけど、とりあえずguvcviewで。
sudo apt install guvcview
PowerShellやコマンドプロンプト等を管理者として開く。
USBデバイスのリストを表示
(今回はカメラを使うのでそこだけ抜粋。IDとか名前は例)
Not shared
になっている。
usbipd.exe list
・・・・
9-2 056e:700a Venus USB2.0 Camera Not shared
・・・・
bindする(busidは上で調べたものを使用)
usbipd.exe bind --busid 9-2
または
usbipd.exe bind --force --busid 9-2
[!NOTE] USBPcapがインストールされている(wiresharkなど)とwarningが表示されてbindできないので
--force
オプションを追加して実行する。
(warningで–forceオプションを付けろと教えてくれる)
確認
Shared
または Shared (forced)
になっている。
usbipd.exe list
・・・・
9-2 056e:700a Venus USB2.0 Camera Shared (forced)
・・・・
attachする(attachする前にWSLの仮想マシンが起動していること)
usbipd.exe attach --wsl --busid 9-2
[!TIP] 以下のようにbindするとUSB挿抜する度に自動でattachしてくれるらしい。確認してないけど。
usbipd.exe attach --wsl --busid 2-1 --auto-attach
確認する
Attached
になっている
usbipd.exe list
・・・・
9-2 056e:700a Venus USB2.0 Camera Attached
・・・・
USB機器が割り当てられたことを確認する。
lsusb
こんな感じで表示される
Bus 001 Device 002: ID 056e:700a Elecom Co., Ltd Venus USB2.0 Camera
デバイスノードも確認しておく。
ls -la /dev/video*
こんな感じ
/dev/video0 /dev/video1
実際に表示してみる。
LANG
がja_JP.UTF8
とかのままだと文字化けしてしまうので、Cに変更して実行。
LANG="C" guvcview
別ウィンドウが表示されるが、何も表示されない コンソールには「V4L2_CORE: Could not grab image (select timeout): リソースが一時的に利用できません」と表示され続ける
GuvcviewウィンドウのVideo Controls をクリックし、
[!NOTE] これらのパラメータが選択できるかは使用するカメラによる。
PCのスペック等によって、もうちょっと大きいサイズでも表示できることがある。
[!TIP] 日本語で表示するには、例えば以下のように日本語フォントをインストールして LANGを指定せずに実行すれば良い。
sudo apt install fonts-noto-cjk
USBカメラを取り外すためにアタッチ解除とバインド解除
usbipd.exe detach --busid 9-2
usbipd.exe unbind --busid 9-2
あまり実用的とは言い難い結果となってしまった。
試しに、Ubuntu PCからUSBカメラをエクスポートしてWSLで表示してみる。
[!NOTE] 「Netive UbuntuあるならWSL使わんでも良いやん」という気もするが…
USBカメラを接続し、認識されているか確認する。
lsusb
こんな感じで表示される
・・・
Bus 003 Device 006: ID 056e:700a Elecom Co., Ltd Venus USB2.0 Camera
・・・
デバイスノードの確認。
ls /dev/video*
こんな感じ。
カメラが他にも接続されているので2×2表示されてるけど…
今回接続されたのは2と3のはず(今はこれを使わないので気にしない)
/dev/video0 /dev/video1 /dev/video2 /dev/video3
必要ならguvcviewをインストールして試してみてちょ。
sudo apt install linux-tools-generic
usbipを実行してみる
usbip
※ linux-tools-≪バージョン≫-generic をインストールしろと言われたら従う。例えば
sudo apt install linux-tools-6.5.0-41-generic
sudo modprobe usbip-host # ドライバ組み込み
sudo usbipd -D # daemon起動
[!NOTE] 起動時に自動で組み込み&実行したいときはsystemdでサービス登録するとできそうだけど、
本筋じゃないのでやめとく。
ここ とか参考になるかも。
sudo usbip list --local # ※ usbipdではないので注意
こんな感じで表示される
・・・
- busid 3-11 (056e:700a)
Elecom Co., Ltd : unknown product (056e:700a)
・・・
[!NOTE] 表示される製品名等が不明確な場合は
lsusb
の結果と突き合わせてみると良い。
(IDはどちらも表示されているので、これを頼りに)
sudo usbip bind --busid 3-11 # ※ usbipdではないので注意
usbip
はWindows側でインストールしたusbipd-winに含まれているのでインストール不要。
別途aptでインストールしても使えるけど結構メンドクサイ。
使いたくなることもあるかもしれんので、手順は残しておく。
[!NOTE]
usbipが入っているパッケージをインストール
sudo apt install linux-tools-generic
usbipを実行してみる
usbip
たぶんこんなメッセージが出る
WARNING: usbip not found for kernel 6.6.87.1-microsoft You may need to install the following packages for this specific kernel: linux-tools-6.6.87.1-microsoft-standard-WSL2 linux-cloud-tools-6.6.87.1-microsoft-standard-WSL2 You may also want to install one of the following packages to keep up to date: linux-tools-standard-WSL2 linux-cloud-tools-standard-WSL2
しかし、指定されたパッケージをインストールしようとしても「そんなもんはない」と怒られる。
しかたないのでゴマカシ。cd /usr/lib/linux-tools ls -la 合計 12 drwxr-xr-x 3 root root 4096 6月 6 13:11 . drwxr-xr-x 65 root root 4096 6月 6 13:11 .. drwxr-xr-x 2 root root 4096 6月 6 13:11 6.8.0-60-generic ← これを覚えておく
isbipを実行した時のメッセージとlsしたときのディレクトリ名から以下のようなシンボリックリンクを作成する
(カーネルバージョンが変わると変更しないといけないので注意)ln -s 6.8.0-60-generic 6.6.87.1-microsoft-standard-WSL2
再度usbipを実行してみる
usbip
USAGEが表示されたらOK。
またWARNINGが表示されたらシンボリックリンクの名前が間違っていると思うので、再確認。
[!TIP] usbipコマンドへのpathを設定してもsudoで実行するときは無効なので、設定せずfullpathで指定する
/mnt/c/Program\ Files/usbipd-win/WSL/usbip list -r ≪UbuntuPCのIPアドレス≫
こんな感じで表示される(BUSIDは例。以下同じ)
Exportable USB devices
======================
- ≪UbuntuPCのIPアドレス≫
3-11: Elecom Co., Ltd : unknown product (056e:700a)
: /sys/devices/pci0000:00/0000:00:14.0/usb3/3-11
: Miscellaneous Device / ? / Interface Association (ef/02/01)
sudo /mnt/c/Program\ Files/usbipd-win/WSL/usbip attach -r ≪UbuntuPCのIPアドレス≫ --busid 3-11
アタッチできたか確認する
lsusb
・・・
Bus 001 Device 003: ID 056e:700a Elecom Co., Ltd Venus USB2.0 Camera
・・・
前と同様にguvcviewを実行してみる。
LANG="C" guvcview
別ウィンドウが表示され、画像が表示される。
それなりに大きなサイズに切り替えても表示できている。
usbipのポートの確認
/mnt/c/Program\ Files/usbipd-win/WSL/usbip port
こんな感じで表示される。
Imported USB devices
====================
Port 00: <Port in Use> at High Speed(480Mbps)
Elecom Co., Ltd : unknown product (056e:700a)
1-1 -> unknown host, remote port and remote busid
-> remote bus/dev 003/006
ポートは0であることが分かる。
デタッチする
sudo /mnt/c/Program\ Files/usbipd-win/WSL/usbip detach --port 0
ということで、どうも、USBIPD-WINの転送速度が遅いようだ。
カメラはビミョーな結果だったので、今度はBluetoothで試してみる。
使用したのは Buffalo BSBT4D09BK(4.0+EDR/LEのアダプタ、中身はCSR製)。
これも結構古いのでもう売ってない。 中身がCSRのアダプタなら動く可能性高い。
Realtekのも使えそうだけど、試してないのでなんとも…
今回はBluetoothなのでBluetooth関連のライブラリ類をインストールしておく。
sudo apt install bluez
USBipd-win
PowerShellやコマンドプロンプト等を管理者として開く。
USBデバイスのリストを表示
(今回はカメラを使うのでそこだけ抜粋。IDとか名前は例)
Not shared
になっている。
usbipd.exe list
・・・・
9-2 0a12:0001 Generic Bluetooth Radio Not shared
・・・・
bindする(busidは上で調べたものを使用)
usbipd.exe bind --busid 9-2
または
usbipd.exe bind --force --busid 9-2
[!NOTE] USBPcapがインストールされている(wiresharkなど)とwarningが表示されてbindできないので
--force
オプションを追加して実行する。
(warningで–forceオプションを付けろと教えてくれる)
確認
Shared
または Shared (forced)
になっている。
usbipd.exe list
・・・・
9-2 0a12:0001 Generic Bluetooth Radio Shared (forced)
・・・・
attachする(attachする前にWSLの仮想マシンが起動していること)
usbipd.exe attach --wsl --busid 9-2
[!TIP] 以下のようにbindするとUSB挿抜する度に自動でattachしてくれるらしい。確認してないけど。
usbipd.exe attach --wsl --busid 2-1 --auto-attach
確認する
Attached
になっている
usbipd.exe list
・・・・
9-2 056e:700a Venus USB2.0 Camera Attached
・・・・
lsusb
こんな感じで表示される
Bus 001 Device 003: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
ローカルデバイスの一覧表示をしてみる。
hcitool dev
例えばこんな感じで表示される。
Devices:
hci0 XX:XX:XX:XX:XX:XX
スキャンしてみる。
bluetoothctl
bluetoothctlが起動され、プロンプトが[bluetooth]#
になる。
スキャンしてデバイス一覧を見てみる
scan on
≪スキャンされたデバイスが表示される≫
≪しばらく待つ≫
scan off
≪表示が止まる≫
list
≪スキャンされたデバイスが表示される≫
exit
≪終了してshellに戻る≫
pyenvでpythonをインストールする場合は pyenvのインストール の注意書きにあるように、コンパイル前に以下を実行しておく。
sudo apt install libbluetooth-dev libglib2.0-dev libboost-python-dev libboost-thread-dev
新しくプログラム作るのは面倒なので以前作った
AndroidでpythonでBLE
を実行してみる。
必要なモジュール類をインストールして
sudo apt install libmtdev-dev
pip install kivy bleak
実行
python kivy_ble.py
動いた。メデタシメデタシ。
USBカメラを取り外すためにアタッチ解除とバインド解除
usbipd.exe detach --busid 9-2
usbipd.exe unbind --busid 9-2
USB接続のSDカードリーダを使えばRaspberryPiのブート用SDカードをWSLにマウントして操作することも可能なはず。
メンドクサくなってきたので試すのはやめておくけど。