Multitasking im Mikrocontroller

T

Thomas Finke

Guest
Hallo,

es wird ja bei Mikrocontrollerprojekten oft eine Art Multitasking im
Mikrocontroller implementiert, da z.B. alle paar Millisekunden eine
Tastatur abgefragt werden soll...dann werden evtl. noch
7-Segment-Anzeigen durch Multiplexing angesteuert um Ports zu
sparen...

Wie wird dieses Multiplexing denn programmtechnisch (interessant wäre
Assembler und C) realisiert? Wie werden die Tasks zeitlich verwaltet?
Weil ja z.B. beim 7-Segement-Multitasking die Segmente alle gleich
lang angesteuert und gleich lang stromlos sein sollten, dass die
Helligkeit einigermaßen stimmt.

Ich weiß zwar, dass dies eine Elektronik-Newsgroup ist und keine
über's Programmieren...aber hier wird es sicher einige Programmierer
geben, die sowas schon des Öfteren implementiert haben.

Mir ist auch bekannt, dass es zig verschiedene Arten von Multitasking
gibt, aber vielleicht kann mir trotzdem jemand kurz auf die Sprünge
helfen, wie ich sowas am einfachsten in nen Controller implementiere.

Danke,

Thomas
 
"Thomas Finke" <finke.thomas@gmx.de> schrieb im Newsbeitrag
news:r7i5s1pa13262b8ecub0hep2qj16dvkrc7@4ax.com...
es wird ja bei Mikrocontrollerprojekten oft eine Art Multitasking im
Mikrocontroller implementiert,

Vergiss den Begriff Multitasking.
So etwas gibt es nur ganz selten.

Was gemacht wird heisst 'ereignisgesteuert' (event driven) und die
Ereignisse beim uC sind Interrupts, vor allem vom Zeitgeber (timer).

Wenn also jede Millisekunde die naechste Stelle ins Display soll,
dann wird auf einen Zeitgeber-Interrupt das Hauptsprogramm
unterbrochen und eine Funktion ausgefuehrt, die eben die naechste
Stelle ins Display schreibt und danach zurueckkehrt.

Das Hauptprogramm macht (nach Initialisierung des Zeitgebers und
der Ports) irgendwas unwichtiges (Daeumchen drehen :)

Alternativ fuer ganz einfache Faelle macht das Hauptprogramm der
Reihe nach ALLES und wiederholt sich gleich wieder in einer Schleife.
Bei jeder Einzelaktion wird gefragt, ob sie in dieser Runde
auch ausgefuehrt werden soll, oder uebersprungen wird.

for(;;)
{
if(tasten) tastenlesen();
if(display) zeigedaten();
ausgangspinssetzen();
}

Man /kann/ so ein Programm so schreiben, das es auf jedem Weg immer
dieselbe Zeit braucht, dann kann es SCHNELL und GENAU reagieren
und das kann leicht GARANTIERT werden.


for(;;)
{
if(tasten) tastenlesen(); else vertue(12);
if(display) zeigedaten(); else vertue(22);
ausgangspinssetzen();
}

--
Manfred Winterhoff, reply-to invalid, use mawin at gmx dot net
homepage: http://www.geocities.com/mwinterhoff/
de.sci.electronics FAQ: http://dse-faq.elektronik-kompendium.de/
Read 'Art of Electronics' Horowitz/Hill before you ask.
Lese 'Hohe Schule der Elektronik 1+2' bevor du fragst.
 
Thomas Finke wrote:

es wird ja bei Mikrocontrollerprojekten oft eine Art Multitasking im
Mikrocontroller implementiert, da z.B. alle paar Millisekunden eine
Tastatur abgefragt werden soll...dann werden evtl. noch
7-Segment-Anzeigen durch Multiplexing angesteuert um Ports zu
sparen...
In den guten alten 8-Bit-Tagen hieß das einfach nur Interrupt --
Multitasking hatten die Schnösel mit dem Amiga ;-)

