STM32CubeIDEでprintf【Semihosting編】

STM32CubeIDEでSemihostingを使ってprintfを使う方法を解説します。

まずは下記の画像をご覧になってください。Semihostingを使うことでデバッグコンソールにprintf出力ができるようになります。

 

デバッグコンソールに出力

 

またUARTの線も使わないので省配線にもなるというメリットもあり、デバッグ作業がとても便利になります。ただし、速度は遅く処理の邪魔になりやすい点には注意してください。

以降では具体的にSemihostingでprintfをするための方法を解説していきます。

 

1.前提条件

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

 

  • STM32CubeIDE ver.1.00
  • NUCLEO-F401RE

 

2.printf用のプロジェクトの準備

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

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

 

2-2.syscall.cの無効化

Semihostingを使う場合はsyscall.cが競合してしまうので無効化しておきましょう。

 

  • プロジェクトを右クリック→Properties
  • C/C++ General→Path and Symbols→Source Locationタブ
  • <プロジェクト名>/Src→Filterを選択して、Edit Filterボタンからsyscall.cを追加してください

 

syscall.cをFilter

 

2-3.リンカの設定

続いてリンカの設定を行います。まずはライブラリの追加です。

 

  • プロジェクトを右クリック→Properties
  • C/C++ Builde→Settings→Tool Settingsタブ→MCU GCC Linker→Libraries
  • Libraries (-l)の『+ボタン』から『rdimon』を追加してください

 

rdimonの追加

 

次にライブラリの有効化の設定をします。

 

  • プロジェクトを右クリック→Properties…
  • C/C++ Builde→Settings→Tool Settingsタブ→MCU GCC Linker→Miscellaneous
  • Other flagsの『+ボタン』から『-specs=rdimon.specs』を追加してください

 

rdimonの有効化設定

 

3.printf用のコードを追加

3-1.printfの初期化

printfを使う前に初期化コードを入れておく必要があります。例えば、下記のように追加します。

 

main.c

/* USER CODE BEGIN 0 */
extern void initialise_monitor_handles(void);
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  initialise_monitor_handles();
  /* USER CODE END 1 */

 

UARTを使った方法とは違い、setbuf()ではないことに注意してください。

 

3-2.printfの追加

実際にprintfを追加してみましょう。今回は定期的に『Hello World!!』するだけのプログラムにしました。

 

main.c

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

 

4.デバッグの設定

このプロジェクト用のデバッグ設定を作成します。

 

  • プロジェクトを右クリック→Debug as→STM32 MCU C/C++ Application
  • デバッガタブ→デバッグプローブで『ST-Link (OpenOCD)』を選択してください

 

OpenOCD

 

続いて、このデバッグでSemihostingを使うための設定を追加します。

 

  • Startupタブ→Initialization Commandsに『monitor arm semihosting enable』を追加してください

 

Semihostingの有効化

 

5.デバッグの実行

ここまでで準備は完了です。最後にDebugボタンを押してデバッグを実行してみましょう。

 

デバッグコンソール

 

デバッグコンソールに出力されましたね!お疲れ様でした!

 

6.おわりに

本記事ではSTM32CubeIDEでSemihostingを使ってprintfを実現する方法をご紹介しました。

Semihostingを使うことで、UARTの線を使うことなくprintfが使えるようになります。また、出力はデバッグコンソールに行われるため、使い勝手は良いと思います。ただし、通信速度はあまり速くありません。

printfの使用頻度が少なく、printfをしても処理への影響が小さい時には便利な方法かと思います。

 

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

関連:STM32CubeIDEでprintf【SWO編】