Hallo allerseits. Ich habe leider ein kleines Problem mit meinem
LPC2148, das ich im Linkerscript bzw. CRT vermute. Und zwar springt der
Controller immer die Data Abort Interruptroutine an, sobald ich mit
einem global initialisierten Pointer in ein globales Array schreibe:
1 | // Verursacht einen Fehler
| 2 | char array[100];
| 3 | char *p = array;
| 4 |
| 5 | void demo() {
| 6 | *p = 'a'; // Data abort
| 7 | }
|
Folgender Fall funktioniert:
1 | // Funktioniert
| 2 | char array[100];
| 3 | char *p;
| 4 |
| 5 | void demo() {
| 6 | p = array;
| 7 | *p = 'a';
| 8 | }
|
Im Fehlerfall müsste ja array im .bss und p im .data Segment liegen. Im
zweiten Fall sollten beide im .bss Segment liegen. Mein Linkerscript
sieht wie folgt aus:
1 | ENTRY(_start)
| 2 | STARTUP("lpc2148-crt.o")
| 3 |
| 4 | MEMORY {
| 5 | flash (rx) : ORIGIN = 0x00000000, LENGTH = 512K /* Flash ROM */
| 6 | ram_isp_low(A) : ORIGIN = 0x40000120, LENGTH = 224 /* ISP low */
| 7 | ram : ORIGIN = 0x40000200, LENGTH = 32513 /* On-chip RAM */
| 8 | ram_isp_high(A) : ORIGIN = 0x40007FE0, LENGTH = 32 /* ISP high */
| 9 | ram_usb_dma : ORIGIN = 0x7FD00000, LENGTH = 8192 /* USB DMA */
| 10 | }
| 11 |
| 12 | _stack_end = 0x40007EDC;
| 13 |
| 14 | SECTIONS {
| 15 | .text 0x0000 : {
| 16 | *(.text)
| 17 | _text_end = .;
| 18 | } >flash =0xFFFF
| 19 |
| 20 | .rodata ALIGN(4) : {
| 21 | *(.rodata*)
| 22 | _rodata_end = .;
| 23 | . = ALIGN(4);
| 24 | _data_romimage = .;
| 25 | } >flash =0x0000
| 26 |
| 27 | .data : AT (ADDR(.rodata) + SIZEOF(.rodata)) {
| 28 | _data_start = .;
| 29 | *(.data)
| 30 | _data_end = .;
| 31 | } >ram =0x0000
| 32 |
| 33 | .bss : {
| 34 | _bss_start = .;
| 35 | *(.bss)
| 36 | *(COMMON)
| 37 | _bss_end = .;
| 38 | } >ram =0x0000
| 39 | }
|
Mein CRT:
1 | .set UND_STACK_SIZE, 0x00000010
| 2 |
| 3 | .set ABT_STACK_SIZE, 0x00000080
| 4 |
| 5 | .set FIQ_STACK_SIZE, 0x00000020
| 6 |
| 7 | .set IRQ_STACK_SIZE, 0X00000200
| 8 |
| 9 | .set SVC_STACK_SIZE, 0x00000020
| 10 |
| 11 |
| 12 |
| 13 |
| 14 |
| 15 | /* Standard definitions */
| 16 |
| 17 | .set MODE_USR, 0x10
| 18 |
| 19 | .set MODE_FIQ, 0x11
| 20 |
| 21 | .set MODE_IRQ, 0x12
| 22 |
| 23 | .set MODE_SVC, 0x13
| 24 |
| 25 | .set MODE_ABT, 0x17
| 26 |
| 27 | .set MODE_UND, 0x1B
| 28 |
| 29 | .set MODE_SYS, 0x1F
| 30 |
| 31 | .set DISABLE_IRQ, 0x80
| 32 |
| 33 | .set DISABLE_FIQ, 0x40
| 34 |
| 35 |
| 36 |
| 37 | .text
| 38 |
| 39 | .arm
| 40 |
| 41 |
| 42 |
| 43 | .global _start
| 44 |
| 45 | .func _start
| 46 |
| 47 |
| 48 |
| 49 | _start:
| 50 |
| 51 | _vectors: ldr PC, Reset_Addr
| 52 |
| 53 | ldr PC, Undef_Addr
| 54 |
| 55 | ldr PC, SWI_Addr
| 56 |
| 57 | ldr PC, PAbt_Addr
| 58 |
| 59 | ldr PC, DAbt_Addr
| 60 |
| 61 | nop
| 62 |
| 63 | ldr PC, [PC,#-0xFF0]
| 64 |
| 65 | ldr PC, FIQ_Addr
| 66 |
| 67 |
| 68 |
| 69 | Reset_Addr: .word Reset_Handler
| 70 |
| 71 | Undef_Addr: .word undefHandler
| 72 |
| 73 | SWI_Addr: .word swiHandler
| 74 |
| 75 | PAbt_Addr: .word pabtHandler
| 76 |
| 77 | DAbt_Addr: .word dabtHandler
| 78 |
| 79 | IRQ_Addr: .word irqHandler
| 80 |
| 81 | FIQ_Addr: .word fiqHandler
| 82 |
| 83 | .word 0
| 84 |
| 85 |
| 86 |
| 87 | Reset_Handler:
| 88 | ldr r0, =_stack_end
| 89 |
| 90 | msr CPSR_c, #MODE_UND
| 91 |
| 92 | mov sp, r0
| 93 |
| 94 | sub r0, r0, #UND_STACK_SIZE
| 95 |
| 96 | msr CPSR_c, #MODE_ABT
| 97 |
| 98 | mov sp, r0
| 99 |
| 100 | sub r0, r0, #ABT_STACK_SIZE
| 101 |
| 102 | msr CPSR_c, #MODE_FIQ
| 103 |
| 104 | mov sp, r0
| 105 |
| 106 | sub r0, r0, #FIQ_STACK_SIZE
| 107 |
| 108 | msr CPSR_c, #MODE_IRQ
| 109 |
| 110 | mov sp, r0
| 111 |
| 112 | sub r0, r0, #IRQ_STACK_SIZE
| 113 |
| 114 | msr CPSR_c, #MODE_SVC
| 115 |
| 116 | mov sp, r0
| 117 |
| 118 | sub r0, r0, #SVC_STACK_SIZE
| 119 |
| 120 | msr CPSR_c, #MODE_SYS
| 121 |
| 122 | mov sp, r0
| 123 |
| 124 |
| 125 |
| 126 | /* copy .data section (Copy from ROM to RAM) */
| 127 |
| 128 | ldr R1, =_text_end
| 129 |
| 130 | ldr R2, =_data_start
| 131 |
| 132 | ldr R3, =_data_end
| 133 |
| 134 | 1: cmp R2, R3
| 135 |
| 136 | ldrlo R0, [R1], #4
| 137 |
| 138 | strlo R0, [R2], #4
| 139 |
| 140 | blo 1b
| 141 |
| 142 |
| 143 |
| 144 | /* Clear .bss section (Zero init) */
| 145 |
| 146 | mov R0, #0
| 147 |
| 148 | ldr R1, =_bss_start
| 149 |
| 150 | ldr R2, =_bss_end
| 151 |
| 152 | 2: cmp R1, R2
| 153 |
| 154 | strlo R0, [R1], #4
| 155 |
| 156 | blo 2b
| 157 |
| 158 |
| 159 |
| 160 | /* Enter the C code */
| 161 |
| 162 | b main
| 163 |
| 164 |
| 165 | .endfunc
| 166 |
| 167 | .end
|
Kann mir vielleicht jemand den entscheidenden Hinweis geben?
Danke!
Der Startup-Code passt nicht zum Linker-Script. Die Initialisierung von
.data kopiert ab Ende von .text, aber da fängt nicht .data an, sondern
.rodata.
Sowohl im Code als auch im Linkerscript das dafür vorgesehene Symbol
_data_romimage für den Anfang der Daten im Flash verwenden. Also
ldr R1, =_data_romimage
und
.data : AT (_data_romimage) {
Autsch, jetzt sehe ich es auch. Durch das viele Ausprobieren ist da in
der Tat was durcheinander gekommen. Vielen lieben Dank für deine Hilfe!!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|