Windows WSL2 の Ubuntu 22.04 上から USB-UART 経由で M5Stack に書き込みする

Windows WSL2 の 1.0 版以降のカーネルでは、usbipd を経由することで Windows 側の USB 機器を IP 経由で参照することができます。

この動きを利用して、USB に接続した M5Stack(USB-UART) に WSL2 Ubuntu 上の esp-tools から書き込みする手順を記載してみます。数コマンド叩くだけで完了します。便利。

手順の例では WSL2 Ubuntu 上にセットアップした Linux 版の esp-idf 開発系から直接マイコンに書き込みを行っています。書き込み処理は Linux 側で動作しますので、Windows 側にUSB-UART ドライバーセットアップは不要です。

おそらく他のマイコンや PlatformIO 環境でも同じ手順で USB を認識させれば Linux 側から書き込みできるようになると思います。

この記事では esp-idf の idf.py コマンドを使ったM5Stack Core2 への書き込み例をメインに、PlatformIO での Longan Nano 書き込み、openocd を使った M5Stamp C3 のデバッグ構成も合わせて記載しました。

環境

Windows WSL2 (Windows 10 の場合 1.0 以降)

> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
MSRDC バージョン: 1.2.3575
Direct3D バージョン: 1.606.4
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windowsバージョン: 10.0.22621.1105

WSL2 Ubuntu 22.04

$ uname -a
Linux minis-um690 5.15.79.1-microsoft-standard-WSL2 #1 SMP Wed Nov 23 01:01:46 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Ubuntu 22.04 上の esp-idf。なお、esp-idf ツールチェインが必要とする Ubuntu の依存関係はこちらに記載されています。(追記: ESP-IDF v4.4.4 でも問題ないことを確認) PlatformIO を使う場合は自動導入されるので、この確認は不要です。

$ get_idf
$ echo ${IDF_PATH}
/home/hiromasa/devel/toolchain/esp-idf
$ idf.py --version
ESP-IDF v4.4.3

Windows に usbipd-win を導入

基本的に以下の Microsoft のガイドに従うと OK ですが、一部コマンドがカーネルバージョンに依存しているので、usbipd-win の手順も参照しています。

USB デバイスを接続する

このガイドでは、USB/IP オープンソース プロジェクト usbipd-win を使用して、WSL 2 で実行されている Linux ディストリビューションに USB デバイスを接続するために必要な手順について説明します。

まずは Windows 側に usbipd-win を導入します。 PowerShell 窓より以下のコマンドにて。

> winget install --interactive --exact dorssel.usbipd-win

次に WSL2 Ubuntu 22.04 に apt で usbipd を導入します。

$ sudo apt update
$ sudo apt upgrade
$ 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

なお、手順中の ls /usr/lib/linux-tools/*/usbip ですがカーネルバージョンに合わせた usbip を登録しています。

ls /usr/lib/linux-tools/*/usbip | tail -n1
/usr/lib/linux-tools/5.15.0-70-generic/usbip

Ubuntu カーネル(tools の)バージョンが上がった場合に、後述の Windows 側からのバインドで以下のエラーとなった場合は再度上記の sudo update-alternatives --installを実行してください。

❯ usbipd.exe wsl attach --busid 9-3
usbipd: error: WSL 'usbip' client not correctly installed. See https://github.com/dorssel/usbipd-win/wiki/WSL-support for the latest instructions.

linux-tools がアップデート(ここでは Kernel 5.15.0-70 から 5.15.0.-71)された後の update-alternatives 設定ログ:

$ sudo update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20
update-alternatives: 警告: /usr/lib/linux-tools/5.15.0-70-generic/usbip の alternative (リンクグループ usbip のパート) が存在しません 。alternatives のリストから削除しています
update-alternatives: 警告: /etc/alternatives/usbip is dangling; it will be updated with best choice
update-alternatives: /usr/local/bin/usbip (usbip) を提供するために自動モードで /usr/lib/linux-tools/5.15.0-71-generic/usbip を使います

