www.mikrocontroller.net

Forum: Projekte & Code Multithreading-OS für AVRs


Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

möchte euch hier mein Betriebssystem für AVRs (momentan ATmega32) 
vorstellen.

Es kann
- Multithreading
- Prozesssynchronisation mit Mutex
- verschiedene Timerfunktionen
- FIFOs

Das OS ist an Win32 angelehnt und hat auch entsprechend ähnlich 
klingende Funktionsnamen. Die Threads können dynamisch erstellt und 
beendet werden, man kann auf Threads warten und mit Mutex verwendete 
Ressourcen blockieren/freigeben. Zusätlich sind ein einfaches 
Massage-Event-System und dynamische 10-ms Timer implementiert.

Im Zip-Ordner befindet sich zusätzlich ein Bespiel, welches die 
Funktionen des OS demonstriert und sich mit einem ATmega32 mit RS232 
(z.b. Pollin Evaluation Board) ausprobieren lässt.

Vor der Verwendung bitte die readme.txt lesen.

MfG Mark

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da fehlt noch der Anhang.
Klassiker ;-)

Autor: Mark .. (mork)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hm, ich wusste doch, dass ich igendwas vergessen habe :).
Danke für den Hinweis.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

... und wo ist die Multithreading fähige C-Laufzeitbibliothek

MfG

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was verstehst Du unter Laufzeitbibliothek? Da der AVR architekturbedingt 
nur einen Prozess (Prozess != Thread) ausführen kann, macht so etwas wie 
eine Laufzeitbibliothek keinen Sinn.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark P. wrote:
> Was verstehst Du unter Laufzeitbibliothek?

Schlag es nach. Das ist kein Begriff, bei dem es einen sonderlich großen 
"was verstehst du darunter"-Spielraum gibt.

> Da der AVR architekturbedingt
> nur einen Prozess (Prozess != Thread) ausführen kann, macht so etwas wie
> eine Laufzeitbibliothek keinen Sinn.

Sorry, aber das ist schlicht Unsinn.

Worauf Gast hinaus wollte, ist, dass die AVR-Libc nicht unbedingt mit 
dem Hintergedanken Multithreading-OS entwickelt wurde. Die eine oder 
andere Funktion darin ist nicht reentrant.

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Stefan
Dann hab ich wohl etwas falsch verstanden. Eine Laufzeitbibliothek ist 
für mich eine Lib, die von mehreren Prozessen, die nichts von einander 
wissen, benutzt weden kann um Platz zu sparen, weil dann gleicher Code 
nicht mehrmals vorhanden sein muss. Der AVR kann aber keine unabhängigen 
Prozesse ausführen, da er weder eine MMU hat, noch Code aus dem RAM 
ausführen kann.

Dass die avr-libc nicht unbedingt thread-save ist, ist mir klar. Das ist 
aber bei Verwendung von Interrupts dann genauso, dass der Anwender bei 
"gefährdeten" Funkionen genauer hinschauen muss. Und bei meinem OS gibt 
es Funktionen, die einen Thread blockieren, so dass er nicht von anderen 
unterbrochen werden kann. Eine spezielle c-lib wird deshalb meiner 
Mainung nach nicht benötigt.

MfG Mark

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark P. wrote:

> Dann hab ich wohl etwas falsch verstanden.

Ja, hast du.
Schlag den Begriff einfach nach (z.B. bei Wikipedia).

> Der AVR kann aber keine unabhängigen
> Prozesse ausführen, da er weder eine MMU hat, noch Code aus dem RAM
> ausführen kann.

Beides sind keine Ausschlusskriterien für "unabhängige Prozesse".

> Dass die avr-libc nicht unbedingt thread-save ist, ist mir klar. Das ist
> aber bei Verwendung von Interrupts dann genauso, dass der Anwender bei
> "gefährdeten" Funkionen genauer hinschauen muss.

Ja, aber bei der Verwendung von Threads rückt das Problem deutlich 
stärker in den Vordergrund.

> Und bei meinem OS gibt
> es Funktionen, die einen Thread blockieren, so dass er nicht von anderen
> unterbrochen werden kann. Eine spezielle c-lib wird deshalb meiner
> Mainung nach nicht benötigt.

"Nötig" nicht (sagt ja auch keiner), aber eine Lib mit threadsicheren 
Varianten der Funktionen (eben unter Zuhilfenahme der vom OS angebotenen 
Funktionalität) wäre nicht unbedingt eine überflüssige Zugabe.