Will sagen: Echtes Multitasking -- ob kooperativ oder präemptiv -- ist
mehr als Du auf einem ľC typischerweise brauchst: Du brauchst nicht n
Anwenderprogramme gleichzeitig -- es genügt, wenn der Prozessor sein
*eines* Anwenderprogramm (oder auch seinen Schönheitsschlaf) regelmäßig
unterbricht, um sich Systemaufgaben wie der nächsten Ziffer in der
Multiplex-Anzeige oder der Tastaturabfrage zu widmen.

Wie wird dieses Multiplexing denn programmtechnisch (interessant wäre
Assembler und C) realisiert? Wie werden die Tasks zeitlich verwaltet?
Weil ja z.B. beim 7-Segement-Multitasking die Segmente alle gleich
lang angesteuert und gleich lang stromlos sein sollten, dass die
Helligkeit einigermaßen stimmt.
Ein Timerinterrupt alle paar Millisekunden sollte genügen.

Michael
 
Bei jeder Einzelaktion wird gefragt, ob sie in dieser Runde
auch ausgefuehrt werden soll, oder uebersprungen wird.
Und das wird bei jedem Timer-Interrupt neu festgelegt, was beim
nächsten Durchgang ausgeführt werden soll und was nicht?
Gibt's da wiederum eine Struktur die man einhalten sollte, damit die
Interrupt-Routine nicht zu groß wird?


Dann noch ne Frage zu den eigentlichen Funktionen die aufgerufen
werden sollen.
Ich habe mal gesehen, dass sehr zeitintensive Funktionen immer nur
einen kleinen Teil des Programmcodes abarbeiten, dann die Funktion
verlassen...damit andere Funktionen auch mal zum Zuge kommen...und
beim nächsten Aufruf arbeitet die Funktion an der Stelle weiter wo sie
vorher rausgesprungen ist...das ganze halt durch ne Variable gemerkt
wo es weitergehen soll.
Wird dies auch so verwendet? Wenn ja, ist es ok die Funktion einfach
zu verlassen und z.B. mit einer SELECT CASE Struktur abzufragen wo es
weitergehen soll....oder gibt es da nen besseren Weg?

Thomas
 
Thomas Finke wrote:

Und das wird bei jedem Timer-Interrupt neu festgelegt, was beim
nächsten Durchgang ausgeführt werden soll und was nicht?
Idealerweise baut man sich eine State-Machine, in dem Fall
auch einfach mitzählen :)

void oninterrupt()
{
digit=(digit+1)%4;
ShowDigit(digit);
}

oder so...

Gibt's da wiederum eine Struktur die man einhalten sollte, damit die
Interrupt-Routine nicht zu groß wird?
Es sollte einfach möglichst wenig unnötiger (Prüf-)Code ablaufen.


Ich habe mal gesehen, dass sehr zeitintensive Funktionen immer nur
einen kleinen Teil des Programmcodes abarbeiten, dann die Funktion
verlassen...damit andere Funktionen auch mal zum Zuge kommen
Idealerweise packt man die langen Funktionen ins Hauptprogramm und
die kleinen Funktionen die auch mal zum Zug kommen sollen in den
Interrupt, dann funktioniert das verlassen und weitermachen nämlich
automatisch.
Ansonsten ist eine State-Machine per switch case vermutlich keine
schlechte Idee...
 
"Thomas Finke" <finke.thomas@gmx.de> schrieb im Newsbeitrag
news:1dj5s1trporrenso250kr979m8gmvqr6oo@4ax.com...
Und das wird bei jedem Timer-Interrupt neu festgelegt, was beim
nächsten Durchgang ausgeführt werden soll und was nicht?
Beim Dispaly: Beim naechsten ist halt die Stelle um 1 hochgezaehlt,
die Funktion nimmt sich die naechste Stelle vor.

