Hallo, ich nutze einen ARM Cortex M3 ( STM32 ) mit GNU Toolchain. Der Startup-Code sorgt dafür, dass .bss / .data Segmente initialisiert werden (mit den im Sourcecode angegebenen Initwerten oder 0). Wie kann ich einen reset-festen Bereich definieren, der vom Startup-Code nicht initialisiert wird? Solche Daten dürfen ja dann weder in .bss noch in .data stehen. Ich kenne mich mit Linker/Lokatierung leider kaum aus... Hat jemand ein Beispiel das zeigt, wie man solche Variablen im Quellcode definieren muss und welche Anpassungen am Linkerscript nötig sind? Die Definition von .bss und .data sieht bei mir so aus: .data : { PROVIDE(_data = .); *(.data) . = ALIGN(4); *(.data.*) . = ALIGN(4); *(.ramtext) . = ALIGN(4); PROVIDE(_edata = .); } > ram AT > flash .bss : { PROVIDE(_bss_start = .); *(.bss) . = ALIGN(4); *(.bss.*) . = ALIGN(4); *(COMMON) . = ALIGN(4); PROVIDE(_bss_end = .); } > ram Danke! Sven
Ich antworte mir mal selbst... int volatile my_test __attribute__((section(".noinit"))); Das funktioniert, der Daten werden allerdings an eine undefinierten Adresse lokatiert. Wenn ich die Daten gerne an einer festen Adresse haben möchte, muss ich die Section im Linkerscript definieren. Laut map-file landen die Variablen dann an der gewünschten Adresse, allerdings wird der Code (ROM) verschoben, und das resultierende .bin File ist größer als das Prozessorflash (vorher ca. 30k, nachher >390k). Was mache ich falsch, warum verschiebt die von mir eingefügte .noinit Section den Code? Danke, Sven .noinit : { PROVIDE(_noinit = .); *(.noinit) . = ALIGN(4); *(.noinit.*) . = ALIGN(4); PROVIDE(_enoinit = .); } > ram .data : { PROVIDE(_data = .); *(.data) . = ALIGN(4); *(.data.*) . = ALIGN(4); *(.ramtext) . = ALIGN(4); PROVIDE(_edata = .); } > ram AT > flash .bss : { PROVIDE(_bss_start = .); *(.bss) . = ALIGN(4); *(.bss.*) . = ALIGN(4); *(COMMON) . = ALIGN(4); PROVIDE(_bss_end = .); } > ram }
Wenn .bss und .noinit nicht im Image auftauchen sollen, dann ist NOLOAD nötig, wie
1 | .bss (NOLOAD) : |
2 | { |
3 | ... |
4 | } > ram |
Danke AK, das so funktionierts. Meine Daten sind jetzt reset-safe an einer festen Wunschadresse lokatiert, ohne dass der Code-Bereich verändert wird. Was ich da getan hab verstehe ich allerdings nicht. Bei den bereits vorhandenen Sections .bss und .data ist kein NOLOAD angegeben, und trotzdem funktioniert es. Woher der Zusammenhang zwischen RAM und ROM Bereich kommt, ist mir nicht klar. Aber Hauptsache es geht.
Sven schrieb: > Was ich da getan hab verstehe ich allerdings nicht. Bei den bereits > vorhandenen Sections .bss und .data ist kein NOLOAD angegeben, und > trotzdem funktioniert es. NOLOAD heisst ja letztlich, dass die Daten in diesem Bereich im Image nicht auftauchen und beim Programmieren nicht geladen werden, nur die Adressen und Symbole verwaltet werden. Wenn in deinem .bss kein NOLOAD drin steht, dann stehen im Image sinnlose Nullen drin. Bei .data wäre NOLOAD hingegen unangebracht, denn dessen initialisierte Daten sollen ja ins Image. Der Unterschied zwischen .bss und .noinit liegt letztlich nur im Startup-Code. Der initialisiert .bss mit Nullen und lässt .noinit in Frieden.
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.