STM32CubeIDEでprintf【SWO編】

STM32CubeIDEでprintfを使う時、UARTを採用することが多いと思いますが、いつもUARTが余っているとは限りません。実はSWOでもprintfを利用することができます。本記事では、SWOを使ってprintfする方法をわかりやすく解説します。

 

はじめに下記の画像をご覧になってください。デバッグ実行中の画面をキャプチャしてものです。printf出力が画面下部のコンソールに出力されているのがわかると思います。

SWO出力を使うことでSWDの線だけでこれを実現することができます。

 

SWOを使ってIDEにprintf出力

 

SWDとかSWOとかよくわからないですか?その場合は、ST-Linkが繋がってればprintfが使えるようになる、とだけ認識してくれれば大丈夫ですよ。

それでは具体的にその実現方法を解説していきます。

 

1.前提条件

今回は下記の環境を前提に話を進めます。STLinkはNUCLEO-F401REに実装されているものをそのまま使いました。

 

  • STM32CubeIDE ver.1.00
  • NUCLEO-F401RE

 

もし、自前の基板を使っている場合は別途ST-Linkを用意してください。ST-Linkを用意する方法は2通りありますので、お好きな方法で選んでください。

  • ST-Link
    • 素直にST-Linkを用意する方法です。
    • 配線方法は公式のマニュアルを参照してください。V2のマニュアルはこちら
    • 非公式のST-LinkだとSWO線がないものがあるようなので、よく確認してください
  • NUCLEOボードをST-Linkとして使う
    • NUCLEOボードをST-Linkとして使うことができます
    • 配線方法は公式のマニュアルを参照してください。NUCLEO-F401REのマニュアルはこちら

 

2-1.プロジェクトの作成

まずは適当にプロジェクトを作成してください。Device Configuration Tool(CubeMX)で特別な設定は必要ありません。

 

2.printfの準備

 

2-2.printfの実装

printfを実装してSWOに出力するようにしてあげましょう。下記のコードをコピペしてください。

 

main.c

/* USER CODE BEGIN 4 */
int _write(int file, char *ptr, int len)
{
  int DataIdx;
  for(DataIdx=0; DataIdx<len; DataIdx++)
  {
    ITM_SendChar(*ptr++);
  }
  return len;
}
/* USER CODE END 4 */

 

2-3.stdio.hのインクルード

stdio.hのインクルードは忘れずに入れておきましょう。

 

main.c

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

 

2-4.printfの追加

とりあえず今回は定期的に『Hello World!!』を出力するようなプログラムを書きました。

 

main.c

/* USER CODE BEGIN WHILE */
while (1)
{
  /* USER CODE END WHILE */
    printf("Hello World!!\r\n");
    HAL_Delay(1000);
  /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */

 

3.デバッグ時にprintf出力を行う

プログラム側の準備はできたので、ここからは実際にprintf出力をしてみましょう。デバッグ中と非デバッグ中でprintfの確認方法が異なるので、まずはデバッグ中での方法を解説します。

下記の画像が使用イメージです。SWV(Serial Wire Viewer)という機能を使ってprintf出力を確認します。

 

SWOでデバッグ中にprintfするシステム構成

 

3-1.デバッグの設定

SWVを使うにはデバッグの設定を適切に行う必要があります。

 

  • プロジェクトを右クリック→Debug as→STM32 C/C++ Application
  • デバッガタブ→シリアルワイヤビューワ(SWV)の有効にチェックを入れてください
  • Clock Settings→Core Clockにマイコンのクロック数を入力してください
  • Debugボタンを押してデバッグを開始してください
    main関数の先頭でデバッグが止まりますが、まだそのままにしてください

SWOデバッグ設定

 

3-2.SWVの起動

printf出力を表示するためのコンソールを起動します。

 

  • メニュー→Window→Show View→Others…
  • SWV→SWV ITM Data Consoleを開いてください
  • 開いたら設定ボタンを押して、SWVの設定ウィンドウを開いてください
  • 画面下部のチェックボックスの一番右の1つだけチェックを入れてください

 

SWV設定

 

これでprintf出力用のコンソールの準備ができました。

 

3-3.動作確認をする

それでは実際に表示させてみましょう。

 

  • SWVのスタートボタン(赤い丸)を押して受信を開始してください
  • デバッグの再開ボタンを押してデバッグを実行してください

 

SWVスタート

 

SWVに『Hello World!!』が追加されていくはずです。確認してみてください。

 

SWOを使ってIDEにprintf出力

 

表示されてますね!お疲れ様です!

なお、デバッグの開始後にSWVのスタートボタンは毎回押す必要があります。ちょっと面倒ではありますが忘れないようにしてくださいね。

 

もし、表示されない場合は、SWOのピンを別の機能でアサインしているのかもしれません。設定をよく確認してみてください。あるいは、Device Configuration Toolを開いて、System Core ->SYS->Mode->Debugを「Serial Wire」から「Trace Asynchronous Sw」にしてください。SWOのピンをSWO専用としてくれます。(このピンはSWO以外の用途には使えなくなります)

 

4.非デバッグ時にprintf出力を行う

先ほどはデバッグ中にprintf出力をしていましたが、非デバッグ時でも可能です。SWVはデバッグ中にしか利用できないため、printf出力の確認はST-Link Utilityを使います。

 

SWOを使ったprintfシステム

 

4-1.プログラムの書き込み

まずは先ほど作成したプログラムをマイコンに書き込んでください。

 

4-2.Printf via SWO Viewerで確認

ビューワーを起動して確認してみましょう。

 

  • ST-Link Utilityを起動する
  • メニュー→ST-LINK→Printf via SWO Viewerをクリック
  • Sysmtem Clock [Hz]:にマイコンのシステムクロックを入力してください
    (ここでは84000000を入力しました)
  • Startボタンをクリックしてください

 

 

表示されましたね!

表示されない方はSystem Clockの値が合ってないかもしれません。よく確認してみてください。

 

5.おわりに

本記事ではSWOを使ってprintfを実現する方法を解説しました。SWOを使うことで、UARTの線を使うことなくprintfを実現できます。

UARTの方法と使い勝手は変わりません。大きな違いは通信線です。どちらの通信線を使った方が良いのかはアプリケーションの要件によってまちまちなので、適切な方法を選んでいきましょう。

printfはデバッグ用途にしか使わない!という方には、UARTよりこちらの方法をお勧めします。

 

関連:【便利】STM32CubeIDEでprintf【UART編】

関連:STM32CubeIDEでprintf【Semihosting編】