texane gdb server과 함께 Sourcery CodeBench Lite 2012.03-56 컴파일러 및 gdb 슈트를 사용하고 있습니다.Cortex m3 첫 번째 명령어 실행
오늘 나는 값싼 STM32VLDISCOVERY 보드에 대해 FreeRTOS 데모 예제를 시험해보고 싶었지만 필요한 모든 소스 파일을 복사하고 오류없이 컴파일했지만 예제가 작동하지 않았습니다. 디버거를 시작하고 GPIO 레지스터에 대한 포인터를 역 참조하려고 할 때 예제가 실패한 것으로 나타났습니다. GPIO에 대한 포인터를 포함 글로벌 배열 변수는 등록 :
GPIO_TypeDef* GPIO_PORT[LEDn] = {LED3_GPIO_PORT, LED4_GPIO_PORT};
가 제대로 초기화되지 않았으며 어떤 임의의 값으로 채워졌다. 나는 전처리 기가 LED3_GPIO_PORT와 LED3_GPIO_PORT를 정의했는지 확인했다.
문제가 발생한 부분을 조사한 후 CMSIS lib에있는 trueSTUDIO에 제공된 시작 파일을 살펴 보았습니다. 원래 startup_stm32f10x_md_vl.S 파일 :
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
...
디버깅하는 동안 나는 레지스터 (R1)가 먼저 명령에 의해 제로로 MOVS의 R1, # 0 초기화되지 않습니다 것으로 나타났습니다. 레지스터 r1은 루프의 카운터로 사용되므로 실행 루프 LoopCopyDataInit에 도달하면 레지스터 r1에 이전 실행의 일부 가비지 데이터가로드되므로 루프에 들어 가지 않습니다. 이 의 결과로 시작 코드는 .data 섹션을 초기화하지 않습니다. 내가 MOVS r1을하기 전에 두 개의 NOP 명령을 배치
, # 0 명령은 다음 R1은 0으로 초기화 된 레지스터 및 예제가 작동하기 시작
startup_stm32f10x_md_vl.S 파일의 수정 된 부분 :
/* Copy the data segment initializers from flash to SRAM */
nop
nop
movs r1, #0
b LoopCopyDataInit
당신은 ISR 벡터 TABL을 볼 수 있듯이
Disassembly of section .isr_vector:
08000000 <g_pfnVectors>:
8000000: 20002000 andcs r2, r0, r0
8000004: 08000961 stmdaeq r0, {r0, r5, r6, r8, fp}
...
Disassembly of section .text:
...
8000960 <Reset_Handler>:
8000960: 2100 movs r1, #0
8000962: f000 b804 b.w 800096e <LoopCopyDataInit>
08000966 <CopyDataInit>:
8000966: 4b0d ldr r3, [pc, #52] ; (800099c <LoopFillZerobss+0x16>)
8000968: 585b ldr r3, [r3, r1]
800096a: 5043 str r3, [r0, r1]
800096c: 3104 adds r1, #4
:
이 최종 코드의 관련 부분의 분해이다 e가 Reset_Handler 주소를 제대로 가리키고 있습니다. 그래서, 무슨 일이 일어나고있는거야? 왜 첫 번째 명령 movs r1, # 0 원래 시작 코드에서 실행 된 적이 있습니까?
편집 : 나는 다시 보드 다시 전원을 전원을 끌 때
원래의 코드가 작동합니다. MCU를 여러 번 리셋 할 수 있습니다. gdb-server를 시작하면 리셋 후에도 코드가 작동하지 않습니다. 다시 작동 시키려면 전원을 켜야합니다. 디버거가 이상하게 여기는 것 같아요.
참고 :
나는 시작 코드는이 MCU와 함께 사용하는 다른 사람들이 무엇을보고 있었다 중복 두 경우 모두에있는 링커 정의 된 값들은 하나 인터럽트를 비활성화 또는 부하 SP 레지스터. 그들이이 이상한 행동에 부딪치게되면 그들은 그것을 알아 채지 못할 것입니다.
해서는 안'08000960'로'g_pfnVectors' 포인트 리셋 벡터가 아닌'08000961'? –
_ ARM 코어 텍스 -M3, Joseph Yiu_, 3.7 리셋 시퀀스 : "Reset vector (프로그램 실행의 시작 주소, LSB는 Thumb 상태를 나타 내기 위해 1로 설정되어야 함)." 이는 8000961이 실제로 08000960 주소임을 나타냅니다. – BlueSky
그건 의미가 있습니다. 분명히 잘못된 것을 볼 수는 없으며 아마도 디버거와의 이상한 상호 작용 일 것입니다. –