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
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.
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.
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.
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ß
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.
Eine eigene Frage?
Dieser Thread ist über 9 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.