M5Stack RCA Module の I2S PCM5102A と Rust ESP32 xtensa-esp32-espidf ビルド

M5Stack RCA Module に搭載されている I2S (PCM5102APWR) を、Rust で生成した PCM 波形で発音させたメモです。

波形の生成は libymfm.wasm として WebAssembly 向けに作成している Rust 製のシーケンサーとサウンドチップエミュレーションをそのまま esp-idf に持ってきて xtensa-esp32-espidf ビルドしています。また、libymfm.wasm は C++ でつくられた FM 音源エミュレータの ymfm もリンクしています。

ESP32 Xtensa の Rust は初挑戦でしたが、確認した範囲で問題なくすんなり動作しました。ESP32 Xtensa Rust ツールチェインの準備やビルドは大変な印象がありましたが、昨今は esp-rs の各プロジェクトを組み合わせることで簡単に設定できるようになっています。

ちなみに ESP32-S3 開発ボードでも軽く動かしてみましたが問題なさそうです。ESP-S3 では PSRAM 80MHz Octa 設定にしているのが効いたか、波形生成は 1.4 倍程度高速でした。(Rust モジュールの細かなメモリ配置については未調査で課題としています)

ということで、この記事には以下の内容が含まれます。

  • I2S PCM5102APWR のイニシャライズ方法
  • ESP32 Xtensa Rust のビルド
実は M5Stack のスタックするモジュールを初めて買ったので、ボトムがないと寂しいことになると知らなかったのは内緒です。でも手軽に接続できてかっこいいです!

ソースコードは以下のリポジトリから見ることができます。詳しくはソースを見ていただくのが早いかもしれません。

https://github.com/h1romas4/m5stack-chipstream

This is a test to port C++’s ymfm and Rust’s vgmplay to ESP32(Xtensa).

Rust でつくられた VGM パーサーと SEGAPCM エミュレーションで I2S を発音させてるデモ:(残念ながら今回のビルドでは、ymfm の FM 音源エミュレーションは ESP32 で処理速度が間に合いませんでした

I2S PCM5102APWR のイニシャライズ

M5Stack Core2 に接続した RCA Module の PCM5102A の i2s_config と pin_config は以下のように設定すると良いようです。

// i2s_driver_install
i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
    .sample_rate = sample_rate,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
    .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_STAND_I2S),
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = dma_buf_count,
    .dma_buf_len = dma_buf_len,
    .use_apll = false,
    .tx_desc_auto_clear = true,
    .fixed_mclk = I2S_PIN_NO_CHANGE
};
ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM_1, &i2s_config, 0, NULL));

// i2s_set_pin
i2s_pin_config_t i2s_pin_config = {
    .mck_io_num = GPIO_NUM_0,
    .bck_io_num = GPIO_NUM_19,
    .ws_io_num = GPIO_NUM_0,
    .data_out_num = GPIO_NUM_2,
    .data_in_num = I2S_PIN_NO_CHANGE
};
ESP_ERROR_CHECK(i2s_set_pin(I2S_NUM_1, &i2s_pin_config));

communication_format は必ず I2S_COMM_FORMAT_STAND_I2S を設定のこと。

うっかり I2S_COMM_FORMAT_STAND_MSB を設定するとなんとなく発音するものの、送信する PCM の先頭 1bit が無視されるような動きになってややはまり。(-32768, 32767 のフルスイング矩形波が正しく発音しなくて気が付きました…)

bits_per_sampleI2S_BITS_PER_SAMPLE_16BITchannel_formatI2S_CHANNEL_FMT_RIGHT_LEFT することで、int16_t のステレオ PCM 形式になります。

DMA バッファは、波形生成側のプリレンダのバッファリングに合わせて dma_buf_len を 1024 で dma_buf_count を 32個設定して動作させています。一度に扱うサンプル数としては int16_t ステレオにて 256 です。

今回のオーディオ系の実装ですが、波形生成を ESP32 の core 0 で、I2S への PCM の送信を core 1 と FreeRTOS タスクを分割して実行しています。なお、i2s_write にはほとんど時間がかからないようですので、波形生成は core 1 に持ってきても影響ないかもしれません。

タスク間の通信には、esp-idf の FreeRTOS Additions になっている RingBuffer の Byte buffers を介して PCM データの送受信を行っています。

FreeRTOS AdditionsRing Buffers

Byte buffers do not store data as separate items. All data is stored as a sequence of bytes, and any number of bytes can be sent or retrieved each time. Use byte buffers when separate items do not need to be maintained (e.g. a byte stream).

