2016-10-25 7 views
0

Я пытаюсь перенести проект mbed-os (RTX RTOS) в CC2538 (ARM Cortex M3), который он скомпилирован с помощью инструментальной привязки mbed-cli, который объединяет arm-none -eabi-НКА. Когда я пытаюсь загрузить MCU, я застрял в ошибке Hard Fault при запуске.Ошибка при запуске CC2538 (Cortex m3), в __lib_init_array

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 

я получил проследили поток кода, последний шаг ПК выполняющийся

2026a4:  d006   beq.n 2026b4 <__libc_init_array+0x3c> 

затем

2026b4:  bd70   pop  {r4, r5, r6, pc} 

в этот момент, PC получить значение 0, а затем перейти на адрес 0x00000000 и вызвало ошибку .

после центрального процессора выполнять

202678:  b570   push {r4, r5, r6, lr} 

[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 

до того центрального процессора выполнять

2026b4:  bd70   pop  {r4, r5, r6, pc} 

Debugger свалка

[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 

И если я вручную изменить StackPointer к 0x200019f0, когда регистры поп-команд выполняются в __libc_init_array. , и я нашел, что он успешно прыгнет в main() в конце. похоже проблема решает. Мой вопрос: почему контроль стека идет неправильно в __libc_init_array() ?? Я даже не могу найти исходный код реализации функции __libc_init_array() в рамках проекта mbed-os.


приложенный файл .ld

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 
} 
+0

'__libc_init_array()', как следует из названия, является частью библиотеки C, поэтому да, вы не найдете его источник в своем проекте. Это также означает, что это вряд ли станет причиной проблемы, а всего лишь симптомом. Ничто в коде здесь даже не касается стека или SP между прологом и эпилогом, но не только изменил SP, но и содержимое стека _above_ текущего кадра полностью изменилось, что гораздо более тревожно. Как выглядит ваш скрипт компоновщика, так как это может быть ваш стек/куча/данные/etc. разделы перекрываются? – Notlikethat

+0

@Notlikethat спасибо за ваш ответ, я просто добавил cc2538.ld в конце вопроса. Я не очень уверен, что эти разделы перекрываются или нет. – Janshiue

ответ

0

@notlikethat является правильным, проблема ссылка на файл сценария, но основная причина не раздел перекрытия. как я выше. в __libc_init_array()

202678:  b570   push {r4, r5, r6, lr} 

в это время, стек указатель указывает на 0x200019F0, но некоторые, как, когда поп-операция указатель стека указывает на 0x200019C0, и это может вызвать ошибку Hardfault. Я проследил поток кода, в __libc_init_array(), он будет прыгать в разделе <_init> на

202698:  f004 fec2  bl  207420 <_etext> 

которой он похож, что в памяти

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 

Я интересно, что эта функция вызывает стек указатель над count, из-за раздела <_init> отображается только команда push, но нет команды pop. Я делаю больше веб-поиска о разделе <_init> и подтверждаю, что это не должно быть всего лишь 2 инструкции. и это происходит с помощью файла компоновщика.

В предыдущем файле компоновщика я не заботился о .init & .fini раздел. И тогда я сделал некоторые изменены, и это выглядит как

.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> раздел изменились следующим образом.

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() успешно.