2017-02-03 175 views
0

私のプログラムを実行するときにハードフォールが発生しています。私はPCの価値を得るために何十もの方法を見つけましたが、私はKeil uVision 5を使用しています。Cortex M0 HardFault_Handlerとフォールトアドレスの取得

私が知る限り私はマルチタスクのコンテキストではなく、PSPには0xFFFFFFF1が含まれているため、24を追加するとオーバーフローが発生します。

は、ここで私は(それがコンパイルおよび実行、のように)作業を取得するために管理してきたものだ:

enum { r0, r1, r2, r3, r12, lr, pc, psr}; 

extern "C" void HardFault_Handler() 
{ 
    uint32_t *stack; 
    __ASM volatile("MRS stack, MSP"); 

    stack += 0x20; 

    pc = stack[pc]; 
    psr = stack[psr]; 
    __ASM volatile("BKPT #01"); 
} 

注C関数スタックを補うためにここにある「+ = 0x20に」、。

私がPCの値を読むときはいつでも、それは0です。 誰かがそれに対応するコードを持っていますか?

そうでない場合は、ここで私は手動でそれを行う方法は次のとおりです。

  • が破断すると、MSP
  • ようになり
  • HardFault_Handlerに(元の)にブレークポイントを置いて、その値に24を追加します。
  • そのアドレスのメモリをダンプします。 それは0x00000000です。

私は間違っていますか?

答えて

0

あなたのコードを持ついくつかの問題

uint32_t *stack; 
__ASM volatile("MRS stack, MSP"); 

MRSはレジスタ・デスティネーションをサポートしています。あなたのアセンブラは最初に一時レジスタに転送するのに十分なほど賢明ですが、それから生成されたマシンコードを見たいと思います。

何らかの種類のマルチタスクシステムを使用している場合、MSPの代わりにPSPを使用する可能性があります。下のリンクされたコードを見て、それをどのように区別できるかを見てください。

pc = stack[pc]; 
psr = stack[psr]; 

これは指標としてpcpsrの以前の値を使用します。私はPCの値を読むたび

pc = stack[6]; 
psr = stack[7]; 

する必要があり、あなたのプログラムが実際に(例えばヌル関数ポインタ経由)0番地に跳ね上がっている場合があります0

、値を実行しようとしたですそれはおそらく有効な命令ではなく、ベクトルテーブルからの最初のSP値であり、それには誤りがあります。このコード

void (*f)(void) = 0; 
f(); 

ないで正確に、私は見ている0x00000000のオフセット24

誰もがそのためのコードを働いていますか?

This works for me. pspとmspの間でコードを選択し、__attribute__((naked))指示に注意してください。コンパイラがスタックフレームをまったく割り当てないように、コンパイラに相当するものを見つけることができます。

+0

ありがとうございました。精度と欠落したコードを追加しました。私のコンパイラ/アセンブラは実際に "MRS R0、MSP"をサポートしていませんが、私の "MRSスタックMSP"の結果は同じです。それは私をたくさん制限します、それはどんなレジスタも理解していないようです。これまでコンパイラで動作する__attribute __((naked))に相当するものは見つかりませんでしたが、とにかくこれが全体的に正しいことを確認しました。それについて考えていなかったヌルポインタのヒントについて、ありがとうございました。 – user1532080

+0

あなたの答えに基づいて、スタックにプッシュされたLRの値を見ました。それは有効な場所を指しているので、それはありがとう!ありがとう! – user1532080

関連する問題