Hallo, kann mir jemand die Funktion der Stack-Tiefe bei FASTAVR erklären, was trägt man warum hier ein, ich denke, es ist Reservierung im RAM für Variablen, aber warum steht dieser meist bei 32 bei z.B. Mega und nicht auf z.B. 128, ich habe jetzt komische Fehler beim Umgang mit Variablen, die Erhöhung des Stack-Wertes soll helfen... Gruss A. Arndt
Kann zu FASTAVR nicht wirklich was sagen, aber mal allgemein zum Stack: Wenn du ein Unterprogramm aufrufst, dann muss der µC sich merken, wo er danach wieder zurückspringen muss. Also wird auf den "Stack", zu deutsch "Stapel", die Rücksprungadresse gelegt. Lokale Variablen werten ebenso auf den Stack gelegt und dort verwendet. Wenn das Unterprogramm beendet ist, werden alle lokalen Variablen wieder vom Stapel genommen (ihr Gültigkeitsbereich ist hiermit beendet), die Rücksprungadresse wird gelesen und angesprungen, das Unterprogramm ist hiermit beendet. Wenn du viele lokale Variablen oder viele verschachtelte Aufrufe hast, kann es sein, dass der Stack stark anwächst. Wie gesagt: Ich weiss jetzt nicht, was 32 oder 128 bei "Stacktiefe" bedeuten soll, aber wenn das die Anzahl der Worte ist, die der Stack fassen kann, dann sollte schnell klar werden, dass man mit den Ressourcen sparsam umgehen soll und evtl. globale Variablen benutzen sollte, wenn dies angebracht ist und Speicher sparen kann, oder eben die Stack-Größe erweitern.
wichtig wäre noch, dass der stack von oben nach unten wächst - also vom ram ende aus. wenn er zu gross wird kann er andere sachen im ram überschreiben (globale variablen etc.) probleme kann es halt bei vielen verschachtelten funktionsaufrufen mit vielen/grossen parametern kommen oder rekursionen usw..
Ersteinmal soll der Stack nur so gross wie nötig sein, um nicht unnötig RAM zu blockieren, der Platz fehlt sonst evtl. für Variablen. Aber das Problem liegt daran, zu erkennen, wie gross der Stack denn nun wirklich sein muss, dass kann kein Compiler erkennen. Ein Stack-Überlauf führt normalerweise zum Absturz und kann von üblichen MCs auch nicht erkannt werden. In erster Linie belasten Funktionsaufrufe und Interrupts den Stack, bei Funktionsaufrufen wird zumindest die Rückkehradresse, manchmal auch die Parameterübergabe über den Stack realisiert, meist wird dazu jedoch ein gesonderter Datenstack benutzt. Interruptroutinen sind im Prinzip ja auch Funktionsaufrufe, nur dass man vorher nicht weiss, wann diese Funktionen aufgerufen werden, also immer mit dem schlimmsten rechnen... Kritisch wirds dann, wenn Funktionen mehrfach wieder andere Funktionen (oder sich selbst, Rekursion) aufrufen und als i-Tüpfelchen dann noch ein Int draufknallt. Der Stacküberlauf überschreibt gnadenlos Variablen, was dann passiert, kannst du dir selbst vorstellen. Für den Test kann man sich Stack-end-marker setzen und dann versuchen in einer Simulation den kritischsten Systemzustand zu erreichen und den dann erreichten Stackwert als Stackgrösse zu setzen. Reicht der RAM nicht, diese Bedingung zu erfüllen, muss das Programm korrigiert werden (Verschachtelungstiefe reduzieren, in kritischen Fällen die Interrupts sperren).
Und um es komplett zu machen: Der so genannte "Heap" wächst von unten nach oben (also von kleinen Speicheradressen zu hohen). Im Heap werden globale Variablen und dynamisch alokkierter Speicher abgelegt. Entweder gibt es eine feste Grenze und wenn der Heap oder Stack über diese Grenze wachsen möchte gibt es einen Heap- resp. Stackoverflow, oder aber die Grenze ist fließend und das große "Bumm" gibt es, wenn Stack auf Heap treffen. Da ich kein Basic (mehr) kann, hier ein Beispiel aus der c-Sprache. Wird z.B. einer Funktion eine große struct übergeben, dann wird sie ganz auf den Stack kopiert. Du kannst in deiner Funktion dann darauf schreiben, wie du lustig bist, ohne den eigentlich übergebenen struct zu ändern, da du ja auf einer Kopie arbeitest. Wenn du den struct aber eh nicht änderst, sondern nur ausliest, dann hast du eine unnötige Kopie gemacht und hättest stattdessen einen Pointer oder eine Referenz auf das struct übergeben sollen. Bei Basic gibt es auch eine Entsprechung zu struct, war das record? Und als Referenz kann man sowas wohl auch übergeben (by ref?).
Hallo, vielen Dank für Eure Antworten, ich arbeite zwar "nur" mit dem einfachen Basic, aber ich denke, ich habe verstanden, was Ihr meint... Gruss A. Arndt
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.