mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Erste Versuche mit FreeRTOS


Autor: Der Thomas (soundso)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,
ich versuche gerade mein erstes -simples- Programm mit FreeRTOS zu 
erstellen, in dem ein Task einen Port (Tasten-Drücke) ließt und ein 
anderer entsprechend einen anderen Port (mit LED's) schreibt. Ich nutze 
IAR Embedded Workbench 5.0 Kickstart mit J-Link (wo sich die FreeRTOS 
Beispiele nicht kompilieren lassen, da es alte Projektdateien sind) mit 
einem ST912FA und habe mir das meiste von einem FreeRTOS-Beispiel zum 
str9-dongle von st abgeschaut. Kompilieren läßt sich mein Programm nun, 
aber trotz positiver Rückmeldung von xTaskCreation laufen meine Tasks 
nach vTaskStartScheduler scheinbar nicht. Ich habe meine normalen 
Startup-Files, Konfigurationen und Projekteinstellungen genutzt, gibt es 
da irgendwas worauf man besonders achten muss? Ich weiß einfach nicht 
wieso es nicht klappt. Danke für jeden Tipp!
Thomas

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hilfe! Kennt sich den keiner ein wenig mit FreeRTOS aus? Sind ja 
wirklich nur Anfänger-Probleme...

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Typischer Fall von falsches Forum. Das was du suchst, sollte hier zu 
finden sein:

> http://sourceforge.net/forum/forum.php?forum_id=382005

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na ihr seit hier halt meine erste Anlaufstelle für alles ;-) Aber guter 
Tipp, danke!

Autor: Berti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du wohl endlosschleifen in deinen tasks?

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klar, der Code im Task ist in einer Endlosschleife. Hab mim Debuger 
geschaut und der Task-Code wird garnicht erst ausgeführt. Gibt es keine 
"Rahmenbedingungen" die ich vieleicht erfüllen muss, damit FreeRTOS 
läuft? Hab den Code auch ans erste Posting angehangen...

Autor: Jojo S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe mit dem RTOS auch noch nichts gemacht, aber was passiert in 
vTaskStartScheduler() ? Kommt das System daraus zurück oder wird die 
Kontrolle komplett an den Scheduler abgegeben?
Wenn das System in main() weiterläuft und danach in der Endlosschleife 
hänge wird eine Idle-Task nicht mehr drankommen, dann müsste man in der 
Idle Task ein Yield() oder sowas zum Freigeben der CPU Resource machen.

Autor: Jojo S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, habe in der Doku gesehen das der Scheduler nicht mehr zurück kommt 
wenn alles ok ist:
     // Will not get here unless a task calls vTaskEndScheduler ()

Aber vielleicht trotzdem mal kontrollieren (durch Ein/Ausschalten einer 
LED vor/nach  vTaskStartScheduler) ob nicht durch einen Fehler der 
Scheduler gar nicht erst startet.

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also es soll wohl so sein, das der Aufruf von vTaskScheduler() nicht 
zurückkehrt, wenn ich das richtig verstanden habe, und folgender Code in 
Main sollte nicht mehr ausgeführt werden. Dann läuft wohl der 
Scheduler-Prozess der entsprechend die Tasks abarbeitet. Ich hab so ein 
Bauchgefühl, das es an den Startup-Files liegt, da ich da meine 
"Originalen" und nicht die aus dem Beispielen verwendet habe, das ich 
damit Assembler-Fehler bekommen habe. Vieleicht muss man da was 
entsprechend Initialisieren, damit FR richtig tickt...

Autor: Berti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann da keinen Timer für den Sheduler sehen...

Autor: Jojo S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, zumindest müsste ja ein zyklischer Interrupt funktionieren. 
Vielleicht in der zugehörigen ISR mal einen Portpin toggeln lassen.

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin davon ausgegangen das der Timer vom FreeRTOS konfiguriert wird, 
da ich im Konfig. ja auch sage ob er Watchdog oder Timer2 verwenden 
soll... Ist das nicht so? Ich habe gerade mal geschaut und mein Programm 
kommt definitiv nicht aus vTaskStartSchedulder zurück.

Autor: Berti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, isr usw freigeben. ich kann in deinem Sourcecode im Anhang nix 
erkennen.

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab in meinem Projekt die 91x_init.s und 91x_vect.s als Startup 
verwendet, die bei EMWB 5 dabei waren, da sich die aus dem 
FreeRTOS-Packet mit Version 5 nicht assemblieren lassen. Aber es 
scheinen schon ein paar Anpassungen bezüglich des Exception-Handlers 
nötig zu sein, nur leider blicke ich da im Moment noch relativ ratlos 
rein, was genau ich da zutuen habe...

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also der erste Fehler war, das der Prozessor nicht im Supervisormode 
war, was sich durch das auskommentieren einer Zeile in91x_init.s ändern 
ließ. In 91x_vect.s habe ich ein "IMPORT vPortYieldProcessor" gemacht 
und SWI_Addr auf vPortYieldProcessor gesetzt. Aber beim SWI scheint 
wahrscheinlich irgendwo das Problem zu liegen, den nun läuft zwar der 
höherpriore Task, aber nur dieser. Es findet also kein Scheduling statt. 
Kennt sich jemand mit dem Kram aus?

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmal ein wenig rumgenerve am Montag, aber auch das Wochenende hat mir 
keine Lichtblicke beschert... Hat wirklich niemand eine Ahnung wieso 
mein Scheduler nicht schudult? Scheint also irgendwie kein 
Timer-Interrupt ausgelößt zu werden oder sowas, fragt sich nur wieso. 
Initialisiert werden müßte der ja durch FreeRTOS, oder? Danke für jeden 
Tipp!!!

