我正在尝试为Tiva C启动板编写最简单的程序。堆栈指针值和程序计数器值自动取自闪存的前两个32位字。但是,由于某种原因,当我使用gdb进行调试时,堆栈指针变为0x0。这导致程序失败。我使用此说明进行调试:
(gdb) target extended-remote :3333
(gdb) monitor reset halt
(gdb) load
(gdb) monitor reset init
程序集中的程序是startup.s:
.syntax unified
.section .vector_interrupt, "x"
g_pfnVectors:
.word 0x20007FFF
.word _Reset
.text
.global _Reset
_Reset:
mov r0, #0
b stop
stop:
add r0, r0, #1
b stop
链接器文件Tiva.lds:
ENTRY(_Reset)
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
SECTIONS {
.vector_interrupt : {
KEEP(*(.vector_interrupt));
} > FLASH
.text : {
. = 0x0000026c;
* (.text);
} > FLASH
}
和makefile:
gcc=arm-none-eabi-gcc
objcopy=arm-none-eabi-objcopy
FLAGS= -ggdb3 -nostdlib -std=c99 -mcpu=cortex-m4 \
-mfloat-abi=softfp -mfpu=fpv4-sp-d16 -Wall \
-Werror -nostartfiles
csum.bin: csum.elf
$(objcopy) -O binary csum.elf csum.bin
csum.elf: startup.s
$(gcc) $(FLAGS) -T Tiva.lds -o csum.elf \
startup.s
openocd:
openocd -f ../openOCD/ek-tm4c123gxl.cfg
有什么问题?
现实化
我试图避免放置异常处理程序。但是,现在我把它们。问题是我在启动时获得了UsageFault。
我做了这些修改: 的Startup.s:
.syntax unified
.section .vector_interrupt, "x"
g_pfnVectors:
.word _stack_start
.word _Reset
.word NMI /* NMI Handler */
.word HardFault /* Hard Fault Handler */
.word MemManage /* MPU Fault Handler */
.word BusFault /* Bus Fault Handler */
.word UsageFault /* Usage Fault Handler */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word SVC /* SVCall Handler */
.word DebugMon /* Debug Monitor Handler */
.word 0 /* Reserved */
.word PendSV /* PendSV Handler */
.word SysTick /* SysTick Handler */
.text
.global _Reset
_Reset:
mov r0, #0
b stop
stop:
add r0, r0, #1
b stop @ Infinite loop to stop execution
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
b .
/* Macro to define default handlers */
.macro def_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_handler NMI
def_handler HardFault
def_handler MemManage
def_handler BusFault
def_handler UsageFault
def_handler SVC
def_handler DebugMon
def_handler PendSV
def_handler SysTick
def_handler DEF_IRQHandler
Tiva.lds:
ENTRY(_Reset)
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
_stack_start = ORIGIN(SRAM)+LENGTH(SRAM);
SECTIONS {
.text : {
KEEP(*(.vector_interrupt));
* (.text);
} > FLASH
}
这是arm-none-eabi-objdump -d csum.elf的输出
csum.elf: file format elf32-littlearm
Disassembly of section .text:
00000000 <g_pfnVectors>:
0: 20008000 .word 0x20008000
4: 00000040 .word 0x00000040
8: 0000004d .word 0x0000004d
c: 0000004d .word 0x0000004d
10: 0000004d .word 0x0000004d
14: 0000004d .word 0x0000004d
18: 0000004d .word 0x0000004d
...
2c: 0000004d .word 0x0000004d
30: 0000004d .word 0x0000004d
34: 00000000 .word 0x00000000
38: 0000004d .word 0x0000004d
3c: 0000004d .word 0x0000004d
00000040 <_Reset>:
40: f04f 0000 mov.w r0, #0
44: e7ff b.n 46 <stop>
00000046 <stop>:
46: f100 0001 add.w r0, r0, #1
4a: e7fc b.n 46 <stop>
0000004c <BusFault>:
4c: f7ff bff8 b.w 4c <BusFault>
UsageFault的原因可能是:
- 非法的未对齐访问
- 指令执行状态无效
- 异常返回时出错
但我不明白是什么原因。
答案 0 :(得分:3)
在ARM程序集中编写是很棘手的。这段代码有三个问题。
.vector_interrupt
部分没有进入二进制文件,因为它没有ALLOC属性。 objcopy
忽略没有ALLOC属性的部分。结果,初始堆栈指针和复位向量为零。要解决此问题,section属性应为“xa”:
.section .vector_interrupt, "xa"
另一个问题:初始堆栈指针未对齐。将其更改为:
.word 0x20008000
这假设MCU至少有32KB RAM。
.thumb_func
应位于标识分支目标的每个标签之前。请参阅https://sourceware.org/binutils/docs/as/ARM-Directives.html