freertos auf dem ct bot

Die Programmierung des c't-Bot
Antworten
quinte17

freertos auf dem ct bot

Beitrag von quinte17 » 18 Sep 2008, 23:21

hallo allerseits!
ich hoffe ihr könnte mir bei einem kleinen problemchen helfen *Gg*

also ich habe www.freertos.org auf den ct-bot gehauen.
die led-ansteuerung funktioniert und das Display kann ich auch problemlos beschreiben.

so, nun das eigentliche problem:

die motorsteuerung verwendet ja zum erzeugen des pwm den timer1.
das freertos bentutzt auch diesen um die eigene zeiteinteilung zu gestallten. dadurch kommt es nun zu problemen wenn ich versuche den timer so einzustellen wie im svn unter stable angegeben.
ist es denn überhaupt möglcih auch andere timer für die motorsteuerung zu verwenden?

ich habe schon kurz über möglichkeiten gelesen diverse timer für mehrere funktionen zu benutzen, wäre das denn überhaupt möglich? also im zusammenhang mit der motorsteuerung?

wäre gut wenn einer vielleicht links zu dieser themaitk hätte, oder vielleicht den einen oder anderen tip parat hätte ;)

vielen dank schonmal, wenn noch informationen fehlen, dann bitte fragen

quinte17

Benjamin.Benz

Beitrag von Benjamin.Benz » 19 Sep 2008, 09:57

Hi,

das einfachste (in Bezug auf Änderungen am Bot-Code) wäre sicher, freertos auf Timer 2 umzustellen. Diesen Timer verwendet derzeit auch unser bereits integriertes Mini-OS.

Ansonsten gäbe es noch Timer0, der kümmert sich derzeit um die PWM des Servos.

Die Motoren steuern wir über die Hardware-PWM an. Wenn Du nicht die PWM in Software nachbasteln wilst (wovon ich aus diversen Gründen stark abrate), müssen die Motoren auf Timer1 bleiben.

Theoretisch kannst Du auch den PWM-Timer zusammen mit dem Interrupt benutzen. Die Motor-PWM sollte das nicht stören, sofern Du nicht an ihren Einstellungen (Frequenz und Compare-Flasg spielst). Allerdings müsstest Du dann damit leben, dass Dein OS immer nur den Task wechselt, wenn der PWM-Counter ein Compare hat.

Und damit bin ich wieder am Anfang: Nimm Timer2 und häng' Den freertos-Kram in dessen Interrupt-Routine (Datei: /mcu/timer-low.c) mit rein. Genauso wie da auch schon ir_isr() und encoder_isr89 drin hängen.

MfG Benjamin Benz

quinte17

Beitrag von quinte17 » 25 Sep 2008, 18:03

danke für die schnelle antwort ;)

ich habe mir das ganze mal durch den kopf gehen lassen und verstehe schon warum timer2 prinzipiell nciht schlecht wäre, wenn ich auch noch die motoren verwenden möchte.

aber was hat das dann für auswirkungen auf das scheduling?

verstehe ich das richtig, dass der 8bit timer wahrscheinlich öffter einen interrupt wirft als der 16 bit timer?
also, wenn ich den 8bit timer immer auf 250 zählen lasse, dann würde ich ja bei einer 16mhz clock eine interruptrate von 64000hz bekommen oder liege ich da falsch?
kann man den 8bit timer auch auf 1000hz einstellen? (oder auch niedrigere werte?)

wäre schön, wenn mir das jemand grob erklären könnte.

vielen dank nochmal
quinte17

edit:
gut, nachdem ich das handbuch des atmegas ein bisschen länger "studiert" habe, glaube ich brauche ich folgende einstellungen:
timer2 im CTC modus
den prescaler auf 256
und OCR2 auf 30

da sollte dann nach der formel bei 16MHz eine frequenz von 1008Hz rauskommen.
gibt es noch möglichkeiten näher an die 1000Hz zu kommen? oder ist das nicht sinnvoll, da die ganze elektronik eher ungenau ist?

edit2: gut habe noch bessere werte gefunden:
prescale auf 32
OCR2 auf 249

bringt theoretisch die 1000Hz

eax
Friends of Robby
Friends of Robby
Beiträge: 755
Registriert: 18 Jan 2006, 16:16
Wohnort: Karlsruhe