ESP32 Xtensa Rust のビルド方法

Xtensa の Rust ツールチェインは espup で導入するのが簡単でした。Windows の場合は WSL2 の Ubuntu 22.04 を使うと便利かもです。(sysroot は esp-idf 4.4.3 を使っています)

詳しくはリポジトリに GitHub Actions のビルドを入れていますの参考にしてください。

https://github.com/esp-rs/espup

Tool for installing and maintaining Espressif Rust ecosystem.

espup で Rust を導入すると ~/.rustup/toolchains/esp に Xtensa の Rust が導入されます。また .espressif/tools/xtensa-esp32-elf-clang に clang が入ります。

$ ls -laF ~/.rustup/toolchains/esp/bin/
合計 58120
drwxr-xr-x 2 hiromasa hiromasa     4096  2月 19 15:56 ./
drwxr-xr-x 7 hiromasa hiromasa     4096  2月 19 15:56 ../
-rwxr-xr-x 1 hiromasa hiromasa 21897920  2月 19 15:56 cargo*
-rwxr-xr-x 1 hiromasa hiromasa   954888  2月 19 15:56 cargo-clippy*
-rwxr-xr-x 1 hiromasa hiromasa  1796976  2月 19 15:56 cargo-fmt*
-rwxr-xr-x 1 hiromasa hiromasa 11781088  2月 19 15:56 clippy-driver*
-rwxr-xr-x 1 hiromasa hiromasa      759  2月 19 15:56 rust-gdb*
-rwxr-xr-x 1 hiromasa hiromasa     1933  2月 19 15:56 rust-gdbgui*
-rwxr-xr-x 1 hiromasa hiromasa     1072  2月 19 15:56 rust-lldb*
-rwxr-xr-x 1 hiromasa hiromasa    17264  2月 19 15:56 rustc*
-rwxr-xr-x 1 hiromasa hiromasa 11124040  2月 19 15:56 rustdoc*
-rwxr-xr-x 1 hiromasa hiromasa 11906968  2月 19 15:56 rustfmt*
$ ls -laF ~/.espressif/tools/xtensa-esp32-elf-clang/esp-15.0.0-20221201-x86_64-unknown-linux-gnu/esp-clang
合計 44
drwxr-xr-x 11 hiromasa hiromasa 4096  2月 19 15:57 ./
drwxr-xr-x  3 hiromasa hiromasa 4096  2月 19 15:57 ../
drwxr-xr-x  2 hiromasa hiromasa 4096  2月 19 15:57 bin/
drwxr-xr-x  4 hiromasa hiromasa 4096  2月 19 15:57 include/
drwxr-xr-x  8 hiromasa hiromasa 4096  2月 19 15:57 lib/
drwxr-xr-x  2 hiromasa hiromasa 4096  2月 19 15:57 libexec/
drwxr-xr-x  5 hiromasa hiromasa 4096  2月 19 15:57 riscv32-esp-elf/
drwxr-xr-x  9 hiromasa hiromasa 4096  2月 19 15:57 share/
drwxr-xr-x  5 hiromasa hiromasa 4096  2月 19 15:57 xtensa-esp32-elf/
drwxr-xr-x  5 hiromasa hiromasa 4096  2月 19 15:57 xtensa-esp32s2-elf/
drwxr-xr-x  5 hiromasa hiromasa 4096  2月 19 15:57 xtensa-esp32s3-elf/

ちなみに espup でツールチェインを入れると、esp-idf とは別のディレクトリ名に同バージョンの gcc が入るようです。(?)

さて、今回は Rust は波形生成をするライブラリの形で、C/C++ の Arduino Loop をメインとしたかったので、”esp-idf first” という構成としています。components 配下に Rust のプロジェクトをおいて、いつも通り idf.py build すると Rust ごとビルドしてくれます。

cargo generate で以下のテンプレートを cmake 指定してビルドスクリプトやディレクトリストラクチャーをつくっています。(引数を cargo にすると Rust 中心の構成になります)

https://github.com/esp-rs/esp-idf-template

cargo generate https://github.com/esp-rs/esp-idf-template cmake

esp-idf first のビルドでは components の下にいつも通りコンポーネントを配置し、CMakeLists.txt から external project として Rust を追加してビルドする動作するようにつくってくれます。

