Forum: Mikrocontroller und Digitale Elektronik avr co-operative scheduler/multitasking


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Jens H. (jens_h791)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
co-operative multitasking
scheduler für avr ohne irq plus framework für TOS

Supported AVR CPUs: m328p, m644, ...

kompilieren: make
flash      : make isp

Anpassen:
CPU und Programmer wird in "makefile" eingestellt
Anzahl Tasks werden in "config.h" definiert


Das Programm eignet sich gut für mehrere parallele Aufgaben.
Er hilft ausufernde state-machines zu vermeiden und eignet
sich sehr gut für Kommunikations-funktionen.
Der scheduler muss explizit aufgerufen werden,
dadurch bewahrt man sich die volle kontrolle über das timing
im Programm. Zudem wird das debuggen möglich.
Zum Testen am besten einen Arduino verwenden. In config.h wird
der PIN für eine LED definiert. Wenn ein anderes Testboard
verwendung findet, sollte dies angepasst werden.


scheduler: wechseln zwischen den tasks
timer2   : millisekunden zähler (bestimmte CPUs!)
xitoa    : elm-chan version von printf und co.
config.h : alle Konfigurationen
master   : das Demo Programm
cpu.h    : viele nützliche macros zb: "cfg_lo(D4); cfg_in(D5)"
serx.h   : zur generierung von code für mehrere serielle ports

BUGS: nur wenige AVR CPUs mit einer USART in serx.h unterstützt,
      timer2 prescaler Berechnung nur eingeschränkt universell


THANKS:
elm-chan : xitoa (he is the KING)
günter greschenz: gos (the scheduler)
avr-freaks: id8 - force 8 bit alu operations in gcc
atmel : please, create seriel bus without usb nonsense

************************************

you are the best ;-)

https://www.mikrocontroller.net

************************************

KEYWORDS: scheduler task tasks arduino avrdude makefile xitoa xatoi 
printf preemptive framework timer ctc-mode milliseconds  wiring avr-libc 
serial communication state-machine multitasking

KISS ;-)

