Ähm gerade fällt mir zum ersten Mal auf, daß mein avr-gcc munter
Fantasieadressen über die RAM-Grenzen hinaus produziert. Man merkts nur
daran, daß das Programm dann nicht so toll läuft.
Blöde Frage aber ist das normal, daß man da selbst aufpassen muß, daß
die data+bss-sections nicht größer als der vorhandene RAM des AVR
werden?
Ich meine bei Überschreiten der text-section meckern ja sowohl avr-gcc
wie auch avrdude aber beim RAM nix? Jetzt bin ich leicht verwirrt.
Aus dem .sym beim ATmega328p:
00800100 D __data_start
...
00800923 B __bss_end
00800923 B _end
batman schrieb:> Blöde Frage aber ist das normal,
Ja, ist es: der Linker kennt praktisch nur Device-Klassen, daher
kann er die Limits des konkreten Devices nicht kennen. Er würde
dir allerdings meckern, wenn du mehr als 64 KiB versuchst zu
allozieren.
batman schrieb:> Der Stack kommt ja sowieso noch darüber am RAM-Ende mit unbekannter> Größe oder?
Ja, der Stack wächst (per default) vom Ende des SRAMs nach unten,
die Variablen dagegen vom Anfang nach oben. Irgendwann „treffen“ sie
sich dann also.
Das alte Dilemma. Kann ich im C-Programm einen Test-String als letzte
globale Variable, also quasi als Puffer anlegen oder läßt sich der
Linker bei der Adressvergabe nicht reinreden?
batman schrieb:> oder läßt sich der Linker bei der Adressvergabe nicht reinreden?
Weder Compiler noch Linker lassen sich durch irgendeine Anordnung
von irgendwas innerhalb deines Quelltextes beeindrucken.
Du kannst natürlich im Linker eine Guard-Variable explizit hinter dem
Rest platzieren, indem du sie im Compiler in eine eigene Section
packst und im Linkerscript dann arrangierst, dass genau diese Section
am Ende des statisch allozierten RAMs liegt.
eagle user schrieb:> Kann man die RAM-Größe nicht im Linker-Script angeben?
Natürlich kann man. AVR-GCC ist aber deutlich mehr „out of the box“
als ARM-GCC; einen Linkerscript gibt man dort daher normalerweise
nicht selbst an. Die generischen Linkerscripts funktionieren gut
genug im Zusammenspiel mit dem Startup-Code der avr-libc, als dass
man das alles direkt benutzen kann. Diese generischen Linkerscripts
sind aber eben, wie ich eingangs schrieb, nicht pro Device vorhanden,
sondern nur grob klassifiziert für jede eigene AVR-Klasse.
Gegen das genannte Problem der Kollision des Stacks mit den statisch
zugewiesenen Daten würde der Linkerscript ohnehin nicht helfen. Es
bleibt damit immer beim Programmierer abzuschätzen, ob der nach dem
Linken vorhandene freie RAM aller Wahrscheinlichkeit nach ausreichend
für den Stack sein wird.
Absolut richtig. Ich hätte das Problem nur einen Tag früher erkannt,
wenn es eine RAM-Overflow-Warnung gegeben hätte. Einen Overflow des (wg.
RTOS) minimalen main-Stacks hatte ich nicht auf dem Schirm.
batman schrieb:> wenn es eine RAM-Overflow-Warnung gegeben hätte
Daher gab's bei WinAVR immer noch so einen Script, der nach dem
Compilieren den Füllstand der Speicher in % ausgegeben hat. Hat
Eric Weddington dann als schrägen Hack ins "size"-Programm hinein
gelegt, aber es war von vornherein klar, dass dieser rein
AVR-spezifische Hack es niemals hätte (in dieser Form) in die Binutils
zurück gemacht.
Die Shellscript-Variante bliebe natürlich nach wie vor.
Vorteil ist, dass man auch die Sache mit dem Stack dann schnell
abschätzen lernt.
Jo, könnte sein, dass das dafür mal da war – dann aber nicht richtig
zu Ende geführt worden ist. Könnte man sich wohl zumindest hinsetzen
und es darauf basierend korrekt machen, anders als der schräge, hart
codierte Hack von Eric dazumals.
Die aktuelleln Versionen vom AtmelStudio geben immer noch einen Meldung
aus:
1
Program Memory Usage : 140188 bytes 13,4 % Full
2
Data Memory Usage : 74200 bytes 56,6 % Full
Im automatisch genereierten Makefile kann man aber keinen Aufruf dafür
erkennen.
Weiß jemand wie das funktioniert? Ich würde die Ausgabe gerne in meinen
manuellen MakeFiles einbauen
Aber immer schon dran denken, dass avr-size nur den Speicherbedarf für
statische Variablen berücksichtigt. Der Stack und dynamischer Speicher
sind nicht mit drin. Ich würde daher stets dafür sorgen, dass mindestens
64 Bytes frei bleiben. Wenn man printf benutzt, dann mindestens 100
Bytes.
Hi,
aber man kann sich doch beliebige neue Speicherklassen im Linkerfile
erzeugen, explizit seine Variablem lokatieren und diese Klassen auf
Grösse überwachen. Dann spukt der Linker die entsprechenden Fehler
aus...
1
.calram(NOLOAD):
2
{
3
PROVIDE(__calram_start=.);
4
*(.calram*)
5
PROVIDE(__calram_end=.);
6
}>data
7
.data:AT(ADDR(.text)+SIZEOF(.text))
8
{
9
PROVIDE(__data_start=.);
10
*(.data)
11
*(.data*)
12
*(.rodata)/* We need to include .rodata here if gcc is used */
adkfsgksadf@gmx.de schrieb:> aber man kann sich doch beliebige neue Speicherklassen im Linkerfile> erzeugen,
Klar kann man das. Aber nochmal: „normale“ AVR-Nutzer mögen sich
eher nicht um den Linkerscript kümmern, denn der, der mit der
Toolchain mitkommt, deckt einen Großteil der Bedürfnisse ab.
Wie schon ausreichend dargelegt worden ist, muss man sowieso extern
den Speicherfüllstand im Blick behalten, damit man ausreichend
Reserve für den Stack hat. (Der Heap gibt sich selbst Mühe, immer
noch genügend Abstand zum Stack als Reserve zu haben.)
> Dann spukt der Linker die entsprechenden Fehler> aus...
Na, hoffentlich spukt er nicht … Halloween ist ja schon vorbei. :)
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang