は、2つのスタックがあると言っておきます。だから、私はそれを自分で試してみた。
ドキュメントは、我々がリセットのうち、スレッドモードであることを述べている、とあなたはopenocdで停止した場合には、
私はレジスタをダンプするためにいくつかのコードがあることを述べている:
20000000 APSR
00000000 IPSR
00000000 EPSR
00000000 CONTROL
00000000 SP_PROCESS
20000D00 SP_PROCESS after I modified it
20000FF0 SP_MAIN
20000FF0 mov r0,sp
then I dump the stack up to 0x20001000 which is where I know my stack started
20000FF0 00000000
20000FF4 00000000
20000FF8 00000000
20000FFC 0100005F
Iのセットアップをsystick割り込みを待つと、ハンドラはレジスタとRAMをダンプし、無限ループに入ります。一般的には悪い習慣ですが、ここでデバッグ/学習するだけです。割り込み前に、私はいくつかのレジスタを準備を:
.thumb_func
.globl iwait
iwait:
mov r0,#1
mov r1,#2
mov r2,#3
mov r3,#4
mov r4,#13
mov r12,r4
mov r4,#15
mov r14,r4
b .
とハンドラで、私はストレートARMのドキュメントのうち、この場合には
20000000 APSR
0000000F IPSR
00000000 EPSR
00000000 CONTROL
20000D00 SP_PROCESS
20000FC0 SP_MAIN
20000FC0 mov r0,sp
20000FC0 0000000F
20000FC4 20000FFF
20000FC8 00000000
20000FCC FFFFFFF9 this is our special lr (not one rjp mentioned)
20000FD0 00000001 this is r0
20000FD4 00000002 this is r1
20000FD8 00000003 this is r2
20000FDC 00000004 this is r3
20000FE0 0000000D this is r12
20000FE4 0000000F this is r14/lr
20000FE8 01000074 and this is where we were interrupted from
20000FEC 21000000 this is probably the xpsr mentioned
20000FF0 00000000 stuff that was there before
20000FF4 00000000
20000FF8 00000000
20000FFC 0100005F
01000064 <iwait>:
1000064: 2001 movs r0, #1
1000066: 2102 movs r1, #2
1000068: 2203 movs r2, #3
100006a: 2304 movs r3, #4
100006c: 240d movs r4, #13
100006e: 46a4 mov ip, r4
1000070: 240f movs r4, #15
1000072: 46a6 mov lr, r4
1000074: e7fe b.n 1000074 <iwait+0x10>
1000076: bf00 nop
だから、見る、それはsp_mainを使用しているSP_processのを使用していません。それは、マニュアルが0x1000074である中断された/戻りアドレスを含むプッシュしていると言う項目を押しています。
ここで、SPSELビットを設定すると(PSPを最初に設定することに注意してください)、アプリケーション/スレッドモードのmov r0、spはMSPではないPSPを使用しているようです。しかし、その後、ハンドラは、したがって、この位置にあるように、MOV r0のためにMSPを使用して、SPが、ハンドラ内で、今
20000000 APSR
00000000 IPSR
00000000 EPSR
00000000 SP_PROCESS
20000D00 SP_PROCESS modified
00000000 CONTROL
00000002 CONTROL modified
20000FF0 SP_MAIN
20000D00 mov r0,sp
スレッド/前景の前に
20000000 APSR
0000000F IPSR
00000000 EPSR
00000000 CONTROL (interesting!)
20000CE0 SP_PROCESS
20000FE0 SP_MAIN
20000FE0 mov r0,sp
dump of that stack
20000FE0 0000000F
20000FE4 20000CFF
20000FE8 00000000
20000FEC FFFFFFFD
20000FF0 00000000
20000FF4 00000000
20000FF8 00000000
20000FFC 0100005F
dump of sp_process stack
20000CE0 00000001
20000CE4 00000002
20000CE8 00000003
20000CEC 00000004
20000CF0 0000000D
20000CF4 0000000F
20000CF8 01000074 our return value
20000CFC 21000000
を
を置くように見えます人々が言及し続けている代替スタックを扱うには、そのポジション(またはあなたが依存するいくつかのコード)に自分自身を置かなければなりません。なぜあなたが知っている単純なベアメタルプログラムでそれをしたいのですが、すべてゼロのコントロールレジスタが素敵で簡単です。ちょうど良いスタックを共有できます。
私はgdbを使用しませんが、見つけたものに応じてすべてのレジスタsp_processとsp_mainをダンプする必要があります。次にダースなどをダンプすると、そこに0xFFFFFFFxがマーカーとして表示されますそれからカウントダウンしてリターンアドレスを確認してください。ハンドラに2つのスタックポインタを読み込ませ、gprsを見ることができます。 gnuアセンブラmrs rX、psp; mrs rX、msp;プロセススタックポインタとメインスタックポインタ。
中断されたコードがメインスタックで実行されていましたか?プロセススタックで実行していた場合、間違ったものを巻き戻しています(Handlerモードは常にMSPを使用するため)。リンクしたドキュメントごとに、関連するスタックはEXC_RETURN値でエンコードされます。 – Notlikethat
うん、私は今、私が前回の場所から正しいPCを実際に読み取るSysTick_Handlerのコードを持っていることに気づいた。それでも、GDBが正しく巻き戻してくれないことは悪いことです。 – Kristoffer
これを行うには 'gdb'マクロを書くことができます。 MSPはcortex-m固有であり、GDBは多くの異なるプラットフォーム上で動作するように記述されており、主にユーザーアプリケーションに関係しています。それはオープンソースだと私は確信していると確信しています。 –