2023年2月19日日曜日

STM32のnucleoの2番目のUSBポートは10Mbps(1MByte/s)弱でシリアル通信できる


背景

前回ESP32S3とC3の内蔵USB回路を利用したシリアル通信の速度を計測した際にUSBポートが2個付いているSTM32の開発ボード(nucleo)でもできるだろう思い、調べて試したら出来たので使い方と性能を記事に残します。

なお、この記事の2週間後にFreeRTOSやSTLink経由のシリアル通信と併用する方法も把握したので、良ければこちらもご覧ください。

STM32のCDCを利用しながらFreeRTOSとSTLinkのシリアル出力を利用

使ったもの

  • platformioをインストールしたPC
  • USB microBケーブル2本
    書き込み用と2番目のUSBポート用です。
  • STM32のnucleo(開発ボード)
    今回利用したのはNUCLEO-H753ZIです。

プログラムはESP32の通信速度測定で使ったものを再利用

下記記事のcppをこの記事でも利用しました。

ESP32 C3やS3の内蔵USBのシリアル通信は最高10Mbit/s

配線: 2番目のUSBポートでは給電できないので2本接続

2番目の書き込みは対応してないポートからは給電できない仕様になっているので、そのUSBポートで通信したい場合は何らかの形で給電が必要です。
今回は書き込み用のSTLinkV3に繋がっているポートをPCに接続したままにして給電しました。


CDC側とSTLink側のmicroB端子は上下逆なので、同じ向きで無理に差し込まないよう注意してください。

2番目のUSBポートを有効化: CDC利用のためにUSBCONとUSBD_USE_CDCを定義

STM32にUSB端子を直接繋ぐとUSB2.0に基づくいくつかの機能が利用可能で、その中でCDC(Communication Device Class)を使うと仮想comポート(virtual comport)がUSBで利用可能になりシリアル通信できます。

クラスとしてはSerialUSBです。
そのクラスはUSBCONとUSBD_USE_CDCが定義されているときに有効になる実装になっています。

platformioの場合はプロジェクトの設定ファイルのビルドフラグでUSBCONとUSBD_USE_CDCを定義すれば使えます。
platformio.ini
[env:stm32h7]
board = nucleo_h743zi
board_build.mcu = stm32h753zit6
platform = ststm32
framework = arduino
build_flags =
-D USBCON
-D USBD_USE_CDC

CDCの通信速度は6.67〜10Mbps(667K〜1M byte/sec)

ESP32C3の通信速度計測でも利用したbps計測プログラムを書き込んで動かしてみます。
表示されるログで6.67〜10Mbpsで通信出来ていると分かりました。
print 1K for 1ms
1.00M byte/s
10.00M bit/s
print 10K for 15ms
666.67K byte/s
6.67M bit/s

10K byte送信時は情報がどこかで詰まるのか10Mbpsに届きませんでした。
CDCなのでserial beginやPC接続時のbpsの値は何でも良く、何bpsを指定しようが期待通りに値を10Mbps弱で受信しました。

Stack overflowのやりとりでもSTM32のCDCの上限速度は1MByte/secと回答があるので、最高速度で通信できているようです。
What is the maximum speed of the STM32 USB CDC?

STM32H7のSTLinkV3経由の通信速度の上限は7Mbps

CDCの通信速度は10Mbit/sと分かったのでSTM32H7のSTLinkV3を介した通信速度の上限も調べたところ7Mbpsが上限と分かりました。
(8Mbpsにするとシリアル通信でログを受け取れませんでした)

platformio.ini
[env:stm32h7]
board = nucleo_h743zi
board_build.mcu = stm32h753zit6
platform = ststm32
framework = arduino
monitor_speed = 7000000 ; ok
; monitor_speed = 8000000 ; bad
build_flags =
-D BAUDRATE=7000000 ; ok
; -D BAUDRATE=8000000 ; bad

CDCとは異なり、STLinkV3を介したシリアル通信は、Serial.beginで指定した通信速度と同じ値でシリアルモニタを開く必要がありました。
monitor_speed = 7000000

受信したログの速度情報はこちらです。
print 10K for 14ms
714.29K byte/s
7.14M bit/s
print 1K for 1ms
1.00M byte/s
10.00M bit/s

Serial.beginもシリアルモニタも7Mbpsを指定しているのに、マイコン内部の送信時間は7Mbpsより速く(短く)計測されていました。
誤差でしょうか。

終わり

STM32のCDCで2番目のUSBポートを仮想comポートとして利用して10Mbps(1MByte/s)で通信できました。
STLinkV3経由のシリアル通信より速くでき、CDCならシリアルモニタを開く際の通信速度を気にしなくて良くなるので、できるだけ速く通信したい場合はCDCを使うのが便利だと思いました。

参考

前回ESP32Cの内装USBシリアルの通信速度を計測した記事です。
ESP32 C3やS3の内蔵USBのシリアル通信は最高10Mbit/s

STM32のUSB接続に関する資料です。
 Introduction to USB with STM32

STM32ArduinoでUSBSerialの利用をマクロで切り替えている行です。
https://github.com/stm32duino/Arduino_Core_STM32/blob/76887a45b43c9e919db17df9e039d96bd01641d1/cores/arduino/USBSerial.cpp#L19

シリアル通信速度計測プログラムです。
https://github.com/asukiaaa/check-arduino-serial-speed

STM32のCDCの通信速度に関するStack overflowのやりとりです。
What is the maximum speed of the STM32 USB CDC?

変更履歴

2023.03.05
STM32のCDCを利用しながらFreeRTOSとSTLinkのシリアル出力を利用する紹介記事のリンクを背景に追加しました。
2023.10.15
利用したプログラムを掲載している記事へのリンクを追加しました。

0 件のコメント :