Gibt's da wiederum eine Struktur die man einhalten sollte, damit die
Interrupt-Routine nicht zu groß wird?

Na, wenn dein Programm jede Millisekunde einen Zeitgeber-Interrupt
ausloest, ist es halt doof, wenn die Zeitgeber-Funktion laenger
als 1 msec braucht.
Ich habe mal gesehen, dass sehr zeitintensive Funktionen immer nur
einen kleinen Teil des Programmcodes abarbeiten, dann die Funktion
verlassen...damit andere Funktionen auch mal zum Zuge kommen...und
beim nächsten Aufruf arbeitet die Funktion an der Stelle weiter wo sie
vorher rausgesprungen ist...das ganze halt durch ne Variable gemerkt
wo es weitergehen soll.
Wenn das nur 1 Funktion ist, macht man das im Hauptprogramm, das dreht
sonst ja nur Daeumchen.

Wird dies auch so verwendet? Wenn ja, ist es ok die Funktion einfach
zu verlassen und z.B. mit einer SELECT CASE Struktur abzufragen wo es
weitergehen soll....oder gibt es da nen besseren Weg?

Kommt drauf an. Letztlich ist immer DAS EINFACHSTE der beste Weg.

(Bruce Eckel: Subtraction: a design is finished when you cannot take
anything else away)

Wie weit du ein Programm vereinfachen kannst (damit es immer noch
seine Aufgabe erfuellt) liegt an dir, gute Programmierer machen
halt einfache kleine schnelle uebersichtliche Programme.

Es kann sinnvoll (notwendig) sein, beim Interrupt erst mal nur eine
kurze Funktion auszufuehren (schnelle Reaktion), dabei einen Wert
zu setzen der 'Nacharbeit' ankuendigt, und diese Nacharbeit weniger
wichtig ausfuehren zu lassen (dabei sollte die Nacharbeit aber nicht
pro Ereignis stattfindne, sondern viele Ereignisse zusammenfassen),
und wenn nichts zu tun ist macht man ganz unwichtiges.
--
Manfred Winterhoff, reply-to invalid, use mawin at gmx dot net
homepage: http://www.geocities.com/mwinterhoff/
de.sci.electronics FAQ: http://dse-faq.elektronik-kompendium.de/
Read 'Art of Electronics' Horowitz/Hill before you ask.
Lese 'Hohe Schule der Elektronik 1+2' bevor du fragst.
 
Thomas Finke <finke.thomas@gmx.de> wrote:

es wird ja bei Mikrocontrollerprojekten oft eine Art Multitasking im
Mikrocontroller implementiert,
Naja, oft wohl eher nicht.

da z.B. alle paar Millisekunden eine
Tastatur abgefragt werden soll...dann werden evtl. noch
7-Segment-Anzeigen durch Multiplexing angesteuert um Ports zu
sparen...
Das macht man mit Interrupts.

Wie wird dieses Multiplexing denn programmtechnisch (interessant wäre
Assembler und C) realisiert?
Das steht bei Assembler im Handbuch des Prozessors, und bei C im
Handbuch des Compilers. Und das ist auch keinesfalls zwischen
verschiedenen CPU-Typen 1:1 uebertragbar. Lediglich das Konzept kann
man mitnehmen. Aber auch da kann man auf die Nase fallen. Z.b hat es
mich oft geraergert das die AVRs keine priorisierten IRQs kennen.

Wie werden die Tasks zeitlich verwaltet?
An erster Stelle im Hirn des Programmierers. Soll heissen du musst
wissen wie wichtig eine bestimmte Aufgabe ist und wie oft sie
auftritt.

Weil ja z.B. beim 7-Segement-Multitasking die Segmente alle gleich
lang angesteuert und gleich lang stromlos sein sollten, dass die
Helligkeit einigermaßen stimmt.
Timer-IRQ.

Olaf
 
Thomas Finke <finke.thomas@gmx.de> wrote:

