Forum: Mikrocontroller und Digitale Elektronik RTOS, auf free warten?!


von Basti (Gast)


Lesenswert?

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:
1
void *osMailAlloc (osMailQId queue_id, uint32_t millisec)
2
{
3
  (void) millisec;
4
  void *p;
5
  
6
  if (queue_id == NULL) {
7
    return NULL;
8
  }
9
  
10
  //// TEIL VON BASTI ////////
11
  uint32_t ticks = osKernelSysTick();
12
  do {
13
    p = osPoolAlloc(queue_id->pool);
14
    if(millisec != osWaitForever && (ticks - osKernelSysTick()) > millisec)
15
    {
16
      break;
17
    }
18
  } while( p == NULL);
19
 ///////////////////////////////////
20
21
  
22
  return p;
23
}

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

von Dampf T. (ouuneii)


Lesenswert?

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.

von hsc (Gast)


Lesenswert?

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.

von Basti (Gast)


Lesenswert?

Hallo hsc,

ja, so habe ich es aus dem Source gelesen...
Vielleicht gibt es schon eine neuere Version?!

Wenn ich das richtig verstehe, dann wird es auch hier nachgefragt:

https://github.com/ARM-software/CMSIS/issues/57

Jedenfalls kann ich alleine vom Quellcode sichten nicht nachvollziehen 
wie Keil RTX das Problem löst:

https://github.com/ARM-software/CMSIS/blob/0156c6f40ec9556bf46b2d4a947ae3ef872cd1bd/CMSIS/RTOS/RTX/SRC/rt_CMSIS.c#L2007

Wie wartet das OS auf den Speicher? Eine Loop gibt es ja nicht direkt...

Und viel wichtiger für mich, wie sieht eine valide FreeRTOS 
Mail-Implementierung aus?

Danke

Basti

von hsc (Gast)


Lesenswert?

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.

von Basti (Gast)


Lesenswert?

Okay, also hat nur der cmsis wrapper von FreeRTOS seine Schwächen?!

https://github.com/dobromyslov/argonio-stm32f0-cmsis-hal-freertos-example/blob/master/lib/argonio-stm32f0-freertos/Source/CMSIS_RTOS/cmsis_os.c#L908

Sehr schade, ich hätte den gern intensiv eingesetzt, um auch im Notfall 
das OS noch tauschen zu können...

von Basti (Gast)


Lesenswert?

push

Ich versuche es nochmal... vielleicht hatte ja jemand schon ähnliche 
Erfahrungen.

von Purist (Gast)


Lesenswert?

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.

von ----------------------- (Gast)


Lesenswert?

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.

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.