私のコードでIRQハンドラの戻りアドレスを取得しようとしています。 WDT_IRQHandler()を使用して、ウォッチドッグ・タイマが期限切れになる直前およびデバッグのためのリセット前に、PCの値を保存することを私の目標としています。私はこのアプローチを他のIRQでテストして、そのアイディアを把握しているかどうかを確認しています。 しかし、私はそうしていないようです。ARM Cortex M0での例外の戻りアドレスの取得
私は利用可能なdocumentationを読んでいます。 例外が発生すると、8個のレジスタがスタックにプッシュされることがわかりました。 R0、R1、R2、R3、R12、LR、PCおよびXPSR。
私はまた、スタックが自動的にダブルワードアライメントされていることを読んだことがあります。だから私の考えでは、返信アドレスの取得は次のように簡単です。
- __builtin_frame_address(0)でspアドレスを取得します。
- スタックされたPCのオフセット(0x18)を追加し、値を読み取ります。この値は、ハンドラが復帰したときにPCに復元される値です。
デバッガが接続されているかどうかをチェックすると、そのメモリアドレスの内容が常にフラッシュ領域または有効な領域を指しているとは限りません。いずれの場合でも値は決してありませんそのPCはPOP命令の後に引き継がれます。
コードはうまく動作するので、どのように動作するかを理解する上で問題があると思います。これが起こらない他のIRQで
私は解体をチェックすると、いくつかのIRQに定数が飛び出る(?)の前のspに追加され
00001924: 0x000009b0 ...TE_IRQHandler+280 add sp, #36 ; 0x24
00001926: 0x0000f0bd ...TE_IRQHandler+282 pop {r4, r5, r6, r7, pc}
。
私は、もっと多くのレジスタがスタックにプッシュされることがありますので、どのようなオフセットでPCを取得するのかをどのように確認できますか?
コードがIRQハンドラにまだ残っているときにSPの周りのメモリダンプをチェックすると、戻りアドレスを見つけることができますが、SPと比較してマイナスのオフセットで常に奇妙な場所にあります。私は正しい住所を得る方法を理解できません。あなたは2つの理由のCハンドラの内部でスタックポインタに頼ることができない
ありがとうございます。 for point 1)MSPとPSPの両方を__get_MSP()と__get_PSP()を使ってCからチェックできると思います。 for 2)私はプッシュ後に、コードがローカル変数をスタックに追加することができ、コンパイル時にそれらが既知であることを知っているので、固定オフセットに依存することはできません。 私はあなたのアプローチを試みます。 – Vitomakes
@Vitomakes Cからの 'MSP'と' PSP'をチェックしても、どちらが正しいかはわかりません。もちろん、 'MSP'(非常に共通)だけを使用する場合は、チェックをスキップすることができます。 –
"ITE"と "MRSEQ/MRSNE"はcortex M0でサポートされておらず、コンパイラは親指モードにあり、TSTを使用できないことに不満を抱いています。しかし、私は考えを持って、私はそれを並べ替えるでしょう – Vitomakes