さて、この流れでついでに Ubuntu の udev を構成して、マイコンの USB 接続をユーザ権限から見れるようにしておきます。 PlatformIO の udev 定義を使うとほとんどのマイコンで使えて便利です。

$ curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules

ここでいったん Windows ごと再起動します。

USB 機器のバインド

Windows 起動後、先に Ubuntu の usbipd を起動するために、WSL2 Ubuntu 窓を上げておきます。

WSL2 では udev サービスが自動起動しませんので、WSL2 起動後に以下のコマンドで起動します。(wsl.conf などで自動起動設定するのもいいかもしれません)

$ sudo service udev restart

次に Windows の PowerShell 窓を「管理者で起動」し、使いたい USB 機器を usbipdにアタッチします。

usbipd wsl list コマンドで USB 機器を表示。

> usbipd wsl list
BUSID  VID:PID    DEVICE                                                        STATE
3-1    17ef:6047  Lenovo USB Interface Device(HID), USB 入力デバイス            Not attached
3-3    0e8d:0608  RZ608 Bluetooth(R) Adapter                                    Not attached
7-1    0499:170d  AG06/AG03, Line (AG06/AG03)                                   Not attached
9-1    10c4:ea60  CP2104 USB to UART Bridge Controller                          Not attached

CP2104 USB to UART が M5Stack なので 9-1 をアタッチ。なお、初回のアタッチの操作のみ管理者権限が必要で次回からはユーザ権限でいけるようです。

> usbipd wsl attach --busid 9-1

なお、ユーザ権限がついたあとは、Ubuntu 側から次のコマンドでも操作可能です。(.exe を付けて明示的に Windows 側のコマンドを呼びます)

$ usbipd.exe wsl attach --busid 9-1

うまくいけば、upsipd wsl list コマンドのデバイス部分が Ubuntu になります。

> usbipd wsl list
BUSID  VID:PID    DEVICE                                                        STATE
9-1    10c4:ea60  CP2104 USB to UART Bridge Controller                          Attached - Ubuntu-22.04

できたら、WSL2 Ubuntu で lsusb してみて機器(CP210)が見えればOKです。

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

PlatformIO からお借りした udev 定義が効いていれば /dev/ttyUSB0 あたりにユーザ権限の書き込み付きでブロックデバイスが見えます。rw-rw-rw なら成功です。

$ ls -laF /dev/ttyUSB*
crw-rw-rw- 1 root dialout 188, 0  1月 28 17:17 /dev/ttyUSB0

マイコンが暴走して USB を抜き差しした後などで、usbipd.exe で再アタッチするも udev が効かないケースがあるようです。その場合は面倒なので手動で chmod するのもありかと思います。

$ sudo chmod 666 /dev/ttyUSB0

マイコンへの書き込み

/dev/ttyUSB0 宛てにそれぞれのマイコンの書き込みツールを設定すれば書けるはずです。esp-idf (esp-tools) は自動的にシリアルポートを探してくれますので、以下のいつものコマンドで書き込みからモニターまで動作します。

$ idf.py build flash monitor
Executing action: all (aliases: build)
Running ninja in directory /home/hiromasa/devel/esp32/m5stack-core2-wasm3-as/build
Executing "ninja all"...
[1/4] cd /home/hiromasa/devel/esp32/m5stack-core2-wasm3-as/b...asa/devel/esp32/m5stack-core2-wasm3-as/build/hello_world.bin
hello_world.bin binary size 0x124cb0 bytes. Smallest app partition is 0x200000 bytes. 0xdb350 bytes (43%) free.
[2/4] Performing build step for 'bootloader'
[1/1] cd /home/hiromasa/devel/esp32/m5stack-core2-wasm3-as/build/bootloader/esp-idf/esptool_py && /home/hiromasa/.espressif/python_env/idf4.4_py3.10_env/bin/python /home/hiromasa/devel/toolchain/esp-idf/components/partition_table/check_sizes.py --offset 0x8000 bootloader 0x1000 /home/hiromasa/devel/esp32/m5stack-core2-wasm3-as/build/bootloader/bootloader.bin
Bootloader binary size 0x6330 bytes. 0xcd0 bytes (11%) free.
Executing action: flash
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting.....
Detecting chip type... ESP32
...以下略...