Beitrag von eax » 28 Sep 2008, 14:09

Hi,

beim Bot-Code wird die Timer-ISR (Zeile 43ff) alle 176 µs aufgerufen. Die eingestellte Frequenz von Timer2 wird vom RC5-Code, der die Fernbedienung auswertet, genau so erwartet. Außerdem sind viele andere Funktionen / Verhalten darauf ausgelegt, dass der Tickcounter in 176 µs Schritten zählt.

Darum wird der Scheduler vom Bot-OS nicht bei jeder Durchlauf der ISR ausgeführt, sondern nur alle 10 ms (ich glaube der entsprechende Kommentar dort im Code ist falsch bzw. veraltet).

Das Bot-OS schaltet im Moment nur zwischen zwei Threads um (aber preemtiv), es ist eher eine Ergänzung für eine spezielle Aufgabe, als eine grundlegende Basis des gesamten Bot-Codes. Um den Overhead möglichst gering zu halten, werden hier ein paar Tricks angewendet, die den Threadwechsel genau auf die derzeitigen Bedürfnisse zuschneiden. Das Prinzip ließe sich natürlich auch bei weiteren oder allen Code-Teile anwenden.

Der Grund ist, dass die Bot-Software von Anfang an an einem anderen Modell ausgerichtet war, sie ist definitiv nicht als Multithreading-System designed. Das lässt sich natürlich beliebig ändern, man sollte sich nur über die Konsequenzen im Klaren sein, insbesondere was Locking-Mechanismen und Abhängigkeiten zwischen den einzelnen Code-Teilen angeht. Hinzu kommt, dass einige Funktionen der avr-libc nicht threadsicher sind, so können z.B. Funktionen der printf-Familie nicht so ohne Weiteres in verschiedenen Threads verwendet werden usw.

Wenn du die Bot-Software from scratch neu machen möchtest, ist das vermutlich alles egal, ein RTOS in den vorhandenen Code zu integrieren erfordert aber eine ganze Menge an Anpassungen, zumindest wenn das Ganze auch einen Vorteil bringen und nicht derselbe Code in langsam werden soll.

Vielleicht hilft dir das etwas weiter.

Viele Grüße,
Timo

quinte17

Beitrag von quinte17 » 28 Sep 2008, 18:24

eax hat geschrieben:Hi,
auch hallo :)
eax hat geschrieben: beim Bot-Code wird die Timer-ISR (Zeile 43ff) alle 176 µs aufgerufen. Die eingestellte Frequenz von Timer2 wird vom RC5-Code, der die Fernbedienung auswertet, genau so erwartet. Außerdem sind viele andere Funktionen / Verhalten darauf ausgelegt, dass der Tickcounter in 176 µs Schritten zählt.

Darum wird der Scheduler vom Bot-OS nicht bei jeder Durchlauf der ISR ausgeführt, sondern nur alle 10 ms (ich glaube der entsprechende Kommentar dort im Code ist falsch bzw. veraltet).
Das Bot OS habe ich mir bisher nicht angeschaut. Ob ich dann auch RC5 Code haben möchte wird sich noch herausstellen ;) bis dahin lasse ich den Scheduler bei 1000Hz laufen. Also 1ms Pro Task Preemptive.
eax hat geschrieben: Das Bot-OS schaltet im Moment nur zwischen zwei Threads um (aber preemtiv), es ist eher eine Ergänzung für eine spezielle Aufgabe, als eine grundlegende Basis des gesamten Bot-Codes. Um den Overhead möglichst gering zu halten, werden hier ein paar Tricks angewendet, die den Threadwechsel genau auf die derzeitigen Bedürfnisse zuschneiden. Das Prinzip ließe sich natürlich auch bei weiteren oder allen Code-Teile anwenden.

Der Grund ist, dass die Bot-Software von Anfang an an einem anderen Modell ausgerichtet war, sie ist definitiv nicht als Multithreading-System designed. Das lässt sich natürlich beliebig ändern, man sollte sich nur über die Konsequenzen im Klaren sein, insbesondere was Locking-Mechanismen und Abhängigkeiten zwischen den einzelnen Code-Teilen angeht. Hinzu kommt, dass einige Funktionen der avr-libc nicht threadsicher sind, so können z.B. Funktionen der printf-Familie nicht so ohne Weiteres in verschiedenen Threads verwendet werden usw.

