動的解析をスタンドアロンで使用

C-RUNはIAR Embedded Workbenchのアドオンとして使用する動的解析ツールです。C-RUNはオーバーフローや境界エラーまたはメモリの誤った使用などを検出することが可能です。通常は統合開発環境およびICEを使用して、検出結果を確認しますが、本稿でご紹介する方法によりスタンドアロンでも使用可能です。

C-RUNのエラーメッセージは、通常デバッグウィンドウに表示され、また任意のウィンドウにリダイレクトすることができます。そして、そのメッセージを保存し、後で確認することも可能です。

ターミナルI/Oに動的解析の出力をリダイレクト

C-RUNのメッセージはセミホスティングによりPCに転送されます。C-RUNのメッセージは<EWARM>\arm\src\lib\crunに実装があります。スタンドアロンでC-RUNを動作させる前に、ターミナルI/Oを試してみましょう。

ワークスペースにReportCheckFailedStdout.cを追加

先述の\crunフォルダにあるReportCheckFailedStdout.cをワークスペースにコピーします。

動的解析をスタンドアロンで使用1

ファイルは読み取り専用モードになっていますのでプロパティを変更しましょう。

動的解析をスタンドアロンで使用2

C-RUNメッセージをリダイレクト

C-RUNエラーメッセージをリダイレクトするためにリンカの設定を変更しましょう。デフォルトでは、__iar_ReportCheckFailedisが呼ばれます。これを、ReportCheckFailedStdout.cで実装されている__iar_ReportCheckFailedStdoutにします。

__interwork void __iar_ReportCheckFailedStdout(void * d)
{

   char buf[200] = {0};
char *b = buf;

  uint32_t const *data = (uint32_t const *)d;
int nr = data[0] >> 24;

  b = putstring(b, "CRUN_ERROR:");
for (int i = 0; i < nr; ++i)
{
    *b++ = ' ';
    b = puthex(b, data[i]); 
  }
  *b++ = '\n';
  __write(_LLIO_STDOUT, (unsigned char const *)buf, (size_t)(b - buf));
  if (__iar_ReportCheckFailedStdoutAbort)
    abort();
}
 

リンカのオプションから、以下のように追加オプションを指定します。
--redirect __iar_ReportCheckFailed=__iar_ReportCheckFailedStdout

動的解析をスタンドアロンで使用3

C-RUNによるデバッグ

デバッグを開始する前に、C-RUNで検出したい問題を指定できているか確認してください。その後、すべてを再ビルドし、ダウンロードしてデバッグを開始しましょう。表示 > ターミナルIOによりウィンドウを開きます。

C-RUNがエラーメッセージを検出したら、ターミナルIOに出力されます。

動的解析をスタンドアロンで使用4

これによりターミナルIO上でC-RUNのメッセージが確認できるようになりました。出力は生データで、cspybat.exeを使用するとメッセージが見えます。

C-RUNの生データをcspybat.exeで見やすく

cspybat.exeは、デバッグのバッチを制御するツールですが、C-RUNの生データを見やすく整形するのにも使用できます。

バッチファイルを修正

プロジェクトをビルドするたび、***.cspy.batというファイルが生成されます。エディタでそのファイルを開いてみましょう。--rtc_enableの後に--rtc_filterを追加して、ファイルを保存してください。

コマンドプロンプトからバッチを実行

コマンドプロンプトを開き、プロジェクトの\settingsフォルダに移動します。そして、バッチファイルを指定、

動的解析をスタンドアロンで使用5

さらに出力ファイルのパスを追加します。

動的解析をスタンドアロンで使用6

この例では、c.outを単純化のために移動しておきました。もちろん、絶対パスによる指定も可能です。

動的解析をスタンドアロンで使用7

これでcspybatがC-RUNの生データを待っている状況になりました。

生データを整形

ターミナルIOで取得したメッセージを整形してみましょう。メッセージは1行で出力すべきということに注意してください。

動的解析をスタンドアロンで使用8

Enterを押すと、以下のように整形されたメッセージが表示されます。

動的解析をスタンドアロンで使用9

整数の型変換に失敗していて、それがmain.cの16行目であることがわかります。C-RUNをデフォルトで使った場合に、C-RUNのメッセージウィンドウに出力されるものと同様です。

注意:C-RUNの生データにはコールスタックが含まれません

C-RUNのメッセージをUARTにリダイレクト

C-RUNのメッセージは他の通信チャネルにももちろんリダイレクト可能です。この場合、単純に、_iar_ReportCheckFailedStdout関数を変更します。

_iar_ReportCheckFailedStdout関数の変更

ReportCheckFailedStdout.cを開きます。

__interwork void __iar_ReportCheckFailedStdout(void * d)
{
  char buf[200] = {0};
  char *b = buf;  

  uint32_t const *data = (uint32_t const *)d;
  int nr = data[0] >> 24; 

  b = putstring(b, "CRUN_ERROR:");
  for (int i = 0; i < nr; ++i)
  {
    *b++ = ' ';
    b = puthex(b, data[i]); 
  }
  *b++ = '\n';
  __write(_LLIO_STDOUT, (unsigned char const *)buf, (size_t)(b - buf));   


  if (__iar_ReportCheckFailedStdoutAbort)
    abort();
}
 

ローカル変数bufにC-RUNのメッセージが含まれます。メッセージは、__write関数により送られます。__write関数をコメントアウトし、代わりにser_printf関数の呼び出しにしてみましょう。

動的解析をスタンドアロンで使用13

ser_printf関数は他のファイルで定義されています。またUARTはC-RUNがメッセージを送る前にセットアップする必要があります。

同様にして、SPIやI2CまたはRAMやFlashへのリダイレクトも可能です。

ターミナルを開いて、プロジェクトを実行

Tera Termなどターミナル・アプリケーションを開き、ダウンロードしてデバッグを開始しましょう。

動的解析をスタンドアロンで使用10

Tera TermにC-RUNのエラーメッセージが出力されるようになります。一文字目のAはアプリケーションからの出力です。

スタンドアロンで実行

ICEをボードからはずし、再度ボードの電源を入れてみましょう。ボード単体でC-RUNのメッセージがターミナルに出力されるはずです。

動的解析をスタンドアロンで使用11

以上で、ICEなしのフィールドテストにおいて、C-RUNのメッセージが収集できるようになりました。集めたメッセージは、前述のとおり、cspybat.exeによって、整形することができます。

動的解析をスタンドアロンで使用12

注意: バッチファイルを生成するとき、デバッガ > ダウンロード > フラッシュローダを使用する(U) チェックボックスをはずしてください。

まとめ

C-RUNは手軽で便利な動的解析のアドオンです。本稿でご紹介した方法により、スタンドアロンのテストでぜひご活用ください。

申し訳ございませんが、弊社サイトではInternet Explorerをサポートしていません。サイトをより快適にご利用いただくために、Chrome、Edge、Firefoxなどの最新ブラウザをお使いいただきますようお願いいたします。