von Codix (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das Ganz ist ziemlich Quick & Dirty programmiert.

Wenn schon bei task_create nicht die Limits, hier NUM_TASKS, abgefragt 
wird, dann ist das nicht schön und neigt zu Fehlern/Fehlverhalten, wenn 
man bei der Programmierung vergisst NUM_TASK seinen Bedürfnissen 
anzupassen.
Der TCB sieht etwas mager aus. Da fehlt mir zuviel, Priorität, Mailbox, 
usw..

Und mal ehrlich, das Beispiel überzeugt nicht wirklich. Das bekomme ich 
mit weniger Code auch hin. Und ohne Overhead für das bissel Taskwechsel.


Multitasking sieht anders aus.
Jens H. schrieb:
> Das Programm eignet sich gut für mehrere parallele Aufgaben.
Wie soll das Deiner Meinung nach funktionieren? Parallel sieht anders 
aus.
Das kann dieser Scheduler nicht leisten.

Das ist ein netter Versuch und das macht auch bestimmt Spass sich in die 
Materie einzuarbeiten.
Aber sinnvoll und professionell einsetzbar ist das nicht.
Da musst Du noch einiges dafür tun.

von Marc V. (Firma: Vescomp) (logarithmus)


Bewertung
0 lesenswert
nicht lesenswert
Jens H. schrieb:
> Das Programm eignet sich gut für mehrere parallele Aufgaben.
> Er hilft ausufernde state-machines zu vermeiden und eignet
> sich sehr gut für Kommunikations-funktionen.

 Will nicht meckern aber das sieht irgendwie unordentlich und
 zusammengekleistert aus.

 Tasks können nicht ausgetragen bzw. gelöscht werden, wenn ein
 Task blockiert, sind alle blockiert und vor allem - da sind keine
 parallelen Aufgaben möglich.
 Du hast es zwar richtig angeführt - kooperativ, aber kooperativ und
 parallel gehen eben nicht zusammen und deswegen eignet sich dein
 Beispiel nicht für irgendwelche Kommunikations-funktionen.

 P.S.
 Und mal ehrlich - das Ganze kann genausogut in einem while(1) loop
 in main() laufen - absolut kein Unterschied...

: Bearbeitet durch User
von dünnwandiger Trog (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Naja, Zielgruppe ist auch eher die Arduino Community.

von Jens H. (jens_h791)


Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:
> Tasks können nicht ausgetragen bzw. gelöscht werden,
dies ist ein Beispiel, also auf das notwendigste reduziert.
Wer in der Lage ist einen scheduler zu benötigen, kann solche Funktionen 
sicherlich selber hinzufügen.

>  Task blockiert, sind alle blockiert und vor allem - da sind keine
>  parallelen Aufgaben möglich.
Wie du erkannt hast, kooperativ!

>  Du hast es zwar richtig angeführt - kooperativ, aber kooperativ und
>  parallel gehen eben nicht zusammen und deswegen eignet sich dein
>  Beispiel nicht für irgendwelche Kommunikations-funktionen.
Aber sicher doch, oder läuft das Programm bei dir nicht ;-) ?


Wenn ein Task blockiert, z.B. mit "while(PIND&1);" kann dir dieser 
scheduler nicht helfen. Das geht nur mit preemptive multitasking!
Wie ich versucht habe, auf ganz einfache weise zu Demonstrieren in 
master.c:comm(), schreibt man solche Warteschleifen um in "while(PIND&1) 
schedule();" und schon läuft es.

>
>  P.S.
>  Und mal ehrlich - das Ganze kann genausogut in einem while(1) loop
>  in main() laufen - absolut kein Unterschied...
Doch ein wesentlicher Unterschied: state-machine.
Es ist mir vollkommen klar, das du mit einer State-Machine dieses 
minimale Beispiel nachprogrammieren kannst, aber es ist nicht das 
gleiche! Angenommen du hast Peripherie per i2c angebunden und musst ein 
Protokoll implementieren bei dem jede Aktion wieder in einzelne 
send/recv Schritte unterteilt ist, dann benötigt jede Function eine 
eigene State-Machine, die wiederum in einer weiteren State-Machine läuft 
usw.usf., mit einem scheduler kann jede dieser State-Machines so 
aussehen wie ich es in master.c:comm() gezeigt haben. Die gleiche 
Funktionalität, aber einfacher und kürzer in der Implementation.
Fazit: jedes aktive warten auf einen Stimulus wird nach dem Muster:
"while( nicht_fertig() ) schedule();" geschrieben, anstelle von:
switch(state) { case 0: aktion(); state=1; break; case 1: 
if(nicht_fertig) return; else state=2;" usw..

Gruß,
Jens

von Marc V. (Firma: Vescomp) (logarithmus)


Bewertung
0 lesenswert
nicht lesenswert
Jens H. schrieb:
> Wer in der Lage ist einen scheduler zu benötigen, kann solche Funktionen
> sicherlich selber hinzufügen.

 Wenn er in der Lage ist solche Funktionen selber hinzuzufügen, dann
 kann er auch gleich alles neu schreiben und seinen Bedürfnissen
 anpassen.


> Fazit: jedes aktive warten auf einen Stimulus wird nach dem Muster:
> "while( nicht_fertig() ) schedule();" geschrieben, anstelle von:
> switch(state) { case 0: aktion(); state=1; break; case 1:
> if(nicht_fertig) return; else state=2;" usw..

 Das sind (in deinem Fall) rein kosmetische Unterschiede.
 Ausserdem ist Statemachine (in meisten Fällen) weitaus effizienter
 als dein Scheduler, alleine schon wegen der PUSH/POP Orgie.
 Auf diese Weise werden andere Tasks zwar nicht blockiert, dafür aber
 solange einfach hintereinander durchlaufen, bis der blockierende Task
 wieder weitergeht.
 Da du nicht mit Timeslices arbeitest, wird z. B. bei 3 blockierenden
 Tasks (von 4) nur der vierte Task immer wieder durchlaufen aber du
 (bzw. dein Programm) hat keine Ahnung davon, dass 3 Tasks blockieren.

 Ehrlich gesagt, ich habe noch nie eine sinnvolle Anwendung mit
 kooperativem Multitasking ohne Timer gesehen.
 Selbst eine einfache Ampelsteuerung geht nicht ohne Timer...


 Schaue mal hier:
 Beitrag "Wartezeiten effektiv (Scheduler)"

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]
  • [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.