Autor: Berti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kommst du in den Sheduler Code beim debuggen? falls du im Code bist 
jedoch nicht zwischen den tasks geswitched wird kann sein das: Die tasks 
falsch angelegt sind, du auf Cooperative und nicht auf Preemtive 
läufst...
Da hat immer der höherwertigste task Prior. bis er selbst die resourcen 
abgibt.

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man, ich dreh echt noch durch!!! Ich will doch nur ein GANZ einfaches 
FreeRTOS Programm für meine CPU und IAR... Nun hab ich sogar EMWB 4 
installiert um das Beispiel zu testen. Hab da alles behalten und nur 
main.c durch meine eigene ersetzt. Der Watchdog-IRQ-Handler wird auch 
regelmäßig ausgeführt und ruft wiederum vTaskSwitchContext() auf 
(configUSE_PREEMPTION ist 1), aber er behält immer noch den höchstpriore 
Task bei und wechselt nicht. Hillllllfeeeee!!!

---------------

Ich gehe in main.c hin und nach Peripherie-Conig mache ich:

xTaskHandle WriteTask, ReadTask;

xTaskCreate( vWriteTask, "WriteTask", configMINIMAL_STACK_SIZE, NULL, 
tskIDLE_PRORITY+4, %xWriteTask );
xTaskCreate( vReadTask, "ReadTask", configMINIMAL_STACK_SIZE, NULL, 
tskIDLE_PRORITY+2, %xReadTask );
vTaskStartScheduler();

Die Task sehen dann so aus:

void vWriteTask(void* pvParameters)
{
  for( ;; ) { GPIO_Write(GPIO6, u_port); // LEDs setzen }
}

void vReadTask(void* pvParameters)
{
  for( ;; ) { u_port = GPIO_Read(GPIO7); // Taster lesen }
}

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich beiden Tasks die selbe Prio. gebe, funktionert es plötzlich - 
auch wenn aus für mich noch unverständlichem Grund. Bei 
unterschiedlichen Prio's allerdings nicht. Muss ich da irgendwas anders 
machen?

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Prinzip eines preemptiven RTOS nicht verstanden?
Denk dran, das ist ein simpler Highest Priority Scheduler. Nix 
Kompliziertes, wo sich die Prioritäten dynamisch mit der Wartezeit 
ändern.

Im Klartext: In beiden Tasks hast Du Endlosschleifen, aber die Task 
werden nicht schlafen geschickt, darum läuft nur der mit der höheren 
Priorität die ganze Zeit.
Wenn beide Tasks die gleiche Priorität haben, werden sie von FreeRTOS 
RoundRobin behandelt, also der Reihe nach laufen gelassen.

Darum müssen höherpriore Tasks immer nur Aufgaben übernehmen, die 
irgendwann beendet sind.

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch, aber manche fangen mit der Thematik halt gerade erst an. Trotzdem 
Danke  für die Antwort, mitlerweile läuft es natürlich ordentlich!

Autor: Matthias Kölling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Seit wann macht man in Tasks überhaupt Endlosschleifen, ob preemptives 
oder nonpreemtives Betriebssystem? Für die Endlosschleife ist der 
Scheduler zuständig.

Gruß Matthias

Autor: Der Thomas (soundso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich mich nicht irre (ist ja nun schon etwas her), hab ich das mit 
der Endlosschleife aus einem FreeRTOS-Beispiel abgeschaut. Soll ein Task 
eine Aufgabe zyklisch wiederholen macht das meiner Meinung nach ja auch 
Sinn, damit der Task sich nicht beendet, oder? Wie bereits erwähnt muss 
er dann nur auch mal schlafen gehen, damit der das System nicht 
blockiert.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Soll ein Task eine Aufgabe zyklisch wiederholen macht das meiner
> Meinung nach ja auch Sinn, damit der Task sich nicht beendet, oder?

Ja. Der Task darf bei FreeRTOS gar nicht zurückkehren. Entweder muß er 
in einer Endlosschleife laufen oder nach getaner Arbeit mit vTaskDelete 
entfernt werden.

> Wie bereits erwähnt mussr dann nur auch mal schlafen gehen, damit der
> das System nicht blockiert.

Ja. Entweder er geht mit z.B. vTaskDelay schlafen, um z.B. zyklisch 
irgendetwas auszuführen, oder er blockiert z.B. auf eine Queue oder 
Semaphore, die ihn dann beim Eintreten irgendeines Ereignisses aufweckt.

Autor: Matthias Kölling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na da hätte ich mich ja voll auf den Arsch gesetzt. Sämtliche 
Betriebssysteme, die mir bisher untergekommen sind, machen so was nicht. 
Bei dem in der Automobilwelt verbreiteten OSEK sehen Tasks wie 
Funktionen aus. Dieses werden entweder zyklisch oder ereignisgetriggert 
abgearbeitet.

Gruß Matthias

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> aber er behält immer noch den höchstpriore
> Task bei und wechselt nicht.

solange die höchstprio-task was zu tun hat, wird auch nicht gewechselt. 
du brauchst mindestens eine task mit gleich hoher prio, damit der 
scheduler zwischen beiden hin und herschaltet. eine niederprio-task 
kommt nur dran, wenn alle hochprio-tasks in einem wait-state sind oder 
beendet wurden.

btw, läuft der timer-interrupt für die task-switches überhaupt?

btw2, free-rtos ist eigentlich ziemlicher mist, kaum 
synchronisationsprimitive usw. nimm besser "TnKernel"
http://www.tnkernel.com/

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.