No tags
|
0 replies
mbed は JTAG などのデバッグに使えるインターフェースが引き出されていない。
そのため、シリアルへ printf() で文字を表示してデバッグすることになる。
プログラム書込み用のUSB接続で、シリアル(COMポート、ttys)が使える。
参照 USBシリアル入出力 (by Tedd OKANO)
ここでは、どうしても暴走して動かなくなるプログラムのデバッグ方法を書き記す。
プログラムの行間に 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 を活用する。
こんなヘッダファイルを用意しておき
#ifdef DEBUG
#define DBG(...) printf("" __VA_ARGS__)
#else
#define DBG(...)
#endif
プログラムに include する。
デバッグ表示のON/OFFは #define DEBUG / #undef DEBUG で切り替える。
#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 にて検出する。
extern "C"
void HardFault_Handler() {
printf("Hard Fault!\r\n");
while(1);
}
動的変数やクラスの場合は 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割込みが発生した時のプログラムカウンタ(PC)はスタックに保存されているので、どのアドレスでエラーが起きたかわかる。
extern "C" void HardFault_Handler() {
register unsigned int _msp __asm("msp");
printf("Hard Fault! address: %08x\n", *((unsigned int *)(_msp + 24)));
while(1);
}
初期状態では、Bus Fault、Memory Manage Fault、Usage Fault の全てがHard 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.