前回は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関数など)にもいちおう対応したが、ブロッキング処理であることに注意。実際にこれらを使うことはあまりないだろう。
サンプルコード
下記のようなサンプルコードで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関数の書式処理の時間のほうが支配的であった。