우리는 여러 가지 형태로이 질문을 계속하고 있습니다. 사람들은 두 개의 스택이 계속 있다고 말합니다. 그래서 나는 그것을 시스템으로 직접 시도했다.
문서는 우리가 리셋에서 스레드 모드에서, 그리고 말한다 당신과 함께 정지 openocd는 말한다면 그 나는 레지스터 덤프 몇 가지 코드가
target halted due to debug-request, current mode: Thread
:
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 인터럽트를 기다리면, 핸들러는 레지스터와 램을 덤프 한 다음 무한 루프로 들어갑니다. 나쁜 연습이지만 일반적으로 여기서 디버깅/학습. 인터럽트 전에 좀 레지스터 수험 :
.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를 사용하는 것처럼 보입니다. 그러나 핸들러는이 위치에 핸들러 그래서
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
지금/전경
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
를 특검팀하는 MOV r0을위한 MSP를 사용하지만 스레드에서 전에
을 넣어 나타납니다 사람들이 계속 언급하고있는 대체 스택을 다룰 때, 당신은 그 위치 (또는 당신이 의존하는 코드)에 자신을 두어야 만합니다. 왜 모든 베어러 컨트롤 레지스터가 좋고 쉬운 지 알 수있는 간단한 베어 메탈 프로그램을 원한다면 한 스택을 잘 공유 할 수 있습니다.
나는 gdb를 사용하지 않지만 모든 레지스터 sp_process와 sp_main을 찾은 다음 찾은 것에 따라 덤프해야한다. 그런 다음 각각에 12 개 정도의 단어를 덤프하면 0xFFFFFFFx가 마커로 표시된다. 그 다음부터 다시 계산하여 반송 주소를 확인하십시오. 당신은 핸들러가 두 개의 스택 포인터를 읽도록 할 수 있습니다. 그러면 gpr을 볼 수 있습니다. gnu 어셈블러 mrs rX, psp; mrs rX, msp; 프로세스와 메인 스택 포인터들.
중단 된 코드가 메인 스택과 함께 실행 되었습니까? 프로세스 스택에서 실행 중이면 잘못된 핸들을 풀고 있습니다 (처리기 모드는 항상 MSP를 사용하기 때문에). 연결된 문서마다 관련 스택이 EXC_RETURN 값으로 인코딩됩니다. – Notlikethat
예, 제가 SysTick_Handler에 실제로 지난번 내가 있던 곳에서 정확한 PC를 읽는 코드가 있습니다.여전히 GDB가 올바르게 풀리지 않는 것은 나쁜 것입니다. – Kristoffer
이렇게하기 위해'gdb' 매크로를 작성할 수 있습니다. MSP는 cortex-m에 고유하며 GDB는 여러 플랫폼에서 실행되도록 작성되었으며 주로 사용자 응용 프로그램과 관련이 있습니다. 즉 오픈 소스이며 기부금을 환영한다고 확신합니다. –