Hallo, Habe mehrere .o Dateien und die sollen in zum Beispiel .Text, .Data oder .mySection gelinkt werden. Kann mann aus der Kommando Zeile den Linker erzwingen dass er sowas tut oder muss den default Linker-Script verändert werden? Die Target Hardware ist ein MSP430 mit dem gcc Kompiler. Wäre super wenn ihr mir paar Tipps gibt.
Du kannst keine ganze Datei in eine section stopfen. Die einzelnen sections sind bereits innerhalb der Datei aufgelistet.
> Du kannst keine ganze Datei in eine section stopfen.
Mit einem entsprechenden Linkerskript geht das schon. Ich wüßte nur
nicht, wozu es gut sein soll, alles aus einer .o-Datei in eine einzelne
Sektion zu stecken.
Man kann zumindest per Linker-Script näher spezifizieren welche "C-Section" eines Object-Files in welche "Linker-Section" aufgenommen werden soll. Aus einerm Beispiel für ARM Ausschnitte aus einem Linker-Script für GNU ld (Prinzip sollte für alle Targets funktionieren, auch für msp430-ld):
1 | SECTIONS |
2 | { |
3 | .text : |
4 | { |
5 | ... |
6 | *(EXCLUDE_FILE (*7xx_flash*.o) .text .text.*) |
7 | ... |
8 | } >CODE =0 |
9 | ... |
10 | |
11 | .data : AT (_etext) |
12 | { |
13 | ... |
14 | *7xx_flash*.o(.text .text.*) |
15 | ... |
16 | } >DATA |
17 | ... |
Damit wird Programmcode (text) aus allen Object-Dateien ausser 7xx_flash auf Addressen im CODE-memory gelinkt. Programmcode aus 7xx_flash.o erhalten eine VMA im DATA-memory. Im Beispiel dient dies dazu, dass die Funktionen aus 7xx_flash.c im RAM ausgeführt werden, dies ist erforderlich, da der Controller beim Schreiben des Flash-Speichers keinen Code aus dem Flash ausführen kann.
Hi, Programmiere momentan an einem Bootloader und da möchte ich dass nur die Firmware in das .Text Section kommt. Das eigentliche Code für das Bootloader wie z.B. eraseFlash() oder writeFalsh() sollen aus dem RAM ausgeführt weden. Deswegen habe ich sowas wie FlashTeiber.o erzeugt un die soll nun ins RAM. Das ist meine Intuition. Der standard Linker Script speichert den Code immmer ins .Text und genau dass möchte ich jetzt ändern. Wüßte zu gern wie das mit dem ld kunktioniert
Hi, Hab den Linker Script wie folgt geändert
1 | .text : |
2 | {
|
3 | . = ALIGN(2); |
4 | *(.init) |
5 | *(.init0) /* Start here after reset. */ |
6 | *(.init1) |
7 | *(.init2) /* Copy data loop */ |
8 | *(.init3) |
9 | *(.init4) /* Clear bss */ |
10 | *(.init5) |
11 | *(.init6) /* C++ constructors. */ |
12 | *(.init7) |
13 | *(.init8) |
14 | *(.init9) /* Call main(). */ |
15 | __ctors_start = . ; |
16 | *(.ctors) |
17 | __ctors_end = . ; |
18 | __dtors_start = . ; |
19 | *(.dtors) |
20 | __dtors_end = . ; |
21 | . = ALIGN(2); |
22 | *(.text) |
23 | . = ALIGN(2); |
24 | *(.text.*) |
25 | . = ALIGN(2); |
26 | *(.fini9) /* */ |
27 | *(.fini8) |
28 | *(.fini7) |
29 | *(.fini6) /* C++ destructors. */ |
30 | *(.fini5) |
31 | *(.fini4) |
32 | *(.fini3) |
33 | *(.fini2) |
34 | *(.fini1) |
35 | *(.fini0) /* Infinite loop after program termination. */ |
36 | *(.fini) |
37 | _etext = .; |
38 | *(EXCLUDE_FILE (*whdh*.o) .text .text.*) |
39 | } > text |
40 | .data : AT (ADDR (.text) + SIZEOF (.text)) |
41 | {
|
42 | PROVIDE (__data_start = .) ; |
43 | . = ALIGN(2); |
44 | *(.data) |
45 | . = ALIGN(2); |
46 | *(.gnu.linkonce.d*) |
47 | . = ALIGN(2); |
48 | _edata = . ; |
49 | *whdh*.o(.text .text.*) |
50 | } > data |
es lässt sich auch fehlerfrei kompilieren nur die enstprechen Funktionen liegen immer noch in der .Text Section. Was könnte an dem Obigen Script-Abschnitt fehlerhaft sein ?
Du fummelst IMHO an der falschen Stelle. Durch ein attribute bei den Funktionsdefinitionen, kannst du veranlassen, dass diese automatisch oder manuell in den Wunschsektionen z.B. im RAM landen. Siehe auch Beitrag "MSP430 C-Funktionen vom RAM ausführen?"
section-Attribute ist sicher auch brauchbar. Ansonsten mal dies versuchen:
1 | .text : |
2 | { |
3 | . = ALIGN(2); |
4 | *(.init) |
5 | *(.init0) /* Start here after reset. */ |
6 | *(.init1) |
7 | *(.init2) /* Copy data loop */ |
8 | *(.init3) |
9 | *(.init4) /* Clear bss */ |
10 | *(.init5) |
11 | *(.init6) /* C++ constructors. */ |
12 | *(.init7) |
13 | *(.init8) |
14 | *(.init9) /* Call main(). */ |
15 | __ctors_start = . ; |
16 | *(.ctors) |
17 | __ctors_end = . ; |
18 | __dtors_start = . ; |
19 | *(.dtors) |
20 | __dtors_end = . ; |
21 | /* ----- */ |
22 | . = ALIGN(2); |
23 | *(EXCLUDE_FILE (*whdh*.o) .text) |
24 | . = ALIGN(2); |
25 | *(EXCLUDE_FILE (*whdh*.o) .text.*) |
26 | /* ----- */ |
27 | . = ALIGN(2); |
28 | *(.fini9) /* */ |
29 | *(.fini8) |
30 | *(.fini7) |
31 | *(.fini6) /* C++ destructors. */ |
32 | *(.fini5) |
33 | *(.fini4) |
34 | *(.fini3) |
35 | *(.fini2) |
36 | *(.fini1) |
37 | *(.fini0) /* Infinite loop after program termination. */ |
38 | *(.fini) |
39 | _etext = .; |
40 | } > text |
41 | .data : AT (ADDR (.text) + SIZEOF (.text)) |
42 | { |
43 | PROVIDE (__data_start = .) ; |
44 | . = ALIGN(2); |
45 | *(.data) |
46 | . = ALIGN(2); |
47 | *(.gnu.linkonce.d*) |
48 | . = ALIGN(2); |
49 | *whdh*.o(.text) |
50 | . = ALIGN(2); |
51 | *whdh*.o(.text.*) |
52 | . = ALIGN(2); |
53 | _edata = . ; |
54 | } > data |
Hi, Danke Martin für deine Hilfe. Es läuft super. Natürlich habe ich das mit dem
1 | void __attribute__ ((section(".data"))) flash_write_block(int) |
und das funktioniert. Warum sollte man nicht den Umweg über dem Linker Script nehmen !!?
Section attribute und die gezeigte Modifikation im Linker-Script sind "doppelt-gemoppelt", könnte sogar sein, dass es mit beidem unangenehme Seiteneffekte gibt. Noch nie zusammen ausprobiert und, da ich kein MSP430 Board habe, erst recht nicht mit MSP. Ein Vorteil bei dem gezeigten Ansatz mit Linker-Skript ist, dass man im C-Code keine herstellerspezifischen Erweiterungen verwenden muss. Dies ist dann nützlich, wenn man Code von Dritten unverändert wiederverwenden will. Ich konnte z.B. für eine ARM-Entwicklung den Flash-Code von ST für STR710 ohne Änderung übernehmen, da EWARM im Prinzip den gleichen Ansatz nutzt, um Routinen an eine RAM VMA zu linken. Ein Nachteil ist, dass man sich mit Linker-Scripts rumschlagen muss, was nicht jedermanns Sache ist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.