環境
- OS: Ubuntu 24.04 LTS (x86_64)
- Device: M5StickC Plus 2
- PlatformIO: version 6.2.0
問題
OSがUSBデバイスとして認識していることを lsusb コマンドで確認しましたが、デバイスへのファームウェアのアップロードには失敗します。
どうすればアップロードできる様になるでしょうか?
% lsusb
︙
Bus 001 Device 005: ID 1a86:55d4 QinHeng Electronics USB Single Serial
︙
% pio run -e m5stick-c-plus2 -t upload
Processing m5stick-c-plus2 (platform: espressif32@6.10.0; board: m5stick-c-plus2; framework: arduino)
--------------------------------------------------------------------------------
︙
Building in release mode
Retrieving maximum program size .pio/build/m5stick-c-plus2/firmware.elf
Checking size .pio/build/m5stick-c-plus2/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [= ] 7.8% (used 25660 bytes from 327680 bytes)
Flash: [= ] 14.5% (used 484589 bytes from 3342336 bytes)
Configuring upload protocol...
AVAILABLE: cmsis-dap, esp-bridge, esp-prog, espota, esptool, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa
CURRENT: upload_protocol = esptool
Looking for upload port...
Warning! Please install `99-platformio-udev.rules`.
More details: https://docs.platformio.org/en/latest/core/installation/udev-rules.html
Auto-detected: /dev/ttyACM0
Uploading .pio/build/m5stick-c-plus2/firmware.bin
esptool.py v4.5.1
Serial port /dev/ttyACM0
A fatal error occurred: Could not open /dev/ttyACM0, the port doesn't exist
*** [upload] Error 2
========================= [FAILED] Took 11.28 seconds =========================
Environment Status Duration
--------------- -------- ------------
m5stick-c-plus2 FAILED 00:00:11.278
==================== 1 failed, 0 succeeded in 00:00:11.278 ====================
解決方法
Warning が出力されている様に、99-platformio-udev.rules への書き込みによって解決しました。
Warning! Please install 99-platformio-udev.rules.
More details: https://docs.platformio.org/en/latest/core/installation/udev-rules.html
記載されたリンク に記載されている、以下のコマンドを実行するだけです。
% 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
% sudo service udev restart
そして再度アップロードを試すと、成功しました。
% pio run -e m5stick-c-plus2 -t upload
⋮
Writing at 0x0007e2c3... (94 %)
Writing at 0x00083b79... (100 %)
Wrote 484960 bytes (269745 compressed) at 0x00010000 in 4.3 seconds (effective 903.6 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
========================= [SUCCESS] Took 8.27 seconds =========================
Environment Status Duration
--------------- -------- ------------
m5stick-c-plus2 SUCCESS 00:00:08.267
========================= 1 succeeded in 00:00:08.267 =========================
解説
Ubuntu 24.04 など、近年の Linux OS は udev という仕組みによってデバイスのアクセス権限を管理します。既定では、non-root ユーザによるシリアル通信デバイスへのアクセスは禁止されています。なので、OSが機器を認識していても、一般ユーザは通信できません。
また、バックグラウンドでは ModemManager が通信モデムの検出を行なっており、シリアル通信デバイスとの接続を占有することがありまます。専有されている間は、別のアプリケーションとデバイスが通信できません。
なので、udev.rules を適用することで、これらを適切な設定に切り替えます。
コマンドの記載リンクを開くと、デバイス別の設定一覧を見ることができます。各項目は以下の通りです。
| 項目 | 概要 |
|---|---|
| ATTRS{idVendor} | デバイスの Vendor ID |
| ATTRS{idProduct} | デバイスの Product ID |
| MODE: | デバイスに対するアクセス権限 ※0666=任意のユーザに対するread/writeの許可 |
| ENV{ID_MM_DEVICE_IGNORE} | ModemManager による検出対象デバイスからの除外 |
| ENV{ID_MM_PORT_IGNORE} | ModemManager による検出対象ポートからの除外 |
つまり、udev.rules を追加することで、PlatformIO が取り扱うデバイスとの接続に関して、
- non-root環境によるアクセス(例. upload / monitor) を許可する
- アクセスの妨げになる処理を無効化する
というわけでした。
例えば、M5StickC Plus 2 に該当するエントリを見つけてみます。
lsusb コマンドを見ると、M5StickC は vid=1a86, pid=55d4 として認識されています。
Bus 001 Device 005: ID 1a86:55d4 QinHeng Electronics USB Single Serial
これに対応するエントリを 99-platformio-udev.rules から検索すると、見つけることができました。
# QinHeng Electronics CH9102 USB-Serial adapter
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"