Gibt's da wiederum eine Struktur die man einhalten sollte, damit die
Interrupt-Routine nicht zu groß wird?
Du solltest sicherstellen das die IRQ-Routine nicht laenger dauert als
die Zeit bis zum naechsten IRQ. :)
Das kannst du z.B durch abzaehlen der Taktzyklen erreichen. Oder man
setzt am Eingang einen Port und loescht dem am Ausgang und schaut sich
am Ossi das Taktverhaeltnis an.

Ich habe mal gesehen, dass sehr zeitintensive Funktionen immer nur
einen kleinen Teil des Programmcodes abarbeiten, dann die Funktion
verlassen...damit andere Funktionen auch mal zum Zuge kommen...und
beim nächsten Aufruf arbeitet die Funktion an der Stelle weiter wo sie
vorher rausgesprungen ist...das ganze halt durch ne Variable gemerkt
wo es weitergehen soll.
Wird dies auch so verwendet?
Nein, eher nicht.

Wenn ja, ist es ok die Funktion einfach
zu verlassen und z.B. mit einer SELECT CASE Struktur abzufragen wo es
weitergehen soll....oder gibt es da nen besseren Weg?
Ich wuerde so ein Vorgehen fuer toedlich halten was das Verstaendnis
eines Programmes angeht. Es ist besser sich vorher genau Gedanken zu
machen was ein Programm machen soll und in wie du es am besten
aufteilen kannst. Dann gibt es Dinge die wirklich wichtig sind und
andere Dinge koennen warten. Z.B darf eine Ansteuerung eines
gemultiplexten Segments nichts aus dem Tritt geraten. Allerdings
reicht es aus im wichtigen IRQ wirklich nur die einzelnen Segmente
auszugeben. Das berechnen von Ausgabewerten und die Uebernahme davon
kann dagegen irgendwann mal geschehen.

Ausserdem sollte man Dinge die sehr wichtig sind und immer statt
finden muessen, sehr kurz halten.

Olaf
 
Thomas Finke wrote:

Wie wird dieses Multiplexing denn programmtechnisch (interessant wäre
Assembler und C) realisiert? Wie werden die Tasks zeitlich verwaltet?
Du musst zunächst zwischen präemptiven (also verdrängendem) und
kooperativen (nichtverdrängendem) Multitasking unterscheiden.

Kooperatives Multitasking bedeuted einfach nur, dass die Aufgaben
abwechselnd drankommen und jede einzelne Aufgabe (jeder "Task") jeweils
"abgibt", wenn ein Teil seiner Arbeit fertig ist. Nachteil hier ist,
dass falls ein Task abstürzt, das ganze System steht: wenn du also
beispielsweise einen Task hast, der ein LCD-Display aktualisieren soll
und auf ein Busy-Flag wartet. Das LCD wird abgesteckt oder geht kaputt,
dadurch wird Busy dauerhaft HIGH. Wenn dein einzelnes Programm diesen
Fall nicht abprüft, steht das System (hängt sich auf). Vorteil ist, dass
du recht wenig Overhead zum Managen der Tasks hast.

Beim präemptiven Multitasking können alle Prozesse so programmiert
werden, als würden sie als einziges Programm auf der Maschine laufen:
alle heilige Zeit kommt ein Timer-Interrupt, der dann den Scheduler
aufruft. Der Scheduler merkt sich, welcher Prozess gerade aktiv war und
an welcher Stelle im Code dieser Prozess sich gerade befunden hat. Dazu
sichert er dann alle CPU-Flags (beispielsweise aus einer
Compare-Operation die Condition Codes) sowie den Stackpointer an eine
definierte Stelle im speicher. Dann werden all diese Werte "verbogen",
also die CPU-Flags von Prozess2, der SP von Prozess2 und die Condition
Codes geladen und an die Stelle zurückgesprungen, an der Prozess2
zuletzt war. Vorteil hier: wenn der Scheduler funktioniert, kann das
System nicht abstürzen, nur einzelne Prozesse. Nachteil: du musst vorher
wenigstens ein bischen über das Speicherlayout nachdenken. Wenn du also
mehrere "virtuelle" Stacks auf einen physikalischen Stack abbildest,
definierst du einfach vorher, dass von Memorystelle 0-31 alles Prozess1
gehört, von 32-63 alles Prozess2 und so weiter. Wenn du einen einfachen
uC nimmst, der keine MMU und damit auch keine Speicherschutzmechanismen
anbietet, dann können Prozesse in den Speicherraum der anderen Prozesse
reinschreiben (wenn beispielsweise rekursive Funktionen einen zu hohe
Schachtelungstiefe erreichen). Das wäre also _die_ Katastrophe für so
eine Systemarchitektur.

