Hallo zusammen, angenommen, ich habe hier einen Mikrocontroller der Cortex M-3 Klasse und die freie Wahl des "Betriebssystems" (bare metal, freertos, keil rtx, usw). Die Software liest Sensoren aus (kurze Interrupts, Frequenz etwa 1 kHz, nachträgliche Filterung/Bearbeitung in dem entsprechenden Task/Modul) und verrechnet diese nach einer Decimation relativ aufwendig (das dauert bis zu 20 ms). Das passiert natürlich wieder in einem eigenen Task. Momentan ist jeder Task eine Funktion, deren Zustandswechsel durch FSM abgebildet werden. Dann gibt es natürlich noch die Kommunikation mit der Außenwelt über CAN. Ich stelle mir hier die Frage der Priorisierung: Ich möchte, dass die Kommunikation nicht bis zu 20 ms still steht. Gleichzeitig MUSS der Berechnungstask nach 50 ms abgeschlossen sein. Gestalte ich den Task blockierend, findet natürlich keine Kommunikation in der Zeit statt. Im Moment kann die Berechnung an zwei sinnvollen Punkten unterbrochen werden (FSM) und das Programm springt zurück zur Hauptschleife. Das ist aber umständlich und wenn ich an weiteren Punkten "Multitasking" haben möchte, brauche ich weitere Zustände, die das ganze noch umständlicher machen. Ein RTOS könnte den Task beliebig unterbrechen und ich brauche keine FSM mehr. Dafür könnte der Kommunikationstask bei entsprechend häufigem Aufrufen bei höherer Priorität als der Berechnungstask ebenjenen komplett blockieren. Hat die Kommunikation eine geringere Priorität, würde sie die Berechnung niemals unterbrechen und ich bräuchte keinen preemptiven Scheduler in diesem Fall. Wie macht ihr das? Danke und schöne Grüße, Jan
> Im Moment kann die Berechnung an zwei sinnvollen Punkten unterbrochen
werden (FSM) und das Programm springt zurück zur Hauptschleife.
Die Berechnung unterteilen, oder noch besser Abkuerzen. Schwer zu
glauben, dass ihr so viel Rechenleistung sinnvoll verballert.
Sapperlot W. schrieb: >> Im Moment kann die Berechnung an zwei sinnvollen Punkten unterbrochen >> werden (FSM) und das Programm springt zurück zur Hauptschleife. > > Die Berechnung unterteilen, oder noch besser Abkuerzen. Schwer zu > glauben, dass ihr so viel Rechenleistung sinnvoll verballert. Weitere Unterteilungen werden umständlich, ginge aber. Per RTOS is sowas nicht lösbar? Das ist übrigens ein Extended Kalman Filter mit 5 Zuständen und Fließkommazahlen. Ja kann man sicherlich optimieren, aber die Lesbarkeit und Anpassbarkeit ist gut.
Jan K. schrieb: > Im Moment kann die Berechnung an zwei sinnvollen Punkten unterbrochen > werden (FSM) Warum nicht die Kommunikation in Interrupt-Routinen abwickeln (natürlich ohne Warteschleifen!!) und die Berechnung in der Main Loop? Kommunikation lässt sich normalerweise als State Machine realisieren, so dass keine Warteschleifen vorkommen. Georg
Berechnungen sollten sich auch im Mainloop erledigen lassen.
Jan K. schrieb: > Wie macht ihr das? Mit einer klassischen Betrachtung der Echtzeitfähigkeit Welche Tasks werden wie oft aufgerufen und haben welche Echtzeitanforderung?
1 | Task Frequenz Dauer Timeout |
2 | ---------------------------------------- |
3 | Sensor 1 1kHz ?? ?? |
4 | Sensor 2 1kHz ?? ?? |
5 | Filter ?? 20ms 50ms |
6 | CAN ?? ?? ?? |
Das lässt sich dann in ein Diagramm gießen, dass in etwa so wie hier aussehen könnte: http://www.freertos.org/implementation/a00008.html Daraus ergeben sich dann die Prioritäten. Jan K. schrieb: > Das ist übrigens ein Extended Kalman Filter mit 5 Zuständen und > Fließkommazahlen. Ja kann man sicherlich optimieren, aber die Lesbarkeit > und Anpassbarkeit ist gut. Nimm einen M4F, damit sparst du ne menge Zeit, da Fließkomma in Hardware berechnet wird. Desweiteren kannst du die Kommunikation mit den Sensoren über DMA laufen lassen, womit du die aktive Rechenzeit auf Mikrosekunden reduzieren kannst.
Georg schrieb: > Jan K. schrieb: >> Im Moment kann die Berechnung an zwei sinnvollen Punkten unterbrochen >> werden (FSM) > > Warum nicht die Kommunikation in Interrupt-Routinen abwickeln (natürlich > ohne Warteschleifen!!) und die Berechnung in der Main Loop? > > Kommunikation lässt sich normalerweise als State Machine realisieren, so > dass keine Warteschleifen vorkommen. > > Georg Timing könnte da ein Problem werden. Das Protokoll ist ziemlich umfänglich, glaube nicht, dass es ne gute Idee ist, das in die ISR zu packen. Das Problem, dass bei dauerhafter "Beschallung" von außen die Berechnung blockiert wird bleibt dabei übrigens auch bestehen. Ich benutze keine Warteschleifen... Sapperlot W. schrieb: > Berechnungen sollten sich auch im Mainloop erledigen lassen. Werden sie ja im Moment. Little B. schrieb: > Jan K. schrieb: >> Wie macht ihr das? > > Mit einer klassischen Betrachtung der Echtzeitfähigkeit > Welche Tasks werden wie oft aufgerufen und haben welche > Echtzeitanforderung? > Task Frequenz Dauer Timeout > ---------------------------------------- > Sensor 1 1kHz ?? ?? > Sensor 2 1kHz ?? ?? > Filter ?? 20ms 50ms > CAN ?? ?? ?? > > Das lässt sich dann in ein Diagramm gießen, dass in etwa so wie hier > aussehen könnte: > http://www.freertos.org/implementation/a00008.html > > Daraus ergeben sich dann die Prioritäten. Ok, mal malen ;) > Jan K. schrieb: >> Das ist übrigens ein Extended Kalman Filter mit 5 Zuständen und >> Fließkommazahlen. Ja kann man sicherlich optimieren, aber die Lesbarkeit >> und Anpassbarkeit ist gut. > > Nimm einen M4F, damit sparst du ne menge Zeit, da Fließkomma in Hardware > berechnet wird. > Wäre natürlich ne Möglichkeit. Aber eigentlich ist der Prozessor ausreichend schnell, es ist ja eher ein Timing Problem und eine Frage der Architektur. Das Problem kann ja auch verallgemeinert werden auf einen Task, der z.B. ne Minute braucht ;) > Desweiteren kannst du die Kommunikation mit den Sensoren über DMA laufen > lassen, womit du die aktive Rechenzeit auf Mikrosekunden reduzieren > kannst. Mach ich natürlich. Werden per DMA in nen Puffer gefüllt, aber hinterher muss noch etwas rumgerechnet werden (Skalierung, Temperaturkompensation, Digitale Filter usw). Vielleicht lautet die allgemeinere Frage: Wie schafft ihr es, bei "Spam" über eine Kommunikationsschnittstelle noch handlungsfähig zu bleiben? Einführung einer minimal möglichen Zeit zwischen zwei Kommunikationsevents? Oder vielleicht eine Art dynamische Priorisierung? Danke & schöne Grüße
Jan K. schrieb: > Wie schafft ihr es, bei "Spam" > über eine Kommunikationsschnittstelle noch handlungsfähig zu bleiben? Ich glaube nicht, dass es mit CAN überhaupt möglich ist, den Prozessor auszulasten. Jan K. schrieb: > Das Protokoll ist ziemlich > umfänglich, glaube nicht, dass es ne gute Idee ist, das in die ISR zu > packen Ich glaube auch nicht, dass man so ein Protokoll nicht per State Machine in kleinste Häppchen aufteilen kann - z.B. ist auf ein ankommendes Zeichen nur eine einfache Reaktion nötig und ein neuer Zustand, und selbst eine CRC-Berechnung ist überschaubar. Wir reden hier ja nicht von einem 8085. Aber das müsste man natürlich konkret durchführen. Wenn du dir das nicht zutraust, ist ein fertiges Realtime OS schon sicherer. Georg
> Die Software liest Sensoren aus (kurze Interrupts, Frequenz etwa 1 kHz, > nachträgliche Filterung/Bearbeitung in dem entsprechenden Task/Modul) OK. jede MS ein oder zwei Interrupts mit etwa 10...100µs. > Dann gibt es natürlich noch die Kommunikation mit der Außenwelt über CAN. OK. Jede 10ms ein Telegramm mit 10 Byte, per (Timer-)Interrupt geringerer Priorität. (?) > Ich möchte, dass die Kommunikation nicht bis zu 20 ms still steht. Tut sie ja nicht. per Timer-Interrupt. > Gleichzeitig MUSS der Berechnungstask nach 50 ms abgeschlossen sein. Berechnungs-Task = Main-Loop. Ggf. mit CAN-Interrupt-Sperrungen falls notwendig. > Gestalte ich den Task blockierend, findet natürlich keine Kommunikation > in der Zeit statt. OK, also CAN-Kommunikation in eigener Task. Auch OK. Aber dann CAN mit höherer Priorität und die Berechnung nicht blockierend. > Im Moment kann die Berechnung an zwei sinnvollen Punkten unterbrochen > werden (FSM) und das Programm springt zurück zur Hauptschleife. ???? Task oder SPS-Loop? > Dafür könnte der Kommunikationstask bei entsprechend häufigem > Aufrufen bei höherer Priorität als der Berechnungstask ebenjenen > komplett blockieren. Nein, wieso? Sie kann sich doch beliebig lange Schlafen legen, wenn sie z.B. 50% der letzten 50ms verbraucht hat. Oder sich mit der Berechnung Synchronisieren. Der genaue Ablauf hängt davon ab, wann genau die Berechnung starten muss und wie lange sie dann brauchen darf. Z.B. im 50ms-Takt starten und innerhalb der nächsten 50ms fertig? Oder maximal 50ms zwischen 2 Ergebnissen (das ist ein Unterschied (!sic)).
Jan K. schrieb: > Wie schafft ihr es, bei "Spam" > über eine Kommunikationsschnittstelle noch handlungsfähig zu bleiben? a) Kommunikationstask schlafen legen für x ms (Telegramme ignorieren) b) verwerfen auf Auswerteebene wenn korrekte Anfragen aber zu schnell nacheinander c) Zusammenfassen (falls Fifo): von 10Mal LED an/aus oder Anfrage des Wertes Y gewinnt nur der letzte d) Handshake (gerne auch als Acknowledge!) e) Den Sender (Spammer) kontrollieren f) entsprechende Adressfilter auf oberster Ebene (für Telegramme, die nicht für mich sind) g) bei Kommunikationsfehlern relativ lange Pausen (halbes Telegramm oder mehr) h) Fehlermeldung Die beste Waffe aber sind separate logische Kanäle. verschiedene Aufgaben bekommen verschiedene Kanäle, die alle parallel verarbeitet werden. Es werden alle Kanäle nacheinander abgearbeitet. Wenn ein Kanal spammt, gehen in diesem ggf. Telegrammer verloren, alle anderen reagieren noch in Echtzeit. Jeder Kanal hat seinen eigenen 1-Telegramm-Fifo, je nach Anwendung auch x-Elemente, wichtig nur, dass sie wirklich parallel/unabhängig sind, nicht z.B. per Prio hirarchisch.
Die Angaben sind doch etwas verwirrend, wie an den Reaktionen hier auch ablesbar ist. Die Frage hängt ja von deinem Anwendungsfall ab, und da hast du noch zu wenig geschildert: 1) Die Berechnung muss nach 50ms abgeschlossen sein. Harte Echtzeitbedinung? Was machst du mit dem Ergebnis? Rausschreiben? Und startet unmittelbar dannach die nächste Berechnungsrunde? Wie wird die Berechnung getriggert, wenn sie nicht dauerhaft läuft? 2) Was heißt "soll nicht 20ms nichts tun" bzgl. der Kommunikation? Sind die Daten, die du versenden/empfangen willst, für die Berechnung wichtig? Oder sind das "ganz" andere Daten (Heartbeat etc.). Warum ist es wichtig, dass die Kommunikation nicht einfach 20ms schläft? Was hast du davon für einen Vorteil, wenn sie z.B. nach 5ms sendet, dafür aber nur einen Teil ihrer Nachrichten? Und dann solltest du dir auch noch über andere Dinge Gedanken machen, die durchaus vorkommen: - Was soll passieren wenn die Berechnung länger als 20ms oder noch schlimmer länger als 50ms dauert? Wenn du einen Programmierfehler drin hast, der auf einmal aus irgendeinem Grund verzögert? Was passiert dann? Erklär erst mal genau was du willst und was du brauchst. Auch mit Prioritäten. Oftmals sind einfache Lösungen die besten, weil schwierige Lösungen oft (eigentlich nicht benötigte) Komplexität mit reinbringt.
Ach ja zum RTOS: Es gibt ja auch noch einen EDF Scheduler. Da könntest du (wenn du weißt wie lange was dauert und wie oft z.B. der Kommunikationstask drankommen soll) entsprechend verfahren.
Achim S. schrieb: > die alle parallel verarbeitet > werden. Es werden alle Kanäle nacheinander abgearbeitet gemeint ist: Es gibt z.B. 8 Eingangs-Kanäle. Jedes einkommende Telegramm wird untersucht, für welchen Kanal es ist und dort abgelegt (überschreibt ggf. das bisherige dort oder wird verworfen wenn voll). Die Eingangs-Telegrammspeicher liegen also "parallel" wie 8 Briefkästen nebeneinander. Abgearbeitet werden sie nacheinander. Zuerst Kanal-1: Ist ein Telegramm da, dann verarbeiten. Danach Kanal-2: " ... Dann wieder von neuem Kanal-1: Wenn es wie hier darum geht, dass die Kommunikation zuviel Rechenzeit raubt, dann wird "von neuem" frühestens 50ms nach dem letzten Lauf oder 30ms nach Kanal-8 gestartet.
Hallo Jan, falls dein gewähltes RTOS Time Sliceing beherscht (wie z.B. FreeRTOS) kannst du beiden Task(Kommunikation und KF) die selbe Priorität zuteilen. Dann sollte dein Rechentask mindestens 50% der Rechenzeit abbekommen. Ob das jetzt schönes Design ist kann ich nicht sagen. Wahrscheinlich wäre ein Buffern der Information via DMA und ein garantiertes zügiges abarbeiten oder falls dies nicht möglich ist das Auslösen eines Fehlerzustands die bessere Lösung. Weil bei hoher Kommunikationslast bleibt ja je nach dem trotzdem nicht genug Zeit um alle Nachrichten zu beantworten. Sprich du verlagerst das Problem zur Kommunikationsseite. Gruß Peter
Jan K. schrieb: > Wie schafft ihr es, bei "Spam" > über eine Kommunikationsschnittstelle noch handlungsfähig zu bleiben? Ich mache das immer nach dem Ping-Pong Prinzip. Master sendet Kommando, Slave antwortet. Außerdem habe ich eine FIFO, d.h. der Master kann 8 Pakete hintereinander senden. Ist die FIFO voll, werden weitere Pakete verworfen und ein Fehlerbit gesetzt. Den CAN betreibe ich mit 500kBit, d.h. die Nutzdatenrate ist maximal 250kBit, das schafft selbst der AT90CAN128 bei 16MHz locker. Die Auswertung erfolgt im Main. Ist das Main durch andere Tasks lange beschäftigt, könnte man dafür auch einen Softwareinterrupt niedriger Priorität verwenden. An ein RTOS habe ich mich bisher nicht getraut. Dadurch, daß dann die Tasks in nicht vorhersehbaren Zeitscheiben und nicht vorhersehbarer Reihenfolge ausgeführt werden, ist die Datenkonsistenz sehr schwierig zu garantieren. Ich mag lieber die volle Kontrolle über den Ablauf, sowie die Unmöglichkeit von Deadlocks.
Peter D. schrieb: > Den CAN betreibe ich mit 500kBit Wenn möglich, ist das wirklich die beste Maßnahme gegen Spam: Die Baudrate so klein, dass selbst Back-To-Back-Telegramme genügend Rechenzeit für den Rest lassen. Nur ggf. darauf achten, dass die Fehlerbehandlung eines Zeichens oder eines Telegramms nicht länger dauert als die Normale Behandlung. Also z.b. Pause einlegen und auf sauberen Neustart achten.
Hallo Jan, für welches RTOS hast du dich denn entschieden? Wir haben ähnliche Anforderungen und arbeiten mit SEGGER embOS. Der Vorteil ist das die Jungs sich mit solchen Sachen extrem gut auskennen und das quasi mit zum Service gehört einem bei so etwas zu beraten. Vielleicht einfach mal bei denen melden? Hat bei mir super geklappt. Vor allem kann man sich das dann alles mit SystemView grafisch anzeigen lassen und einfach überprüfen, ob alles so läuft, wie man es sich vorgestellt hat: https://www.segger.com/systemview.html Ich hatte da auch zuerst falsche Vorstellungen und musste lernen das ein RTOS nicht dafür sorgen kann die CPU zu mehr als 100% auszulasten. Aber es hilft einem unwahrscheinlich die Arbeit in mehrere Tasks aufzuteilen und alle Timings einzuhalten. Den Ansatz mit der klassischen Betrachtung der Echtzeitfähigkeit in einer Tabelle ist schon der richtige. Man muss sich halt entscheiden was für einen die höchste Echtzeitanforderung haben soll.
Wow, das sind ja viele Beiträge, danke! Ich versuche mal auf alle einzugehen. Georg schrieb: > Jan K. schrieb: >> Das Protokoll ist ziemlich >> umfänglich, glaube nicht, dass es ne gute Idee ist, das in die ISR zu >> packen > > Ich glaube auch nicht, dass man so ein Protokoll nicht per State Machine > in kleinste Häppchen aufteilen kann - z.B. ist auf ein ankommendes > Zeichen nur eine einfache Reaktion nötig und ein neuer Zustand, und > selbst eine CRC-Berechnung ist überschaubar. Wir reden hier ja nicht von > einem 8085. > > Aber das müsste man natürlich konkret durchführen. Wenn du dir das nicht > zutraust, ist ein fertiges Realtime OS schon sicherer. Es ist eher eine Frage der Übersichtlichkeit und der Zeit. Das eigentliche Parsen der reintröpfelnden Daten könnte man aber wirklich auch als FSM machen, werde ich angehen. Achim S. schrieb: >> Die Software liest Sensoren aus (kurze Interrupts, Frequenz etwa > 1 kHz, >> nachträgliche Filterung/Bearbeitung in dem entsprechenden Task/Modul) > > OK. jede MS ein oder zwei Interrupts mit etwa 10...100µs. > >> Dann gibt es natürlich noch die Kommunikation mit der Außenwelt über CAN. > > OK. Jede 10ms ein Telegramm mit 10 Byte, per (Timer-)Interrupt > geringerer Priorität. (?) Jain - es gibt zwei Modi, einmal werden Daten mit 10 ms Zykluszeit broadcastet (Timer Interrupt), der mit einem Befehle deaktiviert werden kann. Dazwischen können natürlich trotzdem Telegramme eintreffen, auf die auch reagiert wird. In meinem Fall geht es um letzteren Betriebsmodus, ich möchte möglichst schnelle und kontinuierliche interne Größen auslesen. Allerdings könnte es sein, dass die Gegenstelle eben nicht wartet, bis eine Antwort kam. Ist natürlich eine Fehlkonstruktion, aber dieser Fehlerfall sollte abgefangen werden. >> Ich möchte, dass die Kommunikation nicht bis zu 20 ms still steht. > Tut sie ja nicht. per Timer-Interrupt. Aber eben nur die broadcast Nachricht. > >> Gleichzeitig MUSS der Berechnungstask nach 50 ms abgeschlossen sein. > Berechnungs-Task = Main-Loop. Ggf. mit CAN-Interrupt-Sperrungen falls > notwendig. > So ist es im Moment, allerdings wird der CAN nicht gesperrt. >> Gestalte ich den Task blockierend, findet natürlich keine Kommunikation >> in der Zeit statt. > OK, also CAN-Kommunikation in eigener Task. Auch OK. Aber dann CAN mit > höherer Priorität und die Berechnung nicht blockierend. Sorry, das war nur eine Überlegung. Momentan gibt es noch keine "echten" preemptive Tasks. Die Kommunikation findet (ausgenommen der 10 ms Broadcast) ebenfalls im Main Loop statt. >> Im Moment kann die Berechnung an zwei sinnvollen Punkten unterbrochen >> werden (FSM) und das Programm springt zurück zur Hauptschleife. > ???? Task oder SPS-Loop? siehe oben :) Ich habe in Gedanken dann angefangen, ein Rtos einzusetzen... >> Dafür könnte der Kommunikationstask bei entsprechend häufigem >> Aufrufen bei höherer Priorität als der Berechnungstask ebenjenen >> komplett blockieren. > > Nein, wieso? Sie kann sich doch beliebig lange Schlafen legen, wenn sie > z.B. 50% der letzten 50ms verbraucht hat. Oder sich mit der Berechnung > Synchronisieren. Der genaue Ablauf hängt davon ab, wann genau die > Berechnung starten muss und wie lange sie dann brauchen darf. Z.B. > im 50ms-Takt starten und innerhalb der nächsten 50ms fertig? Oder > maximal 50ms zwischen 2 Ergebnissen (das ist ein Unterschied (!sic)). Die Berechnung und die Ausgabe müssen nicht synchronisiert werden. Die Berechnung startet, sobald die dafür benötigten Sensorwerte gefiltert und dezimiert wurden (alle 100 ms, somit ist theoretisch für alle Berechnungen mehr als genug Zeit). Es ist keine harte Echtzeit gefordert, insofern muss ich das "MUSS nach 50 ms fertig sein" etwas revidieren, sorry. Aber es darf sich halt nicht aufschaukeln, sodass die Latenz immer größer wird. Und es wäre schön, wenn die Deadline eingehalten würde. Vielen Dank noch für deine 2. Antwort Achim, da stehen ein paar gute Ideen drin, die ich mir zu Gemüte führen werde. ui schrieb: > Die Angaben sind doch etwas verwirrend, wie an den Reaktionen hier auch > ablesbar ist. > Ja, merke ich auch. Tut mir Leid. > Die Frage hängt ja von deinem Anwendungsfall ab, und da hast du noch zu > wenig geschildert: > 1) Die Berechnung muss nach 50ms abgeschlossen sein. Harte > Echtzeitbedinung? Was machst du mit dem Ergebnis? Rausschreiben? Und > startet unmittelbar dannach die nächste Berechnungsrunde? Wie wird die > Berechnung getriggert, wenn sie nicht dauerhaft läuft? > Sie wird nach Beendigung der Sensordaten-Verarbeitung getriggert. Das Ergebnis wird rausgeschrieben. Es ist keine harte Echtzeit, die Verzögerungen dürfen sich aber nicht akkumulieren. > 2) Was heißt "soll nicht 20ms nichts tun" bzgl. der Kommunikation? Sind > die Daten, die du versenden/empfangen willst, für die Berechnung > wichtig? Oder sind das "ganz" andere Daten (Heartbeat etc.). Warum ist > es wichtig, dass die Kommunikation nicht einfach 20ms schläft? Was hast > du davon für einen Vorteil, wenn sie z.B. nach 5ms sendet, dafür aber > nur einen Teil ihrer Nachrichten? Nein, die sind nicht für die Berechnung wichtig. Es handelt sich um interne Daten zu Debug/Visualisierungszwecke, die am PC dargestellt werden. > > Und dann solltest du dir auch noch über andere Dinge Gedanken machen, > die durchaus vorkommen: > - Was soll passieren wenn die Berechnung länger als 20ms oder noch > schlimmer länger als 50ms dauert? Wenn du einen Programmierfehler drin > hast, der auf einmal aus irgendeinem Grund verzögert? Was passiert dann? Es sollte geloggt werden und auch kommuniziert. Dafür gibt es bereits ein Status Byte. Aber ich habe mir noch gar nicht überlegt, wie ich ein eventuelles Verpassen überhaupt detektiere. Der Cyclecounter ist da sinnvoll, oder? > Erklär erst mal genau was du willst und was du brauchst. Auch mit > Prioritäten. Oftmals sind einfache Lösungen die besten, weil schwierige > Lösungen oft (eigentlich nicht benötigte) Komplexität mit reinbringt. Ich merke gerade selber, dass das eigentliche Problem woanders liegt. Es ist im Grunde nicht die lange Berechnung, sondern der Fakt, dass ich die Kommunikation robuster gestalten muss. Peter schrieb: > Hallo Jan, > falls dein gewähltes RTOS Time Sliceing beherscht (wie z.B. FreeRTOS) > kannst du beiden Task(Kommunikation und KF) die selbe Priorität > zuteilen. Dann sollte dein Rechentask mindestens 50% der Rechenzeit > abbekommen. Ob das jetzt schönes Design ist kann ich nicht sagen. > Wahrscheinlich wäre ein Buffern der Information via DMA und ein > garantiertes zügiges abarbeiten oder falls dies nicht möglich ist das > Auslösen eines Fehlerzustands die bessere Lösung. Weil bei hoher > Kommunikationslast bleibt ja je nach dem trotzdem nicht genug Zeit um > alle Nachrichten zu beantworten. Sprich du verlagerst das Problem zur > Kommunikationsseite. > Gruß > Peter Hi Peter, ja tut es. Heißt da Round-Robin Scheduling und teilt zur Ausführung bereite Tasks in gleiche "slices" ein. Wenn nicht alle Nachrichten beantwortet werden können ist das weniger schlimm als eine verpasste Berechnung. Ist das unschönes Design? Achim S. schrieb: > Peter D. schrieb: >> Den CAN betreibe ich mit 500kBit > Wenn möglich, ist das wirklich die beste Maßnahme gegen Spam: Die > Baudrate so klein, dass selbst Back-To-Back-Telegramme genügend > Rechenzeit für den Rest lassen. Nur ggf. darauf achten, dass die > Fehlerbehandlung eines Zeichens oder eines Telegramms nicht länger > dauert als die Normale Behandlung. Also z.b. Pause einlegen und auf > sauberen Neustart achten. Da muss ich mal rechnen, wie viel Zeit im schlimmsten Fall übrig bleibt. Peter D. schrieb: > Jan K. schrieb: >> Wie schafft ihr es, bei "Spam" >> über eine Kommunikationsschnittstelle noch handlungsfähig zu bleiben? > > Ich mache das immer nach dem Ping-Pong Prinzip. Master sendet Kommando, > Slave antwortet. > Außerdem habe ich eine FIFO, d.h. der Master kann 8 Pakete > hintereinander senden. Ist die FIFO voll, werden weitere Pakete > verworfen und ein Fehlerbit gesetzt. > Es gibt hier auch einen Ausgangs-FIFO. Ist allerdings etwas kleiner als bei dir. Ping Pong machen wir ja. > Den CAN betreibe ich mit 500kBit, d.h. die Nutzdatenrate ist maximal > 250kBit, das schafft selbst der AT90CAN128 bei 16MHz locker. > Ok.. > Die Auswertung erfolgt im Main. Ist das Main durch andere Tasks lange > beschäftigt, könnte man dafür auch einen Softwareinterrupt niedriger > Priorität verwenden. > Software Interrupt ist auch eine interessante Idee, z.B. der SVC Handler oder so? Guest schrieb: > Hallo Jan, > > für welches RTOS hast du dich denn entschieden? Wir haben ähnliche > Anforderungen und arbeiten mit SEGGER embOS. Der Vorteil ist das die > Jungs sich mit solchen Sachen extrem gut auskennen und das quasi mit zum > Service gehört einem bei so etwas zu beraten. Vielleicht einfach mal bei > denen melden? Hat bei mir super geklappt. Vor allem kann man sich das > dann alles mit SystemView grafisch anzeigen lassen und einfach > überprüfen, ob alles so läuft, wie man es sich vorgestellt hat: > https://www.segger.com/systemview.html > Ich hatte da auch zuerst falsche Vorstellungen und musste lernen das ein > RTOS nicht dafür sorgen kann die CPU zu mehr als 100% auszulasten. Aber > es hilft einem unwahrscheinlich die Arbeit in mehrere Tasks aufzuteilen > und alle Timings einzuhalten. Den Ansatz mit der klassischen Betrachtung > der Echtzeitfähigkeit in einer Tabelle ist schon der richtige. Man muss > sich halt entscheiden was für einen die höchste Echtzeitanforderung > haben soll. Heho, für noch gar keines. Eine Überlegung ist, CMSIS-RTOS oder CMSIS-RTOS++ einzusetzen, um unabhängiger von der konkreten Implementation zu werden, aber zurzeit wird noch keines eingesetzt. Dass ein RTOS nicht zaubern kann und mehr als 100 % rauskitzeln kann ist mir komplett klar. Es ist ja eher eine Timing Geschichte. Danke für eure Antworten! Ich muss nochmal über einiges nachdenken und melde mich dann nochmal :) Schöne Grüße, Jan
CMSIS-RTOS ist kein RTOS sondern nur ein Abstraktionslayer. Tu dir das aber bitte nicht an. Das Ding ist reiner Marketingkram von ARM und technisch total sinnfrei. Wenn man wöchentlich sein RTOS wechselt macht man eh was falsch ;-).
Peter D. schrieb: > > An ein RTOS habe ich mich bisher nicht getraut. Dadurch, daß dann die > Tasks in nicht vorhersehbaren Zeitscheiben und nicht vorhersehbarer > Reihenfolge ausgeführt werden, ist die Datenkonsistenz sehr schwierig zu > garantieren. > Ich mag lieber die volle Kontrolle über den Ablauf, sowie die > Unmöglichkeit von Deadlocks. Ich kann die Position verstehen, aber die Vorteile dauern nur eine gewisse Zeit. Solange die Aufgabenstellung relativ klein und übersichtlich ist, reicht eine Message Pump in main() als "handgestricktes OS" (mehr oder weniger als das ist es eigentlich nicht) aus, aber sobald neue features oder Anforderungen dazu kommen, wird das Ganze schnell zu einem unleserlichen und unwartbaren Moloch. Du kannst fast Alle RTOS auch als nicht preemptiv konfigurieren, dann gibt es keine Zeitscheiben, aber trotzdem Prioritätssteuerung (d.h. tasks höhrerer Priorität leeren tasks niedrigerer Priorität, aber tasks gleicher Priorität müssen sich explizit die CPU abgeben). Ich schildere den Umstieg auf ein RTOS beispielhaft in Kapitel 3 von (jaja, schon gut). Bei einem meiner Kunden (Zk Bereich) war die main message pump für einen Leser, der "nichts Anderes" machen muss als Karten zu lesen, die Werte zum Zk Terminal zu kommunizieren und im Gegenzug LEDs leuchten zu lassen, schon nach der ersten Anforderung komplett überfordert. Bei der nächsten Version haben wir dann ein RTOS benutzt (Konfiguration: 256 k internes Flash und 32 K internes RAM and that's it), und es funktioniert prima.
Peter D. schrieb: > Ich mag lieber die volle Kontrolle über den Ablauf, sowie die > Unmöglichkeit von Deadlocks. Gibt es nicht. Das würde implizieren du - machst keine Programmierfehler - hast nie auch nur irgendeinen Designfehler (absichtlich/unabsichtlich) Und jeder weiß, dass beides (oder auch nur eines davon) nicht funktioniert, zumindest nicht in Projekten/Programmen die über UART rein, rechne A+B, UART raus hinausgehen.
Guest schrieb: > CMSIS-RTOS ist kein RTOS sondern nur ein Abstraktionslayer. Tu dir das > aber bitte nicht an. Das Ding ist reiner Marketingkram von ARM und > technisch total sinnfrei. Wenn man wöchentlich sein RTOS wechselt macht > man eh was falsch ;-). Ich arbeite seit Jahren mit CMSIS-RTOS. Und bin sehr zufrieden damit. Für einfache Sachen, wo es nur darum geht, ein paar Sensoren einzuselesen und Berechnungen durchzuführen, setze ich ganz gerne Protothreads ein. http://dunkels.com/adam/pt Die Anforderungen des TO waeren aus meiner Sicht für Protothreads geeignet.
Peter D. schrieb: > Ich mag lieber die volle Kontrolle über den Ablauf, sowie die > Unmöglichkeit von Deadlocks. Hallo, also Deadlocks entstehen, wenn 2 Prozesse gegenseitig Ressourcen blockieren. Das setzt voraus, dass diese dynamisch angefordert werden. Das macht man in diesem Fall aber nicht, man fordert sie stattdessen statisch beim Programmstart (Speicher) an bzw. sie sind implizit fest zugeordnet (Ports oder andere Hardware). Blockaden durch Warten auf Ereignisse die nie eintreten sind keine Deadlocks und können auch ohne RTOS entstehen. Ich erinnere mich da an meinen UART per Interrupt, bei dem unter gewissen Umständen der Interrupt ausblieb. So was ist ein einfacher BUG (edit: obwohl es nicht einfach zu debuggen war). Was die Übersichtlichkeit anbelangt ist eine RTOS-Implementierung meist enger am Problem programmiert und damit besser zu Warten. Gruß, Michael
Michael A. schrieb: > also Deadlocks entstehen, wenn 2 Prozesse gegenseitig Ressourcen > blockieren. Das setzt voraus, dass diese dynamisch angefordert werden. Nö, dynamisch ist da nichts. Ich programmiere vorwiegend Steuerungen, wo viele Tasks untereinander kommunizieren müssen. Dazu habe ich einen globalen Datensatz. Als Main-Loop kein Problem, jede Task liest Daten, verarbeitet sie und schreibt die Änderungen zurück. Beim RTOS müßte aber jede Task die Daten für alle anderen sperren, damit ihr nicht die Daten unterm Hintern weggeändert werden oder halb neue, halb alte Daten drin stehen. Da ist ein Deadlock quasi unvermeidlich. Für die Steuerung ist es wichtig, daß alle Daten in einer definierten Reihenfolge und immer vollständig abgearbeitet werden. Z.B. wäre es blöd, wenn erst die Ausgabetask die Daten ausgibt, dann die Verarbeitungstask rankommt und dann die Eingabetask. Damit würde ich unnötig Zeit verlieren bzw. schlimmer noch, die Regelung hätte kein definiertes Zeitverhalten. Ein RTOS ist dann schön, wenn die Tasks weitgehend unabhängig voneinander ihr Ding machen können. P.S.: Es kann natürlich sein, daß es bessere Konzepte für eine Steuerung gibt, als ich es verwende. Nur kenne ich (noch) keins.
Peter D. schrieb: > Ein RTOS ist dann schön, wenn die Tasks weitgehend unabhängig > voneinander ihr Ding machen können. Jain, ich denke deine Steuerungen sind ein Sonderfall in dem es ohne RTOS einfacher funktioniert aber in deinem Beispiel ist es kein Problem mit Semaphoren den gegenseitigen Zugriff zu verhindern. Vernünftige RTOS haben dann auch Methoden implementiert um solche Deadlocks zu vermeiden (Priority inheritance, Priority ceiling protocol). Ich hatte mir das mal bei verschiedenen RTOS angeschaut und es scheint das embOS bis jetzt das einzige RTOS ist das Priority inheritance komplett implementiert hat (bei allen anderen gibt es tatsächlich Fälle, in denen es zu Problemen kommen kann). Demnach sollte man natürlich schon schauen welches RTOS man benutzt.
Peter D. schrieb: > Beim RTOS müßte aber jede Task die Daten für alle anderen sperren, damit > ihr nicht die Daten unterm Hintern weggeändert werden oder halb neue, > halb alte Daten drin stehen. Da ist ein Deadlock quasi unvermeidlich. > Naja, so stimmt es natürlich nicht. Ein deadlock setzt immer ein zirkuläres Warten mindestens zweier tasks auf mindestens zwei Synchronisationsressourcen voraus. In deinem Fall würde eine Mutexvariable zum "globalen" Sperren des kritischen Datensatzes ausreichen, und bei einem Mutex kann es keinen deadlock geben. Aber deine Argumentation ist natüclich nicht ganz falsch; man hat nichts von einem RTOS, wenn am Ende des Tages der gesamte Kontrollfluß doch wieder durchserialisiert wird, dann hat man im Gegenteil noch die penalty durch den Kontext Switch Overhead. > Ein RTOS ist dann schön, wenn die Tasks weitgehend unabhängig > voneinander ihr Ding machen können. > Auch das stimmt, aber bei genauer Analyse gibt es wenig Fälle, in denen der Kontrollfluss streng serialisiert sein muss; meistens ist die Abfolge im Kopf strikter als sie sein muss, und man erkennt beim drüber nachdenken Dinge, die auch nebenläufig sein können.
Tom schrieb: > Peter D. schrieb: >> Ein RTOS ist dann schön, wenn die Tasks weitgehend unabhängig >> voneinander ihr Ding machen können. > > Jain, ich denke deine Steuerungen sind ein Sonderfall in dem es ohne > RTOS einfacher funktioniert aber in deinem Beispiel ist es kein Problem > mit Semaphoren den gegenseitigen Zugriff zu verhindern. Vernünftige RTOS > haben dann auch Methoden implementiert um solche Deadlocks zu vermeiden > (Priority inheritance, Priority ceiling protocol). > Ich hatte mir das mal bei verschiedenen RTOS angeschaut und es scheint > das embOS bis jetzt das einzige RTOS ist das Priority inheritance > komplett implementiert hat (bei allen anderen gibt es tatsächlich Fälle, > in denen es zu Problemen kommen kann). Demnach sollte man natürlich > schon schauen welches RTOS man benutzt. Nein, FreeRTOS macht bei Mutexen auch priority inheritance, aber kein PCP. Es ist übrigens ein sehr gängiger Fehler, Mutexe und Semaphoren durcheinanderzumischen. Das sind zwei sehr verschiedene Konzepte, und in 90% der Fälle, wo Jemand Semaphore sagt/schreibt sind eigentlich Mutexe gemeint.
Ruediger A. schrieb: > Nein, FreeRTOS macht bei Mutexen auch priority inheritance, aber kein > PCP. Ja, aber nicht vollständig. Das Problem taucht dann auf wenn man mehrere Tasks hat mit mehreren Mutexen. Zwei Tasks und eine Mutex funktioniert bei den meisten noch problemlos aber man kann sich auch komplizierte Fälle ausdenken und da funktioniert es z.B. bei FreeRTOS nicht mehr. Bei embOS ist das Konzept stark erweitert worden. Es geht letztlich um die Problematik zu wissen welche Priorität man man wann von wem erbt. > Es ist übrigens ein sehr gängiger Fehler, Mutexe und Semaphoren > durcheinanderzumischen. Das sind zwei sehr verschiedene Konzepte, und in > 90% der Fälle, wo Jemand Semaphore sagt/schreibt sind eigentlich Mutexe > gemeint. Jep, ich gehöre zu den 90% ;-), an der Stelle ist natürlich Mutex gemeint.
Tom schrieb: > > Ja, aber nicht vollständig. Das Problem taucht dann auf wenn man mehrere > Tasks hat mit mehreren Mutexen. Zwei Tasks und eine Mutex funktioniert > bei den meisten noch problemlos aber man kann sich auch komplizierte > Fälle ausdenken und da funktioniert es z.B. bei FreeRTOS nicht mehr. Bei > embOS ist das Konzept stark erweitert worden. Es geht letztlich um die > Problematik zu wissen welche Priorität man man wann von wem erbt. > als ich das zuerst gelesen habe, klang es so wie "Mein Vetter 3. Grades hat einen Klassenkameraden, dessen Schwiegermutter gelesen hat..." mAW etwas inkonkret. Da mich das Thema aber interessiert, habe ich etwas gespielt und rumcodiert und tatsächlich etwas gefunden, was in die Richtung geht: http://ruediger-asche.de/Blog Ist es das? Wenn ja, wie löst embOS das Problem? Danke!
Ruediger A. schrieb: > als ich das zuerst gelesen habe, klang es so wie "Mein Vetter 3. Grades > hat einen Klassenkameraden, dessen Schwiegermutter gelesen hat..." mAW > etwas inkonkret. lach ehrlich gesagt bin ich näher dran als du denkst ;-). Ruediger A. schrieb: > Ist es das? Wenn ja, wie löst embOS das Problem? Ich habe den Blog nicht gelesen aber embOS löst das Problem indem man sich Gedanken darum macht welche Priorität man wann von wem erbt. Details kann ich hier nicht nennen da Segger bestimmt nicht den Wettbewerb schlau machen möchte ;-).
Tom schrieb: > Ruediger A. schrieb: >> als ich das zuerst gelesen habe, klang es so wie "Mein Vetter 3. Grades >> hat einen Klassenkameraden, dessen Schwiegermutter gelesen hat..." mAW >> etwas inkonkret. > > lach ehrlich gesagt bin ich näher dran als du denkst ;-). > > Ruediger A. schrieb: >> Ist es das? Wenn ja, wie löst embOS das Problem? > > Ich habe den Blog nicht gelesen... Solltest Du aber, Du bist in dem blog entry dankend erwähnt ;-) Ich habe das Problem mal mit Richard Barry (Papa von FreeRTOS) diskutiert (der ist sehr offen für technische Diskussionen von allen Seiten und antwortet auch in der Regel sehr schnell und selbst). Bei FreeRTOS wird einfach weniger Information vorgehalten. Wenn eine Task X eine von Task Y besetzte Mutex versucht zu kriegen, ist mit der Mutex eine Rückwärtsreferenz auf Y verknüpft, was es FreeRTOS erlaubt, die Priorität von Y temporär entsprechend anzupassen, und zwar in Abhängigkeit von der Priorität von X (das ist "1st level priority inheritance"). Soweit so gut, aber spannend wird es, wenn X selber nun später das Objekt von Priority Inheritance wird. D.h. eine Task Z würde über denselben Mechanismus die Priorität von X umsetzen - in dem Moment weiss FreeRTOS zwar die momentane Priorität von X, aber es fehlt die Rückwärtsverkettung zu Y, mit der umgekehrt Y nun die Priorität von Z erben könnte ("2nd level priority inheritance"). Da zwar eine Mutex unter FreeRTOS mit ihrem momentanen Halter assoziiert ist, aber umgekehrt eine Task keine Informationen darüber vorhält, welche Mutexes sie gerade hält, fehlt die Information, die wir brauchen würden, um PI durchgehend implementieren zu können. Eine saubere Lösung würde erfordern, dass eben eine solche Rückwärtsverfolgungskette aufgebaut würde. Das wäre vermutlich auch der Schlüssel zu einer Deadlockerkennung (die dann aber ja wieder nur aus Mutexbenutzung resultierende deadlocks erkennen könnte und wie weiter oben beschrieben auch sonst nur beschränkten Wert hätte). So eine Rückwärtsverkettung ist bereits mehrmals an Richard herangetragen worden, aber aus verschiedenen Gründen bislang nicht realisiert. Ich vermute aber auch, dass so eine mehrstufige PI Potential für Nachfolgeprobleme beinhaltet, z.B. würde bei einer zweistufigen Anhebung der Priorität von Y die erste Stufe komplett verloren gehen, d.h. die Priorität Y wird grundsätzlich niemals auf die (zwischendurch gültige) Priorität von X zurückfallen, sondern immer auf ihre Basispriorität, was in manchen Szenarien zu unerwartetem Verhalten führen könnte (darüber muss ich nochmal nachdenken und das in den Blog nachtragen). In jedem Fall Danke nochmal für den Input!
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.