はじめに
2021年秋にMicrosoftが紹介していた WSL2でUSBデバイスと接続する方法 を用いて、WSL2上の ESP-IDF で ESP32 に flash, monitor できることを確認しました。
注意点としては、
ESP32の開発ボードである ESP32-DevKitC では、記事の方法だけでは flash や monitor ができないことです。
原因は、WSL2標準のLinuxカーネルが CP210x 用のドライバーを無効化されていることです。
自分でカーネルをビルドし直して、それを WSL に読ませることで解決します。
この記事は特に 上記の問題点の所に焦点を当てた内容となっています。
ほぼ forum の受け売りですが、日本語情報が見つからなかったのでここにメモしておきます。
検証環境
- Ubuntu 20.04 (Microsoft Store で入手)
- ESP32-DevKit-C (他にも、CP210x を搭載しているボードなら同じ方法で対応できると思います)
手順
- usbipd 機能の設定
- Linux Kernel をビルドする
- WSLから自作カーネルを読み込ませる
- (Docker向け) Docker に device を指定する
1. usbipd 機能の設定
具体的な手順は下記にまとまっているので、ここでは省略します。
しかし、上記の対応を済ませても、ESP32-DevKitC との接続はできませんでした。
どうやら、ESP32(CP2102) はWSLで検知しているものの、シリアル通信デバイスとして認識されていないようです。
$ dmesg
[34209.280578] usb 1-1: New USB device found, idVendor=10c4, idProduct=ea60, bcdDevice= 1.00
[34209.280580] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[34209.280581] usb 1-1: Product: CP2102 USB to UART Bridge Controller
[34209.280582] usb 1-1: Manufacturer: Silicon Labs
[34209.280583] usb 1-1: SerialNumber: 0001
# "/dev/tty** に attach しました!" みたいな文言が出てこない
$ lsusb # "CP2102 USB to UART Bridge Controller" が見つからない
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
2. Linux Kernel をビルドする
はじめにも書きましたが、CP210x 系のドライバーが Kernel で無効化されていることが問題の原因です。
必要な作業自体は単純で、Kernel Configuration でチェックボックス1か所に * をつけるだけで有効化したカーネルを作成できます。
まず、WSL2に必要なパッケージをインストールします。
$ sudo apt update && sudo apt install -y build-essential flex bison libssl-dev libelf-dev dwarves libncurses-dev
次に WSL2 用 Linux Kernel のソースをダウンロードして、Kernel Configuration を開きます。
$ git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
$ cd WSL2-Linux-Kernel
$ make menuconfig KCONFIG_CONFIG=Microsoft/config-wsl
Device Drivers -> USB support -> USB Serial Converter support -> USB CP210x familyof UART Bridge Controllers に * のチェックを入れます。
※ キー操作は下記の通りにできます
- 上下キー: 選択項目の変更 (上下移動)
- Enter キー: 下の階層に移動
- Space キー: チェックボックスの切り替え
- 左右キー: 下部メニューの選択
Save -> Exit したあとに、 make
コマンドを実行すれば、カーネルが作成されます。
これを、Windows から閲覧できるディレクトリに配置してください。
$ make
...(略)...
Kernel: arch/x86/boot/bzImage is ready (#1)
$ cp arch/x86/boot/bzImage /mnt/c/Users/{あなたのユーザー名}/wsl_kernel
Windows 側のホームディレクトリの.wslconfig
に下記を追記します。.wslconfig
がなければ作成してください。
[wsl2]
kernel = C:\\Users\\{あなたのユーザー名}\\wsl_kernel
WSLを再起動すれば、これ以降は読み込めるようになるはずです。
再起動した状態なので、usbipd から attach することもお忘れなく!
> wsl --shutdown
> wsl
$
> usbipd wsl attach --busid ${busid}
$ dmesg | tail -10
[ 21.778229] usb 1-1: new full-speed USB device number 2 using vhci_hcd
[ 21.858058] vhci_hcd: vhci_device speed not set
[ 21.928043] usb 1-1: SetAddress Request (2) to port 0
[ 21.965415] usb 1-1: New USB device found, idVendor=10c4, idProduct=ea60, bcdDevice= 1.00
[ 21.965419] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 21.965420] usb 1-1: Product: CP2102 USB to UART Bridge Controller
[ 21.965422] usb 1-1: Manufacturer: Silicon Labs
[ 21.965423] usb 1-1: SerialNumber: 0001
[ 21.969170] cp210x 1-1:1.0: cp210x converter detected
[ 21.978875] usb 1-1: cp210x converter now attached to ttyUSB0 #<- /dev/ttyUSB0 からアクセスできるようになった!
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 10c4:ea60 Silicon Labs CP210x UART Bridge # <- 出てきた!
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
4. (Docker) device を指定する
純粋な WSL2 からアクセスする場合には、すでに接続されていますが、
Docker からアクセスする場合には、さらに Docker コンテナ起動時にデバイスを伝える必要があります。
$ docker run -it --device=/dev/ttyUSB0:/dev/ttyUSB0 ${Docker名}
# python $IDF_PATH/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 write_flash @flash_project_args
esptool.py /dev/ttyUSB0 write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x10000 my_custom_app.bin
esptool.py v3.3-dev
Serial port /dev/ttyUSB0
Connecting.................
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, Coding Scheme None
Crystal is 40MHz
# python $IDF_PATH/tools/idf_monitor.py --port /dev/ttyUSB0 my_custom_app.elf
/root/esp/esp-idf/tools/idf_monitor.py:518: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.
if StrictVersion(serial.VERSION) < StrictVersion('3.3.0'):
--- idf_monitor on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7208
load:0x40078000,len:14880