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 :)
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?
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
Hat dein RTOS nicht vllt die Funktion schon eingebaut? FreeRTOS kann afaik den Stack überwachen.
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?
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.