Forum: Mikrocontroller und Digitale Elektronik Beispiele fuer Betriebssysteme


von Owen S. (senmeis)


Lesenswert?

Servus,

ich verwerde einen XC164CM und uVision3 von Keil. Keil bietet ein 
kleines Betriebssystem RTX166 Tiny an. Nun will ich zwei Beispiele 
schreiben, mit und ohne das Betriebssystem, um zu zeigen, wie nötig 
dieses ist. Bisher fallen mir noch keine sinnvollen eindeutigen 
Beispiele ein. Kann mir jemand was beibringen?

MfG
Senmeis

von Albert .. (albert-k)


Lesenswert?

Schreib mal ein Programm welches 2 Tasks hat die auf einen shared memory 
zugreifen. Wenn einer der tasks auf den Bereich zugreift muss der andere 
Task am Zugriff gehindert weren (Stichpunkt Semaphore oder Mutex). Diese 
Behinderung darf nicht busy-waiting sein sondern muss den Task in den 
"blocked" Zustand versetzen und wieder starten sobald der shared memory 
wieder verfügbar ist (der andere task ist fertig mit seinem Zugriff und 
gibt den shared Memory wieder frei).
Das ist mit einem Betriebssystem sehr leicht zu realisieren. Auf dem 
reinen Mikrocontroller jedoch nicht ganz trivial.

von Peter (Gast)


Lesenswert?

@ Albert
das ist aber schon ein konkrete umsetzung eines Problemes. Wenn ich kein 
Betriebsystem habe, würde ich vielliecht nicht auf die Idee kommen 
überhaupt 2 Task zu verwenden. Damit macht am ende das Programm 
vermutlich das gleiche auch ohne BS.

von Alexander V. (avogra)


Lesenswert?

Was spricht denn gegen ein konkretes Beispiel? Dazu sind Beispiele doch 
da. Prinzipiell lässt sich vermutlich jede Aufgabe auch ohne 
Betriebssystem umsetzen, ist halt oft deutlich einfacher, wenn man eines 
verwendet. Wirklich zwingend nötig wird es also selten sein.
Wozu willst du das ganze denn machen?

von Albert .. (albert-k)


Lesenswert?

Doch, würde ich. Ich habe bsw. einen ADC mit 12bit auf einem 8bit 
Mikrocontroller. Das bedeutet das der Mikrocontroller mindestens zwei 
Befehle braucht um den 12bit Wert irgendwo abzuspeichern. Wenn wir nun 
annehmen das der ADC nur neue Werte reinschreiben darf wenn der alte 
ausgelesen wurde, und eine Routine die den Wert ausliest nur lesen darf 
wenn der ADC was neues fertig geschrieben hat kann es zu 
Zugriffsproblemen kommen.

Wenn bsw. der ADC gerade enen neuen Wert schreibt und die Routine nun 
nach dem ersten byte lesen möchte darf sie dies ja nicht, denn der ADC 
ist ja noch nicht fertig. Man würde also im einfachsten Falle den 
Zugriff durch die Routine unterbrechen und später neu starten. Dies ist 
aber ineffizient, ich müsste ja nur kurz warten bis ich zugreifen darf 
statt viel später es erneut zu versuchen. Hier kommt dann der blocked 
Mechanismus zum Einsatz.

Wenn ich nicht über den "blocked" Mechanismus arbeite verschwende ich 
Rechenzeit da die Routine es zyklisch immer wieder probiert bis sie es 
kann. Dasselbe für den ADC, soalnge noch nicht ausgelesen wurde probiert 
er immer wieder was neues reinzuschreiben bis er es darf. Busy Waiting 
ist auch blöd, denn zwischenzeitlich kann ich ja schonmal was anderes 
machen.

von Peter (Gast)


Lesenswert?

