Hi zusammen! Sagt mal, gibts beim (AVR-)GCC eine Möglichkeit, den (maximalen) Stackbedarf seines Programms statisch analysieren zu lassen. Mein Keil+Realview für ARM kann das. Die Sache ist die: Werkele grad nebenbei noch mit nem AVR und FreeRTOS herum und habe grad mal feststellen müssen, dass mein Programm irgenwann anfing total herumzuzicken oder sich gleich zu resetten, wenn ich einem Task noch etwas Code (und lokale Variablen) hinzugefügt hatte. Durch Anpassung der Stackgröße für die Tasks liefs dann wieder. Aber irgendwie ist mir das ein bisschen zu gewagt einfach nur irgendeine Hausnummer für den Stack anzugeben. Wie wäre denn mal die analytische Herangehensweise? Danke und Gruß, Frank
Die Erfassung des benötigten Stackbedarfs ist nicht so einfach. Eine Möglichkeit, vorausgesetzt das MAP-File liefert die RAM-Adressen des Stackbereichs (Prozessorstack (C-Stack) bzw. Interruptstack (I-Stack)), wäre das Beschreiben der letzten 8 Bytes des Stacks mit definierten Werten, z.B. 8* 0xAA. Nach x-Stunden/Tagen werden die Speicherzellen ausgelesen und auf Veränderung der manipulierten Speicherzellen geprüft, dies kann zum einen via Schnittstelle bzw. EEPROM Speicher erfolgen. Ergbnis : Sind die manipulierten Bytes verändert, könnte der Stack zu klein sein. Daher, zuerst einen "sehr" großen Stack wählen und diesen schrittweise verringern. Leider bietet das Map-File des WinAVR´s keine Angabe des RAM-Bereiches des Stacks. Hierfür muss man schon den IAR-Compiler benutzen.
Aber wie komme ich denn mal zu ner groben Abschätzung? Was wandert denn alles so auf den Stack? Rücksprungadressen.. also Tiefe der Unterpgrammaufrufe ist zu bedenken. Wie ists mit lokalen Variablen im Task und in den aufgerufenen Unterfkt? Noch was? Und wieviel geht da jeweils drauf?
> Rücksprungadressen.. also Tiefe der Unterpgrammaufrufe ist zu bedenken. Ja. > Wie ists mit lokalen Variablen im Task und in den aufgerufenen > Unterfkt? Die auch, sofern sie nicht static sind. > Noch was? Register, die innerhalb der Funktion gesichert werden müssen, weil sie temporär für etwas verwendet werden und nachher wieder den alten Wert brauchen. Außerdem muß man an Interrupt-Routinen denken, die zusätzlich an jedem Punkt zuschlagen können und alle benötigten Register und das SREG zwischendurch auf den Stack speichern. Und da du FreeRTOS erwähnt hast: Das speichert meines Wissens den Kontext auch auf dem Task-Stack, was wohl so ca. 35 Bytes sein dürften. > Und wieviel geht da jeweils drauf? Eine Rücksprungadresse ist je nach Prozessor 2 oder 3 Bytes groß. Die lokalen Variablen brauchen halt soviele Bytes wie deren Datentyp groß ist.
Im generierten Assemblercode (Achtung!, das ist nicht das Disassemblerlisting, das du gemeinhin als .lss bekommst) steht die Größe des jeweiligen Stackframes als Kommentar mit drin. Den Aufrufgraphen musst du aber selbst ermitteln...
Hi, für avr-gcc mache ich das mittls einer kleinen Routine: http://www.roboternetz.de/wissen/index.php/Speicherverbrauch_bestimmen_mit_avr-gcc man muss dazu also seine Software instrumentieren... Eine statische Berechnung (also auch Abschätzung nach oben) des Benötigten Hepa-/Stapel-Verbrauchs bedeutet im allgemenen Falle IMHO das Halteproblem (siehe http://de.wikipedia.org/wiki/Halteproblem) zu lösen. Deine Software muss also spezielle Eigenschaften aufweisen, um eine statische Analyse machen zu können (zB. keine Rückwärts-Sprünge). Zur Abschätzung aufm Papoer kannst du dir im asm-Dump anschauen, wieviel Platz ne Funktion belegt (Stack-Frame) und die Call-Chain und maximale ISR-Tiefe analysieren. Allein anhand der C-Quelle zu entscheiden, wie groß der Frame einer Funktion ist, ist nicht wirklich machbar...das siehst du wie gesagt viel einfachen am Assembler-Dump (http://www.roboternetz.de/wissen/index.php/Assembler-Dump_erstellen_mit_avr-gcc)
Him ich grad den mal aus, weil ich auch gerade wissen will wie groß mein stack maximal werden kann, ohne das zur laufzeit zu messen. Prinzipiell, sollte es bei Programmen ohne rekursive funktionen doch möglich sein die maximal vom Programm genutzte Stacktiefe zu ermitteln. Selber variablen zählen bringt ja nicht so viel, da ja der compiler ordentlich optimiert, bzw auch mal was zwischen pusht und popt. Einzig kompliziert sind ISRs, da kann der kompiler natürlich nicht wisse, wann die gecallt wird. Damit könnt ich aber leben, wenn ich bei den wenigen ISRs grob überschlage, welche den größten stack braucht und ca wieviel und das einfach drauf addiere. gibts nicht ein tool, was so eine auswertung anhand des avr-gcc-output- assemblerlsitings automatisch macht?
hey das ging fix, Danke, ich glaub genau sowas hab ich gesucht! Mgf, vlad
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.