FreeRtos Task neustart

OP #6574609
Lesenswert?

Hallo,

in einem FreeRtos (preemptive) Programm habe ich folgendes Problem:

Es existieren :

Task A  (höchste Prio)
Task B  (niedrigste Prio)

Nachdem in Task-A ein bestimmtes Event ausgelöst wird, startet Task-B 
für n-Sekunde. Ist die Zeitabgelaufen wird wieder in Task-A gewechselt. 
Wenn Task-B noch nicht abgeschlossen war, so soll sie beim nächsten 
Aufruf "neu-gestartet" werden. D.h. sie soll nicht an der Adresse 
fortgeführt werden, wo sie verlassen wurde, sondern von Beginn an.

Ich wollte die Problemstellung erstmal allgemein halten, kann aber gerne 
noch näher drauf eingehen. Eventuell bin ich gerade auf dem Holzweg, um 
das Problem anzugehen und ein anderer Ansatz führt erst gar nicht zu dem 
Problem.
Gast #6574668
Lesenswert?

Dustin B. schrieb:
> Wenn Task-B noch nicht abgeschlossen war, so soll sie beim nächsten
> Aufruf "neu-gestartet" werden. D.h. sie soll nicht an der Adresse
> fortgeführt werden, wo sie verlassen wurde, sondern von Beginn an.

z.B. vTaskDelete ist dafür zuständig, Tasks aus dem System zu entfernen
Und wie man eine "frische" Task erzeugt, weißt du ja....
OP #6574673
Lesenswert?

Ist mein erstes FreeRtos-Programm...

Problemstellung:

1. uC empfängt ein Signal, das für 5ms High sein muss, damit es als 
gültiges Signal weiterverarbeitet werden kann.
2. Eingangssignal okay --> uC schaltet einen externen Sensor zur 
Kommunikation frei
3. Starte Kommunikation mit externen Sensor via I²C (darf nicht länger 
als 30 ms sein)  <-- Hier bei 3. greift mein Problem
4. Kommunikation abgeschlossen --> mache andere Sachen


Task A: höchste prio
 - Auswertung eines Eingangssignal via Input Capture
 - Wenn Eingangssignal in Ordnung, schalte externen Sensor frei.
 - Sende Event-Signal an Task-B
 - Gehe für 30 ms in den Block-Zustand
 - Rückkehr nach 30 ms --> deaktiviere/reset externen Sensor

Task B: niedrigste prio
 - starte Kommunikation via I²C mit externen Sensor

Mein Problem ist, wenn Task-B unterbrochen und später wieder aufgerufen 
wird. Könnte es sein das noch die I²C-Kommunikation (mittendrin) 
fortgesetzt wird. Das soll verhindert werden. Deswegen wollte ich die 
Task "Neustarten".

Eventuell habe ich da auch einen falschen Ansatz.
Beitrag #6574676 wurde von einem Moderator gelöscht.
OP #6574677
Lesenswert?

Arduino Fanboy D. schrieb:
> Dustin B. schrieb:
>> Wenn Task-B noch nicht abgeschlossen war, so soll sie beim nächsten
>> Aufruf "neu-gestartet" werden. D.h. sie soll nicht an der Adresse
>> fortgeführt werden, wo sie verlassen wurde, sondern von Beginn an.
>
> z.B. vTaskDelete ist dafür zuständig, Tasks aus dem System zu entfernen
> Und wie man eine "frische" Task erzeugt, weißt du ja....

Daran hab ich auch schon gedacht, war mir nur nicht ganz sicher ob dass
der korrekte weg ist.
#6574692
Lesenswert?

Dustin B. schrieb:
> Eventuell habe ich da auch einen falschen Ansatz.

Also ich lasse immer alle Tasks laufen und zerstöre/erzeuge die nicht 
zur Laufzeit.

Wenn es Abhängigkeiten zwischen Tasks gibt, benutze ich entweder eine 
Queue, wenn der eine Task dem anderen noch Daten übermitteln soll, oder 
wenns nur darum geht, den anderen Task anzustossen, eine binäre 
Semaphore oder Notification.
Wie es im Detail funktioniert, ist auf der FreeRTOS Webseite gut 
beschrieben.
OP #6574713
Lesenswert?

Johnny B. schrieb:
> Dustin B. schrieb:
>> Eventuell habe ich da auch einen falschen Ansatz.
>
> Also ich lasse immer alle Tasks laufen und zerstöre/erzeuge die nicht
> zur Laufzeit.
>
> Wenn es Abhängigkeiten zwischen Tasks gibt, benutze ich entweder eine
> Queue, wenn der eine Task dem anderen noch Daten übermitteln soll, oder
> wenns nur darum geht, den anderen Task anzustossen, eine binäre
> Semaphore.
> Wie es im Detail funktioniert, ist auf der FreeRTOS Webseite gut
> beschrieben.