Autor: Harald Freudenberger (snuggles)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hört sich sehr interessant an. Deine Implementierung werd ich mir mal 
anschauen. Ich hatte vor ein paar Tagen selbst ein bischen Assemblercode 
geposted (siehe 'multithreading auf dem AVR') der es erlaubt genau einen 
weiteren Thread aufzumachen. Mein Gedanke war, das ganze so klein wie 
möglich zu halten. Immerhin braucht ja jeder Thread seinen eigenen Stack 
Space und zusammen mit z.B. einem Ethernet Device Driver + TCP/IP Stack 
+ Webserver wird es ja dann irgendwann schon ein bischen eng bez. RAM.
Mich interressiert vor allem, wie du das ganze pop/push aller Register 
beim Thread Wechsel gelößt hast...

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan
Ok ok hab mir die Definition von Laufzeitbibliothek nochmal genau 
angeguckt und Du hattest da recht. Ich hab es mit einer dynamischen 
Bibliothek verwechelt.

>> Der AVR kann aber keine unabhängigen
>> Prozesse ausführen, da er weder eine MMU hat, noch Code aus dem RAM
>> ausführen kann.

>Beides sind keine Ausschlusskriterien für "unabhängige Prozesse".

Man könnte natürlich einen Compiler+Linker bauen, der Code für den AVR 
erzeugt, bei dem sowohl das text- als auch das data-Segment zur Laufzeit 
beliebig verschoben werden könnten. Mit dem normalen avr-gcc geht das 
aber nicht, weder das eine noch das andere.

>> Dass die avr-libc nicht unbedingt thread-save ist, ist mir klar. Das ist
>> aber bei Verwendung von Interrupts dann genauso, dass der Anwender bei
>> "gefährdeten" Funkionen genauer hinschauen muss.

>Ja, aber bei der Verwendung von Threads rückt das Problem deutlich
>stärker in den Vordergrund.

>> Und bei meinem OS gibt
>> es Funktionen, die einen Thread blockieren, so dass er nicht von anderen
>> unterbrochen werden kann. Eine spezielle c-lib wird deshalb meiner
>> Mainung nach nicht benötigt.

>"Nötig" nicht (sagt ja auch keiner), aber eine Lib mit threadsicheren
>Varianten der Funktionen (eben unter Zuhilfenahme der vom OS angebotenen
>Funktionalität) wäre nicht unbedingt eine überflüssige Zugabe.

Mein OS war nicht dazu gedacht, um einen PC durch einen AVR ersetzen zu 
können, sondern ist nur deswegen entstanden, weil man mit Threads 
gewisse Sachen einfacher bzw. schneller lösen kann als ohne. Deshalb 
bein ich persönlich der Meinung, dass eine extra angepasste C-Bibliothek 
komplett oversized wäre.

MfG Mark

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Harald

Ich hab mir mal Deinen Code angeschaut, und im Prinzip macht es das 
selbe wie meiner, nur dass bei mir der nächste Thread aus einem 
Ringbuffer ausgelesen wird.

>Mich interressiert vor allem, wie du das ganze pop/push aller Register
>beim Thread Wechsel gelößt hast...

Genauso wie Du, sprich es werden alle Register gepusht, der SP 
gewechselt und alle Register wieder gepoppt. Hab das mal nechgerechnet, 
bei 1000Hz Threadwechsel @16MHz sind es etwa 1.1% Rechenleistung. Geht 
eben nicht anders.

MfG Mark

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark P. wrote:

> Man könnte natürlich einen Compiler+Linker bauen, der Code für den AVR
> erzeugt, bei dem sowohl das text- als auch das data-Segment zur Laufzeit
> beliebig verschoben werden könnten. Mit dem normalen avr-gcc geht das
> aber nicht, weder das eine noch das andere.

text-Segment zur Laufzeit verschieben:
Unnötig.

data-Segment zur Laufzeit verschieben:
Umkopieren des Speichers, was vom OS beim Prozesswechsel zu erledigen 
wäre.

Startupcode und Linkerscript wären zu ändern, aber mit dem Compiler an 
sich hat das alles nichts zu tun. Auch mit dem avr-gcc in seiner 
jetzigen Form wäre ein OS mit "unabhängigen Prozessen" machbar. 
Natürlich wäre das weit entfernt von "effizient" oder "sinnvoll", aber 
prinzipiell machbar wäre es schon.

> Mein OS war nicht dazu gedacht, um einen PC durch einen AVR ersetzen zu
> können, sondern ist nur deswegen entstanden, weil man mit Threads
> gewisse Sachen einfacher bzw. schneller lösen kann als ohne.

Wass soll das denn jetzt mit dem Vergleich zum PC?
Wie ich bereits sagte, ist es natürlich nicht absolut nötig, aber es 
wäre auch alles andere als "oversized" oder "überflüssiger Luxus", wenn 
man z.B. eine malloc-Variante anbieten würde, die einfach das vorhandene 
malloc im Rahmen der OS-Möglichkeiten kapselt.

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan

>text-Segment zur Laufzeit verschieben:
>Unnötig.

Und wie soll das gehen? Wenn auf einem Controller ohne MMU zwei Prozesse 
laufen sollen, die nichts von einander wissen, dann bedeutet es, dass 
sie sich an verschiedenen Stellen im Speicher befinden. Da der Compiler 
aber nicht zu compile-Zeit weiss, wo sich die erstellte Anwendung im 
Flash befinden wird, muss er den Code so schreiben, dass er von jedem 
Ort aus lauffähig wär. Und das kann_ der normale avr-gcc _nicht.