Albert ... schrieb:
> Wenn ich nicht über den "blocked" Mechanismus arbeite verschwende ich
> Rechenzeit da die Routine es zyklisch immer wieder probiert bis sie es
> kann. Dasselbe für den ADC, soalnge noch nicht ausgelesen wurde probiert
> er immer wieder was neues reinzuschreiben bis er es darf. Busy Waiting
> ist auch blöd, denn zwischenzeitlich kann ich ja schonmal was anderes
> machen.

es gibt auch mit einem BS und mehren Task nicht mehr Rechenzeit, es ist 
sogar weniger als wenn man kein BS und keine Task hat.
Warum sollte man ohne Task denn warten, man kann sich genau so eine 
Liste von Aufgaben aufbauen und bei jedem durchlauf schauen ob jetzt der 
passende Zeitpunkt zum ausführen ist.
Das das ganze etwas komplizierter ist und auch etwas mehr Planung 
erforder ist klar. Das hat aber auch den Vorteil das es jetzt ebend 
keine gleichzeitige zugriffe gibt die man sonst erst wieder verhindern 
müsste. Auch die Fehlersuche ist einfachen wenn nicht mehrere Dinge 
gleichzeitig laufen.

von user (Gast)


Lesenswert?

> Warum sollte man ohne Task denn warten, man kann sich genau so eine
> Liste von Aufgaben aufbauen und bei jedem durchlauf schauen ob jetzt der
> passende Zeitpunkt zum ausführen ist.

das ist genau der Kern was ein Betriebsystem macht. also im prinzip, 
wenn du sowas machst hast du schon ein kleines betriebsystem geschrieben

von Albert .. (albert-k)


Lesenswert?

Ich denke nicht das es die Frage des  Threadstartes ist ob ein OS für 
solche Aufgaben Sinnig oder Unsinnig ist, sondern was man als Beispiel 
heranziehen könnte. Dies ist das gängigste und beste Beispiel um einen 
den Vorteil eines OS zu zeigen => Abstraktion!

P.S.
Wenn man direkt auf dem Controller programmiert und die Aufgaben 
entsprechend timed ist man natürlich effizienter, aber es ist auch 
deutlich aufwendiger. Und ab einer bestimmten Anzahl an Tasks kannst du 
vergessen diese effizient zu parallelisieren. Dann spielt das OS seine 
Vorteile aus.

von Marcus W. (Gast)


Lesenswert?

Peter schrieb:
> Auch die Fehlersuche ist einfachen wenn nicht mehrere Dinge
> gleichzeitig laufen.

Man braucht ja nicht zwingend ein BS mit preemption-Mechanismus.
Auch statisches oder kooperatives Scheduling gehört laut Definition zum 
BS.

Ist alles eine Frage der Anwendung:
Hast du nur deterministische Ereignisse/Interupts die auftreten, so 
wirst du vielleicht schon mit einem normalen Loop hinkommen. Sind die 
Ereignisse stochastisch und die Periodendauer/Ausführungszeit der 
Ereignisse stark verschieden (und evtl. noch eine sehr hohe 
Systemauslastung ~80%) so wirst du um komplexere Methoden mit preemption 
nicht herumkommen.

von Peter D. (peda)


Lesenswert?

Albert ... schrieb:
> Wenn einer der tasks auf den Bereich zugreift muss der andere
> Task am Zugriff gehindert weren (Stichpunkt Semaphore oder Mutex).

Das ist ein Problem, welches nur bei einem OS auftreten kann und dort 
extra gelöst werden muß.
Bei einem Mainloop-Programm läuft immer nur eine Task und die kann daher 
ungehindert zugreifen.

Der Unterschied ist daher an anderer Stelle:
In einem OS kann man Tasks so schreiben, daß sie unendlich warten und 
unendlich laufen.

In der Mainloop muß man Tasks so schreiben, daß sie nach einer 
bestimmten Zeit wieder zum Main zurückkehren, damit andere Tasks zum 
Zuge kommen. Die Task muß sich z.B. in einer State-Variable merken, wo 
sie beim nächsten Aufruf weiter macht.


