2016-10-25 5 views
0

Ich versuche, ein mbed-os (RTX RTOS) -Projekt zu CC2538 (ARM Cortex M3) portieren, die es mit mbed-CLI Toolchain kompiliert, die Arm-None integriert -eabi-gcc. Wenn ich versuche, die MCU zu booten, bleibe ich beim Start im Hard Fault-Fehler stecken.Hardfault auf CC2538 (Cortex m3) Start, in __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 

Ich habe den Code Fluss zurückgeführt, der letzte Schritt PC ausgeführt wird

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

dann

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

in diesem Moment, PC den Wert 0 erhalten, springen dann 0x00000000 zu adressieren und verursacht Hard Fault Fehler.

nach cpu

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 

vor cpu

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

Debugger Dump ausführen ausführen

[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 

Und wenn ich manuell StackPointer zu 0x200019f0 ändern, wenn Pop-Register-Anweisung in __libc_init_array ausgeführt wird. und ich fand, dass es am Ende erfolgreich zu main() springen wird. scheint es Problem zu lösen. Meine Frage ist, warum Stack-Kontrolle in __libc_init_array() falsch? Ich kann sogar nicht die Implementierung Quellcode von __libc_init_array() -Funktion unter mbed-os gesamten Projekt finden.


die .LD Datei

angebracht
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()' ist, wie der Name schon sagt, Teil der C-Bibliothek, also werden Sie die Quelle in Ihrem Projekt nicht finden. Das bedeutet auch, dass es sehr unwahrscheinlich ist, dass es die Ursache des Problems ist, sondern nur ein Symptom. Nichts im Code hier berührt sogar den Stack oder SP zwischen dem Prolog und dem Epilog, aber SP hat sich nicht nur geändert, sondern der Stack-Inhalt _über dem aktuellen Frame hat sich komplett verändert, was viel besorgniserregender ist. Wie sieht Ihr Linker-Skript aus, da es möglich ist, dass Ihr Stack/Heap/Data/etc. Abschnitte überschneiden sich? – Notlikethat

+0

@Notlikethhat für Ihre Antwort, ich habe gerade cc2538.ld Inhalt am Ende der Frage angefügt. Ich bin nicht sicher, ob diese Abschnitte sich überschneiden oder nicht. – Janshiue

Antwort

0

@notlikethat richtig ist, ist das Problem Link Skriptdatei, aber die Ursache ist nicht Abschnitt überlappend. wie ich oben poste. in __libc_init_array()

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

zu diesem Zeitpunkt, Stack-Zeiger zeigt auf 0x200019F0, aber einige, wie, wenn Pop-Operation des Stapelzeiger zeigt auf 0x200019C0 und den Hardfault Fehler verursachen. Ich verfolgte den Code fließen, in __libc_init_array(), wird es <_init> bei

202698:  f004 fec2  bl  207420 <_etext> 

Abschnitt springen, die sie, dass im Speicher aussehen wie

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 

Ich wundere mich, dass diese Funktion bewirken, dass der Stapel über Zeiger zählen, wegen der <_init> Abschnitt zeigt nur Push-Anweisung, aber keine Pop-Anweisung. Ich mache mehr Web-Suche über <_init> Abschnitt, und bestätigen, dass das nicht nur 2 Anweisungen sein sollte. und es wird durch Linker-Datei bewirkt.

In der zuvor Linker-Datei habe ich mich nicht um .init & .fini Abschnitt kümmern. Und dann habe ich getan einige geändert, und es sieht aus wie

.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) : 

Nach der Kompilierung dann < _init> & < _fini> -Abschnitt wie folgt geändert haben.

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 

und dann erfolgreich in main() springen.

Verwandte Themen