Eine andere Idee war von mir eine übergeordnete Monitoring-Task zu 
erstellen (wo auch der Watchdog laufen sollte). Die erstmal alle 
Events/ISR bekommt und dann über Queues an die entsprechenden Task 
weiterleitet. Jede Task sollte dann nach dem Finite-State-Machine 
Prinzip ihre Funktionen entsprechend der Queue-Message ausführen.

Vielleicht könnte mir einer dazu ein Feedback geben, ob dies ein 
annehmbarer Ansatz ist oder sollte man doch die Events/ISR direkt an die 
jeweiligen Task übergeben?
Gast #6574719
Lesenswert?

Dustin B. schrieb:
> enn Task-B unterbrochen und später wieder aufgerufen
> wird. Könnte es sein das noch die I²C-Kommunikation (mittendrin)

Allgemein: Task-B wird doch ohnehin laufend im configTICK_RATE_HZ Takt 
unterbrochen, oder was meinst Du mit "unterbrechen"? Das ist ja ein 
"Feature" eines RTOS ;)

Konkret1: die nicht saubere "separation of concerns" ist m.E. schon ein 
Grund für die eigentliche Frage:
Warum kümmert sich Task-B nicht komplett um die I2C Kommunikation inkl. 
der Verwaltung der/des Geräte(s).
Task-B könnte ja (so es nicht anders abgebildet werden kann) sich selbst 
NACH dem erfolgreichen I2C Zyklus selbst suspenden. Task-A weckt 
(resume) Task-B dann nur auf. Task-B könnte aber auch laufend (das ganze 
scheint ja keine einmal-Aktion zu sein) den Datentransfer managen und 
die (konsistenten) Daten in einer ProxyStruktur lesend für die Restwelt 
zur Verfügung stellen...

Aber ketzerische Frage: warum brauchst Du für das alles überhaupt ein 
RTOS?

Konkret2: von was für einer Platform redest Du? Es gibt von vielen 
µC-Herstellern auch für freeeRTOS angepasste I2C (und andere) Treiber, 
die (sogar via DMA) sauber (d.h. entweder blocken sie sauber oder sind 
preemtiv) im freeRTOS laufen.

Konkret3: von einem taskCreate/Delete Pattern in regelmässigen kurzen 
Zeitabständen würde ich abraten. Dann lieber die I2C-Kümmert-sich-Task 
immer laufen lassen und ggf suspenden oder mit den anderen Bordmitteln 
von freeRTOS mit der/einer übergeordneten Task synchronisieren...

VG, Stephan
OP #6574732
Lesenswert?

Mit unterbrechen meinte ich schon, wie du auch schreibst, den 
eigentlichen Rtos-Vorgang ;)

Ich glaube ich habe mich in der Task Aufteilung verrannt. Zuerst war die 
ganze I2C + Verwaltung in einer Task. Mir kam dann bloß der Gedanke, 
dass es wahrscheinlich besser ist die Verwaltung des externen Sensors in 
einer übergeordneten Task auszuführen. Ich wollte damit sicherstellen, 
dass auf jedenfall der externe Sensor deaktiviert wird.

Für zukünftige Erweiterungen wollte ich das ganze auf ein Rtos aufbauen. 
Z.B. weitere Kommunikationswege zu anderen Komponenten

Der uC ist ein STM32F091RC schreibe das ganze in der STM32XCubeIDE
#6574817
Lesenswert?

Was fuer eine ausserordentlich schwache Idee soll das sein, eine I2C 
Kommunikation abzubrechen und neu zu starten ? Wenn sie das erste Mal 
nicht beendet,.. weswegen sollte sie's bei zweiten Mal dann tun ?

Klopp das Design in die Tonne, das wird so nichts. Der Witz an Echtzeit 
ist ja eben grad, dass die Prozesse von einander entkoppelt sind. Du 
hast einen Task, der den I2C macht. Der bekommt den Auftrag mit dem I2C 
etwas zu machen, und das macht er mit seinem eigenen Timing. Auch wenn 
das voellig schraeg zum Rest ist. Eine Resource - ein Prozess.
Vergiss mal das Preemptive, das macht alles schwieriger. Du musst den 
Prozessen einfach genuegend Haltestellen geben und nirgendwo busy 
warten.

Zeig mal das Design

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren