Forum: Mikrocontroller und Digitale Elektronik FreeRtos Task neustart


von Dustin M. (db1234)


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.

von Stephan (Gast)


Lesenswert?

Dustin B. schrieb:
> Eventuell bin ich gerade auf dem Holzweg,

Das scheint mir bei der Faktenlage der  wahrscheinlichste Zustand.
Du könntest natürlich mal die Entitäten: Task-A/B,Event in einer 
sinnvollen Art beschreiben.
Das Gesamtprodukt/SW existiert schon? Du hast FreeRTOS schon einmal 
eingesetzt? Ggf wäre https://forums.freertos.org geeigneter.

von Einer K. (Gast)


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....

von Dustin M. (db1234)


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.
von Dustin M. (db1234)


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.

von Einer K. (Gast)


Lesenswert?

Dustin B. schrieb:
> Daran hab ich auch schon gedacht, war mir nur nicht ganz sicher ob dass
> der korrekte weg ist.

Die Alternative wäre, der vorhandene Task eine Message senden, so dass 
sie aus eigener Kraft neu beginnen kann

von Johnny B. (johnnyb)


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.

von Dustin M. (db1234)


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?

von Stephan (Gast)


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

von Dustin M. (db1234)


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

von Pandur S. (jetztnicht)


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

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.