ビルドさえできてしまえば、あとは std 環境の Rust で、今回は外部ライブラリとしてバイナリーパーサ nom や JSON シリアライズ serde などを入れていますが、そのまま動作しました。

一点、Rust から返した *const i16 (16bit) の RAW ポインターを C 側から読むとメモリーの状態によって 1 byte (?) ズレるような動作がありました。いったん C からポインターを渡して Rust 側から書き込むことで修正していますが、Xtensa 特有なのか自分のミスなのかまだ詳しく原因を調査できていません。(Rust 構造体内の配列ポインターなのですがアライメント関連?)

というわけで、ESP32 で Rust std が呼べる。とても便利す。

Rust の特定モジュールを IRAM に載せたり、ヒープアロケータの SRAM/PSRAM コントロール(できる?)など未調査の部分もありますので、引き続きやってみたいと思います。

関連

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

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

この動きを利用して、USB に接続した マイコン(M5Stack/USB-UART等々) に WSL2 Ubuntu 上のツールチェインから書き込みする手順を記載してみます。数コマンド叩くだけでセットアップは完了します。便利。

書き込み処理(libusb) は Linux 側で動作しますので、Windows 側にUSB-UART ドライバーなどのセットアップは不要です。

本記事では WSL2 を使った書き込み実用例として以下の手順を記載しています。

  • esp-idf の idf.py コマンドを使った M5Stack Core2 への書き込み
  • PlatformIO を使った書き込み例
  • openocd を使った M5Stamp C3 のデバッグ構成
  • LicheePi 4A への fastboot コマンドを使ったファームウェア書き込み

環境

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

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

UPDATE – 2023-12 usbipd 4.0 リリースに伴い以下の Ubuntu 側へのクライアントツールのインストールは不要になりました。

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

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install linux-tools-virtual hwdata

usbipd を登録。

$ sudo update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20

さて、この流れでついでに 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

これで WSL2 側から接続された USB を認識させる準備は完了です。手順上、いったん状態をクリアするため Windows ごと再起動します。

USB 機器のバインド

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

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

$ sudo service udev restart

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

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

4.0 系:

> usbipd list

3 系:

> 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 をアタッチ。なお、初回のアタッチの操作のみ管理者権限が必要で次回からはユーザ権限でいけるようです。

4.0 系:

> usbipd attach --wsl --busid 9-1

3 系:

> usbipd wsl attach --busid 9-1

3 系:

この操作で以下のエラーが出力された場合は、再度 Ubuntu 側で sudo update-alternatives --install を実行してください。(Ubuntu カーネル(tools の)バージョンが上がった場合に発生します)

❯ 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 側 WSL2 窓から次のコマンドでも操作可能です。(.exe を付けて明示的に Windows 側のコマンドを呼びます)

4.0 系:

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

3 系:

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

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

4.0 系:

> usbipd list

3 系:

> 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 定義が効いていれば、USB-UART では /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

esp-idf の idf.py コマンドを使った M5Stack Core2 への書き込み

Ubuntu 22.04 上に esp-idf を構成して idf.py コマンドで書き込む例です。なお、esp-idf ツールチェインが必要とする Ubuntu の依存関係はこちらに記載されています。

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

esp-idf (esp-tools) は自動的にシリアルポートを探してくれますので、以下のいつもの idf.py flash monitor コマンドで書き込みからログ入力まで動作します。

$ 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 周りのツールで揃えることができるので便利なのではないかと思います。

WSL2 からのマイコンへの書き込みの操作は以上です。usbipd 経由で接続された USB が WSL2 側から認識できれば、他は特殊な操作は不要で書き込みすることができます。


VS Code の WSL Remote 拡張は、先に Windows 側の VS Code で拡張を導入した上で一度終了。 WSL2 側のターミナルでプロジェクトディレクトリにカレントディレクトリを cd で移し、

$ code .

とすると、外見は Windows で中身は Linux の VS Code が起動します。初回起動、及びアップデートがあった場合のみ、Linux 版の VS Code backend (vscode-server) をダウンロードするため少しだけ時間がかかります。

起動したら、その他で Linux 側に必要な拡張がある場合(PlatformIO 等)は、拡張を入れる画面から「WSL2 に入れる」的なボタンを押してあげてください。


PlatformIO を使った書き込み例

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が悪いのかもしれません)

Lichee Pi 4A の fastboot による Flash

Lichee Pi 4A の boot ボタンを押しながら PC の USB-C に接続。