Was nun komplizierter ist, ist daher schwer zu sagen.
Die OS-Task muß für jeden Ressourcenzugriff spezielle Funktionen 
benutzen, muß aber auf andere Tasks keine Rücksicht nehmen.
Die Mainloop-Task kann nach Belieben alle Ressourcen direkt verwenden, 
darf aber nirgends blockieren.


Was man aber sagen kann, ein OS benötigt deutlich mehr CPU-Zeit und RAM.

Peter

von Marcus W. (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Albert ... schrieb:
>> Wenn einer der tasks auf den Bereich zugreift muss der andere
>> Task am Zugriff gehindert weren (Stichpunkt Semaphore oder Mutex).
>
> Das ist ein Problem, welches nur bei einem OS auftreten kann und dort
> extra gelöst werden muß.

Ist Korrekt, aber spezieller:
Dieses Problem, kann nur bei Betriebssystemen/Scheduling-strategien mit 
preemption auftreten.

Peter Dannegger schrieb:
> In der Mainloop muß man Tasks so schreiben, daß sie nach einer
> bestimmten Zeit wieder zum Main zurückkehren, damit andere Tasks zum
> Zuge kommen. Die Task muß sich z.B. in einer State-Variable merken, wo
> sie beim nächsten Aufruf weiter macht.

Kooperatives Multitasking (ohne preemption)...
Das ist ebenfalls ein Mini-Betriebssystem

Jede Task gibt freiwillig die Kontrolle an den Scheduler - in deinem 
Fall die einfache main-loop - zurück.

von Karl H. (kbuchegg)


Lesenswert?

> Nun will ich zwei Beispiele
> schreiben, mit und ohne das Betriebssystem, um zu zeigen,
> wie nötig dieses ist.

Ich denke:
Im Prinzip ist ein BS niemals wirklich 'nötig'. 'nötig' in dem Sinne das 
es ohne gar nicht geht. Aber ein BS kann natürlich Dinge vereinfachen, 
indem man den Programmierer
a) von Standardaufgaben entlastet
b) eine Umgebung schafft, in der er auftragsbezogen arbeiten kann

Der Auftrag laute:
Bringen sie 2 LED zum blinken, die eine mit 5Hz die andere mit 7Hz

Habe ich ein BS, welches Multitasking unterstützt, dann ist das eine 
ganz einfache Aufgabe, in der der Auftrag ziemlich 1:1 umgesetzt werden 
kann: Jeder LED wird ein Task zugeordnet. Mittels sleep, wait oder was 
auch immer wird es so eingerichtet, dass sich die Frequenzen ergeben. 
Fertig.

Ohne BS kann ich diese Aufgabe natürlich auch lösen, keine Frage. Aber 
die Denkweise ist eine völlig andere und zwar weg von der 
Auftragsbeschreibung. Ich brauche einen Basistakt und eine 
Hauptschleife, weiters rechne ich mir aus nach wievielen 
Basistalteinheiten eine Umschaltung welcher LED erfolgen muss. Ich muss 
also selbst mit Hilfe des Basistakts die beiden Teilaufgaben so 
ineinander verchachteln, dass sich das Gewünschte ergibt.

Bei der Lösung mit Tasks brauchte ich das nicht. Jeder Task konzentriert 
sich auf seine Aufgabe: seine LED mit der richtigen Frequenz zum Blinken 
zu bekommen. Was die anderen Tasks machen interessiert ihn nicht weiter.

Da liegt für mich ein fundamentaler Unterschied in der Denkweise und in 
der Art wie man derartige Probleme mit und ohne BS angehen kann.

Aber nötig, im Sinne von 'ohne gehts nicht', ist ein BS sicherlich 
nicht.
Es vereinfacht die Dinge.     Manchmal.

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.