Wie auch immer: es ist ein Haufen Aufwand, präemptives Multitasking zu
realisieren. Viel einfacher ist kooperatives MT. Auch beim Scheduling
(also das Verteilen der Zeitscheiben) kannst du nach belieben vorgehen:
es gibt einfache RR-Scheduler (Round-Robin, also einer nach dem
anderen), SPF (Shortest Process First => der Prozess, der als nächstes
wohl die geringste Zeit braucht, kommt dran) bishin zu komplexen MFQ
(Multilevel Feedback Queue - mehrere "gestackte" FIFO-Warteschlangen) -
ein Verfahren, das z.B. unter Solaris zum Einsatz kommt (und IIRC sogar
patentiert ist).

Viele Grüße,
Johannes
 
Thomas Finke wrote:
Hallo,

es wird ja bei Mikrocontrollerprojekten oft eine Art Multitasking im
Mikrocontroller implementiert, da z.B. alle paar Millisekunden eine
Tastatur abgefragt werden soll...dann werden evtl. noch
7-Segment-Anzeigen durch Multiplexing angesteuert um Ports zu
sparen...

Wie wird dieses Multiplexing denn programmtechnisch (interessant wäre
Assembler und C) realisiert? Wie werden die Tasks zeitlich verwaltet?
Weil ja z.B. beim 7-Segement-Multitasking die Segmente alle gleich
lang angesteuert und gleich lang stromlos sein sollten, dass die
Helligkeit einigermaßen stimmt.
Ich schreibe gerade an einem Firmware-Handbuch.
Da sind solche Sachen mannigfaltig erklärt.

http://www.schellong.biz/tmp/ka.pdf

kann einen Eindruck vermitteln.


--
Mit freundlichen Grüßen
Helmut Schellong var@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
 
Hallo,

MaWin schrieb:
...
Das Hauptprogramm macht (nach Initialisierung des Zeitgebers und
der Ports) irgendwas unwichtiges (Daeumchen drehen :)
Man kann Programme schreiben, wo nach der Initialisierung alles
in der Interruptserviceroutine läuft, Siebensegmentanzeige
multiplexen, Tastatur abfragen und entprellen Sekunden, Minuten
und Stunden zählen usw.
Das Hauptprogramm besteht nur aus einem Jump auf sich selber
(dynamischer Halt - Daeumchen drehen).

Funktioniert bei mir in mehreren Küchen- und Belichtungstimern
seit Jahren prima :)

Gruß Reinhard
 
"Thomas Finke" schrieb .

es wird ja bei Mikrocontrollerprojekten oft eine Art Multitasking im
Mikrocontroller implementiert, da z.B. alle paar Millisekunden eine
Tastatur abgefragt werden soll...dann werden evtl. noch
7-Segment-Anzeigen durch Multiplexing angesteuert um Ports zu
sparen...
Hallo Thomas,

