..das natürlich nie wie gewünscht funktioniert.
Hallo zusammen,
Wegen der Uni brauche ich eine Einführung in Echtzeitssysteme und
Arduino.
Im Internet bin ich auf diesen Port des FreeRTOS
http://code.google.com/p/rtoslibs/ der sehr vielversprenchend ist und
daher ich damit anfangen wollte.
Angenommen, dass ich erst jetzt mit Echtzeitprogrammierung angefangen
habe, habe ich mich die Examples in der Bibliothek angeschaut und das
folgende Programm für Arduino 2009 geschrieben und hochgeladen habe
// Loop is the idle thread. The idle thread must not invoke any
68
// kernel primitive able to change its state to not runnable.
69
voidloop(){
70
// Not used.
71
}
Nun ich habe 2 Tasks erzeugt, damit die an den Pins 4 und 5 verbundenen
Led ein-ausgeschaltet werden können.
Die gewünschte Reihenfolge ist folgende:
redLed ON redLed OFF greenLed ON greenLed OFF
|-------------|--------------|----------------|-----------------------> t
t0 = 0 t1 = 200 ms t2 = 400 ms t2 = 600 ms
ABER, wenn ich das Programm kompilieren und hochladen lasse, dass werden
alle 2 Led gleichzeitig ein- und ausgeschlatet.
Also....ich hatte mir gedacht, dass da die 2 Tasks zwei verschiedene
Prioritäten haben. Infolgedessen wird zuerst die Task mit prio 1
ausgeführt und dann die Task mit prio 2. Hingegen passiert alles
gleichzeitig.
Wie soll ich das Programm ändern? Wo steckt der Fehler?
Danke und Gruß!!!
vTaskDelay() gibt die CPU anderen Prozessen anstelle die Zeit in einer
Endlosschleife zu verbraten. Zum Vergleich kannst du die Funktion ja mal
durch das Arduino delay() ersetzen.
Im FreeRTOS Manual ist das Verhalten in den ersten Kapiteln auch sehr
gut beschrieben.
Naja, ich dachte mir, dass der Sinn eines RTOS darin bestand, ein
Programm in verschiedenen Tasks aufzuteilen und ausführen lassen. Aus
der Webseite ist hier zB eine kurze Einführung zu ersehen:
http://www.freertos.org/implementation/TaskExecution.gif
und anscheinend ähnelt mein Program dem ersten Graf oben, währenddessen
das Verhalten in dem zweiten Graf gewünscht ist. Ich verstehe nicht, wie
ich die 3 Tasks miteinander koordinieren kann.
ich werde mir nun das Manual besorgen. Leider gibt es nicht so viele
info im Internet, sondern muss man das Buch kaufen.
Danke!
Task1 startet und schaltet die rote LED an und wartet dann. Wenn Task1
anfängt zu warten kommt die nächste Task dran, also Task2 und schaltet
die grüne LED an. Das passiert mit nicht sichtbarem Zeitversatz, einigen
mikrosekunden. Wenn die grüne LED versetzt blinken soll müsstest du vor
die while Schleife in Task2 noch ein vTaskDelay setzen.
Wenn die Task voneinander abhängig laufen sollen dann sieh dir das
Kapitel mit den Semaphoren an. Damit kann man eine Task anhalten bis sie
durch ein Ereignis einer anderen wieder freigegeben wird.
Danke Jojo!!
Ich habe seit Stunden versucht, mit einer Semaphore das Programm
umzuschreiben. Dennoch läuft es gar nicht. Die Led werden ein- und
ausgeschaltet @ random.
Hier der Code:
// Loop is the idle thread. The idle thread must not invoke any
83
// kernel primitive able to change its state to not runnable.
84
voidloop(){
85
// Not used.
86
}
Vielleicht verwende ich die Semaphore nicht richtig (meine Vermutung),
aber Tutorial im Internet sind echt schwer zu finden und die meisten
sind für mich unverständnis.
Bezüglich der Erklärung des ersten Problems, habe ich verstanden, wieso
die Led fast gleichzeitig leuchteten. Nun verstehe was du mit delay()
von Arduino meintest. Danke!!!
Hallo Dave,
da ich mich nicht mit FreeRTOS auskenne: Wie aufwendig ist es, das
System für Arduino in Betrieb zu nehmen? Muss man viel Zeit investieren,
bis es mal grundsätzlich kompiliert?
Gruß,
chris
Hi chris
Ich bin auch in der gleichen Situation und daher sage ich dir, dass das
Ganze im Betrieb zu bringen nicht so schwierig ist. Ich konnte die
ersten 2 Led mit Arduino 2009 innerhalb ein paar Stunden blinken lassen.
Was schwierig ist, ist in Echtzeitsysteme umzudenken.
Semaphore, Mutex und so weiter benötigen richtig Zeit um RTOS zu lernen.
Ich habe mit diesen 2 FreeRTOS-like RTOSs angefangen:
http://code.google.com/p/rtoslibs/ (meine Empfehlung +++++)
https://bitbucket.org/ctank/ardos/wiki/Home (meine Empfehlung ++++)
Mit dem zweiten habe ich Probleme beim kompilieren aber hat den Vorteil,
dass die Beispiele einfacher zu verstehen sind.
Im Internet habe ich nichts viel gefunden. Was ich ich fand, war
andereseits unverständlich.
Ich würde mich aber drüber freuen, wenn wir hier unsere Erfarhungen
austauschen würden.
gruß
>Ich habe seit Stunden versucht, mit einer Semaphore das Programm>umzuschreiben. Dennoch läuft es gar nicht.
Kein Wunder, du fragst ja gar nicht ab ob du die
Semaphore bekommen hast oder nicht und schaltest trotzdem
munter weiter die LEDs.
holger schrieb:>>Ich habe seit Stunden versucht, mit einer Semaphore das Programm>>umzuschreiben. Dennoch läuft es gar nicht.>> Kein Wunder, du fragst ja gar nicht ab ob du die> Semaphore bekommen hast oder nicht und schaltest trotzdem> munter weiter die LEDs.
Ich meinte damit, dass die Led nicht nach der gewünschten Reihenfolge
schalten. Das liegt bestimmt an der Semaphore. Ich kann noch nicht deren
Funktion in einem Programm implementieren. Das Programm hingegen lässt
sich kompilieren.
>Ich meinte damit, dass die Led nicht nach der gewünschten Reihenfolge>schalten. Das liegt bestimmt an der Semaphore.
Ich denke eher das das an deinen unterschiedlichen
Task Prioritäten liegt. Wer sagt denn das wenn Task2
fertig mit einmal blinken ist dann auch sofort Task1
drankommt? Task2 hat höhere Priorität und kann durchaus
auch zweimal nacheinander aufgerufen werden.
Was passiert wenn du beiden Tasks gleiche Priorität gibst?
>Was passiert wenn du beiden Tasks gleiche Priorität gibst?
Wird auch nichts breingen wenn man mal weiter nachdenkt.
Es ist ja nicht sicher das der Task sich die Semaphore
gleich wieder schnappt.
Nach dem xSemaphoreGive(); könnte ein taskYield();
klappen. Damit gibst du dem zweiten Task die Chance
die Semaphore zu schnappen.
Aber Semaphore geht bei dir ja noch nicht.
Mal abgesehen davon hast du da EINE Aufgabe in zwei Tasks
gepackt. Das ist irgendwie nicht so sinnvoll.
Wie man Probleme mit HiTec löst, die man ohne sie nie hätte ;-)
Der OP muss glaub ich noch ein wenig das Grundkonzept von
Multitasking verstehen, einfach nur hippes Arduino + RTOS reicht bei
weitem nicht.
Das Programm ist kein gutes Beispiel für Semaphoren. Dafür nimmt man
Message Queues.
1
Task A:
2
- Warten auf Nachricht
3
- Blinken
4
- Nachricht an B
5
6
Task B:
7
- Warten auf Nachricht
8
- Blinken
9
- Nachricht an A
Hier gibt es am Anfang ein Henne/Ei Problem weil beide Tasks warten.
Das kann man lösen in dem eine Task sofort eine Nachricht schickt und
dann wartet oder daß in einer Task initial eine Nachricht verschickt
wird.
Diese Tests mit LEDs halte ich aber für fragwürdig da ein reelles
Programm doch etwas anders gestrickt ist. Hier wird im Grunde genommen
ein typisches Mainloop Design auf ein RTOS abgebildet. Ohne Vorteil aber
mit allen Problemen die ein RTOS machen kann. Kein Wunder daß sich RTOS
Verweigerer ins Fäustchen lachen.
Klar, irgendwie muß man anfangen aber das Ziel sollte man halt nicht aus
den Augen verlieren.
Ok danke an Stefan und Holger.
Nur ist es mir klar geworden, dass das Beispiel mit den Leds eher
Probleme erzeugt als was zu klären. Nun lerne ich FreeRTOS direkt aus
dessen Manual.
Die Idee mit den Nachrichten ist gut. Nun habe ich verstanden wie ich
meine programme umschreiben soll.
Wie gesagt, ich muss wegen der Uni ein RTOS lernen und die ersten
Programme habe ich immer mit Leds angefangen.
Der
1
configTICK_RATE_HZ
ist anscheinend ein Port für AVR und ARM.
Wenn ihr bessere Beispiele um FreeRTOS habt, bitte Bescheid geben!!!!
Danke