Hallo,
ich bin mir beim Entwicklen bei folgender Frage nicht ganz sicher.
Wieviel flüchtigen Variablenspeicher hat z.B. ein ATTiny45, 256Byte aus
SRAM?
Kann ich dann z.B. 256 int8_t oder 128 int16_t oder 32 uint64_t bzw.
eine Mixture welche in Summe nicht über 256Byte kommt verwenden?Der
avr-gcc kümmert sich dann um die optimale Anordnung/Verwendung im
ATTiny45_Prtogramm.hex?
Über Tipps und Infos wäre ich sehr dankbar.
Gruß Markus
mgolbs schrieb:> Kann ich dann z.B. 256 int8_t oder 128 int16_t oder 32 uint64_t bzw.> eine Mixture welche in Summe nicht über 256Byte kommt verwenden?
ja, aber dann musst du in ASM ohne stack arbeiten.
Du brauchst du C noch ram für den Stack. solltest auf jeden fall unter
200byte bleiben.
Hallo,
danke für die Info, besonders auch für die Aussagen zum Stack. Wenn ich
also nur 50% des SRAM für Variablen verwende, sollte es keine Probleme
in dieser Hinsicht geben?
Gruß und Dank Markus
mgolbs schrieb:> Wenn ich> also nur 50% des SRAM für Variablen verwende, sollte es keine Probleme> in dieser Hinsicht geben?
kann man leider nicht pauschal sagen. Wenn du dann versucht weiter
200byte auf den Stack zu legen geht es nicht mehr. Das ist als Abhänig
von Programm.
Hallo,
danke für die Antwort. Gibt es eine Doku, wo was zur Abschätzung
bezüglich Stack Größe zu finden ist? Welche Vorgänge, Methoden,...
benötigen viel Platz für den Stack?
Gruß und Dank Markus
mgolbs schrieb:> danke für die Antwort. Gibt es eine Doku, wo was zur Abschätzung> bezüglich Stack Größe zu finden ist?
keine ahnung, kann man eigentlich im Kopf überschlagen
> Welche Vorgänge, Methoden,...> benötigen viel Platz für den Stack?
1
intFoo(inta,intb,intc){
2
char*tmp[20];
3
sprintf(tmp,"%d %d %d",a,b,c)
4
return0;
5
}
braucht schon mal mindestens
Stack:
20 byte für tmp
6 byte für paramter
8 byte für printf parameter
2 byte für stackpointer
Ram:
9byte für "%d %d %d"
mgolbs schrieb:> Welche Vorgänge, Methoden,... benötigen viel Platz für den Stack?
Eine endlose Rekursion benötig endlos viel Stack. ;-)
Scherz beiseite, das soll nur aufzeigen, dass es extrem von
deinem tatsächlichen Code abhängt, wieviel Stack du benötigst.
Man kann in den Startup-Code eine kleine Schleife einbauen, die
den SRAM mit einem Muster vorbelegt. Dann kann man, nachdem die
Applikation eine Weile gelaufen ist, nachsehen, wie weit dieses
Muster „nach unten“ durch den Stack überschrieben worden ist und
auf diese Weise ganz praktisch abschätzen, wie viel man dafür
wirklich einplanen sollte.
Bei so einem kleinen Controller nicht vergessen, die Funktion
main() als “__attribute__((OS_main))” zu deklarieren, damit der
Stack nicht noch zusätzlich durch das für main() unnötige Retten
irgendwelcher Register belastet wird.
Jörg Wunsch schrieb:> Scherz beiseite, das soll nur aufzeigen, dass es extrem von> deinem tatsächlichen Code abhängt, wieviel Stack du benötigst.> Man kann in den Startup-Code eine kleine Schleife einbauen, die> den SRAM mit einem Muster vorbelegt. Dann kann man, nachdem die> Applikation eine Weile gelaufen ist, nachsehen, wie weit dieses> Muster „nach unten“ durch den Stack überschrieben worden ist und> auf diese Weise ganz praktisch abschätzen, wie viel man dafür> wirklich einplanen sollte.
Wie kann ich das eigentlich nachsehen?
Nicolas S. schrieb:> Wie kann ich das eigentlich nachsehen?
Entweder online mit einem geeigneten Debugger (via debugWIRE bei
den von dir benutzten Controllern), oder du musst dir irgendwas in
deine Applikation dafür einbauen. Wenn du sowieso einen Kanal zur
Kommunikation nach draußen hast (RS-232 oder dergleichen), dann
kannst du natürlich einfach einen kompletten Hexdump des SRAM
rübersenden. Ansonsten halt eine Funktion implementieren, die den
SRAM von oben nach unten durchläuft, bis sie auf wenigstens einigen
hintereinander gelegenen Adressen das während der Initialisierung
geschriebene Bytemuster gefunden hat, und dann diese Adresse nach
draußen kommunizieren.
Hallo Jörg,
danke für den Tipp. Hatte mich genau das gefragt ("Wie kann ich ohne
DebugWIRE oder JTAG einen Speicher-Dump machen? Gibt es da einen
Trick?"), habe aber mal wieder zu kompliziert gedacht. Kann ja auf den
gesamten Speicher bequem per Pointer zugreifen.
Viele Grüße
Nicolas
mgolbs schrieb:> 8 byte für printf parameter nicht verstanden ???
sprintf ruft intern vfprintf auf.
> Kann man diese SRAM Auslastungen im AVRStudio 5.1 Simulator auch> ermitteln?
Solange deine Applikation simulierbar ist (also nicht von externen
Ereignissen abhängt, die du nicht in die Simulation rein bekommst),
sollte das gehen, denn schließlich kannst du dir ja auch damit den
kompletten SRAM-Inhalt anzeigen lassen.
Hallo,
danke. Dann werde ich das mal tun. Mein Progrämmchen ist etwas ADC, IO
_delay_ms() while(1){}... Habe mit dem Simulator schon etwas probiert.
Mal sehen was dann so im SRAM steht.
Gruß & Dank
Markus
Peter II schrieb:> int Foo( int a, int b, int c ) {> char* tmp[20];
Schreibfehler?
Damit es nicht falsch stehen bleibt:
Mit der obigen Deklaration wäre tmp ein Array aus char-Pointern und
benötigte 20 * sizeof(char *), beim AVR also 40 Bytes.
char tmp[20];
würde 20 Byte belegen.
Grüße
Stefan
Nochmal zum Thema Speicherbelegung anzeigen:
Ich könnte ja am Anfang meines main()-Programms den ganzen Speicher mit
0xAAs füllen und irgendwann, wenn mich die Belegung interessiert, das
Muster z.B. auf einem Grafikdisplay darstellen. Bis auf das, was das
Display braucht, kann ich so ja auf einen Blick feststellen, wie weit
Variablenraum und Stack noch voneinander entfernt sind. Und wie weit
überhaupt der Variablenraum die Speicherbelegung verändert hat.
Den ganzen Speicher? Besser nicht. Schon am Anfang von main() sind ja
schon Sachen initialisiert, die ich besser nicht überschreibe. Wie weit
ich am Ende auffüllen darf, verrät mir der Stackpointer. Aber wo darf
ich anfangen?
Viele Grüße
Nicolas
Nicolas S. schrieb:> Den ganzen Speicher? Besser nicht. Schon am Anfang von main() sind ja> schon Sachen initialisiert, die ich besser nicht überschreibe. Wie weit> ich am Ende auffüllen darf, verrät mir der Stackpointer. Aber wo darf> ich anfangen?
in dem Artikel zu dem Link, den ich am 27.6. gepostet habe, steht doch
alles beschrieben.
Die Funktion init_mem() wird vor dem Start von main() ausgeführt (dann
ist noch nichts initialisiert); die beschreibt den Speicher mit einem
Muster.
Mit get_mem_unused() kannst du dann bei Bedarf den freien Platz
feststellen.
Anhand des Quelltextes kann man auch lernen, wie man so etwas macht.