dafür brauchst du einen Timerinterrupt und sonst nichts.
Wenn du mehrere Programmteile mit langen Rechen oder Wartezeiten hast,
dann macht (einfaches) Multitasking einen Sinn.
Die rechenintensiven Teile werden dann scheibchenweise abgearbeitet,
wenn nichts wichtigeres zu tun ist.
Die wartenden Teile werden schlafen gelegt und durch das Ereignis auf das
sie warten
wieder aufgeweckt.
Aber wie schon gesagt ... Richtiges Multitasking mit Kommunikation und
Synchronisation
zwischen Tasks sind aber auf Micros selten.

Gruß

Hans-Georg
 
Vergiss den Begriff Multitasking.
So etwas gibt es nur ganz selten.
Die Sprache ADA-97 ist per Definition Multitasking-fähig,
hat aber auch Elemente der Interrupt-Steuerung.

Leider war die Sprache ein Flop, da sie kaum genutzt wurde
und sich gegen C nicht durchsetzen konnte. (ist grob gesagt
ein abgewandeltes C). Jedenfalls gibt es seit einiger Zeit keine
neuen Compiler mehr, da die USA die Gelder gestrichen hat.

Man hat sie im selben Minitsterium umgeschichtet um
aktive Überzeugungsarbeit mit Diskutierwerkszeugen gegen
den Terrorismus zu führen --> F wie Frieden.

Es soll auch Varianten für diverse Microcontroler gegeben haben,
welche genau konnte ich nie in Erfahrung bringen.

Andere Sprachen lassen Multitasking simulieren (hatte mal
ein Buch zu Pascal liegen)
 
Gibt's da wiederum eine Struktur die man einhalten sollte, damit die
Interrupt-Routine nicht zu groß wird?

Du solltest sicherstellen das die IRQ-Routine nicht laenger dauert als
die Zeit bis zum naechsten IRQ. :)
Das kannst du z.B durch abzaehlen der Taktzyklen erreichen. Oder man
setzt am Eingang einen Port und loescht dem am Ausgang und schaut sich
am Ossi das Taktverhaeltnis an.
Wenn die IRQ-Routine nur manchmal länger dauert, als das Timer-Intervall,
kann man bei
einigen Microcontrollern, z.B. 8031 auch eine Zieladresse auf den Stack
schreiben und ein RETI
(Return from Interrupt) ausführen. Das Programm verzweigt dann an die
Zieladresse, an der
der zeitaufwändige Teil abgearbeitet wird. Der Timer-Interrupt kann dann
zwischendurch erneut
aufgerufen werden.
Das funktioniert z.B. dann, wenn du für eine kurze Routine einen 100us Int
benötigst und jedes
1000. Mal eine längere Routine aufrufen willst.

mfg

Stefan
 
(ist grob gesagt ein abgewandeltes C).
Da müssen sie aber schwer geändert haben,
früher wurde Ada als aufgemotztes Pascal
gehandelt.
Es gab ehedem als Ausgangspunkt eine Liste
vorhandener Sprachen die analysiert wurden
ob sie als Grundlage für Ada dienen könnten.
Z.B. auch Pearl, nicht aber FORTH, bei C
hat DoD bei Bell Labs nachgefragt wo ihnen
beschieden wurde für sicherheitskritische
Anwendungen ungeeignet, sodaß auch C nicht
auf der Liste war.
Am Ende der Vorauswahl war die einstimmige
Meinung das Pascal die beste Grundlage
sei. Wobei ein Teilnehmer nachträchlich
allerdings feststellte es wäre damals
politischer Selbstmord gewesen nicht zu
sagen man nehme Pascal als Ausgangspunkt wenn
man in die nächte Runde des Auswahlverfahrens
kommen wollte.

Es soll auch Varianten für diverse Microcontroler
gegeben haben,
DoD hat keine Subsets erlaubt also war Float
erforderlich. Der typische Prozessor war damit
Mil-Std-1750 der Float im Microcode mitmachte.

MfG JRD
 
