Hallo, ich möchte mich in das Echtzeitbetriebssystem freertos einarbeiten. Weiss jemand wie der "kooperativer Betrieb" in freertos funktioniert. Gibt es dazu eine Beispielapplikation?
user0815 schrieb:
> Weiss jemand wie der "kooperativer Betrieb" in freertos funktioniert.
Hallo,
kooperativ allgemein (Windows 16): die Applikationen müssen nach jeweils
kurzer Laufzeit an das Betriebssystem zurückgeben (dazu genügt auch ein
Aufruf einer Systemfunktion). Tut die Applikation das aber nicht, wird
sie NICHT vom BS zwangsweise abgebrochen, d.h. sie kann das ganze System
beliebig lange blockieren.
Gruss Reinhard
bin kein freertos Experte, aber wie es in folgendem Link steht, stelle ich es mir so vor ... http://www.freertos.org/tutorial/solution4.html ... dass der Sceduler beide Task-Arten kennt und aufrufen kann: - preemptiv - kooperativ Die preemptiven werden nach Pio und vielen weiteren Flags deterministisch aufgerufen, dabei wird Stackpointer, Akku und alles weitere im Taskswitch wieder hergestellt. Die jeweilige Task "denkt" der Speicher/Prozessor "gehört" ihr allein und muss keine Ressourcen teilen. Das OS lässt die Tasks in diesem glauben und unterbricht sich an irgend einer Stelle, wenn der SysTick-Timer den Sceduler wieder aktiviert hat. Die Kooperativen Tasks werden laut der Quelle nur bei bedarf vom jeweiligen Applikations-Code aufgerufen. Damit verhalten sie sich, wie eine Unterfunktion, die auch statische Variablen enthalten kann. Kooperativ sind sie deswegen, weil sie die Kontrolle (Program-Counter) durch ihr return wieder freiwillig an die aufrufende Stelle abgeben (sollten). Wie in der Quelle aber schon genannt, geht dabei die zeitliche Vorhersagbarkeit verloren. Gruß, Kay
Erstmal vielen Dank für eure Unterstützung. Den kooperativen Betrieb kann ich den bei freertos mittels den Co-routines realisieren? Auf der Wiki Seite hab ich gelesen das freertos keine Eventfunktionalität besitzt. Wie kann ich sowas mit freertos realisieren?
Kann meinen kooperativen Betrieb etwa so realisieren?
1 | // Co-routine to be created.
|
2 | void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) |
3 | {
|
4 | // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
5 | // This may not be necessary for const variables.
|
6 | static const char cLedToFlash[ 2 ] = { 5, 6 }; |
7 | static const portTickType xTimeToDelay[ 2 ] = { 200, 400 }; |
8 | |
9 | // Must start every co-routine with a call to crSTART();
|
10 | crSTART( xHandle ); |
11 | |
12 | for( ;; ) |
13 | {
|
14 | // This co-routine just delays for a fixed period, then toggles
|
15 | // an LED. Two co-routines are created using this function, so
|
16 | // the uxIndex parameter is used to tell the co-routine which
|
17 | // LED to flash and how long to delay. This assumes xQueue has
|
18 | // already been created.
|
19 | vParTestToggleLED( cLedToFlash[ uxIndex ] ); |
20 | crDELAY( xHandle, uxFlashRates[ uxIndex ] ); |
21 | }
|
22 | |
23 | // Must end every co-routine with a call to crEND();
|
24 | crEND(); |
25 | }
|
26 | |
27 | // Function that creates two co-routines.
|
28 | void vOtherFunction( void ) |
29 | {
|
30 | unsigned char ucParameterToPass; |
31 | xTaskHandle xHandle; |
32 | |
33 | // Create two co-routines at priority 0. The first is given index 0
|
34 | // so (from the code above) toggles LED 5 every 200 ticks. The second
|
35 | // is given index 1 so toggles LED 6 every 400 ticks.
|
36 | for( uxIndex = 0; uxIndex < 2; uxIndex++ ) |
37 | {
|
38 | xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex ); |
39 | }
|
40 | }
|
@ user0815 (Gast) >Kann meinen kooperativen Betrieb etwa so realisieren? Nö. Kooperativ heißt, dass deine Funktion/Task beim Aufruf einmal zügig durchlaufen wird, etwas Artbeit verrichtet und danach GARANTIERT wieder verlassen wird. Denn die anderen Aufgaben wollen ja auch beackert werden. Eine Endlosschleife ist dazu denkbar ungeeignet, vor allem ohne break. Siehe Multitasking, die II. Was du da oben skizziert hast ist das Gegenteil, nämlich päemtiv. MfG Falk
Danke für deine Erklärung. Ja wie funktioniert bei freertos der kooperative Betrieb? Gibt es dazu auch ein Beispiel?
Hallo, ich hab gerade kein Code zur Hand, aber wenn ich mich recht erinnere wird bei FreeRtos auch beim kooperativem Betrieb eine Endlosschleife erwartet (bei FreeRtos wird niemals ein Task beendet). Der Rücksprung zum Betriebssystem und damit zu anderen Tasks erfolgt durch einen Befehl an einer entsprechenden Stelle (dies kann eine Wartezeit sein oder die generelle Abgabe des Tasks, Genaue Befehle kenne ich nicht mehr aus dem Kopf und hab die Doku gerade nicht zur Hand).
Der kooperative Betrieb ist generell, dh nicht bezugnehmend auf ein RTOS, immer eine schnelle Sequenz von Befehlen die jeweils auf einen blockierenden Event/Wait warten. Dh sie warten immer auf eine Semaphore oder was Abgeleitetem, dh Event, Message, Mailbox, usw. Schnelle Squenz deshalb, weil sonst das System auf den langsamsten wartet. Wenn also ein Task die Floatingpoint Matritzen abspult, sollte dieser Task hin und wieder auf ein nichtblockierendes wait() durchlaufen. Ein nichtblockierendes Wait() ist eigentlich ein Polling, das der tiefst priorisierte Task machen darf um dem System Zeit fuer irgendwas zu geben.
Auf der http://www.freertos.org/ konnte ich nichts konkretes dazu finden, wie man so einen kooperativen Betrieb realisieren kann. Weiterhin ist mir auch noch ein Rätsel, wie man in feeertos Events erzeugen bzw. darauf reagieren kann. Laut wiki Seite kann der keine Events erzeugen.
Wenn ich das Zeitscheibenverfahren (round robin scheduling) einsetzen möchte, muss ich dann allen Tasks die gleiche Priorität vergeben? Beispiel: drei Tasks mit der Priorität: Nr.: 1
Hi! Bzgl. der Events: Du kannst ja die BinarySemaphore dazu benutzen. Oder was meinst du genau mit Events? Mit den Semaphoren kann du ja solange in einem Task warten bis diese (von einem anderen Task) gesetzt/signalisiert wird. Lg
Bzgl Round Robin: kA wie das in FreeRTOS implementiert ist, würde aber sagen, dass wenn alle Task die selbe Prio haben das ganze nach dem Round Robin Scheduling funktioniert (wie den auch sonst). Wie und in welcher Reihenfolge die Task dann aktiviert werden musst im Code nachsehen (obs wirklich round robin ist).
Hallo FreeRtosAnswer, zum Thema Events: Ich möchte zum Beispiel in einer Task einen Event senden. In einer zweiten Task möchte ich dort auf diesen Event reagieren bzw. empfangen. Kann ich dies mit einer "BinarySemaphore" realisieren?
user0815 schrieb: > Hallo FreeRtosAnswer, > > zum Thema Events: > > Ich möchte zum Beispiel in einer Task einen Event senden. > In einer zweiten Task möchte ich dort auf diesen Event reagieren bzw. > empfangen. > > Kann ich dies mit einer "BinarySemaphore" realisieren? Wie du das dann nennst, ist egal. Du kannst es natürlich Event nennen. Der eine signalisiert etwas, der andere wartet auf die Signalisierung. Ich würde mal sagen, in anderen Betriebssystemen nennt man so etwas einen Event. Und der Mechanismus, mit dem ein Task einem anderen etwas mitteilt, ja das kann eine Semaphore sein. Alles in allem verraten deine Fragen, dass du im Moment zu große Bissen vom Kuchen abbeist. Du gehst zur Zeit anscheinend auf dein Ziel zu, ohne wenigstens ein bischen was über den Weg zu kennen. Mein Vorschlag: lerne FreeRTOS kennen, und zwar unvoreingenommen von deiner eigentlichen Aufgabenstellung. Programmier ein wenig. Übe ein wenig. Sieh dir an, welche Dinge es gibt, wie man sie benutzt. Und erst dann wendest du dich deinem eigentlichen Problem zu. Zuerst muss man seinen Werkzeugkasten kennen, ehe man sich daran macht damit etwas zu bauen.
Danke für den Rat. Ich werde mir freertos unabhängig von meiner Aufgabe erst etwas besser kennelernen. Vielleicht kaufe ich mir auch das eBook von http://www.ebookaktiv.de/eBook_RTOS/eBook_FreeRTOS.htm. Kennt jemand dieses eBook genauer?
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.