ししかわのマウス研修マウス自作研修

STM32のデバッグログをUSBで出力する – 元Web屋のマイクロマウス製作記 Part.17

ししかわのマウス研修

ししかわです。

社員研修の一環でマイクロマウスを自作します。

記事一覧 – 元Web屋のマイクロマウス製作記 | RT MicroMouse

前回、STM32に光センサを繋いで動かしてみましたが、
センサ値などのデバッグログをPCに出力できないので不便です。
今回はBluePillのUSB端子とPCを接続して、デバッグログをPCに出力できるようにしました。

環境

  • STM32 F103 Blue Pill Board
  • Ubuntu: 18.04.3 LTS

詳しくは環境構築の記事を参照ください。

STM32とPCをUSBで接続する

STM32とPCで通信する方法は幾つかありますが、
Blue Pill BoardにはmicroUSBの端子が付いているので、今回はUSB経由での接続を試してみます。

以降ではSTM32にUSBデバイスとして振る舞うための設定を加え、仮想COMポートを介したシリアル通信ができるようにします。

CubeMXの設定

  • 左メニューの「Connectivity->USB」を選択します
  • 「USB Mode and Configuration->Device(FS)」にチェックを入れます

  • 左メニューの「Middleware->USB_DEVICE」を選択します
  • 「USB_DEVICE Mode and Configuration->Class For FS IP」を「Communication Device Class(Virtual Port Com)」に変更します

  • 左メニューの「System Core->RCC」を選択します
  • 「RCC Mode and Configuration->High Speed Clock(HSE)」を「Crystal/Ceramic Resonator」に変更します

これで設定できました。「GENERATE CODE」をクリックして雛形を生成します。
生成した雛形には、新たにUSB通信用のミドルウェア(外部プログラム)が含まれているのが確認できます。

通信処理を使う

STM32からPCへ送信するにはCDC_Transmit_FS関数を使います。
次にコード例を示します。

// main.c
  /* USER CODE BEGIN 2 */
  char cdcBuffer[40];
  uint16_t count = 0;

  /* USER CODE END 2 */

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    sprintf(cdcBuffer, "Count: %d\n\", count++);
    CDC_Transmit_FS((uint8_t*)cdcBuffer, strlen(cdcBuffer));
    HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

次の点に注意しましょう。

  • 送信する文字列末尾に改行コード”\n\r”を入れないとターミナルに出力されません
  • CDC_Transmit_FSは通信中に他の処理をブロックしません。言い換えると、関数の呼び出し直後はまだ通信が完了していません。
    CDC_Transmit_FSを続けて呼ぶと送信は行われず、戻り値に1(= USBD_BUSY)が返ります。
    これを防ぐにはコールバックを管理するか、単に送信成功する(USBD_OKが返る)まで処理を繰り返します。
  while (1)
  {
    sprintf(cdcBuffer, "Count: %d\n\r", count++);
    while(CDC_Transmit_FS((uint8_t*)cdcBuffer, strlen(cdcBuffer)) == USBD_OK) {}
    HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

動作確認

  • Blue Pillにプログラムを書き込みます
  • Blue PillのBootピンを0にしてRESETボタンを押し、プログラムを起動します
  • Blue PillとPCをUSBで接続します
    • dmesgコマンドを打ってカーネルのログを確認し、Blue Pillのデバイスファイル名を確認します。
      次の場合、/dev/ttyACM0となります。
$ dmesg | tail -n 7

[121717.645332] usb 1-5: new full-speed USB device number 11 using xhci_hcd
[121717.794612] usb 1-5: New USB device found, idVendor=0483, idProduct=5740, bcdDevice= 2.00
[121717.794614] usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[121717.794616] usb 1-5: Product: STM32 Virtual ComPort
[121717.794617] usb 1-5: Manufacturer: STMicroelectronics
[121717.794618] usb 1-5: SerialNumber: 8D83385E5748
[121717.795946] cdc_acm 1-5:1.0: ttyACM0: USB ACM device
  • PCからscreenコマンドを打ってボードに接続します
$ screen /dev/ttyACM0

Count: 22
Count: 23
Count: 24
Count: 25
...

これでログを出力できるようになりました。
なお、プログラムを再度起動するときにCOMポートの接続もリセットされるので、
USBは挿し直す必要があります。

ログやデバッグ、テストの環境などは開発の初期にしっかり作っておくと、
後の開発がずっと楽になります。

タイトルとURLをコピーしました