> usbipd.exe wsl list
BUSID  VID:PID    DEVICE                                                        STATE
6-1    2345:7654  USB download gadget                                           

初回の場合は PowerShell 管理者で実行。

> usbipd.exe wsl attach --busid 6-1

WSL2 側で認識確認。

$ sudo dmesg
[   31.713030] usb 1-1: new high-speed USB device number 2 using vhci_hcd
[   31.873057] usb 1-1: SetAddress Request (2) to port 0
[   31.920340] usb 1-1: New USB device found, idVendor=2345, idProduct=7654, bcdDevice= 2.23
[   31.921254] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[   31.921580] usb 1-1: Product: USB download gadget
[   31.921790] usb 1-1: Manufacturer: T-HEAD
[   49.129386] hv_balloon: Max. dynamic memory size: 14204 MB

あとは fastboot コマンドで書き込めば OK です。

$ pwd
/home/hiromasa/devel/riscv/lip4a/images/0511_gnome
$ ls -laF
合計 4259020
drwxrwxr-x 2 hiromasa hiromasa       4096  5月 12 12:04 ./
drwxr-xr-x 3 hiromasa hiromasa       4096  6月  2 17:24 ../
-rw-rw-r-- 1 hiromasa hiromasa   62914560  5月 12 11:35 boot-20230510-230240.ext4
-rwxrwxrwx 1 hiromasa hiromasa        368  5月 12 11:29 burn_gnome_gpu.sh*
-rwxrwxrwx 1 hiromasa hiromasa    2230360  5月  5 23:47 fastboot*
-rw-rw-r-- 1 hiromasa hiromasa       2022  5月 12 11:38 image_intro.txt
-rw-r--r-- 1 hiromasa hiromasa      68443  5月 12 11:36 light-lpi4a_1.85GHz.dtb
-rw-r--r-- 1 hiromasa hiromasa      68464  5月 12 11:36 light-lpi4a_2Ghz.dtb
-rw-rw-r-- 1 hiromasa hiromasa        259  5月 12 11:21 md5sum.txt
-rw-rw-r-- 1 hiromasa hiromasa 4294967296  5月 12 11:32 rootfs-20230511-183752-gnome.ext4
-rw-rw-r-- 1 hiromasa hiromasa     957728  5月 12 11:21 u-boot-with-spl-lpi4a-20230510.bin
$ file fastboot
fastboot: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, not stripped

なのですが、一度 uboot を書く前のファームウェア書き込み後に一度リセットがかかり <waiting device..> となりますので、ここのタイミングで再度 PowerShell 側で usbipd.exe wsl attach --busid 6-1 すれば完走できます。

$ ./burn_gnome_gpu.sh
Sending 'ram' (935 KB)                             OKAY [  0.248s]
Writing 'ram'                                      OKAY [  0.002s]
Finished. Total time: 0.256s
Rebooting                                          OKAY [  0.001s]
Finished. Total time: 0.202s
< waiting for any device > # ←ここで再度 wsl attach する
Sending 'uboot' (935 KB)                           OKAY [  0.058s]
Writing 'uboot'                                    OKAY [  0.031s]
Finished. Total time: 0.113s
Sending 'boot' (61440 KB)                          OKAY [  2.568s]
Writing 'boot'                                     OKAY [  1.535s]
Finished. Total time: 4.241s
Invalid sparse file format at header magic
Sending sparse 'root' 1/33 (113316 KB)             OKAY [  4.680s]
Writing 'root'                                     OKAY [  2.791s]
Sending sparse 'root' 2/33 (110992 KB)             OKAY [  4.660s]
Writing 'root'                                     OKAY [  2.568s]
...(snip)...
Writing 'root'                                     OKAY [  2.891s]
Sending sparse 'root' 32/33 (114684 KB)            OKAY [  4.709s]
Writing 'root'                                     OKAY [  2.617s]
Sending sparse 'root' 33/33 (9492 KB)              OKAY [  0.417s]
Writing 'root'                                     OKAY [  0.236s]
Finished. Total time: 264.331s

関連

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 キーボードで縦・横スクロールが出来なくなった場合の対処法

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

UPDATE 2024-01 気分転換に新型トラックポイントキーボードII に買い替えたところ、該当の事象は発生しなくなりました。Windows 11 の場合は接続するだけでドライバ・ユーティリティも自動導入されるようです。快調。

Lenovo(レノボ)USB-C ThinkPad トラックポイント キーボード 89キー 日本語配列 4Y40X49522

4Y40X49522