首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在CC2538 (Cortex m3)启动时的硬故障,在__lib_init_array中

在CC2538 (Cortex m3)启动时的硬故障,在__lib_init_array中
EN

Stack Overflow用户
提问于 2016-10-25 07:16:25
回答 1查看 660关注 0票数 0

我试图将一个mbed( RTOS)项目移植到CC2538 (ARM M3),该项目是使用mbed工具链编译的,该工具链集成了arm- to eabi-gcc。当我试图引导MCU时,我在启动时陷入了硬故障错误。

代码语言:javascript
复制
00202678 <__libc_init_array>:
  202678:       b570            push    {r4, r5, r6, lr}
  20267a:       4e0f            ldr     r6, [pc, #60]   ; (2026b8 <__libc_init_array+0x40>)
  20267c:       4d0f            ldr     r5, [pc, #60]   ; (2026bc <__libc_init_array+0x44>)
  20267e:       1b76            subs    r6, r6, r5
  202680:       10b6            asrs    r6, r6, #2
  202682:       bf18            it      ne
  202684:       2400            movne   r4, #0
  202686:       d005            beq.n   202694 <__libc_init_array+0x1c>
  202688:       3401            adds    r4, #1
  20268a:       f855 3b04       ldr.w   r3, [r5], #4
  20268e:       4798            blx     r3
  202690:       42a6            cmp     r6, r4
  202692:       d1f9            bne.n   202688 <__libc_init_array+0x10>
  202694:       4e0a            ldr     r6, [pc, #40]   ; (2026c0 <__libc_init_array+0x48>)
  202696:       4d0b            ldr     r5, [pc, #44]   ; (2026c4 <__libc_init_array+0x4c>)
  202698:       f004 fec2       bl      207420 <_etext>
  20269c:       1b76            subs    r6, r6, r5
  20269e:       10b6            asrs    r6, r6, #2
  2026a0:       bf18            it      ne
  2026a2:       2400            movne   r4, #0
  2026a4:       d006            beq.n   2026b4 <__libc_init_array+0x3c>
  2026a6:       3401            adds    r4, #1
  2026a8:       f855 3b04       ldr.w   r3, [r5], #4
  2026ac:       4798            blx     r3
  2026ae:       42a6            cmp     r6, r4
  2026b0:       d1f9            bne.n   2026a6 <__libc_init_array+0x2e>
  2026b2:       bd70            pop     {r4, r5, r6, pc}
  2026b4:       bd70            pop     {r4, r5, r6, pc}
  2026b6:       bf00            nop

我跟踪了代码流,最后一步PC正在执行

代码语言:javascript
复制
 2026a4:       d006            beq.n   2026b4 <__libc_init_array+0x3c>

然后

代码语言:javascript
复制
 2026b4:       bd70            pop     {r4, r5, r6, pc}

此时,PC机得到值0,然后跳转到地址0x00000000,造成硬故障错误。

cpu执行后

代码语言:javascript
复制
 202678:       b570            push    {r4, r5, r6, lr}
代码语言:javascript
复制
[register]
R0 =00000000
R1 =00000001
R2 =00000000
R3 =00000002
R4 =00000000
R5 =00000000
R6 =00000000
R7 =00000000
R8 =00000000
R9 =00000000
R10=00000000
R11=00000000
R12=00200F51
SP =200019F0
LR =00200A77
PC =0020267A
[memory]
200019b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
200019c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
200019d0: f0 09 00 20 00 00 00 00 00 00 00 00 04 0a 00 20
200019e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
200019f0: 00 00 00 00 00 00 00 00 00 00 00 00 77 0a 20 00
20001a00: 00 00 00 00 5d 0c 20 00 00 04 00 00 01 01 00 00

在cpu执行之前

代码语言:javascript
复制
2026b4:       bd70            pop     {r4, r5, r6, pc}

调试器转储

代码语言:javascript
复制
[register]
R0 =00000000
R1 =00000001
R2 =00000000
R3 =00000002
R4 =00000000
R5 =00000000
R6 =00000000
R7 =00000000
R8 =00000000
R9 =00000000
R10=00000000
R11=00000000
R12=00200F51
SP =200019C0
LR =0020269D
PC =002026B4
[memory]
200019b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
200019c0: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
200019d0: 00 00 00 00 9d 26 20 00 02 00 00 00 00 00 00 00
200019e0: 00 00 00 00 00 00 00 00 00 00 00 00 9d 26 20 00
200019f0: 00 00 00 00 00 00 00 00 00 00 00 00 77 0a 20 00
20001a00: 00 00 00 00 5d 0c 20 00 00 04 00 00 01 01 00 00

当pop寄存器指令在StackPointer中执行时,如果我手动将0x200019f0修改为0x200019f0。最后我发现它会成功地跳到main()。看来问题解决了。我的问题是为什么堆栈控制在__libc_init_array()中出错?我甚至无法在mbed整个项目下找到__libc_init_array()函数的实现源代码。

附加了.ld文件

代码语言:javascript
复制
MEMORY
{
    FLASH_FW (rx) : ORIGIN = 0x00200000 + 0,
                    LENGTH = (0x00200000 + (((((0) << 0 | (512) << 4 | (32) << 16 | ((1) ? 0x01000000 : 0) | ((1) ? 0x02000000 : 0)) & 0x0000FFF0) >> 4) << 10) - 0x0000002C) - (0x00200000 + 0)
    FLASH_CCA (RX) : ORIGIN = (0x00200000 + (((((0) << 0 | (512) << 4 | (32) << 16 | ((1) ? 0x01000000 : 0) | ((1) ? 0x02000000 : 0)) & 0x0000FFF0) >> 4) << 10) - 0x0000002C), LENGTH = 0x0000002C
    NRSRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0
    FRSRAM (RWX) : ORIGIN = (((((((0) << 0 | (512) << 4 | (32) << 16 | ((1) ? 0x01000000 : 0) | ((1) ? 0x02000000 : 0)) & 0x00FF0000) >> 16) << 10) - ((((((((0) << 0 | (512) << 4 | (32) << 16 | ((1) ? 0x01000000 : 0) | ((1) ? 0x02000000 : 0)) & 0x00FF0000) >> 16) << 10)) < (16384)) ? ((((((0) << 0 | (512) << 4 | (32) << 16 | ((1) ? 0x01000000 : 0) | ((1) ? 0x02000000 : 0)) & 0x00FF0000) >> 16) << 10)) : (16384))) ? 0x20000000 : 0x20004000), LENGTH = (((((0) << 0 | (512) << 4 | (32) << 16 | ((1) ? 0x01000000 : 0) | ((1) ? 0x02000000 : 0)) & 0x00FF0000) >> 16) << 10)
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __exidx_start
 *   __exidx_end
 *   __etext
 *   __data_start__
 *   __preinit_array_start
 *   __preinit_array_end
 *   __init_array_start
 *   __init_array_end
 *   __fini_array_start
 *   __fini_array_end
 *   __data_end__
 *   __bss_start__
 *   __bss_end__
 *   __end__
 *   end
 *   __HeapLimit
 *   __StackLimit
 *   __StackTop
 *   __stack
 */
ENTRY(flash_cca_lock_page)

SECTIONS
{
    .text :
    {
        _text = .;
        *(.vectors)
        *(.text*)
        *(.rodata*)
        _etext = .;
    } > FLASH_FW= 0
    .socdata (NOLOAD) :
    {
        *(.udma_channel_control_table)
    } > FRSRAM
    .data : ALIGN(4)
    {
        _data = .;
        *(.data*)
        _edata = .;
    } > FRSRAM AT > FLASH_FW
    _ldata = LOADADDR(.data);
    .ARM.exidx :
    {
        *(.ARM.exidx*)
    } > FLASH_FW
    .bss :
    {
        _bss = .;
        *(.bss*)
        *(COMMON)
        _ebss = .;
    } > FRSRAM

    .heap :
    {
        __end__ = .;
        end = __end__;
        *(.heap*)
        __HeapLimit = .;
    } > RAM

    .stack (NOLOAD) :
    {
        *(.stack)
    } > FRSRAM
    _heap = .;
    _eheap = ORIGIN(FRSRAM) + LENGTH(FRSRAM);
    .nrdata (NOLOAD) :
    {
        _nrdata = .;
        *(.nrdata*)
        _enrdata = .;
    } > NRSRAM
    .flashcca :
    {
        *(.flashcca)
    } > FLASH_CCA
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-01 06:24:21

@这是不对的,问题是链接脚本文件,但根本原因不是节重叠。就像我上面贴的一样。在__libc_init_array()

代码语言:javascript
复制
202678:       b570            push    {r4, r5, r6, lr}

此时,堆栈指针指向0x200019F0,但是当pop操作堆栈指针指向0x200019C0时,它会导致硬错误。我跟踪了代码流,在__libc_init_array()中,它将跳转到<_init>

代码语言:javascript
复制
 202698:       f004 fec2       bl      207420 <_etext>

就像记忆中的那样

代码语言:javascript
复制
00207420 <_init>:
  207420:       b5f8            push    {r3, r4, r5, r6, r7, lr}
  207422:       bf00            nop

00207424 <_fini>:
  207426:       b5f8            push    {r3, r4, r5, r6, r7, lr}
  207428:       bf00            nop

我想知道这个函数是否导致堆栈指针超过计数,因为<_init>部分只显示push指令,而没有pop指令。我做了更多关于<_init>部分的网页搜索,并确认这不应该仅仅是2个指令。并受链接器文件的影响。

在以前的链接器文件中,我不关心.init & .fini部分。然后我做了一些修改,看起来

代码语言:javascript
复制
.text :
{
    _text = .;
    *(.vectors)
    *(.text*)

    KEEP(*(.init))
    KEEP(*(.fini))

    /* .ctors */
    *crtbegin.o(.ctors)
    *crtbegin?.o(.ctors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
    *(SORT(.ctors.*))
    *(.ctors)

    /* .dtors */
    *crtbegin.o(.dtors)
    *crtbegin?.o(.dtors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
    *(SORT(.dtors.*))
    *(.dtors)

    *(.rodata*)

    KEEP(*(.eh_frame*))

    _etext = .;
} > FLASH_FW= 0
.socdata (NOLOAD) :

编译后,<_init> & <_fini>部分更改如下。

代码语言:javascript
复制
00207040 <_init>:
  207040:       b5f8            push    {r3, r4, r5, r6, r7, lr}
  207042:       bf00            nop
  207044:       bcf8            pop     {r3, r4, r5, r6, r7}
  207046:       bc08            pop     {r3}
  207048:       469e            mov     lr, r3
  20704a:       4770            bx      lr

0020704c <_fini>:
  20704c:       b5f8            push    {r3, r4, r5, r6, r7, lr}
  20704e:       bf00            nop
  207050:       bcf8            pop     {r3, r4, r5, r6, r7}
  207052:       bc08            pop     {r3}
  207054:       469e            mov     lr, r3
  207056:       4770            bx      lr
  207058:       6465626d        .word   0x6465626d
  20705c:       73736120        .word   0x73736120
  207060:       61747265        .word   0x61747265
  207064:       6e6f6974        .word   0x6e6f6974
  207068:       69616620        .word   0x69616620
  20706c:       3a64656c        .word   0x3a64656c
  207070:       2c732520        .word   0x2c732520
  207074:       6c696620        .word   0x6c696620
  207078:       25203a65        .word   0x25203a65

然后成功地跳入main()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40233656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档