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
Hilfe! Kennt sich den keiner ein wenig mit FreeRTOS aus? Sind ja wirklich nur Anfänger-Probleme...
Typischer Fall von falsches Forum. Das was du suchst, sollte hier zu
finden sein:
> http://sourceforge.net/forum/forum.php?forum_id=382005
Na ihr seit hier halt meine erste Anlaufstelle für alles ;-) Aber guter Tipp, danke!
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...
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.
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.
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...
ja, zumindest müsste ja ein zyklischer Interrupt funktionieren. Vielleicht in der zugehörigen ISR mal einen Portpin toggeln lassen.
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.
Tja, isr usw freigeben. ich kann in deinem Sourcecode im Anhang nix erkennen.
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...
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?
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!!!
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.
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 } }
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?
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.
Doch, aber manche fangen mit der Thematik halt gerade erst an. Trotzdem Danke für die Antwort, mitlerweile läuft es natürlich ordentlich!
Seit wann macht man in Tasks überhaupt Endlosschleifen, ob preemptives oder nonpreemtives Betriebssystem? Für die Endlosschleife ist der Scheduler zuständig. Gruß Matthias
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.
> 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.
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
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.