Forum: Projekte & Code Multitasking kernel für ATtinys in ASM


von Mark S. (struberg)


Angehängte Dateien:

Lesenswert?

Ein immer wieder auftretendes Problem bei den ATtinys ist das
gleichzeitige Abhandeln mehrerer Aktionen.

Ich habe mir die Mühe gemacht ein kleines cooperatives Multitasking
Systemchen in ASM zu stricken, weil ich für den beengten Speicher der
ATtinys noch nichts derartiges gefunden habe.


Die Eckpunkte:
Speicherverbrauch:
1 byte für Timer
4 byte für Taskhandling
+ 4 byte pro reserviertem Task

CPU-Belastung
ca 70 Taktzyklen für Taskwechsel
ca 70 Taktzyklen für TaskTick-handling
70 CPU-cycles klingt auf den ersten Blick viel sind aber in
Wirklichkeit grade mal 3% der CPU Last, ergo 97% frei für
Userprogramme.

Anwendung:
Das Hauptprogramm initialisiert alle IO und ruft den MosInit auf.
Anschließend werden mit AddTask die einzelnen Tasks eingetragen und das
Multitasking mit einem rjmp mosStartScheduler gestartet.

Jeder Task erledigt die notwendigen Teile, und gibt anschließend mit
rcall MosNextTask die CPU an den nächsten Task ab. Alternativ kann sich
ein Task mit rcall MosSleep (Sleep Wert in MosTicks in R26/R27) eine
gewisse Zeit lang warten. Ein MosTick beträgt standardmäßig 2048
Taktcyklen, also bei 8MHz sind das 256µS. Ein MosSleep(4) wartet also
1ms. Ein MosSleep(0xfffe) wartet also knapp 17 Sekunden Mit
MosSleep(0xffff) kann man den Task anhalten bis er von einem anderen
Task mit MosNotify wieder 'aufgeweckt' wird.
Die MosTicks werden mit dem Timer0 Overflow int (prescaler=8=>256*8)
erzeugt, näheres siehe Beschreibung in den Sourcen.

Eine Tastenentprellung würde also zB folgendermaßen aussehen
(Pseudocode):
lies Taste
wenn Taste gedrückt
MosSleep(8)
Taste noch immer gedrückt? dann kein Tastenprellen
etc...
rjmp zurück auf lies Taste

Und zwischen den beiden Abfragen können alle anderen Tasks machen was
sie wollen...

Das task-switching funktioniert übrigens indem ich mir die beim Call
vom Aufrufer abgelegte Adresse vom Stack hole und in der Taskliste
zwischenspeichere. Dann wird zum nächsten Task geschalten und die
vormals abgelegte Adresse des neuen Tasks auf den Stack gepusht und ein
ret ausgeführt.

Da ich den AVR erst seit einigen Wochen verwende, gibt es sicher einige
Dinge die man noch verbessern kann. Ich hoffe also auf eure Hilfe und
Verbesserungsvorschläge.

LieGrü,
strub

von TravelRec. (Gast)


Lesenswert?

Der Link ist ein - für mich - unlesbares Format. Geht das auch anders
(txt / asm...), dann kann ich vielleicht auch verstehen, worum es geht?

von Axel R. (Gast)


Angehängte Dateien:

Lesenswert?

ich war mal so frei. ZIP sollt egehen - hoffe ich.
Mein RAR-Packer konnte das tar.gz auspacken

von Mark S. (struberg)


Lesenswert?

oh sorry, da ich unter Linux und Solaris arbeite habe ich nicht daran
gedacht.

Geschrieben habe ich das ganze übrigens mit gavrasm
http://www.avr-asm-tutorial.net/gavrasm/index_de.html

und simuliert mit dem AVRsimu
http://www.sourceforge.net/projects/avrsimu

von gerd (Gast)


Lesenswert?

Hallo.

Mir ist nicht so ganz klar, wozu Task Scheduler bei AVRs gut sind.
(Wozu sie bei riesigen Betriebssystemen gut sind, verstehe ich schon.)
Ist doch ein sehr starres Prinzip. Wenn ich meine Software um
Interrupts herum aufbaue, kriegt jeder "Task" sofort das Zepter in
die Hand, wenn er das braucht und gerade kein anderer Int mit höherer
Priorität ansteht. Den Overhead spare ich mir, und nach spätestens 10
us ist der entsprechende Task dran.

mfg
gerd

von Marcel Pokrandt (Gast)


Lesenswert?

na, und wenn du mehr regelmäßige aufgaben als timer hast?

von peter dannegger (Gast)


Lesenswert?

@Gerd

"Mir ist nicht so ganz klar, wozu Task Scheduler bei AVRs gut sind."


Man kann damit Wartezeiten vermeiden, besonders, wenn viel Sachen
gleichzeitig zu machen sind.

Der Scheduler ist aber nur eine Task in der Mainloop, d.h. Sachen, die
ihn nicht brauchen, laufen direkt in der Mainloop, wie sonst auch.

Man könnte ihn auch in einen Timerinterrupt setzen, muß dann aber
darauf achten, daß alle ihm übergebenen Funktionen als Interrupt laufen
(nichtatomare Parameterzugriffe unter Interruptsperre usw.).


Allerdings programmiere ich sowas lieber in C:

http://www.mikrocontroller.net/forum/read-4-49709.html#new


Peter

von peter dannegger (Gast)


Lesenswert?

P.S.:

Zum Tastenentprellen würde ich ihn nicht mißbrauchen, das geht
wesentlich effektiver so (gleich 8 Tasten auf einmal):

http://www.mikrocontroller.net/forum/read-4-310276.html#new


Peter

von Mark S. (struberg)


Lesenswert?

Hallo Peter!

Bin zufällig wieder über meinen eigenen Beitrag gestolpert. Der Vorteil 
meines kleinen schedulers liegt im minimalen Ressourceverbrauch. Der 
Code ist grade mal ein paar dutzend Byte groß und sogar mit einem tiny13 
mit minimalem SRAM kommt man locker über die Runden.
Wenn man das ganze in C sauber lösen wollte, dann würde man alleine für 
das swappen der registers für jeden task 32 byte brauchen.

LieGrü,
strub

von Thomas (kosmos)


Lesenswert?

ist avrsimu nur für linux oder läufts auch unter windows

von Mark S. (struberg)


Lesenswert?

ist ANSI C, läuft also auch unter Windows.

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.