Forum: Mikrocontroller und Digitale Elektronik FreeRTOS und AVR


von marc (Gast)


Lesenswert?

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

von Daniel B. (khani)


Lesenswert?

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.

von Daniel B. (khani)


Lesenswert?

Nochmal ich : Man kann basierend auf dem ATmega32 - Port ganz leicht
Ports für andere AVR-Controller erstellen.

von marc (Gast)


Lesenswert?

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

von marc (Gast)


Lesenswert?

hallo daniel

dachte du wolltest mir helfen? ;-)

von Daniel B. (khani)


Lesenswert?

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.

von marc (Gast)


Lesenswert?

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

von Daniel B. (khani)


Lesenswert?

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.

von marc (Gast)


Lesenswert?

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

von Werner B. (Gast)


Lesenswert?

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.

von Werner B. (Gast)


Lesenswert?

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;

von marc (Gast)


Lesenswert?

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?

von marc (Gast)


Angehängte Dateien:

Lesenswert?

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

von Werner B. (Gast)


Lesenswert?

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

von marc (Gast)


Lesenswert?

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

von marc (Gast)


Lesenswert?

ich bins nochmal...

Die zwei Warnungen, von welchen Werner geschrieben hat, kommen bei mir
immernoch...
weiss wer wie ich die beseitigen kann?

gruss marc

von AndreasH (Gast)


Lesenswert?

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

von Sven (Gast)


Lesenswert?

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

von Gilles R. (roodemol)


Lesenswert?

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

von Maximilian K. (laplace)


Lesenswert?

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

von Gilles R. (roodemol)


Lesenswert?

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

von hacker (Gast)


Lesenswert?

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?

von Ulli (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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

von Ulli (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Dominik (Gast)


Lesenswert?

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

von W.S. (Gast)


Lesenswert?

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.

von fddgddg (Gast)


Lesenswert?

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

von Dominik D. G. (dominikd_g)


Lesenswert?

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