Forum: Compiler & IDEs AVR-GCC Stack-Bedarf ermitteln


von ARM-Fan (Gast)


Lesenswert?

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

von Gast (Gast)


Lesenswert?

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.

von ARM-Fan (Gast)


Lesenswert?

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?

von Rolf Magnus (Gast)


Lesenswert?

> 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.

von ARM-Fan (Gast)


Lesenswert?

Dankeschön! Dann fang ich mal an zu rechnen ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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...

von G. L. (sprintersb)


Lesenswert?

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)

von Vlad T. (vlad_tepesch)


Lesenswert?

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?

von Stefan E. (sternst)


Lesenswert?


von Vlad T. (vlad_tepesch)


Lesenswert?

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
Noch kein Account? Hier anmelden.