STM32F030 启动时出现硬故障,__libc_init_array

Posted

技术标签:

【中文标题】STM32F030 启动时出现硬故障,__libc_init_array【英文标题】:Hardfault on STM32F030 startup, __libc_init_array 【发布时间】:2014-12-22 12:27:33 【问题描述】:

我正在尝试使用 arm-none-eabi-gcc 和 Makefile 编译一个 STM32Cube 项目。 我已指定:

CFLAGS = -mthumb\
         -march=armv6-m\
         -mlittle-endian\
         -mcpu=cortex-m0\
         -ffunction-sections\
         -fdata-sections\
         -MMD\
         -std=c99\
         -Wall\
         -g\
         -D$(PART)\
         -c

和:

LDFLAGS = -Wl,--gc-sections\
          -Wl,-T$(LDFILE)\
          -Wl,-v

固件构建没有问题。但是当我启动 MCU 时,我陷入了硬故障。 堆栈跟踪是:

#0  HardFault_Handler () at ./Src/main.c:156
#1  <signal handler called>
#2  0x0800221c in ____libc_init_array_from_thumb ()
#3  0x080021be in LoopFillZerobss () at Src/startup_stm32f030x8.s:103
#4  0x080021be in LoopFillZerobss () at Src/startup_stm32f030x8.s:103
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

当我在启动文件中步进到bl __libc_init_array 时直接进入硬故障。

/* Zero fill the bss segment. */
FillZerobss:
  movs r3, #0
  str  r3, [r2]
  adds r2, r2, #4


LoopFillZerobss:
  ldr r3, = _ebss
  cmp r2, r3
  bcc FillZerobss

/* Call the clock system intitialization function.*/
  bl  SystemInit
/* Call static constructors */
  bl __libc_init_array
/* Call the application's entry point.*/
  bl main

有什么想法可能是错的吗?

我的 arm-none-eabi-gcc 版本是 4.8.4 20140725 (release)

[编辑] 调用的反汇编

08002218 <____libc_init_array_from_thumb>:
8002218:   4778        bx  pc
800221a:   46c0        nop         ; (mov r8, r8)
800221c:   eafff812    b   800026c <__libc_init_array>

0800026c <__libc_init_array>:
800026c:   e92d4070    push    r4, r5, r6, lr
8000270:   e59f506c    ldr r5, [pc, #108]  ; 80002e4 <__libc_init_array+0x78>
8000274:   e59f606c    ldr r6, [pc, #108]  ; 80002e8 <__libc_init_array+0x7c>
8000278:   e0656006    rsb r6, r5, r6
800027c:   e1b06146    asrs    r6, r6, #2
8000280:   12455004    subne   r5, r5, #4
8000284:   13a04000    movne   r4, #0
8000288:   0a000005    beq 80002a4 <__libc_init_array+0x38>
800028c:   e2844001    add r4, r4, #1
8000290:   e5b53004    ldr r3, [r5, #4]!
8000294:   e1a0e00f    mov lr, pc
8000298:   e12fff13    bx  r3
800029c:   e1560004    cmp r6, r4
80002a0:   1afffff9    bne 800028c <__libc_init_array+0x20>
80002a4:   e59f5040    ldr r5, [pc, #64]   ; 80002ec <__libc_init_array+0x80>
80002a8:   e59f6040    ldr r6, [pc, #64]   ; 80002f0 <__libc_init_array+0x84>
80002ac:   e0656006    rsb r6, r5, r6
80002b0:   eb0007ca    bl  80021e0 <_init>
80002b4:   e1b06146    asrs    r6, r6, #2
80002b8:   12455004    subne   r5, r5, #4
80002bc:   13a04000    movne   r4, #0
80002c0:   0a000005    beq 80002dc <__libc_init_array+0x70>
80002c4:   e2844001    add r4, r4, #1
80002c8:   e5b53004    ldr r3, [r5, #4]!
80002cc:   e1a0e00f    mov lr, pc
80002d0:   e12fff13    bx  r3
80002d4:   e1560004    cmp r6, r4
80002d8:   1afffff9    bne 80002c4 <__libc_init_array+0x58>
80002dc:   e8bd4070    pop r4, r5, r6, lr
80002e0:   e12fff1e    bx  lr
80002e4:   08002258    .word   0x08002258
80002e8:   08002258    .word   0x08002258
80002ec:   08002258    .word   0x08002258
80002f0:   08002260    .word   0x08002260

[编辑 2] 来自 gdb 的寄存器值:

(gdb) info reg
r0             0x20000000   536870912
r1             0x1  1
r2             0x0  0
r3             0x40021000   1073876992
r4             0xffffffff   -1
r5             0xffffffff   -1
r6             0xffffffff   -1
r7             0x20001fd0   536879056
r8             0xffffffff   -1
r9             0xffffffff   -1
r10            0xffffffff   -1
r11            0xffffffff   -1
r12            0xffffffff   -1
sp             0x20001fd0   0x20001fd0
lr             0xfffffff9   -7
pc             0x800067c    0x800067c <HardFault_Handler+4>
xPSR           0x61000003   1627389955

【问题讨论】:

反汇编文件,看看跳转到哪里,然后检查那个地址的代码。您链接的 libc 可能存在问题,导致跳转中断或其他问题。 @unwind 会不会是它使用b 指令进行了分支但跳转超过了+/-2kB? 【参考方案1】:

__libc_init_array 是 ARM 代码,而不是 Thumb,因此 M0 会在尝试执行一些它不理解的废话时摔倒(实际上,它永远不会到达那里,因为它在尝试切换到 ARM 状态时出错bx,但是,嘿,同样的区别......)

您需要确保使用任何库的纯 Thumb 版本 - 特定于 Cortex-M 的工具链可能比通用 ARM 工具链更好。如果您有一个 multilib 工具链,我建议您检查 arm-none-eabi-gcc --print-multi-lib 的输出,以确保您已指定所有相关选项以获得正确的 Cortex-M 库,如果您使用单独的链接步骤,请确保你用LD=arm-none-eabi-gcc(加上相关的multilib选项)调用它,而不是LD=arm-none-eabi-ld

【讨论】:

我错过了将 -mcpu=cortex-m0 和 -mthumb 作为链接时间标志。 好答案。对于遇到这种情况的人,可能还有其他原因:如果您自己构建了工具链,则确实应该启用 multilib 并确保您的 t-arm-elf 支持所有 Cortex-M(也许还有 arm7tdmi-s) .

以上是关于STM32F030 启动时出现硬故障,__libc_init_array的主要内容,如果未能解决你的问题,请参考以下文章

STM32F030 IO口外部中断应用

STM32F030F4 BLDC

STM32 尝试打印数字 >= 10 时出现硬故障

求教stm32f030 HAL库,怎么关闭和打开所有中断

STM32F030F4 之ADC使用

stm32f030 模拟IIC