Stefan U. schrieb:
>> Leg die Variablen in die .noinit section
>
> Wie macht man das in C?
Gar nicht :-)
In GNU-C/C++ geht's wie oben gezeigt mit section-Attribut, einer
C-Erweiterung. Dies setzt allerdings voraus, dass es von der Toolchain
unterstützt wird, also insbesondere durch Zusammenspiel von
Linker-Skript und Startup-Code:
Das ld-Skript legt .noinit in eine alloc noload section, die nicht vom
Startup-Code genullt wird.
Ohne Nennung im ld-Skript ist .noinit eine Orphan-Section und deren Lage
geschieht nach spezellen[tm] Regeln.
.noinit wird von den GNU avr-Tools unterstützt; bei ARM sind
"standardisierte" ld-Skripte und Startup-Code wie von der avr-libc weit
weniger verbreitet.
Schließlich ist der Name der Section im Endeffekt Wurscht — es kommt auf
deren Unterstützung in Startup-Code und dem Zusammenspiel zwischen
Symbolen aus dem Start-Code und dem ld-Skript an. Beispiel:
1 | .data:
|
2 | {
|
3 | PROVIDE (__data_start = .) ;
|
4 | ...
|
5 | PROVIDE (__data_end = .) ;
|
6 | } > data AT> text
|
7 | .bss ADDR(.data) + SIZEOF (.data) : AT (ADDR (.bss))
|
8 | {
|
9 | PROVIDE (__bss_start = .) ;
|
10 | ...
|
11 | PROVIDE (__bss_end = .) ;
|
12 | } > data
|
13 | __data_load_start = LOADADDR(.data);
|
14 | __data_load_end = __data_load_start + SIZEOF(.data);
|
15 | /* Global data not cleared after reset. */
|
16 | .noinit ADDR(.bss) + SIZEOF (.bss) : AT (ADDR (.noinit))
|
17 | {
|
18 | PROVIDE (__noinit_start = .) ;
|
19 | *(.noinit*)
|
20 | PROVIDE (__noinit_end = .) ;
|
21 | ...
|
22 | } > data
|
Die zur Verfügung gestellten Symbole werden dann im Start-Code
verwendet; je nach verwendetem Code heißen die anders und sind an diesen
anzupassen.