以上です。

本環境設定と合わせて、プロジェクトディレクトリを VSCode の WSL Remote 拡張で開けば、ソースコードの編集からマイコンへの書き込みまで Linux 周りのツールで揃えることができるので便利なのではないかと思います。

以下は他のマイコンでの設定例です。

Longan Nano (GD32V) + VSCode + PlatformIO

Longan Nano dfu 用の udev 構成。

$ cat /etc/udev/rules.d/70-ttyusb.rules #ファイル追加
# Longan Nano
SUBSYSTEM=="usb", ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", MODE="0666"
SUBSYSTEM=="usb_device", ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", MODE="0666"
$ sudo service udev restart # udev restart

Longan Nano を BOOT + RESET 起動で dfu モードに入れて attach。

> usbipd wsl list
BUSID  VID:PID    DEVICE                                                        STATE
3-1    17ef:6047  Lenovo USB Interface Device(HID), USB 入力デバイス            Not attached
3-3    0e8d:0608  RZ608 Bluetooth(R) Adapter                                    Not attached
7-1    0499:170d  AG06/AG03, Line (AG06/AG03)                                   Not attached
9-1    28e9:0189                                                                Not attached

先に管理者権限 PowerShell でアタッチした後、リセットするとアタッチが切れるので、再アタッチ。 WSL2 Ubuntu 側からも Windows の usbipd.exe を呼べる動作を活用してアップロード操作前にアタッチコマンドを実行できるようにタスクを組むと便利。

$ usbipd.exe wsl attach --busid 9-1
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 28e9:0189 GDMicroelectronics GD32 DFU Bootloader (Longan Nano)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

あとは WSL2 側に入れた VSCode と PlatformIO 拡張から、いつも通り Upload を起動すれば書き込みできます。

openocd デバッグを行う場合

M5Stamp C3 の USB JTAG デバッグを行う設定です。

M5Stamp C3 は 「M5Stamp C3 用の開発向けボードを製作」のように USB JTAG を引き出すことができます。また、M5Stamp C3U では付属の USB ポートでいけると思います。

openocd の依存となる libusb の導入(esp-idf の依存で導入されているかもですが念の為。どちらかでだけでもいいかものと、-dev を入れているのは癖なので外しても OK です)

$ sudo apt install libusb-dev libusb-1.0-0-dev

openocd の依存となる libpython2.7 導入

$ sudo apt install libpython2.7

USB ポートに M5Stamp C3 の JTAG USB 側(?) を引き出して接続、Windows 側でアタッチ後 Linux で USB 認識確認

$ lsusb | grep JTAG
Bus 001 Device 007: ID 303a:1001 Espressif USB JTAG/serial debug unit

udev 構成追加( 303a の 追加)

$ cat /etc/udev/rules.d/99-platformio-udev.rules | grep 303a
# 以下を追加
ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"

udev restart

$ sudo service udev restart

接続確認

いったん USB を抜き差しして、Windows 側で再アタッチなどして、接続確認します。

$ ls -laF /dev/ttyACM*
crw-rw-rw- 1 root dialout 166, 0  1月 28 19:46 /dev/ttyACM0

openocd 起動

$ which openocd
/home/hiromasa/.espressif/tools/openocd-esp32/v0.11.0-esp32-20221026/openocd-esp32/bin/openocd
$ openocd -f board/esp32c3-builtin.cfg
Open On-Chip Debugger  v0.11.0-esp32-20220706 (2022-07-06-15:48)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Info : esp_usb_jtag: VID set to 0x303a and PID to 0x1001
Info : esp_usb_jtag: capabilities descriptor set to 0x2000
Warn : Transport "jtag" was already selected
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : esp_usb_jtag: serial (34:B4:72:12:94:14)
Info : esp_usb_jtag: Device found. Base speed 40000KHz, div range 1 to 255
Info : clock speed 40000 kHz
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Info : datacount=2 progbufsize=16
Info : Examined RISC-V core; found 1 harts
Info :  hart 0: XLEN=32, misa=0x40101104
Info : starting gdb server for esp32c3 on 3333
Info : Listening on port 3333 for gdb connections