"MaWin" <me@private.net> wrote:
Es kann sinnvoll (notwendig) sein, beim Interrupt erst mal nur eine
kurze Funktion auszufuehren (schnelle Reaktion), dabei einen Wert
zu setzen der 'Nacharbeit' ankuendigt
Eine Methode die ich gerne anwende ist, eine Zählervariable im RAM zu
definieren, die vom Timerinterrupt (den braucht man eigentlich immer)
dekrementiert wird (es sei denn sie ist bereits 0).

Das Hauptprogramm kann sich dann einfach alle N Interrupts wecken
lassen, indem es N in den Counter schreibt und darauf wartet, daß
er 0 wird. Wenn die CPU sowas unterstützt, packt man noch ein WAIT
oder SLEEP in die Schleife um die CPU bis zum nächsten Interrupt
schlafen zu legen.


XL
 
"Stefan Engler" <Lehrerfreund@web.de> schrieb im Newsbeitrag
news:1136886163.481712.47770@g43g2000cwa.googlegroups.com...
Vergiss den Begriff Multitasking.
So etwas gibt es nur ganz selten.

Leider war die Sprache ein Flop, da sie kaum genutzt wurde
und sich gegen C nicht durchsetzen konnte. (ist grob gesagt
ein abgewandeltes C). Jedenfalls gibt es seit einiger Zeit keine
neuen Compiler mehr, da die USA die Gelder gestrichen hat.

Hallo Stefan,

da muss ich dir etwas wiedersprechen ;-).
Beim Militär und der Luftfahrindustrie wird ADA sehr wohl verwendet.
Dort benutzt man sogar stellenweise redundante Hardware einmal mit C
und einmal mit ADA programmiert.
Sonst ist aber C die Norm. Embedded C++ konnte sich bisher noch nicht
durchsetzen.

Gruß

Hans-georg
 
"Axel Schwenke" schrieb
Wenn die CPU sowas unterstützt, packt man noch ein WAIT
oder SLEEP in die Schleife um die CPU bis zum nächsten Interrupt
schlafen zu legen.
Hallo Axel,

welcher Micro unterstützt das direkt ?
Oder meinst du diese Stromsparmodis ?

Gruß

Hans-Georg
 
"Hans-Georg Lehnard" <hans-georg.lehnard@gmx.de> wrote:
"Axel Schwenke" schrieb

Wenn die CPU sowas unterstützt, packt man noch ein WAIT
oder SLEEP in die Schleife um die CPU bis zum nächsten Interrupt
schlafen zu legen.

welcher Micro unterstützt das direkt ?
Die meisten. Bei AVR heißt das SLEEP, beim 68HC11 heißt es WAI.

Oder meinst du diese Stromsparmodis ?
Ja. BTW: Modi ist bereits Plural von Modus. Modis ist also Quatsch.
~ ~

XL
 
Michael J. Schülke wrote:
Will sagen: Echtes Multitasking -- ob kooperativ oder präemptiv -- ist
mehr als Du auf einem ľC typischerweise brauchst: Du brauchst nicht n
Anwenderprogramme gleichzeitig -- es genügt, wenn der Prozessor sein
*eines* Anwenderprogramm (oder auch seinen Schönheitsschlaf) regelmäßig
unterbricht, um sich Systemaufgaben wie der nächsten Ziffer in der
Multiplex-Anzeige oder der Tastaturabfrage zu widmen.
Ja und nein. Ich habe - lang ist es her - ein Chipkartentelefon mit
integrierter Verzonungsauswertung gemacht, da liefen (auf einem 80C32 @
4,x MHz) insgesamt 13 Prozesse (kooperatives "event polling" mit state
machines) zuzüglich 4 Interrupt-Routinen parallel. Der Code ist
hauptsächlich in C (Keil) geschrieben, einige wenige Funktionen wurden
in Assembler laufzeitoptimiert. ROM-Codegröße knapp unter 32K.

Und die Geräte laufen heute noch.

Beste Grüße

Stefan

--
http://www.svb-wagner.de
 

Welcome to EDABoard.com

Sponsor

Back
Top