ARM Cortex M4启动时无法加载堆栈指针(Tiva C系列TM4C123GH6PM)

时间:2017-11-15 02:29:09

标签: gcc arm cortex-m bare-metal

我正在尝试为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的原因可能是:

  • 未定义的指令

- 非法的未对齐访问

- 指令执行状态无效

- 异常返回时出错

但我不明白是什么原因。

1 个答案:

答案 0 :(得分:3)

在ARM程序集中编写是很棘手的。这段代码有三个问题。

  1. .vector_interrupt部分没有进入二进制文件,因为它没有ALLOC属性。 objcopy忽略没有ALLOC属性的部分。结果,初始堆栈指针和复位向量为零。要解决此问题,section属性应为“xa”:

    .section .vector_interrupt, "xa"
    
  2. 另一个问题:初始堆栈指针未对齐。将其更改为:

    .word 0x20008000
    
  3. 这假设MCU至少有32KB RAM。

    1. 分支目标地址应将LSB位设置为1以指示Thumb模式。 Cortex-M4仅支持Thumb指令集,因此在尝试跳转到偶数地址时会产生错误。为了让汇编程序生成正确的地址值,.thumb_func应位于标识分支目标的每个标签之前。
    2. 请参阅https://sourceware.org/binutils/docs/as/ARM-Directives.html