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
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.
@ 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.
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?
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.
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.
> 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
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.
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.
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
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.
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.