Moin,
die cmsis-os hat ja das schöne Mail-handling. Leider ist das Warten zum
Reservieren einer Mail im FreeRTOS-Wrapper nicht korrekt implementiert.
Unabhängig der Wartezeit wird einfach geprüft ob der Speicher verfügbar
ist und wenn nicht sofort mit NULL zurückgekehrt.
Beim Keil RTX-Wrapper wird versucht den Speicher anzulegen, wenn das
nicht klappt wird die eingestellte Zeit gewartet, aber ohne erneut zu
versuchen den Speicher zu reservieren.
Das ganze Verhalten macht die Verwendung von "Mails" irgendwie für meine
Anwendung überflüssig.
Achso, meine Anwendung: Ich möchte gern einen Debug-Task anlegen. Der
bekommt eine Struktur mit Werten...
- Nachricht [String]
- DBG-Level [uint8_t]
- DBG-Modul [uint8_t]
- Timestamp [uint32_t]
Ich würde nun gern aus unterschiedlichen Tasks dem Debug-Task was
zu-mailen.
Meine Lösung bisher -> cmsis-os leicht modifizieren...
Das funktioniert bisher ganz gut, leider ist es eine pollende
Endlosschleife. Um es etwas effektiver zu machen, würde ich gern darauf
Warten das FreeRTOS ein "free" durchgeführt hat und dann erst den Task
wiederbeleben.
Gibt es ein solche Möglichkeit? Wie kann ich das Problem sonst noch
lösen?
Ich bin recht neu was RTOS'e angeht...
Hier mal meine Implementierung für osMailAlloc:
Wie gesagt... Wenn der Mail-Pool voll ist, wird hier ewig gepollt bis
wieder ein Speicherplatz frei ist.
Es gibt sicher noch die Lösung alles mit Counting-Semaphoren zusätzlich
abzusichern... also die Mail-Plätze zu "tracken".... finde ich aber auch
nicht so sauber...
VG
Basti
Was soll denn alloziert werden ? Speziell fuer Debuggeschichten nimmt
man statisches Memory und einen Pointer drauf. Wegen dem String ? Der
passt auch in statisches Memory, man muss ja nicht wahlweise ganze
Buecher uebergeben.
eigentlich sollte man sowieso auf dynamisches Memory verzichten, ausser
man implementiert eine Relaissteuerung, oder aehnlich.
Das beschriebene Verhalten des Keil RTX kann ich nicht nachvollziehen.
Der versucht einen Speicher zu belegen, wenn keiner frei ist, gibt es
einen sobald er frei wird. Sonst käme der ja nie mit osWaitForever raus.
In der Funktion darf auch kein while stehen. Diese Funktion
(sysMailAlloc) läuft als Interrupt. Wenn nicht direkt etwas frei ist,
wird der aktuelle Thread in die Warteliste der Mailbox gehängt. Wenn
irgendwo anders osMailFree ausgerufen wird, wird dann der Thread wieder
von der Warteliste geholt und auf ready gesetzt. Ein while(..) wird dazu
führen, dass der Scheduler blockiert und rein gar nichts mehr ausgeführt
wird.
Also meine Lösung wäre, auf die wrappers total zu verzichten und
"native" in FreeRTOS zu codieren.
Der einzige Vorteil so einer Abstraktion liegt darin, dass Du
plattformübergreifenden Code benutzen kannst, also falls der Code unter
verschiedenen OS laufen können *muss,* kannst Du (in der Theorie...) auf
eine gemeinsame Codebasis zugreifen.
Ansonsten haben slcherlei Abstraktionen nur Nachteile:
1. Du kaufst Dir einen "kleinesten gemeinsamen Nenner," d.h. OS
Funktionen, die der Wrapper nicht kennt, fallen unter den Tisch
2. Erhöhter Footprint
3. Höherer Stackbedarf durch das Traversieren redundanter Aufrufketten
4. Schwerer zu lesender Code (z.B. Kinetis SDK: Da jede Middlerware
ihren eigenen Abstraktionslayer hat, gibt es bei einigen
Codebeispielen bis zu 6 verscheidene Möglichkeiten, einen task zu
erzeugen!)
5. Fehlerpotential in den Implementationen der Wrappers.
6. Kontrollverlust über Speicherlayout (das tut besonders beim Thema
Bootloader weh).
7. Interdependenzen zwischen verschiedenen Versionen der Layers (sh.
Browserversionshölle bei Websites, gleiches in Grün).
Die Abstraktionslayer werden hauptsächlich aus politischen Gründen
gepusht, um entweder vendor lock-in zu erreichen oder (im Fall der
CMSIS) die ARM Plattform insgesamt attraktiver zu machen (was natürlich
den Chipherstellern überhaupt nicht gefällt und in direkter Konkurrenz
mit deren HALs liegt).
Am Beispiel lwip kann man z.B. auch sehr schön sehen, dass
Abstraktionslayer eine potentiell grosse Fehlerquelle sind; es hat z.B.
fast jede Beispielsuite seine eigene Implementation von sys_arch.c (OS
Abstraktion), von der 90% Blindflüge oder Schnellschüsse sind.
In der Praxis ist die Hoffnung, durch die Abstraktionen eine
Middlewarekomponente plug-und-play tauschen zu können, sowieso
unrealistisch, gerade bei Betriebssystemen, wo der Teufel im Detail
liegt (das habe ich mehrfach selber erleben dürfen) und ein
Entwicklunsghaus sich in der Regel auf sehr lange Zeit auf ein RTOS
committed. Die PC Welt ist durch diese Illusion schon vor vielen Jahren
gegangen, als mit Paketen wie XVT versucht wurde, OS-unabhängige UIs zu
erzeugen. Folge: Wartungsprobleme und #ifdef ohne Ende, und da am Schluß
in der Regel nur eine Plattform übriggeblieben ist, war der
Abstraktionslayer nicht nur redundant, sondern aus denselben Gründen wie
oben genannt sogar der nativen Implementation unterlegen.
Dein Fall zeigt eigentlich als case in point, das der Abstraktionslayer
(in diesem Fall CMSIS) statt einer Verbesserung nur Folgeprobleme
bringt. Ich schmeiße in der Regel erstmal Alles überflüssiges Zeug aus
einem Projekt heraus, um mich auf die wahren Herausforderungen
konzentrieren zu können.
du kannst zB fixe Buffergrößen verwenden. Wenn ein Buffer alloziert wird
und keiner zur verfügung steht dann blockiert der Thread in einer Liste.
Wenn ein anderer Thread einen Buffer zurückgibt dann wird der erste
Thread in der blockierenden Liste wieder aufgeweckt und bekommt den
Buffer. Allerdings blockiert dann jeder Thread wenn er eine debug
Message absetzt und kein Buffer zur Verfügung ist. darum sollten die
Buffer auch nur für die debug Messages verwendet werden.
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang