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.
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.
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....
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.
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.
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
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.
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?
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.