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