>data-Segment zur Laufzeit verschieben:
>Umkopieren des Speichers, was vom OS beim Prozesswechsel zu erledigen
>wäre.

Sollen da bei jedem einzelnen Prozesswechsel Kilobytes an Speicher 
bewegt werden oder wie stellst Du Dir das vor?

>Wass soll das denn jetzt mit dem Vergleich zum PC?

Das war eine sehr starke Übertreibung, um mein Anliegen zu 
verdeutlichen.

>Wie ich bereits sagte, ist es natürlich nicht absolut nötig, aber es
>wäre auch alles andere als "oversized" oder "überflüssiger Luxus", wenn
>man z.B. eine malloc-Variante anbieten würde, die einfach das vorhandene
>malloc im Rahmen der OS-Möglichkeiten kapselt.

Finde ich nicht. Wenn Du solche Funktionen haben willst, kannst Du sie 
ja gerne schreiben. Ich benutze das OS seit ein paar Monaten (kein allzu 
langer Zeitraum, ich weiss) und hab sowas noch nie benötigt.

MfG Mark

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark P. wrote:

> Und wie soll das gehen? Wenn auf einem Controller ohne MMU zwei Prozesse
> laufen sollen, die nichts von einander wissen, dann bedeutet es, dass
> sie sich an verschiedenen Stellen im Speicher befinden. Da der Compiler
> aber nicht zu compile-Zeit weiss, wo sich die erstellte Anwendung im
> Flash befinden wird, muss er den Code so schreiben, dass er von jedem
> Ort aus lauffähig wär. Und das kann_ der normale avr-gcc _nicht.

Totaler Quatsch. Auch jetzt weiß der Compiler nicht, wo im Flash der 
Code letztlich landen wird. Schlag mal nach, was der Linker ist und 
macht.

> Sollen da bei jedem einzelnen Prozesswechsel Kilobytes an Speicher
> bewegt werden oder wie stellst Du Dir das vor?

Ja natürlich. Was meinst du, wie es ein "richtiges" Multitasking-BS (wie 
z.B. Linux) auf einem Prozessor ohne MMU (z.B. 68000) macht?
Außerdem sagte ich ja bereits, dass es ineffizient ist. Es geht ja auch 
nur ums Prinzipielle, schließlich hast du behauptet, dass es 
grundsätzlich nicht gehen würde.

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan

>Totaler Quatsch. Auch jetzt weiß der Compiler nicht, wo im Flash der
>Code letztlich landen wird. Schlag mal nach, was der Linker ist und
>macht.

Dann weiss es eben der Linker. Und dieser muss nun mal z.B. beim 
jmp-Befehl die Labels in absolute Adressen auflösen können. Und das ist 
der Knackpunkt.

>Ja natürlich. Was meinst du, wie es ein "richtiges" Multitasking-BS (wie
>z.B. Linux) auf einem Prozessor ohne MMU (z.B. 68000) macht?
>Außerdem sagte ich ja bereits, dass es ineffizient ist. Es geht ja auch
>nur ums Prinzipielle, schließlich hast du behauptet, dass es
>grundsätzlich nicht gehen würde.

Das bei z.B. µCLinux bei jedem Prozesswechsel das ganze data-Segment, 
welches durchaus einige MB haben kann, umkopiert, wird glaube ich nicht. 
Ich weiss zwar nicht wie es gemacht wird, aber ich vermute, dass das OS 
dem Prozess beim Start das Offset des data-Segments übergibt, sodass der 
Prozess auf globale Variablen immer über dieses Offset zugreift.

MfG Mark

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da der Thread sowieso schon stark off topic ist, mal eine eher 
allgemeine Frage zum Multithreading auf AVRs:
Wie sieht das eigentlich bei 16bit Zugriffen auf Register aus? Diese 
benutzen doch dieses interne Highbyte Register. Wenn genau zwischen dem 
Zugriff auf die beiden High/Low Register umgeschaltet wird, und der 
andere Thread auch ein 16bit Register liest oder schreibt, dürfte im 
ersten Thread Mist rauskommen, da der alter Wert in dem Highbyte 
Register dann überschrieben ist. Oder sehe ich das falsch?

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Benedikt

Du siehst es richtig. Deshalb sollte man den Zugriff auf Ressourcen, die 
von mehreren Threads verwendet werden, mit Mutex regeln oder bei kurzen 
Zugriffen die Interrupts abschalten. Um zu vermeiden, dass ein Thread 
über einen längeren Zeitraum nicht von einem anderen Thread unterbrochen 
werden darf, aber die Interrupts trotzdem aktiviert bleiben sollen, gibt 
es bei meinem OS extra Funktionen, die das regeln.

MfG Mark

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.