見出し画像

Cortex-M マイコンにRTTを導入してみた

初めに

マイコンのデバッグの方法の1つに、プログラムの実行状態(変数の内容、分岐条件など)をターミナル(PCの画面上)に表示してバグを見つける方法があります。
そして、この表示データをターゲットからPCに送信する方法として、USBや、UART、ICE経由(セミホスティング)などがあります。
RTT(Real Time Transfer)は、SEGGER 社が提供するICE:J-LINKを使用して、データをPCに送信する方法の1つです。
今回は、Cortex-MマイコンにRTTを用いたターミナル出力に関して記載します。

目的

従来プログラム評価の際に、USB経由で実行状態をPCに送信して表示していましたが、この方式だと、不具合を評価時に見逃してしまう可能性が有りました。
この方式は、表示データを送信する処理をマイコンのプログラムが担う事になり、評価時(表示データ送信有)と製品版(表示データ送信無)で動作が異なってしまい、この差異で発生したり、しなかったりする不具合があるためです。今回RTTを導入する事にした目的は、上記の不具合の見逃しを防止することにあります。

RTTを選定した理由

前述の目的を達成するため下記の特徴があるRTTを選定しました。

  • マイコンの負荷が少ない

    • 送信バッファにデータを書込んで置くだけで、J-LINKが自動でPCにデータを送信します。

    • 他の方式では、マイコンのプログラムを動かしてデータを送信するためマイコンの負荷が発生します。

  • 通信速度が速い

    • RTT 1に対して、SWO(Serial Wire Output) 120 / セミホスティング 10,700 の時間を要します。

  • デバッグ時と製品版で同じコードを使用できる

    • 前述しましたが、RTTは送信バッファにデータを書込んでおけば、マイコンのプログラムの動作無しで、J-LINKが自動でPCにデータ送信します。J-LINKが接続されていなければ、送信バッファにデータを書くだけとなるので、デバッグ版のコードを製品版として使用する事が可能となります。

サンプルプログラムでの確認

  • IAR社のEWARMでRTTを試してみました。

ダウンロード&インストール

ソース追加

  • インストールしたフォルダ(SEGGER\JLink\Samples\RTT)下のzipファイルを解凍すると下記4つのフォルダにソースファイルがあります。

  • RTTフォルダ下のソースをEWARM のプロジェクトに追加します。

  • exsamples/MainRTT_PrintfTest.c をリンクするとSEGGER_RTT_printf関数によりターミナル出力ができます。

  • Syscalls/SEGGER_RTT_Syscalls_IAR.c をリンクすると、IDE(IARのEWARM)が提供しているprintf の出力先がRTTに変更されます。

    • IDE提供の weak __write() をオーバーライドしています。

    • SEGGER_RTT_Syscalls_IAR.c をリンクしない事で、printfを従来のターミナルIO 出力とし、SEGGER_RTT_printf をRTT出力とする事もできます。

出力結果

  • ターミナル出力した結果は、RTT Viewer等のSEGGER が提供しているツールや、TeraTerm等のターミナルソフト、ブラウザで表示する事が可能です。

  • 下記出力結果となります。

製品版への組み込み

  • 製品版に組み込む時は、exsamples/MainRTT_PrintfTest.c をプロジェクトから除外して、SEGGER_RTT.c の下記を修正します。

    • _SEGGER_RTT 構造体を固定アドレス(0x2000 0000)に配置します。

    • 0x2000 0000 は、今回使用したマイコンのRAMの先頭アドレスです。

    • RTT Control Block(_SEGGER_RTT)を Auto Detect するため、RAMの先頭に配置します。

      • RAMの先頭に配置されていないとViewer がRTT Control Blockを自動検索できませんでした。

    • RAMの先頭に配置できない場合は、RTT Viewerの設定を変更する事で対応できます。

      • アドレス指定:「Address」(RTT Control BlockのアドレスをMAPから検索してアドレスを入れます。)

      • 検索範囲指定:「Search Range」(RAMの先頭アドレスとサイズを入れます。)

    • RAMの先頭に配置するのが、RTT Viewerのデフォルト設定値「Auto Detection」が使用できるので分かりやすいと思います。

【_SEGGER_RTTを0x2000 0000 に配置するための変更】
SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT@));
    ↓
SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT@0x20000000));
  • RTT Viewer のRTT Control Block検出の設定画面

Auto Detection を選択した理由

RTT Control Blockの検索手段は、3種類あります。

  • 「Address」:RTT Control Blockのアドレスをピンポイントで指定する

  • 「Search Range」:検索する領域を指定する

  • 「Auto Detection」:自動で検索する(デフォルトの指定。当初製品版では接続できなかった)

Addressは、リンクのたびにアドレスが変化する(リンク時アドレス指定がない場合)ので都度設定の変更が必要、Search Rangeの場合、マイコンが変わると設定変更が必要となるため、Auto Detectionを使用したいと思いました。
そこで、サンプルと製品版で異なる箇所を探すためにリンクで作成されるMAPファイルを比較したところ、RTTの構造体のアドレスが、サンプルは、RAMの先頭付近にあり、製品版はRAMの後端にある事が分かりました。前記をもとに、構造体をRAMの先頭に配置した所、製品版でも「Auto Detection」で接続する事ができました。

今回使用したマイコンだけ、この現象が発生するかどうかは分からないのですが、「Auto Detection」で、コネクトできない場合は、RTT Control Blockのアドレスを変更してみてください。

最後に

通信速度が速く、製品版でもデバッグ用のターミナル出力が行えるRTTを活用しましょう。

【カシオのソフトウェア採用についてはこちら】

この記事が参加している募集