VSCode などから接続(設定例

おそらく openocd 接続後初回の Debug Launch は(マイコンの状態により)失敗するので、2回 Debug Launch するとブレイクすると思います。(WSL2 ではない Ubuntu でも再現するので自分の setupCommandsが悪いのかもしれません)

関連

Windows 11 で USB ThinkPad トラックポイント・キーボードの縦スクロールがダウンする

USB (有線)版の ThinkPad トラックポイント・キーボードで、真ん中ボタンによる縦スクロールを行った場合に「ThinkPad 優先スクローリング」機能がダウンする場合があります。抜本的に解決できませんでしたがメモ。

利用しているドライバー(Windows 11 は対応しておらず古い)

ThinkPad Compact USB Keyboard with Trackpoint Driver (18.8 MB)

https://support.lenovo.com/jp/ja/solutions/pd026745-thinkpad-compact-usb-keyboard-with-trackpoint-overview-and-service-parts

このドライバーを導入すると、マウスのプロパティーに次の設定が追加されます。

ThinkPad 優先スクローリング機能はおそらく、ソフトウェアの中ボタン処理を無効にして、スクロールイベントを発生させる機能です。(中ボタンを押したときに、スクロールバーアイコンになれば機能しています)

この機能が特定のソフトウェアで動作した場合にダウンし(Visual Studio 2022 で確認)、スクロール機能が動かなくなるようです。

なお、ThinkPad 優先スクローリングを無効にすると、アプリ側のスクロールが効くので動くようになりますが、Microsoft Edge などが微妙な動きになります。

残念ながら対応する方法は分かりませんでしたが、以下の .exe を起動することで、OS の再起動をすることなく復帰は可能なようです。スタートメニューにピン止めしておくといいかもです。

“C:\Program Files (x86)\Lenovo\ThinkPad Compact Keyboard with TrackPoint driver\HScrollFun.exe”

Visual Studio 利用時は ThinkPad 優先スクロールのチェックを外すことにより対応。

古い製品なのでしょうがないですかね。。対応されたドライバーがでるといいのですが。いったんがまんして使うこととします。

追伸。同件を書かれている方がいらっしゃいました。Bluetooth 版でも発生するようです。 Visual Studio で起きるのも同じですね。。とほほ。

ThinkPad Bluetooth キーボードで縦・横スクロールが出来なくなった場合の対処法

トラックポイントとセンターボタンによる、縦および横スクロールが全くできない

Cubase で複数の YAMAHA Steinberg USB ASIO 機器がある場合にひとつしか表示されない

新規の Windows 11 に Cubase を導入していて分からなくなったので備忘録にて。

Windows に ASIO 機器を複数台接続した場合に、Cubase 上に選択したい機器のポートが表示されませんでした。

  • YAMAHA MODX7
  • YAHAMA AG06

いずれも YAMAHA Steinberg USB Driver にて管理。

Cubase のスタジオ設定より USB ASIO 項目からコントロールパネルを開き Device で使いたい機器を選択して OK ボタンを押下すると、その機器のポートがスタジオ設定に現れます。(ここが分からなかった)

接続機器を変更すると、オーディオコネクションが外れて発音しなくなるかもなので、Cubase -> スタジオ -> オーディオコネクションから再割当て。

ASIO コントロールパネルの Device 選択設定に Cubase が連動しているのに気がつくのに時間がかかりました。タブが ASIO として独立していることに納得。

以上です。(短い)

ついでにメモ。 opsix Native 単体起動時の ASIO と MIDI IN の設定は、右上ハンバーガメニューより「Sound Settings」から次の部分。

YAMAHA Steinberg USB ASIO は選択時にエラーになる場合があるけれど、がちゃがちゃしていると機器を見るけるようだメモ。