Wenn du die Bot-Software from scratch neu machen möchtest, ist das vermutlich alles egal, ein RTOS in den vorhandenen Code zu integrieren erfordert aber eine ganze Menge an Anpassungen, zumindest wenn das Ganze auch einen Vorteil bringen und nicht derselbe Code in langsam werden soll.
Ich bin mir schon im klaren, was ein RTOS macht. Ein Vorteil zum Beispiel ist, dass man keinen Busywait mehr beim Display braucht, sondern einfach einen non-blocking Sleep machen kann (bei mir ist das Display eh Invertiert angeschlossen, damit ich vielleicht mal in Zukunft das busy-bit auslesen kann, mit dem sleep aber vollkommen unnötig). Oder einen Task, der die LEDs im Sekundentakt Blinken lassen kann.
Das Programm wird halt einfach Strukturierter und ist einfacher zu lesen.
Hier mal mein bisherirger erfolg mit timer2: http://www.youtube.com/watch?v=lspVANG8bt0
eax hat geschrieben: Vielleicht hilft dir das etwas weiter.

Viele Grüße,
Timo
Danke für die Antwort! Schönen abend noch
Bis demnächst

eax
Friends of Robby
Friends of Robby
Beiträge: 755
Registriert: 18 Jan 2006, 16:16
Wohnort: Karlsruhe

Beitrag von eax » 29 Sep 2008, 15:11

Hi,
quinte17 hat geschrieben:Ich bin mir schon im klaren, was ein RTOS macht. Ein Vorteil zum Beispiel ist, dass man keinen Busywait mehr beim Display braucht, sondern einfach einen non-blocking Sleep machen kann (bei mir ist das Display eh Invertiert angeschlossen, damit ich vielleicht mal in Zukunft das busy-bit auslesen kann, mit dem sleep aber vollkommen unnötig). Oder einen Task, der die LEDs im Sekundentakt Blinken lassen kann.
Na ja, die Wartezeit beim Display beträgt 47 µs, bei 16 MHz sind das rund 750 Taktzyklen. Freertos (außer es hat sich da in der neuesten Version etwas geändert) sichert bei jedem Taskwechsel den gesamten Kontext (ginge sicherlich auch cleverer), dafür gehen ca. 80 Taktzyklen drauf + noch mal 80 Taktzyklen um den Kontext der dann gewählten Task wiederherzustellen.
Außerdem muss der Scheduler eine andere bereite Task auswählen, wenn das sagen wir mal 200 Taktzyklen dauert, sind wir schon bei 360 Taktzyklen, um das Display-Update schlafen zu legen und etwas anderes auszuführen.
Da die Wartezeit des Displays so kurz ist, musst du die Zeitscheiben für die Tasks sehr klein einstellen (z.B. 1 ms), der Overhead um wieder zur Display-Task zurück zu wechseln beträgt wieder 360 Taktzyklen, damit wären wir in der Überschlagsrechnung schon bei 720 Taktzyklen. Zwischendurch eintreffende Interrupts und die Statusupdates (Task blockieren) mal außer Acht gelassen.
Natürlich hat man den Rückwechsel-Overhead auf Grund des Timerticks immer, bei längeren Zeitscheiben tritt der aber seltener auf.

Außerdem wird mehr RAM benötigt. Da ergibt sich die Frage, ob sich das Ganze beim Display-Update noch lohnt.

Hinzu kommt noch, dass sich das Display Leitungen mit den Schieberegistern für die LEDs und ENA teilt, es darf also keine Task unterbrochen werden, die LEDs oder ENA ansteuert, wenn sie sich gerade in bestimmten Codebereichen befindet. Ebenso darf parallel zum Display-Update kein I2C-Transfer laufen.

Viele Grüße,
Timo

quinte17

Beitrag von quinte17 » 29 Sep 2008, 18:46

eax hat geschrieben: Außerdem wird mehr RAM benötigt. Da ergibt sich die Frage, ob sich das Ganze beim Display-Update noch lohnt.

