我們一直在以各種形式看到這個問題,人們總是說有兩個堆棧。所以我用systick自己試了一下。
文檔說,我們是在線程模式復位的,如果你停止與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
我的設置並等待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 .
,並在處理程序中我看到
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
因此,在這種情況下,徑直出了ARM的文檔,所以不能用它使用sp_main的sp_process 。它正在推送手動表示它正在推送的項目,包括0x1000074被中斷/返回的地址。現在
,如果我設置SPSEL位(注意首先設置PSP),似乎一個MOV R0,SP在應用程序/線程模式使用PSP沒有MSP。但隨後的處理程序現在使用MSP爲MOV R0,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作爲標記然後倒數,看到返回地址。您可以讓您的處理程序讀取兩個堆棧指針,然後您可以查看gprs。用gnu彙編語言rX,psp; mrs rX,msp;對於進程和主棧指針。
與主棧運行中斷的代碼?如果它與進程堆棧一起運行,那麼你解開了錯誤的一個(因爲處理程序模式總是使用MSP)。根據鏈接的文檔,相關的堆棧以EXC_RETURN值編碼。 – Notlikethat
是的,我注意到了,我現在已經在我的SysTick_Handler代碼實際上讀出從那裏我最後一次正確的PC。儘管如此,GDB並沒有正確的放鬆。 – Kristoffer
你可以編寫'gdb'宏來做到這一點。 MSP特定於cortex-m,GDB被編寫爲可在多種不同平臺上運行,主要關注用戶應用程序。這就是說,它是開源的,我相信我們的貢獻是值得歡迎的。 –