Hallo! Seit kurzem verwende ich den MSP430-Port des GCC (unter Windows/MinGW). Es ist mir aufgefallen, dass dem Linker keine Stackgrösse übergeben werden kann, die er reservieren soll. Auch im Linkerscript (<prg>\mspgcc\msp430\lib\ldscripts\msp430x147.x) ist keine Stackgrösse definiert. Da ich relativ wenig RAM habe, möchte ich die Prüfung dem Compiler überlassen (und nicht dem Zufall...). Kann man das irgendwie? Wenn man dazu das Linkerscript anpassen muss: hat jemand ein funktionierendes Beispiel? Ich bin für jeden Hinweis dankbar. Daniel
Dem GCC musst du keine Stackgröße übergeben, da er anders als manch anderer Compiler nach dem Unix-Modell arbeitet: der Stack beginnt ,,ganz oben'' und wächst nach unten, die Variablen werden von unten nach oben belegt. Dazwischen befindest sich der mögliche Raum für den Stack (und ggf. den Heap). Lokale Variablen werden auf dem gleichen Stack abgelegt wie Funktionsrücksprungadressen. Der Compiler kann deine Stacktiefe sowieso nicht ermitteln. Du könntest ja z.B. eine Funktion rekursiv aufrufen, dann entscheidet nur deine Abbruchbedingung über die erreichte Stacktiefe. Andere Compiler benutzen zwei Stacks und legen diese auch noch an den Anfang des RAMs, daher muss man bei denen die gewünschte (maximale) Stacktiefe angeben -- und sollte sich tunlichst nicht verrechnet haben... Denn s.o., wirklich überprüfen tun sie's wohl auch nicht.
Es ist mir schon klar, dass der GCC so arbeitet :-) Nur nützt mir das nicht viel. Bei anderen Toolchains wird üblicherweise Stack reserviert. Wenn das RAM nicht für (statische) Variable und Stack ausreicht, gibt es einen Linkerfehler. Das ist es, was ich irgendwie erreichen möchte.
Wie willst du das denn herausfinden? Statische Variablen ja, aber wie willst du den Stackverbrauch herausfinden? Davon abgesehen, dass der Linker ja eine komplette Aufrufgraph-Analyse machen müsste (was ich anzweifle), wie soll er herausfinden, nach der wievielten möglichen Rekursion einer Funktion selbige abbricht?
Der Linker soll ja den "Stackverbrauch" nicht ermitteln, sondern einfach einen manuell vorgebenen Stack - z.B. 100 Byte - einplanen und sicherstellen, dass er nicht mit etwas anderem überlappt. Die Stackgrösse kann - wie Du schreibt - nicht automatisch ermittelt werden, sondern wird vom Entwickler abgeschätzt.
Wie soll sichergestellt werden dass der Stackpointer nicht aus dem vorgegebenen Bereich herausläuft? Fügt der Compiler Code zur Überprüfung des Stackpointers ein?
>sicherstellen, dass er nicht mit etwas anderem überlappt.
Und was, wenn der Stack zu Ende geht?
Ich sehe da keinen Sinn drin. Ausserdem besteht so die Möglichkeit, daß
kein Platz mehr für den Stack vorhanden ist, aber trotzdem noch RAM
verfügbar wäre.
Also überlasse ich jeglichen verfügbaren Platz, der nicht für statische
Variablen draufgeht, dem Stack...
Ok, ich formulier's mal anders: Gegeben: Manuell gewählte Stackgrösse STACK_SIZE in Byte (z.B. 100). Fall A: genügend RAM für alle Variablen und mind. STACK_SIZE Byte Stack. Fall B: nicht genügend RAM für alle Variablen und mind. STACK_SIZE Byte Stack. Ziel: - Für Fall A: keine Veränderung was Code (Compiler) und Speicherlayout (Linker) betrifft - Für Fall B: Beim Linken Fehlermeldung "zuwenig RAM".
1. Linker-Script kopieren und ändern: MEMORY { ... data (rwx) : ORIGIN = 0x0200, LENGTH = 1K - 256 /* dirty hack! */ ... 2. Linkerscript verwenden: gcc -Wl,--script=..
Einfacher: die Speicherverbrauchsausgabe am Ende (bei WinAVR) so weit ergänzen, dass sie beim Fehlen einer ausreichenden Reserve an RAM für den Stack eine Fehlermeldung von sich gibt. Das Ganze ist ja ein eher einfacher Script. Natürlich variiert die ,,ausreichende Reserve'' von Fall zu Fall drastisch, insofern muss sie (über einen make-Makro) konfigurierbar sein. Ich bin sicher, wenn du mit Eric Weddington mal darüber redest, lässt sich sowas in diesen Script noch mit hineinzimmern.
Achja, da fällt mir ein, daß ich Eric noch auf die falsche Ausgabe bei Verwendung von externem RAM hinweisen wollte...
Moin! Hat von Euch mal jemand versucht easyweb von Andreas Dannenberg mit dem IAR-Compiler auszuführen? Kriege diverse Fehlermeldungen... Steve
kein wunder! die compiler sind so sehr verschieden, wie hund und katz (haben zwar beide vier beine, mit denen sie laufen können aber vertragen können sie sich nicht ;-) du müßtest z.b. alle interrupts umschreiben,... aber ich meine die ti-appnote, auf die easyweb aufbaut ist compatibel mit dem board und unter iar geschrieben.
Naja, ich weiß nicht. IAR EW 4.x kann _Pragma(). Das ist zwar ziemlich buggy implementiert und auch noch zusätzlich eingeschränkt im Vergleich zu #pragma (z. B. kann man mit _Pragma() keine einzelnen Warnungen ausschalten). GCC's _Pragma() ist deutlich besser implementiert, obwohl GCC gar keine Pragmas wirklich benutzt... Anyway, mit IAR EW 4.x ist es mir in einer größeren kommerziellen Applikation (nach Umschiffung o.gen. Bugs) gelungen, die komplette Compiler-/Library-Abstraktion für AVR-GCC vs. IAR in einem Headerfile abzuhandeln. Ich würde mal vermuten, dass das für den MSP430-GCC nicht anders sein sollte.
Es gibt beim mspgcc in den Beispielen ein Stackcheck-Beispiel in C, das man leicht in eigene Programme einbauen kann, beispielsweise um gelegentlich abzufragen, wie gross der Stack geworden ist (war). Das funktioniert natürlich nur ohne Heap, also ohne malloc/alloc, das normalerweise niemand benutzt. Allerdings weiss ich aus eigener Erfahrung, dass in den meisten Firmen sowas als Luxus gesehen wird und die Kunden quasi als Beta-Tester dienen, auch weil die Bosse meist keine Ahnung davon haben und die Sachen möglichst schnell auf dem Markt sollen.
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.