Hallo,
ich verwende freeRTOS und habe einen Task, der mir einen (double)Wert
setzt und einen anderen Task, der diesen Wert gelegentlich lesen muss.
Nun habe ich gelegentlich (aber ganz selten) das Problem, dass der
zweite Task glaubt einen (sehr großen) Wert in der Variable zu lesen,
der jedoch gar nicht möglich sein kann.
In der Suche konnte ich nicht findig werden, aber kann es sein, dass man
Variablen in Verbindung mit verschiedenen Task als
1
volatile
deklarieren muss? Also genauso, als wären es interrupts?
brechbunkt schrieb:> Also genauso, als wären es interrupts?
Korrekt.
Ein Taskwechsel ergibt sich oft als Folge eines Interrupts, indem der
Interrupt-Handler nicht in die ursprüngliche Task zurückkehrt, sondern
in eine andere. Präemptives Multitasking wirkt folglich in diesem
Zusammenhang analog zu Interrupts.
Dein Problem löst dies allerdings noch nicht.
brechbunkt schrieb:> Nun habe ich gelegentlich (aber ganz selten) das Problem, dass der> zweite Task glaubt einen (sehr großen) Wert in der Variable zu lesen,> der jedoch gar nicht möglich sein kann.
Vermutlich braucht double mehrere Befehle, dann müssen die Zugriffe
atomar erfolgen (in beiden Tasks).
A. K. schrieb:> Präemptives Multitasting wirkt folglich in diesem> Zusammenhang analog zu Interrupts.
Nur zur Ergänzung: Alle Zugriffe auf "shared memory" (was anderes ist
diese Variable ja nicht) müssen aus dem gleichen Grund atomar erfolgen.
Güße
Stefan
Edit: Peter war etwas schneller...
FreeRTOS enthält Methoden, mit denen man sich diesem Problem widmen
kann. Nämlich in erster Linie Mutexe (siehe Semaphoren), und in
Härtefallen taskENTER_CRITICAL/taskEXIT_CRITICAL.
Alex schrieb:> http://www.freertos.org/Embedded-RTOS-Queues.html
Hübscher Link, er zeigt sehr schön, wie kompliziert das ganze RTOS
Gedöns ist. Da raucht einem schnell der Schädel beim Lesen.
Also Queues sind schonmal nicht. Sie funktionieren nur dann, wenn exakt
gleichviel gesendet und empfangen wird. Ansonsten gibt es nen Über- bzw.
Unterlauf. Und sie sind auch deutlich aufwendiger als "atomar".
Mutexe und Semaphoren aber auch nicht, denn jeder muß jederzeit drauf
zugreifen können.
Weiß jemand, wie "atomar" in RTOS-Sprech heißt?
Peter Dannegger schrieb:> Mutexe und Semaphoren aber auch nicht, denn jeder muß jederzeit drauf> zugreifen können.>> Weiß jemand, wie "atomar" in RTOS-Sprech heißt?
Wenn ein Zugriff atomar geschehen soll, darf doch eben nicht jeder
jederzeit drauf zugreifen, sondern schön der Reihe nach. Das geht mit
einem Semaphor bzw. Mutex.
Ohne die korrekte Syntax zu kennen, also etwa so:
Hallo zusammen,
eine von mehreren Tasks gemeinsam genutzte Variable ist eine "shared
ressource" und der Zugriff kann unter FreeRtos mit einer Mutex
geschützt werden. Siehe hier:
http://www.freertos.org/Real-time-embedded-RTOS-mutexes.html
Das funktioniert wunderbar. Die Synchronisation verursacht natürlich
einen gewissen overhead ...
Gruß
swausd
Siegfried W. schrieb:> Die Synchronisation verursacht natürlich> einen gewissen overhead ...
Ja, das wird um Größenordnungen teurer sein, als ein simples
CLI,Zugriff,SEI.
Peter Dannegger schrieb:> Siegfried W. schrieb:>> Die Synchronisation verursacht natürlich>> einen gewissen overhead ...>> Ja, das wird um Größenordnungen teurer sein, als ein simples> CLI,Zugriff,SEI.
über die Synchronisation zweier Prozesse/Tasks sollte man sich schon ein
paar Gedanken machen. Einen oft geänderten Schleifenzähler sollte man
nicht mit Mutex teilen müssen. Alle Interrupts des Systems sollte man
dann allerdings auch nicht ausschließen ...
Gruß
swausd
Peter Dannegger schrieb:> Alex schrieb:>> http://www.freertos.org/Embedded-RTOS-Queues.html>> Hübscher Link, er zeigt sehr schön, wie kompliziert das ganze RTOS> Gedöns ist. Da raucht einem schnell der Schädel beim Lesen.>> Also Queues sind schonmal nicht. Sie funktionieren nur dann, wenn exakt> gleichviel gesendet und empfangen wird. Ansonsten gibt es nen Über- bzw.> Unterlauf. Und sie sind auch deutlich aufwendiger als "atomar".>> Mutexe und Semaphoren aber auch nicht, denn jeder muß jederzeit drauf> zugreifen können.>> Weiß jemand, wie "atomar" in RTOS-Sprech heißt?
Ich kann mich dunkel erinnern, dass ich auf Windows-Rechnern für
"atomaren" Zugriff auch das Mutex-Object verwendet habe (lange ists
her):
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684266(v=vs.85).aspx
Man kann glaube ich auch einfach checken, ob das Object grad belegt ist,
ohne auf die Freigabe zu warten.
Wie das jetzt aber bei den RTOS für uC ist, weiss ich ehrlich gesagt
nicht.
Edit: zu langsam
Peter Dannegger schrieb:> Ja, das wird um Größenordnungen teurer sein, als ein simples> CLI,Zugriff,SEI.
Ist es. Es ist eine Abwägung des Aufwands. Wenn nur wenige Befehle zu
schützen sind, dann ist die oben ebenfalls angeführte critical section
billiger.
Je nach Prozessor und RTOS ist eine critical section entweder identisch
mit einer simplen Interrupt-Sperre, oder setzt den Interrupt-Level so,
dass nur noch Interrupts durchkommen, die keine RTOS-APIs nutzen und
daher nicht preempten können. Beim NVIC der Cortex-M Cores lässt sich
das effektiv nutzen um die Latenzzeit kritischer Interrupts nicht zu
gefährden.
Kein Name schrieb:> Für diesen Fall ginge auch eine sehr einfache Strategie. Den Wert> mehrmals lesen.
Dummerweise verbessert das die Situation nur statistisch, nicht aber
absolut. Ist also nur sinnvoll, wenn ein extrem seltener Fehlwert
toleriert werden kann.
Peter Dannegger schrieb:> Siegfried W. schrieb:>> Die Synchronisation verursacht natürlich>> einen gewissen overhead ...>> Ja, das wird um Größenordnungen teurer sein, als ein simples> CLI,Zugriff,SEI.
Das funktioniert z.B. nicht bei echter Parallelität. Oder willst du
alle anderen Cores anhalten?
Johann L. schrieb:> Das funktioniert z.B. nicht bei echter Parallelität. Oder willst du> alle anderen Cores anhalten?
Yep, aber das ist dann meistens ausserhalb des hier üblichen Kontextes
"Mikrocontroller". Da kann man sich dann auch schon mal mit dem Gedanken
an Spinlocks anfreunden, garniert mit resourcensparenden Delays um sich
bei SMT nicht gegenseitig zu bremsen. Oder kann mit transactional memory
gleich noch eine Stufe weiter gehen.