2023年11月26日日曜日

PCに複数繋げたstm32を判別してplatformioでプログラムを書き込む


背景

複数のstm32を同時にPCに繋げてplatformioを利用していたところ、uploat-portの指定が効かず片方にしかプログラムを書き込めない場面に出くわしました。
調べたところopenocdかmbedの設定に従えば判別できると分かりました。
備忘録として対応内容を記事に残します。

使ったもの

  • ubuntu22.04をインストールしたPC
  • VSCode + platformioプラグイン
  • nucleo-f429zi
  • nucleo-l432kc
  • usbハブ

upload_protocol = stlink (標準)の場合

stlinkはopenocdを使っているため、それのオプションで対象を指定できます。
調査と試行の結果2種類の指定方法を把握したので、それぞれ解説します。

adapter serial(旧hla_serial)でserialのidを指定

stlinkのserialのidは認識されているシリアルポートに対してudevadmコマンドを実行して確認できます。
udevadm info /dev/ttyACM0 | grep SERIAL
E: ID_SERIAL=STMicroelectronics_STM32_STLink_066BFF494877514867174753
E: ID_SERIAL_SHORT=066BFF494877514867174753

調べたserialのidをupload flagsでadapter serialとして指定します。
platformio.ini
upload_flags =
-c
adapter serial 066BFF494877514867174753

1行で書く場合は、1行書きで-cとadapterの間にスペースがあると正しく解釈されず動かない場合があるので、スペース無しで記述するのが良いです。
問題に取り組んでいるときはその不具合が発生したのですが、記事を書いているときはスペースがあっても動いたので、何が悪いのか不明です。
参考: Unnecessary double quotes with upload_flags
platformio.ini
upload_flags =
-cadapter serial 066BFF494877514867174753

上記の設定で書き込めば、指定した装置に対して書き込めます。

環境変数PLATFORMIO_BUILD_FLAGSを使えば設定ファイルに書き込まずコマンドで指定できます。
PLATFORMIO_UPLOAD_FLAGS="-cadapter serial 066BFF494877514867174753" pio run -t upload

adapter usb locationでstlinkが繋がっているusbポートを指定

usbポートを指定して書き込みます。
「IDは指定しなくて良いが、この目的のこの種類のマイコンはこのUSBポートに繋ぐ」ような場面で便利です。

シリアルポートからusbポートの場所を探る場合、udevadmで表示されるパスから読み取れます。
udevadm info /dev/ttyACM0 | grep P:
P: /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1.1/2-1.1:1.2/tty/ttyACM0

上記の表示の場合、下記の2-1.1がusbポートの場所情報です。
P: /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1.1/2-1.1:1.2/tty/ttyACM0
^^^^^

usbポートの全体像は下記コマンドで確認できます。
lsusb -t
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
|__ Port 1: Dev 6, If 0, Class=Hub, Driver=hub/4p, 5000M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/9p, 480M
|__ Port 1: Dev 75, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 84, If 3, Class=CDC Data, Driver=cdc_acm, 12M << ここ
|__ Port 1: Dev 84, If 1, Class=Mass Storage, Driver=usb-storage, 12M << ここ
|__ Port 1: Dev 84, If 2, Class=Communications, Driver=cdc_acm, 12M << ここ
|__ Port 1: Dev 84, If 0, Class=Vendor Specific Class, Driver=, 12M << ここ
|__ Port 2: Dev 77, If 0, Class=Vendor Specific Class, Driver=, 12M
|__ Port 2: Dev 77, If 1, Class=Mass Storage, Driver=usb-storage, 12M
|__ Port 2: Dev 77, If 2, Class=Communications, Driver=cdc_acm, 12M
|__ Port 2: Dev 77, If 3, Class=CDC Data, Driver=cdc_acm, 12M
|__ Port 4: Dev 2, If 0, Class=Wireless, Driver=btusb, 12M
|__ Port 4: Dev 2, If 1, Class=Wireless, Driver=btusb, 12M
|__ Port 5: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 6: Dev 4, If 0, Class=Video, Driver=uvcvideo, 480M
|__ Port 6: Dev 4, If 1, Class=Video, Driver=uvcvideo, 480M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/3p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
|__ Port 7: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 8: Dev 6, If 0, Class=Human Interface Device, Driver=usbhid, 12M
「<<ここ」と示しているのが今回の書き込み先です。
Bus 02 の Port 1 のPort 1 であり、udevadmで読み取った2-1.1と合っているのが分かります。

これをadapter usb locationとして指定します。
platformio.ini
upload_flags =
-c
adapter usb location 2-1.1

上記の設定で書き込めば、指定した装置に対して書き込めます。

環境変数PLATFORMIO_BUILD_FLAGSを使えば設定ファイルに書き込まずコマンドで指定できます。
PLATFORMIO_UPLOAD_FLAGS="-c adapter usb location 2-1.1" pio run -t upload

upload_protocol = mbedの場合

mbedモードの場合は、stlinkがマウントされているメディアのパスを指定します。
ubuntuの場合は「/media/${USER}/」にマイコンの名前を含んだメディアとしてマウントされます。
pio run -t upload --upload-port /media/asuki/NODE_L432KC/

mbedモードでシリアルポートを--upload-portとして指定していると、それはディレクトリではないというエラーが出ます。
*** [upload] /dev/ttyACM0/firmware.bin: Not a directory

おわり

stlinkの場合はserialのidを、mbedの場合はマウントされたメディアを指定することで、優先的に書き込まれる装置のUSBを外して書き込み後につなぎ直してシリアルモニタを繋ぎ直すという手間なことをしなくても複数同時にstm32をstlinkで開発できるようになりました。

記事にまとめた方法の他に便利な指定方法がありましたら、コメントなどで共有していただけると嬉しいです。

続編情報

ポートを指定したらstlinkでプログラムを書き込める便利スクリプトを書きました。
よかったらご利用ください。

stm32に対してポートを指定してplatformioでプログラムを書き込むlinux向けのスクリプトを書いた
https://github.com/asukiaaa/useful-scripts/blob/master/platformio/upload-to-stm32-port

参考

stlink利用時の指定方法を把握したページです。
Programming with multiple ST-Link programmers
More than one ST-Link for upload (several devices are connected to PC_
STLink upload_port

upload_flagsの指定で改行の位置が解釈不具合の原因と把握したページです。
Unnecessary double quotes with upload_flags

openocdのadapterコマンドの解説ページです。
8 Debug Adapter Configuration

usbポートの位置把握の参考にしたページです。
How to interpret tcl command in openOCD manual
How to get Bus and Device relationship for a /dev/ttyUSB

mbed利用時の指定方法を把握したページです。
Error `upload_port` for environment or use global `–upload-port` option

変更履歴

2023.12.03 続編情報として便利スクリプトと紹介ページへのリンクを追加しました。

0 件のコメント :