« 開発環境 | トップページ | DWT追記 »

2019年1月12日 (土)

DWT

新幹線移動中の開発により、DWTを動作させることができるようになった。
割り込みで処理を追加した後に、正常動作に復帰できるし、これはいい。

純粋にデバッガの動作だけど、オンチップペリフェラルだけで
(アダプタとかプローブの類なしで)実現できるのはありがたい。

スタックの上限(というか余裕を持たせた警告エリアの方がいいが)
にウオッチポイントとアクセス方法(読み、書きの別など)を設定しておく。

スタックが侵食して、アクセスの条件が成立すると、
デバッグベクタに分岐して、通常の割り込みと同様に処理できる。

スタックポインタに余裕を持たせておけば、破綻することなしに
処理が続けられ、スタックの残りが少ないことが
実行されているプログラム自身で把握できる。

------

今回のターゲットはstm32l433だけど、Cortex-M3,M4なら
どれでも使える可能性はありそうだ。
設定例は以下。

プログラムの初期設定部分に記述して、DWTを有効にする。

    //  デバッグ例外、モニタ制御レジスタ
    CoreDebug->DEMCR =
        (1 << 24)|    //    TRCENA
        (1 << 16)|    //    MON_EN
        0;

    CoreDebug->DHCSR =
        (0xa05f << 16) |        //    書き込みキー
        (1 << 0) |
        0;

    *(volatile unsigned long*)(0xe0001020) = 0x2000e000;    //    DWT_COMP0
    *(volatile unsigned long*)(0xe0001024) = 0x00000000;    //    DWT_MASK0
    *(volatile unsigned long*)(0xe0001028) = 0x00000007;    //    DWT_FUNCTION0  書き込み/読み出しのウオッチポイント
    *(volatile unsigned long*)(0xe0001000) |= 0x00000001;    //    DWT_CONTROL




割り込みハンドラも記述する。

//****************************************************************
//          デバッグ   割り込みハンドラ
//****************************************************************
void DebugMon_Handler(void) {

    static unsigned char temp[32];
    volatile int i;

    sprintf(temp, "\r\nDebug [%08X]\r\n\r\n", *(volatile unsigned long*)(0xe0001020));
    Puts(temp);

    stop = 1;

}

DWTがウオッチポイントへのアクセスを検出すると、
ハンドラが呼ばれるので、コンソールにメッセージを出力する。

0xe0001020は、DWTのコンペアレジスタ。
全部で4つあるので、最大4つのアドレス(エリア)を
同時に監視できる。
グローバル変数で定義されているstopにフラグを立てて戻る。

------

テストに、実際にスタックポインタを進めて、
どの辺で止まるか試してみる。

再起呼び出しで、毎回AUTO変数を定義するコードを書く。
一回の呼び出しで、116バイト分の変数を宣言するのだけど
実際のアドレスは、変数の呼び出し分のレジスタ退避エリア
などで、もう20バイト使われて、136バイトづつ消費されるようだ。

スタックの初期値は、0x20010000。
DWTの設定は上記のコードの通り、0x2000e000として、
動作させてみる。

シリアルコンソールに動作状態を出力させてみる。

1901122_2

58回目の呼び出しで、DWTが動作して、再起呼び出しが停止している。
この時のAUTO変数のポインタは、0x2000e0bcあたりを示していて、
DWTの設定値には、もう少しあるようにも見える。

今の場合でnewlib(sprintfとか)が、内部で使っているエリアが、180バイトくらい
あるのかなあ、という印象。

まあ、現実的な処かな?と思うので、なんとなく意図通りの
動きはしているように思える。

------

スタックの監視だけでなく、任意のエリアの不正なアクセスも
実行状態で、オーバヘッドなしにソフトウエアだけで監視できるので、
発見しにくいバグ(アクセス違反)を押さえるのに、大変役立ちそうだ。

標準コマンドとして整備しよう。

|

« 開発環境 | トップページ | DWT追記 »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: DWT:

« 開発環境 | トップページ | DWT追記 »