アプリケーションの動的な解析手法として、以前printfデバッグについて書きましたが、今回もprintfデバッグについてのTipsです。
おさらい
通常、アプリケーションのコードが正しいか、計算された値が正しいか確認するため、一旦プログラムの実行を止めて(ブレイク)、コードを一つひとつ実行していきレジスタやメモリの値を確認する、いわゆるステップ実行、デバッグという作業が必要となります。
こういったデバッグ手法は一旦プログラムを止めなければならないために、プログラムの意図した動きや振る舞いが変わる可能性があります。
そのため、動的な解析の手段として、printfデバッグが有効なわけです。詳しくは、以前記事『LPCでPrintfデバッグとセミホスティング 』を参考にしてください。
しかしながら、printfデバッグでも、printf()関数を実行するためにプログラムの振る舞いに少なからずとも影響を与えてしまいます。
当然、アプリケーションの機能や振る舞いに影響を与えてしまう可能性があります。そのため、プログラムの動的解析は、非常に気を使ったデバッグをしなければいけません。
ITM拡張機能(SWO)
ARM Cortex-M3、M4でサポートされている機能ですが、ITM(Instrument Trace Macrocell)というデバッグ拡張機能がサポートされています。
これは、printf形式のデバッグ拡張機能として、OSやアプリケーションのイベント(ITM用マクロ関数)をトレースして、ITMレジスタに書き込まれた、または書き込まれている値を高速にSWO経由で出力します。
このITMトレース機能は、デバッガーのコンソール上で確認できたり、そのイベント情報を時系列的に表示させたりできます。
更に、ARM CoreSightというデバッグ拡張モジュールが行うため、CPUコアがprintf関数を実行するような負荷は無く、プログラム実行に影響を及ぼさずにデバッグ情報を出力してくれるのです。
プログラムをステップ実行することができないアプリケーションや、ソフトウェアとハードウェアのタイミングが問題となるような不具合の動的解析などに有効です。ただし、プログラムの実行や振る舞いに全く影響を与えない訳では無く、影響を劇的に抑えることが可能なものです。
こんな良い機能があるのなら、使わない手はないですね。
この便利なITM機能を使用するためには、いくつか制限があります。マイコンやその開発環境がITM機能に対応している必要があるので、注意が必要です。
ITM(SWO)機能をサポートしているNXPマイコン
Kinetisシリーズ:
全てのKシリーズ、KV3x、KW2xD
LPCシリーズ:
LPC13xx LPC15xx, LPC17xx/18xx, LPC40xx/43xx
Cortex-M0/M0+ではITMがサポートされていません。
開発統合環境(IDE):
ITM機能をサポートしている代表的なIDEのみご紹介します
- IAR EWARM
- ARM Keil
- Atomic True Studio
- MCUXpresso IDE
NXPの開発統合環境MCUXpresso IDEでもサポートしています。
デバッグプローブ:
NXPのMCUXpresso IDEでは、SWO機能はLink Serverでのみサポートされます。
ITMのSWO出力は、LPC-LINK2ボード、LPCXpressoのオンボードICE(CMSIS-DAP)が対象になります。FRDMボードのオンボードICE(CMSIS-DAP、JLINK、P&Eマルチリンク)やmbedのopenSDAオンボードICEなどは、MCUXpresso IDEではSWO機能が非対応となっています。LPC-LINK2、LPCXpressoオンボードICEのみサポートされています。
では、実際に使い方を見ていくとしましょう。
ITM Printfデバッグをやってみよう!
printfデバッグに使用するプロジェクトは、今回も同様にK64を使用することにします。
準備
ハードウェア
- FRDM-K64F
開発統合環境(IDE)
MCUXpresso IDE
MCUXpresso IDEは、コードサイズの上限が無いフリーツールです。個人使用目的にも開発にも使用できるのはいいですね。
ダウンロードはこちらから(NXP MCUXpresso IDE ダウンロードページ)
デバッグプローブ
- LPC-LINK2(CMSIS-DAP)
LPC-LINK2を使用します。FRDM-K64ボードのオンボードICEでは、CMSIS-DAPでもSWO機能されていないので、LPC-LINK2ボードを使用します。
ボードの接続
FRDM-K64FのオンボードICEもSWDデバッグインタフェースを使用しています。J26のUSBコネクタに接続すると、オンボードICEが駆動してLPC-LINK2と衝突してしまいます。
そこで、反対側のJ22にUSB microを接続するとオンボードICEは動作させずにFRDM-K64Fへの給電が可能です。あとは、LPC-LINK2 のSWDインタフェースを接続します。
ソフトウェア
Hello_worldプロジェクトを使用します。
MCUXpresso SDK K64のSDKを使用します。
SWO機能を使うのは取っても簡単
ITMのSWO出力を使用するのは、実はとっても簡単です。MCUXpresso IDEでは、新しいプロジェクト作成ウィザードで自動的にSWO出力に設定されます。
SWOを使用するためには、ITMイベントからCライブラリにパラメータを渡すためにグローバル変数を用意したり、その関数が必要になります。この関数も自動的にプロジェクトに組み込まれます。
では、早速プロジェクトの作成から見ていきます。
MCUXpresso IDEの起動
ワークスペースは、任意の場所にフォルダーを作成することが可能です。そのフォルダーを指定していきます。
プロジェクトの作成
今回は、SDKのサンプルプロジェクト(Hello World)からプロジェクトを作成します。
評価ボードの選択
使用する評価ボードを選択して、Nextをクリックします。
FRDMボードは、事前にSDKを作成して取り込んでおく必要があります。以前の記事『MCUXpresso SDK〜SDKの作り方〜』を参考にして、SDKを事前に作成しておいてください。
生成されたSDKファイル(ZIP)を”Installed SDKs”という画面にドラッグ&ドロップすることで、FRDM-K64FのSDKを取り込むことが可能です。
プロジェクトの選択
Cライブラリオプションの設定
ここでITMトレース機能(SWO)の肝となる設定です。
尚、Newlibやnewnanolibを使用することも可能なはずですが、Redlinkのライブラリでしか上手くいきません。今後、NXPには修正してもらいたいですね。
Redlinkのライブラリを選択し、更に”PRINTF”をC標準ライブラリのprintfへのリダイレクト(Redirect SDK “PRINTF” to C library “printf”)のチェックボックスを選択します。
更に、今回の目的でもあるITMのprintf/scanfを使用する(redirect printf/scanf to ITM)にチェックをしてFinishをクリックします。
プロジェクトのビルド
これでHello Worldのプロジェクトを取り込むことができました。早速、ビルドしてみます。
デバッグ開始
Quick Startビューからデバッグをクリックしてデバッグを開始します。
SWO設定
デバッグを開始するとMain()関数の先頭で一旦ブレイク(停止)します。ここで、SWO出力設定を行います。
SWO設定は、”SWO Trace Config”というタブを開くと設定できます。
SWOのクロック設定で、CPUコアへアクセスするためコアと同じクロック周波数を設定します。FRDM-K64Fは120MHzなので、120000000と入力して設定します。
Main()関数先頭でブレイクしたとき、クロックなどの初期化が完了していませんので、SWOクロック設定時に”Detect”をクリックすると初期クロック20.975MHzになってしまい、正しく接続できません。
続いて、ITM Consoleを開くとコンソール画面が表示されます。
SWOのPrintf出力を確認
ブレイクを解除すると、通常のConsole画面に戻りますが、SWOコンソールにタブをクリックするとHello Worldが表示されています。
Hello Worldのサンプルコードは、Scanf()も可能で常にキーボードからの入力をモニタリングしています。試しに入力してみるとSWOコンソールにタイプしたアルファベットが表示され、Enterで決定するとprintfで折り返し出力されます。
まとめ
ITM printfデバッグは、プログラムの動作への影響を抑え、高速にPrintf出力、scanf入力が行えます。動的なデバッグが必要な場合にはITM Printfデバッグが有効です。
MCUXpresso IDEなら特別な設定なし、プロジェクト作成時にITM Printfをイネーブルにしておくだけで、自動的にプロジェクトに組み込んでくれるので、簡単に手軽にITM Printfデバッグが行えます。
これから、MCUXpresso IDEで高速ITM printfデバッグはいかがでしょうか?
最後までお読みいただきありがとうございます。 もし、良かった!と思われたら、シェアして頂ければ幸いです。