Wenn ich mit dem AVR-Studio in C mit einem Atmega88 den Befehl
uint8_t xxx;
schreibe, wo wird xxx gespeichert? Ist es auch möglich, dass der
Compiler einfach so die Variable im Flash ablegt? Oder schiebt der
Compiler die generell ins Ram? Ich frage deshalb - wenn ich zB. eine
Zählervariable in einer For-Schleife hab, kann sich der Wert sehr oft
verändern, und da EEPROM und Flas nur begrenzte Schreibzyklen haben,
wollte ich das man nachfragen, weil ich noch nicht die Stelle in dem
GCC-Tutorial gefunden hab, wo das stehen koennte.
Anfänger schrieb:> Wenn ich mit dem AVR-Studio in C mit einem Atmega88 den Befehl>> uint8_t xxx;>> schreibe, wo wird xxx gespeichert?
Irgendwo im SRAM
> Ist es auch möglich, dass der> Compiler einfach so die Variable im Flash ablegt?
Nein.
> Oder schiebt der> Compiler die generell ins Ram?
So wie oben geschrieben, kommen die ins SRAM.
> wollte ich das man nachfragen, weil ich noch nicht die Stelle in dem> GCC-Tutorial gefunden hab, wo das stehen koennte.
Es ist eigentlich sehr einfach
Flash - enthält das Programm
SRAM - Variablen
EEPROM - kannst du von deinem Programm aus benutzen.
Programm kommt immer ins Flash
Ohne irgendwas sonstiges, kommen Variablen ins SRAM. Flash kann schon
mal nicht gehen, weil sich das Flash gar nicht so einfach beschreiben
lässt.
Und EEPROM geht nur dann, wenn du das explizit so programmierst.
Brauchst Dir keine Sorgen zu machen.
In C wird davon ausgegangen das Variablen im RAM abgelegt werden.
Nur im Embedded-Bereich kann die Frage auftauchen, ob das evtl. auch im
FLASH oder EEPROM erfolgt, denn nur die haben das gegenüber dem immer
vorhanden RAM zusätzlich.
Da RAM der Normalfall ist, gibt es besondere
Nicht-Standard-Schlüsselworte wie PROGMEM die den Compiler anweisen eine
Variable im Flash anzulegen.
Also, allses ok. Du musst erst umgekehrt dann besondere Maßnahmen
treffen wenn Du Daten NICHT im RAM anlegen willst.
Ich hab mir im Datenblatt zu dem Atmega88 "Data Memory Map" angeschaut,
dort gibt es drei(vier) Bereiche - 32 Register (0x00-0x001F), 64
IO-Register (0x0020-0x005F).(160 Ext IO, 0x0060-0xFF), Internal Ram
(0x0100-0x04FF).
speichert der Compiler dann Variablen im Bereich Internal Ram? Oder ist
es jetzt auch wieder falsch, sich darüber "Gedanken" zu machen und Angst
zu haben, es könnte etwas am Anfang bei den 32 Registern verändert
werden, weil man in C nicht dierekt wie in Assembler mit Registern
programmiert?
Anfänger schrieb:> speichert der Compiler dann Variablen im Bereich Internal Ram?
Genau
> Oder ist> es jetzt auch wieder falsch, sich darüber "Gedanken" zu machen
falsch nicht, aber unnütz.
Genau deswegen benutzt du ja einen Compiler, damit du dich nicht um
sochen Kleinkram kümmern musst.
> werden, weil man in C nicht dierekt wie in Assembler mit Registern> programmiert?
Exakt.
wenn Du unbedingt willst, dann kannst Du aber Variablen im Flash
speichern:
unsigned char xxx PROGMEM;
Mit folgender Testroutine sollte...
unsigned char xxx[4000] PROGMEM;
unsigned int x,y;
void main(void)
{
while(1)
{
for (x=0;x<4000;x++)
for (y=0;y<=255;y++) xxx=y;
}
}
... der Flash nach zwei Tagen im Arsch sein... :)
Peter schrieb:> ... der Flash nach zwei Tagen im Arsch sein... :)
Darüber solltest du nochmal nachdenken :-)
Dem Flash passiert da im AVR genau gar nichts - weil nicht geschrieben
wird.
> schreibe, wo wird xxx gespeichert? Ist es auch möglich,> dass der Compiler einfach so die Variable im Flash ablegt?> Oder schiebt der Compiler die generell ins Ram? Ich frage> deshalb - wenn ich zB. eine Zählervariable in einer For-Schleife> hab, kann sich der Wert sehr oft verändern, und da EEPROM> und Flas nur begrenzte Schreibzyklen haben, wollte ich das> man nachfragen
Der Compiler legt Deine Variablen natürlich in der erzeugten
Programmdatei mit ab. Die Programmdatei wird dann mit einem Programmer
oder einem Bootloader in den Flash-Programmspeicher geladen. Und dort
liegen die Variablen dann munter mit dem Programm zusammen im
Programmspeicher abgelegt, solange der Controller "stromlos" ist und
nicht läuft. Ader das ist nicht der Ort, an dem die Variablen bei
laufendem Controller verwendet werden.
Sobald der Controller eingeschaltet wird, führt er einen Reset aus,
dabei kopiert er die Variablen aus dem Flash-Programmspeicher in den
RAM-Speicher und sobald das Programm startet, wird nur mit den Variablen
im RAM-Speicher gearbeitet. Du brauchst keine Befürchtungen zu haben,
dass Variablen aus versehen vom Compiler anders abgelegt werden, als
dass sie zur Laufzeit im RAM-Speicher sind und dort beliebig oft
beschrieben werden können.
Variablen belegen also doppelt Platz in Deinem Controller: Einerseits
wird durch die Deklaration von Variablen das Programm größer, d.h. es
wird Platz im Flash-Programmspeicher belegt. Andererseits wird zur
Laufzeit des Programms der Variablenplatz auch im RAM-Speicher belegt.
Für "Variablen" oder eigentlich "Konstanten", die sich zur Laufzeit
nicht ändern und auf die nur lesend zugegriffen werden muß, z.B. Menü-
und Fehlermeldungen, gibt es allerdings die Möglichkeit, diese Variablen
nur im Flash-Programmspeicher anzulegen und von dort auszulesen. Dies
ist mit (mehr oder weniger) zusätzlichem Programmieraufwand verbunden,
aber in dem Fall (und nur in dem Fall) landen die Variablen dann nicht
im RAM-Speicher.
Jürgen. Sei mir nicht böse. Aber du erzählst hier Unsinn. Etwas weiter
ausgelegt, kann man gelten lassen, dass die Defaultwerte (so sie nicht 0
sein) aus dem Flash kommen. Aber zu sagen: die Variablen sind erst mal
im Flash - sorry, das kann man auch mit beide Augen zudrücken so nicht
gelten lassen.
Karl Heinz Buchegger schrieb:> Jürgen. Sei mir nicht böse. Aber du erzählst hier Unsinn. Etwas weiter> ausgelegt, kann man gelten lassen, dass die Defaultwerte (so sie nicht 0> sein) aus dem Flash kommen. Aber zu sagen: die Variablen sind erst mal> im Flash - sorry, das kann man auch mit beide Augen zudrücken so nicht> gelten lassen.
Also wenn ich (Arduino IDE, Compiler ist gcc) ein Programm schreibe mit:
1
char myString[5]="Test";
2
Serial.println(myString);
dann ist das kompilierte Programm, das in den Flash-Speicher geladen
wird, um ziemlich genau (kleinere Differenzen treten auf) 100 Bytes
kleiner als dasselbe Programm mit dem Code:
1
char myString[105]="Test";
2
Serial.println(myString);
Wenn man das Programm mit einem Hex-Editor betrachtet, dann liegen die
Variablen mit ihren Initialisierungswerten da auch drin im Programmfile.
Die Variablen kommen beim Reset ja nicht von irgendwoher ins RAM.
Der Vollständigkeit halber sei noch erwähnt, daß der Compiler Variablen
auch in Registern (und nur da, nicht extra im RAM) ablegen kann.
Perfekt für Variablen mit kleinem Geltungsbereich, etwa lokale Variablen
in einer Funktion oder innerhalb einer Schleife.
Der AVR-gcc macht davon aber nur sehr sparsam Gebrauch.
Aber wie schon erwähnt, ist es nicht notwendig, sich darüber Gedanken zu
machen, weil man ja u.A. deswegen C nimmt, damit sich der Compiler um
solche Details kümmern kann.
XL
Karl Heinz Buchegger schrieb:> Peter schrieb:>>> ... der Flash nach zwei Tagen im Arsch sein... :)>> Dem Flash passiert da im AVR genau gar nichts - weil nicht geschrieben> wird.
Doch wird geschrieben, allerdings ins RAM (sic!).