Forum: Mikrocontroller und Digitale Elektronik RAM-Nutzung und Stack-Overflow zur Laufzeit bei Cortex-M4 anzeigen lassen


von Michael L. (michael_dresden)


Lesenswert?

Hallo,
ich baue gerade einen Webserver inkl. CMSIS RTOS, lwip und netconn auf 
einem XMC4500 mit DAVE, dieser funktioniert auch erst einmal wunderbar, 
crasht jedoch nach einigen Aufrufen, sodass die Webseiten-Ladezeit um 
mehrere Größenordnungen langsamer wird (Hello-World-Seite benötigt 
vorher 5ms, später einige Sekunden).
Nun hatte ich die Idee, eventuell habe ich einen Fehler im C-Code und 
der RAM (160 kByte) bzw. ein Thread-Stack läuft voll.

Wie kann ich mir denn zur Laufzeit (UART ist dran und gibt printfs aus) 
nun den aktuell benutzen RAM-Bereich ausgeben lassen?
Die Code-Größe im RAM (data+bss) ist bei mir 64 kByte, ist dies auch die 
maximal benutze RAM-Größe?
Und wie kann ich mir die aktuelle Stack-Auslastung bzw. den 
Stack-Pointer anzeigen lassen?
(OS-Threads je 256 Byte Stack, User-Threads je 4 kByte Stack, maximal 10 
User-Threads, hab mit den Werten schon etwas rumgespielt, ergibt jedoch 
keine Verbesserung)
Oder hättet ihr noch Ideen was den Fehler verursachen könnte?
Danke für eure Hilfe :)

von Dennis R. (dennis_r93)


Lesenswert?

Die Problematik Stacküberläufe zuverlässig zu erkennen gibt es bis 
heute.
Ein Controller mit Speicherschutz könnte einen Guardbereich am Ende vom 
Stack anlegen und im IRQ dann immer Protokollieren wie groß ungefähr der 
Stack ist. Es ist aber nicht 100% zuverlässig, der geschützte Bereich 
könnte auch übersprungen werden.

In deinem Fall vermute ich weniger, dass es ein Stack Überlauf ist 
sondern eher, dass Restdaten von den letzten Aufrufen noch dein 
Prozessor blockieren.

Was heißt der webserver crasht?

von Michael L. (michael_dresden)


Lesenswert?

Er "crasht" nicht wirklich, sondern wird unheimlich langsam, es treten 
TCP Retransmissions, Resets, Dup ACKs, Zero Windows, Out Of Orders auf, 
die Hälfte des WireSharks ist schwarz :) Daten kommen noch durch, aber 
eben erheblich langsamer, sodass wohl etliche Timeout-Counter 
anschlagen.
Dank lwIP-Debug-Ausgaben sieht man, dass Daten vom PC zum XMC dort erst 
viel später ankommen, dann aber sofort verarbeitet werden.

: Bearbeitet durch User
von Jan K. (jan_k)


Lesenswert?

Hat dein RTOS nicht vllt die Funktion schon eingebaut? FreeRTOS kann 
afaik den Stack überwachen.

von Matthias (Gast)


Lesenswert?

RAM-Nutzung kann man sich anzeigen lassen, wenn man Zugriff auf die
"sbrk" bzw. das Backend der dynamischen Speicherverwaltung hat.
Dann kann man sich eine Funktion schreiben (falls nicht schon 
vorhanden),
und (Heapgrenze - Aktuellen sbrk-Wert = Rest vom Heap, der nicht in 
Verwendung ist.)

Hinweis:
sbrk wir über die Dynamische Speicherverwaltung aufgerufen und liefert
dann einen Speicherblock, der dann von der Speicherverwaltung intern
"verhackstückselt" und zur Verfügung gestellt wird. Man sollte daher 
immer
nach einer gewissen Laufeit die maximale Heap-Auslastung ermitteln 
können.
Und sollte damit auch RAM-Fresser und starke Fragmentierung erkennen 
können
(beides führ dazu, dass mit zunehmender Laufzeit der Reast an Heap immer 
weiter abnimmt).

Beim Stack ist das etwas schwieriger. Ich kenne jetzt nur freeRTOS und 
das hat einen Zähler für den maximalwert des Stackverbrauches für jeden 
Task.
Wenn man den Source vom RTOS hat, könnte man sich diese Funktion auch 
selber dazu bauen (viel Spass beim Reverse Engineering).
Im Prinzip muss für jeden TAsk ein eigener Stack-Pointer vom RTOS 
verwaltet werden. Die Verwaltungsstrukturen des RTOS, sollten sich 
erweitern lassen, wenn die "sauber" generisch programmiert wurden.

Was passiert eigentlich, wenn Du für 2-3 Minuten überhaupt keinen 
Zugriff auf auf den Webserver tätigst? Bleibt das dann mit der 
Verzögerung?

von Bege (Gast)


Lesenswert?

Free-RTOS erzeugt für jeden Task einen eigenen Context auf dem Heap.
Wenn ständig Tasks gestartet/beendet werden, wird der Speicher 
fragmentiert und je nach verwendeter Heap-Verwaltungs-Algo(kann man im 
FreeRTOS einstellen), dauert es eine gewisse Zeit bis der Speicher 
aufgeräumt ist und Speicheranfragen (malloc) abgeschlossen werden 
können.

Du könntest versuchen, die angeforderten Speicherblöcke gleich groß zu 
wählen. Oder du verhinderst dass die Tasks sich ständig beenden und neu 
erzeugt werden müsse. Eventuell kann man die Tasks auch schlafen legen 
oder deaktivieren. Dazu sind aber sicher auch Anpassungen an den anderen 
Softwarecomponenten notwendig.

von Jim M. (turboj)


Lesenswert?

Michael L. schrieb:
> (OS-Threads je 256 Byte Stack,

Verdammt wenig für einen Cortex M4F. Allein die FPU Registerbank braucht 
AFAIK 128 Bytes beim Kontext Wechsel (Interrupt/Exception).

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.