Hinzu kommt noch, dass sich das Display Leitungen mit den Schieberegistern für die LEDs und ENA teilt, es darf also keine Task unterbrochen werden, die LEDs oder ENA ansteuert, wenn sie sich gerade in bestimmten Codebereichen befindet. Ebenso darf parallel zum Display-Update kein I2C-Transfer laufen.
Mit dem Speicherverbrauch und der Taskwechsel gebe ich dir schon recht.

Um die Schieberegister vor zugriff zu schützen werden Semaphoren verwendet.
Desweiteren haben die Tasks auch noch Prioritäten, dadurch können wichtigere Dinge bevorzugt werden. (die Prioritäten werden natürlich von den Semaphoren und dem Scheduler beachtet)
Da das Display die meiste Zeit eh wartet, ist die Rechnung speziell für das Display ohne Argumentation. Kein Mensch kann im µs-Bereich lesen ;) genauso mit den LEDs und den ENA-Leitungen.

Mein jetziges System schläft die meiste Zeit, da ich noch keine Task habe, die alle Sensoren auswertet. Diese task wird allerdings noch eine kleinere Priorität bekommen als alle anderen, weil dies ständig passieren muss und erst auf gewisse ergebnisse langsam reagiert werden soll.
Wenn da dann mal kurz eine LED verändert wird (alle 250ms) ist dies kein Problem. (selbiges trifft auf Display und Motoranpassung zu)

Aber erstmal genug implementieren, bisher hatte ich ja noch nicht so viel zeit um mich mit jedem Detail zu beschäftigen. Ich muss die Sensorplatinen noch vor kurzschlüssen sichern, die Spannungsversorgung ein wenig Stabilisieren und noch ein paar kleinigekeiten ;)

Eine Gesamtsystemplanung wird dann natürlich auch fällig, was auch nicht wenig Zeit kostet...

Schönen Abend noch!

eax
Friends of Robby
Friends of Robby
Beiträge: 755
Registriert: 18 Jan 2006, 16:16
Wohnort: Karlsruhe

Beitrag von eax » 29 Sep 2008, 22:34

Hi,
quinte17 hat geschrieben:Mein jetziges System schläft die meiste Zeit, da ich noch keine Task habe, die alle Sensoren auswertet. Diese task wird allerdings noch eine kleinere Priorität bekommen als alle anderen
ich würde ihr die Höchste geben, damit die Verhalten immer auf aktuelle Sensordaten reagieren können (du möchtest einen Abgrund so früh wie möglich registrieren, um noch rechtzeitig bremsen zu können).

Prinzipiell ist das schon eine sehr interessante Sache, dem Bot ein kleines OS zu verpassen, die Idee ist ja nicht neu und wurde auch schon auf der Mailingliste angesprochen.
Wobei ich freertos allerdings nicht so optimal finde.

Außerdem ist es sicherlich sehr sinnvoll, den Bot-Code weiterhin simuliert ausführen zu können - gerade bei der Entwicklung (komplexer) Verhalten spart das Testen und Ausprobieren im Sim sehr viel Zeit.

Danke, ebenfalls noch einen schönen Abend! ;-)

eax
Friends of Robby
Friends of Robby
Beiträge: 755
Registriert: 18 Jan 2006, 16:16
Wohnort: Karlsruhe

Beitrag von eax » 17 Nov 2008, 23:21

Hi,

bist du bei der Sache inzwischen schon was weitergekommen?
Ich bin auch am Nachdenken über solch einen Ansatz (u.a. um die Einschränkung von nur einer Verhaltensinstanz aufzuheben) und vielleicht muss man das Rad ja nicht zweimal erfinden. ;-)

Grüße,
Timo

chivu

Re: freertos auf dem ct bot

Beitrag von chivu » 19 Feb 2011, 08:42

quinte17 hat geschrieben:hallo allerseits!
ich hoffe ihr könnte mir bei einem kleinen problemchen helfen *Gg*

also ich habe www.freertos.org auf den ct-bot gehauen.
die led-ansteuerung funktioniert und das Display kann ich auch problemlos beschreiben.

quinte17
Hallo zusammen,

ich habe 2 Fragen was auf FreeRtos betrifft.

a) Wie kann ich FreeRtos auf ct Bot drauf spielen bzw. auf was muss ich achten oder ändern?

b) Sollte ich bei a erfolgreich werden wie kann ich Led und Display ansteuern?

Vielen Dank im Voraus.

Antworten