Forum: Mikrocontroller und Digitale Elektronik FreeRTOS One-To-Many Problem


von Stephan (Gast)


Lesenswert?

Hallo

ich habe eine grundsaetzliche Frage zur Programmstrukturierung unter 
FreeRTOS. Ein uC (CortexM3) System hat verschiedene HardwareDriver 
Tasks, welche periodisch Messdaten liefern. Diese Messdaten sollen dann 
global fuer alle SteuerTask zur Verfuegung stehen.

Problem ist: Die SteuerTask sind sehr Problemabhaehngig. Es kann sein, 
das neue SteuerTask hinzukommen. Auf jeden Fall soll ein grosser 
Datenpool die Schnittstelle zwischen HardwareDriverTasks und Steuertask 
darstellen.
Die Anzahl der HardwareDriverTask ist relativ definiert.

Wie loesst man das Problem, dass Daten aus einem HardwareDriverTask von 
einer unbekannten Anzahl an SteuerTasks gelesen werden koennen und 
gleichzeitig sichergestellt wird, dass sie waehrend des lesens nicht 
veraendert werden?

A) Theroretisch muesste man fuer jeden Empfaenger Task eine eigene Queue 
haben. Dies ist aber unpraktisch falls neue Steuertask hinzukommen 
(Speicherverbrauch und Arbeitsaufwand.)

B) Eine globale Struktur wird von einem DatenTask gefuellt. Dieser 
DatenTask wartet auf die Queues der einzelnen HardwareDriverTask und 
kopiert die Daten in die globale Struktur. Hat der DatenTask eine 
genuegend hohe Prioritaet, so ist der Schreibeprozess sicher. Jedoch 
kann es passieren, das ein SteuerTask mehrere Daten aus der globalen 
Struktur lesen moechte und dabei durch einen Schreibvorgang auf die 
gleichen Daten durch den DatenTask unterbrochen wird. Somit liest der 
SteuerTask teils alte und teils neue Daten.
Somit muesste man ein Mutex fuer diese globale Struktur definieren. Dann 
muss ich jedesmal einen Mutex nehmen und zurueckgeben um nur 1-2 Werte 
zu lesen. --> Overhead

Gibt es eine Patentloesung fuer das One-To-Many Problem?

Wie strukturiert man so ein Programm/Problem am besten.

Vielen Dank
Stephan

von (prx) A. K. (prx)


Lesenswert?

Warum sollten sich die Steuertasks nicht jeweils die nächste Message aus 
einer globalen Queue fischen können? Oder sind die unterschiedlich, d.h. 
die müssten bei einem globalen Pool sich die ihnen zugedachten Daten 
dort mittendrin raussuchen.

NB: Egal wie du das machst, du hast praktisch immer pro Zugriff eine 
Mutex an der Backe - oder eine Critical Section, aber die ist auch nicht 
besser. Der Unterschied ist bloss, dass du in A pro Steuertask eine hast 
(die Queue), in B insgesamt eine. Solange dein Controller nicht mehrere 
Cores hat sollte das aber egal sein.

Dass man Mutexe nicht ewig hält, sondern so kurz wie möglich, das sollte 
wohl klar sein.

von Stephan (Gast)


Lesenswert?

Hi
danke schonmal für deine Antwort.

Natürlich könnte sich Task B den nächsten Wert aus der Queue nehmen. 
Aber dann haben TaskA und TaskB auf jeden Fall verschiedene Messwerte 
(zeitlich gesehen). Könnte unter umständen nicht erwünscht sein. Oder 
der eine Task bekommt gar keine Daten ab, da ein anderer Task mit höhere 
Prirorität jedesmal alle Daten liest.

Ist der generelle Ansatz eines globalen Datenpools (Structur, die von 
einem Task gefüllt wird) in der freeRTOS Umgebung brauchbar?

Das Konzept der Queues ist in meinen Augen nur geeignet, wenn man im 
Vorfeld genau weiß wer die Daten erhalten soll und wenn es nur einen 
Empfänger gibt. Zu mehr aber auch nicht. Liege ich da richtig?

Stephan

von (prx) A. K. (prx)


Lesenswert?

Stephan schrieb:

> Natürlich könnte sich Task B den nächsten Wert aus der Queue nehmen.
> Aber dann haben TaskA und TaskB auf jeden Fall verschiedene Messwerte
> (zeitlich gesehen). Könnte unter umständen nicht erwünscht sein.

Der übliche Weg, mit Queues umzugehen, ist, die Elemente sukzessive 
rauszuholen. Wenn natürlich die Forderung bestehen sollte, dass alle 
lesenden Tasks das gleiche Element lesen und dies erst verschwindet wenn 
alle Tasks damit durch sind, dann sind Queues ungeeignet.

> Ist der generelle Ansatz eines globalen Datenpools (Structur, die von
> einem Task gefüllt wird) in der freeRTOS Umgebung brauchbar?

Wenn ein RTOS keine schlüsselfertige Lösung für ein Problem bietet, dann 
macht man sich die selber. Entscheidend dabei ist, dass man sich über 
Race Conditions, Deadlocks etc. klar ist. Ohne Mutex oder 
CriticalSection wird das wie schon erwähnt nicht abgehen.

> Das Konzept der Queues ist in meinen Augen nur geeignet, wenn man im
> Vorfeld genau weiß wer die Daten erhalten soll und wenn es nur einen
> Empfänger gibt. Zu mehr aber auch nicht. Liege ich da richtig?

Nein. Nicht auf deine Anwendung bezogenes Gegenbeispiel: Es gibt mehrere 
bearbeitende Tasks gleicher Art. Jede schnappt sich die älteste Message 
(löschendes Lesen), bearbeitet sie und holt sich dann die nächste. Es 
sind mehrere Tasks, weil jede davon irgendwelche Wartezeiten hat und 
eine allein den Durchsatz nicht schafft.

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.