Forum: Compiler & IDEs Keil Stack-Heap Größe STM32Fxxx


von KeilBenutzer (Gast)


Lesenswert?

Hallo,

ich würde gerne die Größe des Stacks und Heaps meines in Keil 
compelierten STM32F4xx Programms wissen. Leider sind die derzeitigen 
Artikel, die ich gefunden habe, für ein STM32Fxxx µC mit 
startup_stm32fxxx.s wenig hilfreich.


Der Keil Linker spuckt ab Verison 4.22 standardmäßig ein paar Parameter 
aus, z.B.:
Program Size: Code=34778 RO-data=526 RW-data=28 ZI-data=102500.

Die Berechnung findet nach http://www.keil.com/forum/10624/ wie folgt 
statt:
Total RAM Size = RW Data + ZI Data
Total ROM Size = Code + RO Data + RW Data

Der Hacken bei der Sache ist, die ZI-Data ist lediglich die Summe aus 
dem im startup_stm32fxxx.s festgelegten Heap+Stack+100 Byte.
Konkret in meinem Fall:
Stack_Size      EQU     0x0000F000

Heap_Size       EQU     0x0000A000

Das hilft mir aber nicht weiter, da ich immer noch nicht weiß, ab wann 
ich einen Stackoverflow erleide. Die Werte sind gerade nur zufällig so 
hoch gewählt, da ich etwas rumprobiert habe... Mein STM32F446RE hat 
128kByte bzw. 0x20000. In der .map-Datei sieht es leider ähnlich 
verwirrend für mich aus.

Jemand eine Idee??

Vielen Dank

von murx (Gast)


Lesenswert?

hallo, der Heap hat nix mit Keil oder stm32 zu tun sondern mit dem 
verwendeten OS oder der Implementierung. Der Stack steht im cmsis 
startup.c und ist dort als unsigned long pulStack[size] definiert. Wenn 
du Multithreading verwendest hast du dann zusätzlich für jeden Thread 
einen eigenen Stack.

von murx (Gast)


Lesenswert?

ok, habe deinen text nicht gut gelesen, also um festzustellen wieviel 
Stack benutzt wurde musst du deinen Stack mit einem Pattern zB. 
0xA5A5A5A5 füllen und das im startup.s im Reset Handler bevor du in die 
erste c Funktion aufrufst und zur Laufzeit überprüfen wieweit dein Stack 
überschrieben oder noch frei ist.
diese Überprüfung solltest nach einer möglichst goßen Codeabdeckung 
machen also die ganze Funktionalitäten ausprobiert worden sind.

von Nop (Gast)


Lesenswert?

KeilBenutzer schrieb:
> Das hilft mir aber nicht weiter, da ich immer noch nicht weiß, ab wann
> ich einen Stackoverflow erleide.

Für den Stack guckst Du in den static call graph, den der Keil als 
HTML-Datei ausgibt, und guckst Dir den Stackbedarf Deiner entry-Funktion 
an (mitsamt Tochterfunktionen). Im Falle von bare metal (also ohne OS) 
ist das main(). Dazu addierst Du noch den Stackbedarf der 
Interruptfunktionen, die ebenfalls in der HTML-Datei stehen.

Obendrein kannst Du damit auch rauskriegen, was den meisten Bedarf 
verursacht. Manchmal kann man eine Funktion mit hohem Stackbedarf auch 
splitten aus zwei Funktionen, die nacheinander aufgerufen werden und für 
sich weniger Stack brauchen. Dann sollte man die aber mit 
Compilerattributen versehen, daß sie nicht inlined werden dürfen.


murx schrieb:
> diese Überprüfung solltest nach einer möglichst goßen Codeabdeckung
> machen also die ganze Funktionalitäten ausprobiert worden sind.

Davon halte ich als alleinige Hauptlösung nichts, weil das nicht 
garantiert, daß der worstcase passiert, nämlich alle Interrupts 
verkettet genau an der Stelle, wo die Anwendung auch schon maximalen 
Stack benutzt.

Zum Überprüfen, ob man in der Analyse (s.o.) was vergessen hat, ist das 
aber nützlich, denn das Ausprobieren darf keine höheren Werte als die 
Analyse geben.

von KeilBenutzer (Gast)


Lesenswert?

Hallo,

danke für die Antworten!

Methode 1: definiertes beschreiben des RAMs hatte ich mir auch schon 
überlegt. Aber ich wollte mir die Mühe ersparen mich im Debug-Memory 
Fenster tot zu suchen :-) Aber nichts für ungut, scheint wohl die 
einzige Möglichkeit zu sein den Heap rauszufinden.

Methode 2: Danke für den Tipp, ich benutze kein RTOS...

Meine HTM-Datei spuckt mir folgendes aus:
1
<H3>Maximum Stack Usage =       4656 bytes + Unknown(Functions without stacksize, Cycles, Untraceable Function Pointers)</H3><H3>

Erst mal sehr schön, leider habe ich eine Menge Interrupt-Funktionen...

Gibts eine ähnliche Möglichkeit auch für den Heap?

Gruß

von Nop (Gast)


Lesenswert?

KeilBenutzer schrieb:

> Erst mal sehr schön, leider habe ich eine Menge Interrupt-Funktionen...

Kein Problem, die einzelnen Funktionen sind ja auch gelistet. Also 
addiert man deren Stackbedarf zum Stackbedarf von main() dazu.

Der Keil-Compiler ist leider ein bißchen blöd, weil er z.B. die 
Software-Floatingpoint-Routinen stackmäßig nicht berechnen kann, obwohl 
das seine eigenen Libraries sind.

> Gibts eine ähnliche Möglichkeit auch für den Heap?

Nein, denn dynamische Allozierung und statische Analyse geht nicht so 
gut zusammen. Bzw. nur dann, wenn man zur Compilezeit schon weiß, 
wieviel man allozieren muß und das nicht erst zur Laufzeit abhängig von 
den Umständen ermittelt wird - dann würde man den Speicher ja gleich 
statisch allozieren.

Das ist einer von mehreren Gründen, wieso die eine Hälfte der Leute hier 
embedded malloc überhaupt nicht verwendet - und auch die andere tut das 
nur unter größtem Bedauern nach Abwägung aller Alternativen und unter 
Berücksichtigung der Fallstricke.

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.