Search Notebooks
デバッグ 256

Page owner: user Suga koubou

Created 27 Dec 2011.
Last updated 27 Dec 2011

デバッグ 256

Page last updated 27 Dec 2011, by   user Suga koubou   tag No tags | 0 replies  

デバッグ

mbed は JTAG などのデバッグに使えるインターフェースが引き出されていない。

そのため、シリアルへ printf() で文字を表示してデバッグすることになる。

プログラム書込み用のUSB接続で、シリアル(COMポート、ttys)が使える。
参照 USBシリアル入出力 (by Tedd OKANO)

ここでは、どうしても暴走して動かなくなるプログラムのデバッグ方法を書き記す。

printf()デバッグ

プログラムの行間に printf を入れて、プログラムの流れを見る。

printf

    :
  printf("A\r\n");
  x = function(value);
  printf("B\r\n");
  if (x == 0) {
    printf("C\r\n");
      :
  } else {
    printf("D\r\n");
      :
  }
  printf("E\r\n");
    :

便利な使い方

デバッグが終了した時に printf を削除するのはめんどくさい。 そんな時は #define を活用する。

こんなヘッダファイルを用意しておき

dbg.h

#ifdef DEBUG
#define DBG(...) printf("" __VA_ARGS__)
#else
#define DBG(...)
#endif

プログラムに include する。

デバッグ表示のON/OFFは #define DEBUG / #undef DEBUG で切り替える。

main.cpp

#define DEBUG
#include "dbg.h"
#include "mbed.h"

int main () {
    :
  DBG("A\r\n");
  x = function(value);
  DBG("B\r\n");
  if (x == 0) {
    DBG("C\r\n");
      :
  } else {
    DBG("D\r\n");
      :
  }
  DBG("E\r\n");
    :    

メモリーあふれ

巨大な変数を定義したために、メモリー(RAM)あふれを起こしている場合、プログラムが動き出す前にFalut割込みが発生してしまう。

静的変数の場合は Hard Fault にて検出する。

HardFault

extern "C"
void HardFault_Handler() {
    printf("Hard Fault!\r\n");
    while(1);
}

動的変数やクラスの場合は set_new_handler にて検出する。

set_new_handler

#include "mbed.h"
#include <new>

void no_memory () {
    printf("panic: can't allocate to memory!\r\n");
    while(1);
}

int main() {
    set_new_handler(no_memory); // new handler function

    :

Faultが発生したアドレス

Fault割込みが発生した時のプログラムカウンタ(PC)はスタックに保存されているので、どのアドレスでエラーが起きたかわかる。

HardFault

extern "C" void HardFault_Handler() {
    register unsigned int _msp __asm("msp");

    printf("Hard Fault! address: %08x\n", *((unsigned int *)(_msp + 24)));
    while(1);
}

その他のFault

初期状態では、Bus Fault、Memory Manage Fault、Usage Fault の全てがHard Fault割込みを発生させる。

個別に割込みベクタを定義し、フラグをセットすることにより、それぞれ個別の割込みルーチンで処理できる。

Fault

extern "C" {

void HardFault_Handler() {
    printf("Hard Fault!\r\n");
    while(1);
}

void MemManage_Handler() {
    printf("MemManage Fault!\n");
    while(1);
}

void BusFault_Handler() {
    printf("BusFault Fault!\r\n");
    while(1);
}

void UsageFault_Handler() {
    printf("Usage Fault!\r\n");
    while(1);
}

} // extern "C"

int main() {
    (*(volatile uint32_t*)0xe000ed24) |= (1<<18)|(1<<17)|(1<<16); // fault handler enable

    :

戻る


Please login to post comments.