Hallo zusammen Wollte mal nachfragen, ob jemand hier im Forum schon Erfahrungen mit FreeRTOS hat, denn viel darüber geschrieben wurde noch nicht gerade.. Gibt es vielleicht schon Ports für andere AVR-Typen wie der Mega323? Und was sind eure Erfahrungen damit? Grüsse marc
JAA FreeRTOS, frag mich - ich habe mich ein halbes Jahr lang jeden Tag damit beschäftigt. Ich kann Dir wahrscheinlich ziemlich viel zum Kernel sagen - die aktuellsten Webserver-Erweiterungen kenn ich nicht. Ports für verschiedene AVR (?) findet man wenn überhaupt (also natürlich gibt es welche) auf der Seite von freeRTOS. Das sind dann wenigstens unterstützte Ports - es gibt auch "unsupported ports" - bei denen ist das Problem, dass sie nur mit bestimmten Kernel-Versionen funktionieren. Meine Erfahrungen mit freeRTOS sind folgende : recht schlank, recht vielseitig. Dokumentation ist gut. Bietet aber nur das Gerippe. freeRTOS ist wirklich nur ein Scheduler mit Queues Lists und Semaphoren. Frag gerne mehr. MfG, Daniel.
Nochmal ich : Man kann basierend auf dem ATmega32 - Port ganz leicht Ports für andere AVR-Controller erstellen.
Danke für die Antwort Ich versuche vergebens eine Port für den Mega16 zu machen, weil ich im Moment nur diesen zuHause hab. Ist es überhaupt möglich FreeRtos auf dem Mega16 zu betreiben? So wie ich das sehe, kann man fast komplett den Port vom Mega323 verwenden, bis auf das CTC-Flag beim 323 dass es so beim Mega16 nicht gibt. Oder muss ich sonst noch was anpassen? Interrupts usw. heissen alle gleich, oder? Grüsse Marc
Hm, ich hatte den Thread nicht mehr gesehen - daher habe ich nix mehr dazu gesagt. Also meiner Meinung nach ist es durchaus möglich, FreeRTOS auch auf einem ATmega16 zum L aufen zu bringen. Das Problem ist dann aber, dass man unter Umständen bei der Speicherverwaltung (also bei den Task-Stacks usw.) ein paar Veränderungen anbringen muss. Prinzipiell sollte man den 323-Port auf den ATmega16 übernehmen können. Binde einfach mal den Header für den 323 nicht ein und setzt stattdessen den Header für den ATmega16 ein. Wenn es sich dann kompilieren lässt, ist das zumindest mal ein gutes Zeichen. Dann machst Du am besten erst mal einen (und nur einen) Task, der eine LED blinken lässt oder so. Der Task hat dann eine Endlosschleife und gibt die Kontrolle niemals an das OS ab. Wenn das dann mal funktioneirt, kann man die Kontrolle auch mal abgeben. Dann fügt man einen zweiten Blinktask dazu (vielleicht mit einer anderen Priorität) und testet sich so vorwärts. Sollte es irgendwann zu merkwürdigen Problemen kommen, dann muss man sich die Speichereinstellungen unter Umständen noch einmal anschauen. Das ist eine nicht triviale Geschichte und man sollte dazu einen Gutteil der Kernel-Sourcen schon mal gesehen haben - ist nicht unbedingt Voraussetzung hilft aber manchmal ungemein. MfG, Daniel.
Juhuu, es läuft... Hab es geschafft zwei verschidene Tasks LED's blinken zu lassen ;-) Nun ist mir aber schleierhaft, wie ich die Blinkfrequenzen berechnen kann... Wenn ich doch eine TickFrequenz von 1000Hz angebe, sollte die LED bei einem Delay von 100 mit 10Hz blinken...? Bei mir sind es dann ca 1Hz? Aber auch wenn ich die Frequenz im FreeRTOSConfig.h ändere, bleibt die Blinkfrequenz gleich... muss ich die FreeRTOSConfig.h noch wo einbinden, damit dies funktioniert? mfg Marc
Schön, das ist schon mal ein großer Schritt nach vorne. So ganz ohne Ansehen der Sourcen kann man da nur wenig sagen. Am besten Du testest das Problem noch ein bißchen aus (eine LED doppelt so schnell wie die andere usw.) und berichtest weiter, falls immer noch das Timing komisch sein sollte doer Du packst Deine Sourcen (zumindest das, was Du selbst änderst) zusammen und ich schau' mal rein. Wenn Du die Sourcen hier reinstellst, dann musst Du die auch ein wenig kommentieren, aber ich denke, das machst Du in Deinem eigenen Interesse eh schon.. MfG, Daniel.
Hallo Hab jetzt noch ein paar versuche mit den Delays gemacht, leider erfolglos... Egal was ich mache, der Code wird nicht mit der Geschwindigkeit ausgeführt, die ich im config eingestellt hab. Ich kann Tick-Frequenz beliebig ändern, es passiert nichts. Die Tick Frequenz bleibt immer um die 100 Hz (zirka) egal was im config steht??? Es genügt doch das File im gleichen Verzeichniss wie main.c zu haben, oder? Gruss marc
Das ist der sinn der Sache, die Blinkgeschwindigkeit ist (bzw. soll sein) unabhängig vom eingestellten timer-faktor. Suche einmal nach Demo/Common/Minimal/flash.c, darin findest Du
1 | #define ledFLASH_RATE_BASE ( ( portTickType ) 333 )
|
Die (basis-) Blinkrate ist also 333 Millisekunden. Weiter unten steht dann
1 | xFlashRate = |
2 | ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) |
3 | uxLED ); |
4 | xFlashRate /= portTICK_RATE_MS; |
hier wird die Blinkrate für jede der LEDs um jeweils 333ms erhöht und anschließend auf den eingestellten Timer normiert.
nachdem ich den "normierungs-teil" nicht sehen kann (Firefox problem???) hier nich einmal die beiden Zeilen ohne C-tag xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) uxLED ); xFlashRate /= portTICK_RATE_MS;
So wie ich das verstanden habe kann man mit folgender Funktion: vTaskDelay( 10 ); angeben wieviele Ticks Pause man machen möchte, was meiner meinung nach von der Tickrate und der Quarzfrequenz abhängig ist... oder sehe ich das falsch?
so, komme nicht weiter... hab jetzt mal mein Proggie angefügt und wäre froh, wenn ihr euch das mal anschauen könnt. kompilieren funktioniert ohne problem (GCC; makefile dabei). Das hex lässt sich bei mir auch programmieren, aber eben läuft 10 mal zu langsam. Auch kann ich das elf nicht im AVR-Studio öffnen er bringt mir immer den fehler: "An error occured while reading the object file. The file may be of wrong type or corrupted, or the object file reader is not up to date." kommt der bei euch auch? Grüsse Marc
FreeRTOSConfig.h - läuft Dein proz mit 8MHz? bei ca. 1/10 tippe ich dass er mit den internen 1MHz läuft. simulator -> makefile ... DEBUG_LEVEL=-gdwarf-2 ... Prototyp: [ ist einfach eine frage des stils ;) ] main.c: In function `main': main.c:38: warning: passing arg 1 of `xTaskCreate' from incompatible pointer type main.c:39: warning: passing arg 1 of `xTaskCreate' from incompatible pointer type
hallo in späten stunden hat es gester dann doch endlich funktioniert... Das problem mit dem Simulator war logischerweise das makefile... danach hatte ich auch endlich die chance zu debuggen Frequenzen stimmten soweit, das Problem war, dass mein Port für den Mega16 einen Fehler drinn hatte. Der Timer wurde nicht richtig initialisiert und hat nur Mist gemacht ;) Wenn jemand sonst noch interesse hat, kann ich den funktionierenden Port ja nochmals hier ins Forum stellen. Vielen Dank Gruss Marc
ich bins nochmal... Die zwei Warnungen, von welchen Werner geschrieben hat, kommen bei mir immernoch... weiss wer wie ich die beseitigen kann? gruss marc
Der erste Parameter von xTaskcreate muss als pdTASK_CODE definiert sein. Bei Dir ist es aber static void "static void vBlink( void );". Habe mir allerdings nicht die Mühe gemacht nachzushen was sich hinter pdTASK_CODE verbirgt. Grüße Andreas
Hallo marc, ich bin auch gerade daran mich mit FreeRTOS zu beschäftigen, habe wie du auch nur einen ATmega16 zu Hause. Doch leider klappt bei mir noch gar nichts. Fehler über Fehler. Könntest du deinen funktionierenden Port (Code usw.) noch mal ins Forum stellen. Wäre dir sehr dankbar dafür, sehe sonst glaub so schnell kein Land ;-) mfg Sven
Hallo, der Thread ist etwas älter, aber ich glaube es passt hierhin. In der Demo von FreeRTOS für den ATmega323 wird mit:
1 | #define configTOTAL_HEAP_SIZE ( (size_t ) ( 1500 ) )
|
Speicher reserviert. Meine Frage, gibt es eine Faustregel mit der man configTOTAL_HEAP_SIZE für verschiedene AVR Mikrocontroller bestimmen kann? Der Speicher der ja mal sicher wegfällt ist die Grösse alle Konstanten und globalen Variablen. MFG
Innerhalb der AVRs bestimmt die Art des Mikrocontrollers nur die Obergrenze für dein configTOTAL_HEAP_SIZE. Du kannst natürlich nicht mehr heap vergeben, als du RAM hast. Vielmehr sollte die configTOTAL_HEAP_SIZE abhängig sein von der Anzahl deiner Tasks + ihrer Stacks. Ich kann dir nicht sagen wieviel RAM nur der Task(-ControlBlock) braucht (ohneStack). Vielleicht weiss es jemand. Ich finde 1500 Byte für den Anfang etwas großzügig. Du kannst den heap bei kleineren Projekten meistens auf 1k verkleinern. Wenn der Wert zu klein wird, merkst du das in der Regel recht schnell (AVR läuft nicht an).
Hat schon jemand die Demo für einen Mega32 unter Ubuntu 7.10 übersetzt und zum laufen gebracht? Unter FreeBSD hat das ohne Probleme geklappt, wenn ich das ganze unter Ubuntu übersetze gehen nur die ersten 3 Leuchtdioden an und das wars. Kann das daran liegen, dass die Ubuntu Pakete leicht veraltet sind? Hat sich schon jemand die Mühe gemacht die Grösse des Kernels zu ermitteln? MFG Gilles
Hallo, ich möchte für ein Mikrocontrollerprojekt ebenfalls das freeRTOS verwenden. Ich möchte iegentlich nur mal zwei Tasks erzeugen und in diese z.B. eine LED blinken lassen. Welche Funktionen muss ich vom freeRTOS verwenden?
Hallo Daniel Braun, ich gerade dabei das FreeRTOS auf einen Mikrocontroller zu portieren. Nun möchte ich Queu's erzeugen. Hast du eventuell eine Beispielapplikation dazu wie das mit den Queue's funktioniert? Gruß Ulli
Ulli schrieb: > Hallo Daniel Braun, > > ich gerade dabei das FreeRTOS auf einen Mikrocontroller zu portieren. > Nun möchte ich Queu's erzeugen. Hast du eventuell eine > Beispielapplikation dazu wie das mit den Queue's funktioniert? Wobei hast du konkret Schwierigkeiten? In der Queue Doku, zb beim Receive ist doch eigentlich ein ganz guter Code Schnipsel, der zeigt, wie man mit einer Queue umgeht. http://www.freertos.org/a00118.html
Danke für den Link. Was mir allerdings da auffällt ist, warum wird in der Task immer die Queue's neu angelegt. Sollte doch eigentlich nur einmal passieren oder?
1 | // Task to create a queue and post a value.
|
2 | void vATask( void *pvParameters ) |
3 | {
|
4 | struct AMessage *pxMessage; |
5 | |
6 | // Create a queue capable of containing 10 pointers to AMessage structures.
|
7 | // These should be passed by pointer as they contain a lot of data.
|
8 | xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) ); |
9 | if( xQueue == 0 ) |
10 | {
|
11 | // Failed to create the queue.
|
12 | }
|
13 | |
14 | // ...
|
15 | |
16 | // Send a pointer to a struct AMessage object. Don't block if the
|
Ulli schrieb: > Danke für den Link. Sag blos, du kennst den nicht? Ts, ts. Software portieren und die Doku nicht zur Hand haben. > Was mir allerdings da auffällt ist, warum wird in > der Task immer die Queue's neu angelegt. Sollte doch eigentlich nur > einmal passieren oder? Langsam. Das ist kein Produktionscode. Das ist typischer Code, wie er in Dokus vorkommt. Er zeigt das Notwendigste und auch ein wenig vom Drumherum, damit man sich nicht die Finger wund sucht bei der Frage: Receive ist klar, aber wo kommt die Queue eigentlich her? Code in Dokus soll Abläufe aufzeigen. In Produktionscode kann man den meistens immer nur abschnittweise übernehmen, wenn überhaupt.
Der Thread ist ja nun schon etwas älter... aber ich war auf das gleiche Problem gestoßen; ebenfalls ATMega16. Vielleicht hilft es ja noch jemandem. Mein Test war ebenfalls vStartLEDFlashTasks und hatte das Problem, dass die Blink-Frequenz nicht stimmte, sobald ich die configTICK_RATE_HZ angepasst hatte. Nach stundenlangem Grübeln stellte sich heraus, dass mein Makefile die Abhängigkeit von FreeRTOSConfig.h in /portable/ATMega16/port.c nicht beachtet hatte, und somit die Timer-Setup-Funktion noch mit den alten Wert kompiliert wurde. Ein "make clean" vor einem neuen Build sorgte für Abhilfe. Ich werde den Build-Prozess entsprechend anpassen. Zu den Compiler-Warnings: Seit 1.7.1 verwendet tasks.c wohl für Zeiger-Casts den im Port definierten "portPOINTER_SIZE_TYPE". Dieser muss in der portable.h definiert werden: #define portPOINTER_SIZE_TYPE uintptr_t Wie an anderer Stelle bereits erwähnt, verwendet der ATMega16 für das CTC ein anderes Bit (WGM12). Meine Definitionen sehen so aus: #define T1_CLEAR_TIMER_ON_COMPARE ( _BV(WGM12) ) #define portCLEAR_COUNTER_ON_MATCH ( ( unsigned char ) CLEAR_TIMER_ON_COMPARE ) Läuft soweit gut...
Dominik schrieb: > Läuft soweit gut... Ähem.. was läuft? Ich sehe ein Betriebssystem eigentlich immer nur als ein Hilfsmittel, um Anwendungen zu betreiben. Und da wäre mir das Blinken von zwei LED's sicherlich etwas zu wenig. Ich hatte mir vor geraumer Zeit auch schon mal so einige "RTOSse" angeschaut und dabei festgestellt, daß damit zumeist nix anderes als ein simpler Scheduler gemeint ist. Sowas ist gut für Leute, die nur prozedural und somit blockierend (also stur nach PAP) programmieren können: while (!ADCistFertig) TrampleAufDerStelle; Wer nicht so trollig ist, kann auf nichtblockierende Weise programmieren und ist damit nicht an ein RTOS angewiesen. Ergebnis: einfacher, zuverlässiger, schneller, geringere Codegröße usw. Also, wo ist der eigentliche Zweck? W.S.
dann gibts noch die , die eine lineare programmierweise erlauben aber durch das einsetzen von hilfsfunktionen und makros doch wieder eventgetrieben sind ... leider sind diese dinge saumäßig unübersichtlich .. ein makro zu wenig oder an der falschen stelle und alles steht dann kommen die nächsten und versuchen C++ in C nachzubilden .. oder objective C ... gibt viele programmierweisen und stile .. frage ist immer .. was soll die aufgabe sein ?????? ein RTOS für 2 blinkende LEDs sind .. naja etwas oversized ^^
W.S. schrieb: > Ähem.. was läuft? Na was wohl... der Timer und der Scheduler - der Test, die Basis ;) > Ich sehe ein Betriebssystem eigentlich immer nur als ein Hilfsmittel, um > Anwendungen zu betreiben. Und da wäre mir das Blinken von zwei LED's > sicherlich etwas zu wenig. Ich weiß nicht wie Du darauf kommst, dass ich mit einem RTOS ein paar LEDs blinken lassen möchte?! > Ich hatte mir vor geraumer Zeit auch schon > mal so einige "RTOSse" angeschaut und dabei festgestellt, daß damit > zumeist nix anderes als ein simpler Scheduler gemeint ist. Nicht ganz richtig. Der Scheduler ist natürlich eine Kernkomponente. Wichtig sind aber auch Funktionalitäten wie Semaphoren etc. > Wer nicht so trollig ist, kann auf nichtblockierende Weise programmieren > und ist damit nicht an ein RTOS angewiesen. Ergebnis: einfacher, > zuverlässiger, schneller, geringere Codegröße usw. > > Also, wo ist der eigentliche Zweck? Ich denke die Aufzählung von Gründen für die Verwendung eines RTOS kann ich mir sparen. Hier ist ein kleines Beispiel, welches ein mittelmäßig komplexes Projekt beschreibt: http://www.freertos.org/index.html?http://www.freertos.org/tutorial/solution1.html Selbstverständlich nimmt man einiges in Kauf: Context-Switching kostet einige Bytes im Flash, einiges an RAM und vor allem Takte. Dafür bekomme ich aber ein Grundgerüst mit einiger Funktionalität (Queues, Semaphores, ....). Ich hatte einmal einen eigenen Minimal-Kernel mit quasi co-operativem Scheduling (ohne Context-Switching). Das, was ich machen wollte, war kaum mehr zu handeln. Das Für und Wider muss jeder selbst abwägen. Für's erste war es ein interessanter Test für mich, ob ich FreeRTOS "zum Laufen" bekomme. Dominik Edit: Noch ein Zusatz: Mein Beitrag sollte eine Ergänzung darstellen, wie man den ATMega323-Port auf einem ATMega16 bekommt. Der ATMega16 ist für ein OS etwas unterdimensioniert. Es war lediglich ein Test, bis mein etwas größerer µC eintrifft.
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.