Forum: Mikrocontroller und Digitale Elektronik Erste Versuche mit FreeRTOS


von Der T. (soundso)


Angehängte Dateien:

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

von Der T. (soundso)


Lesenswert?

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

von Niels H. (monarch35)


Lesenswert?

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

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

von Der T. (soundso)


Lesenswert?

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

von Berti (Gast)


Lesenswert?

Hast du wohl endlosschleifen in deinen tasks?

von Der T. (soundso)


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...

von Jojo S. (Gast)


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.

von Jojo S. (Gast)


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.

von Der T. (soundso)


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...

von Berti (Gast)


Lesenswert?

Ich kann da keinen Timer für den Sheduler sehen...

von Jojo S. (Gast)


Lesenswert?

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

von Der T. (soundso)


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.

von Berti (Gast)


Lesenswert?

Tja, isr usw freigeben. ich kann in deinem Sourcecode im Anhang nix 
erkennen.

von Der T. (soundso)


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...

von Der T. (soundso)


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?

von Der T. (soundso)


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!!!

von Berti (Gast)


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.

von Der T. (soundso)


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 }
}

von Der T. (soundso)


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?

von Dieter (Gast)


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.

von Der T. (soundso)


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!

von Matthias Kölling (Gast)


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

von Der T. (soundso)


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.

von Rolf Magnus (Gast)


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.

von Matthias Kölling (Gast)


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

von Peter (Gast)


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/

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