MCUXpressoでRTT printf (その2)

前回はMCUXpressoでRTTを使用する方法を説明した。今回はprintf等の標準入出力関数をRTTにリダイレクトする方法を説明する。前回の内容の準備を前提とする。

MCU Xpressoで標準入出力をRTTにリダイレクトする設定

(1) 標準入出力をUARTへリダイレクトしない

ボードライブラリのプロジェクトのboard.c内の #include "retarget.h" をコメントアウトする。

#include <string.h>
#include "board.h"
// #include "retarget.h"
(2) 標準入出力をRTTへリダイレクトする

アプリケーションのプロジェクトに下記のretarget_rtt.cを追加する。

なお、標準入力関数(scanf関数やgetchar関数など)にもいちおう対応したが、ブロッキング処理であることに注意。実際にこれらを使うことはあまりないだろう。

(3) nohostのライブラリを選択する

アプリケーションのプロジェクトの[Properties] > [C/C++ Build] > [Settings] > [Tools Settings]タブ > [MCU Linker] > [Managed Linker Script] で Redlib(nohost) を選択する。

サンプルコード

下記のようなサンプルコードでprintf関数の出力がRTTに表示される。

#include <stdio.h>
#include "board.h"
#include "SEGGER_RTT.h"

// called every 1msec
void SysTick_Handler(void)
{
    static int cnt = 0;
    static int x = 0;
    if (x++ > 1000) {
        x = 0;
        cnt++;
        Board_LED_Set(0, false);

        printf("Count up! %d\n", cnt);

        Board_LED_Set(0, true);
    }
}

int main(void)
{
    SystemCoreClockUpdate();
    Board_Init();

    // call SysTick_Handler every 1msec
    SysTick_Config(SystemCoreClock / 1000);

    printf("Hello, world!\n");

    while(1) {
        ;
    }
    return 0 ;
}

速度の比較

セミホスティング、ITM、RTTのprintfの速度を比較する。
条件は以下の通りとする。

  • ターゲット: LPC1857, 180MHz
  • デバッグプローブ: LPC-Link2 (RTTの場合はJ-Link化、それ以外はCMSIS-DAP)
  • printf関数で10文字を出力 ( printf("123456789\n"); )

結果は以下のようになった。

方式 時間
セミホスティング 40~70 msec
ITM 20 usec
RTT 12 usec

セミホスティングは論外な遅さ(しかも一定しない)であるが、ITMとRTTは思ったほど差がなかった。これは、printf関数は書式処理のオーバーヘッドが大きいためと思われる。検証のために下記のような各処理の時間を計測した。

処理 時間
printf("%d\n", 123456789); 30 usec
printf("123456789\n"); 12 usec
SEGGER_RTT_printf(0, "123456789\n"); 10 usec
SEGGER_RTT_Write(0, "123456789\n", 10); 2.6 usec

以上のように、RTTの処理よりもprintf関数の書式処理の時間のほうが支配的であった。