Benutzt irgendeiner von euch Adam Dunkels Protothreads in Projekten, die
nicht mit seinem TCP/IP Stack zu tun haben?
Ich nutze es in nur einem Projekt mit µIP.
Ich frage mich, ob sein Konstrukt für andere Programme empfehlenswert
ist?
Ich nutze einen (selbstgeschriebenen) Bruder davon. Habe mir beim Dunkel
dafür einiges abgeschaut.
Nutze es hauptsächlich um endliche Automaten zu basteln.
Für nebeläufige Dinge.
Also: Schleifen unterbrechen, und als DropIn Ersatz für delay().
Was mir beim Dunkel nicht gefällt, ist die komplizierte/unübersichtliche
Handhabung, das habe ich komplett eliminiert/verborgen.
Kann ich dir gerne zukommen lassen, wenn du möchtest...
Ja bitte, zeige mal deine Lösung.
Ich finde nämlich, dass die Protothreads den Code von Endlichen
Automaten deutlich besser lesbar machen. Allerdings muss man starke
Einschränkungen bei der Nutzung lokaler Variablen berücksichtigen, die
gerade wegen der Protothreads nicht immer offensichtlich (aber immerhin
logisch) sind.
Stefan U. schrieb:> Allerdings muss man starke> Einschränkungen bei der Nutzung lokaler Variablen berücksichtigen, die> gerade wegen der Protothreads nicht immer offensichtlich (aber immerhin> logisch) sind.
Ja, das ist bei meinem Kram genau so.
Habe keinen Weg gefunden, das abzuändern. Die Alternative: Preemptives
Multitasking.
Siehe:
Im Anhang, als Arduino Lib, mit ein paar einfachen Beispielen.
Das ist sicherlich ne solide 9.5 auf der WTF!!!?-Skala von [0..10]
Ich kenne persönlich mehr als eine Person die von diesen gleichermaßen
genialen wie auch grenzwertig kriminellen Makro-Konstrukten glasige
Augen, Kammerflimmern und Schnappatmung bekommen würden.
Ich glaube das sollte man nur verwenden wenn man eine ausführliche
Erläuterung der Funktionsweise, der Nebenwirkungen und (wichtig!) der
Wechselwirkungen mit anderen Sprachkonstrukten als Kommentar
voranstellt, zusammen mit Links auf weiterführende Literatur.
Ob es das wert ist?
> Versuche mal diesen Makro-Scheiss zu debuggen
Geht bestimmt nicht gut.
Sobald ich das Programm anhalte, fällt die Netzwerk-Kommunikations aus.
Wenn ich das bei einem Roboter machen würde, würder er völlig faösche
Bewegungen durchführen.
Ich kann mir ohnehin kaum vorstellen, laufende Zustandsautomaten zu
debuggen - da nutze ich eher Logmeldungen.
Hi,
warum eine wiederaufgewärmte uralte C-Obfuscation-Platte mit
irreführendem Namen immer noch Anhänger findet, ist mir schleierhaft.
Auf jeden Fall gilt bei mir die Doktrin: Funktionalität einer Mainloop,
insbesondere wenn Teil eines bare metal OS, muss explizit dastehen.
Somit würden Protothreads in der Code Review gnadenlos durchfallen.
Aber wenn ihr mit akademischen Spielereien glücklich seid, warum nicht.
Ich sehe den Nutzen jedenfalls nicht, im Gegenteil, aber das
Debug-Argument wurde ja bereits gebracht.
Rechtfertigung:
Fitzebutze schrieb:> Obfuscation
In "Obfuscation" steckt eine Verschleierungsabsicht.
Das muss ich ja mal ganz klar abweisen!
Der Anwendungscode wird übersichtlicher.
Der Präprozessor Output ist allerdings für Menschen schwerer lesbar. Den
Compiler kümmert es nicht.
Zum Thema "Debuggen" bin ich etwas befangen. Das Debuggen, der Makros,
war schon ein Abenteuer. Das Debuggen einer Anwendung ist dagegen kein
Problem, wenn man denn verstanden hat, was die Makros tun.
Wie ist es überhaupt soweit gekommen?
Ein bisschen Erfahrung habe ich ja auch mit anderen Systemen. Wenn man
da eine Nebenläufigkeit braucht, dann baut man sich einen
Prozess/Thread/Task und überlässt einem Scheduler, dieser Task heimlich
die Kontrolle zu entziehen, andere Dinge zu erledigen, und dann an der
alten Stelle weiter zu machen. Da ist "das heimliche verschwinden aus
der Funktion" ein akzeptiertes/gewolltes Verhalten.
Meine kleine Arduino Welt, hauptsächlich bestehend Mega328 und Tiny85,
bietet da nicht allzuviel Unterstützung.
Aber nichts desto Trotz, führt meist kein Weg an Nebenläufigkeiten
vorbei. Irgendwie MUSS man das abhandeln. Immer wieder, an 1000 Ecken.
Preemtives Multitasking, z.B. RTOS, ist Ressourcen intensiv. Jede Task
braucht eine Struktur im RAM. U.A, einen Stack Bereich und ein paar
Flags. Auf meinen Zwergen ist RAM knapp. Meine Tests haben ergeben, dass
die Anzahl Tasks zu begrenzt ist. Und das Debuggen ist da auch keine
reine Freude!
Und da ist im Grunde einer der Vorteile meiner Makros zu sehen. Diese
Tasks geben den Stack immer wieder frei. Stackneutral? Ist das das
richtige Wort?
Für statische Variablen werden 2 Byte reserviert. Der Rückkehr Punkt.
Welcher gleichzeitig den Zustand eines endlichen Automaten abbildet.
Wenn man denn eine Task als einen solchen Automaten betrachtet. Wird
eine Zeitsteuerung benötigt, kommen noch 4 Byte dazu.
Ist ein schlankeres Multitasking auf den AVR Dingern möglich?
Bei einem preemptiven System würde sich keiner über das Bild wundern:
1
Taskblink()
2
{
3
while(1)
4
{
5
PINB=(1<<PB5);
6
Pause(500);
7
}
8
}
Jedem ist klar, dass der Kontrollfluss in der Funktion jederzeit
unterbrochen werden kann. Ja, auch, dass Pause() aktiv Rechenzeit
abgibt.
Fitzebutze schrieb:> muss explizit dastehen
Auf dem ersten Blick ist zu erkennen, dass das blink() Konstrukt ewig
blinkt. Will man das alles explizit notieren, dann muss man die Schleife
eliminieren, und die Zeitverwaltung ausbreiten.
Und das, meine Lieben, ist der zweite Vorteil der Makros.
1. Was eine Schleife ist, bleibt eine Schleife. Und das ist eine ganz
ungeliebte Aufgabe für mich: Ich mag keine "Schleifen ausrollen". Wenn
etwas 5 mal getan werden will, dann möchte ich da eine for Schleife
verwenden. Das empfinde ich als offensichtlich.
Noch etwas komplexer wirds, wenn da Schleifen geschachtelt vorkommen,
mit Break und Continue, Gespickt mit ein paar if Konstrukten. Das was da
am Ende raus kommt, wenn es dann mal platt gebügelt ist, ist wirklich
oft schwer lesbar. Auf jeden Fall, ist es seiner ursprüngliche Struktur
beraubt. Und man muss schon genau hinschauen, wenn man da eine zählende
Schleife identifizieren will.
2. Das Arduino delay() wird 1:1 durch taskPause() ersetzt. Eine Pause
ist eine Pause und bleibt eine Pause. Die ganze Belastung, mit der
Zeitabhandlung, ist komplett raus, auf ein (sichtbares) Statement in der
Anwendung reduziert.
Die beiden Punkte vereinfachen die Übernahme von vorhandenem Code in
eine von Nebenläufigkeiten geprägte Anwendung.
Bernd K. schrieb:> Ob es das wert ist?
Ich, für mich, bin damit im Reinen!
Die Antwort: Ja!
Stefan hat gefragt, und seine Antwort bekommen.
Was er damit anstellt, überlasse ich ganz ihm.
Ob das Vorgehen empfehlenswert ist?
KA...
Für Anfänger nicht geeignet, würde ich mal sagen.
Etwas erfahrenen, stellen sich die Nackenhäärchen auf.
(incl. mir)
Übrigens:
Bernd K. schrieb:> grenzwertig kriminellen Makro-Konstrukten
Es gibt in meiner Schublade noch eine Variante, welche das switch-case
nicht vergewaltigt, dafür allerdings fleißig gotos verwendet.
:-) irgendwie muss man ja hüpfen :-)
> Stefan hat gefragt, und seine Antwort bekommen.> Was er damit anstellt, überlasse ich ganz ihm.
Ich hab's mir inzwischen angeschaut. Ist dem Lösungsansatz von Herrn
Dunkels sehr ähnlich. Vor allem hat es meines Meinung nach die gleichen
vor- und Nachteile, insofern passte dein Post sehr gut zum Thema.
Ich persönlich stehe nicht so sehr auf Code-Generatoren und "Magie" im
Hintergrund. Im Java Enterprise Umfeld stößt man ständig auf sowas.
Diese Makros (bzw. in Java die Annotationen) machen den Code zweifellos
besser lesbar. Aber sie verbergen eine Menge Details, die man wissen
muss, um die Makros korrekt anzuwenden. Und genau das stört mich mehr,
als ich den Vorteil wertschätze.
Vermutlich liegt das auch daran, dass ich Programmierer der alten Schule
bin. Ich habe mit Assembler angefangen und ich schaue heute noch ab und
zu in das Assembler Listing, um sicher zu stellen, das der Compiler auch
wirklich den Code erzeugt hat, den ich haben wollte.
Ich bin mir aber auch bewusst, dass diese Arbeitsweise nicht mehr
zeitgemäß ist. Insofern könnten diese gar nicht so neuen Protohtreads
für jüngere Entwickler wesentlich attraktiver sein, als für mich.
Wenn man die bisherigen Antworten hier betrachtet, scheinen mir
Protothreads dennoch nicht empfehlenswert zu sein. Zu wenig Interesse
und zu viel Ablehnung lese ich da heraus.
Arduino F. schrieb:> Im Anhang, als Arduino Lib, mit ein paar einfachen Beispielen.
Ja, das sieht sehr elegant aus.
Allerdings hab ich ne Weile gebraucht, dahinter zu steigen und den
Präprozessoroutput darf man sich wirklich nicht ansehen.
Ich denke allerdings, daß die Kollegen mich steinigen würden, wenn ich
das auf Arbeit einsetzen würde.
Ich nehme daher die klassischen switch/case Statemaschines und definiere
die Cases mit beschreibenden States per Enum-Liste.
Verzögerte Aufrufe mache ich mit meinem Scheduler:
Beitrag "Wartezeiten effektiv (Scheduler)"
Zu RTOS haben ich mich noch nicht durchringen können. Der
RAM-/CPU-Bedarf ist heutzutage weniger wichtig. Aber bei einen RTOS
entstehen ne Menge neuer Probleme, die man erstmal erkennen, verstehen
und lösen muß, wie z.B. unbekannte
Ausführungs-/Unterbrechungsreihenfolge, Datenkonsistens, Deadlocks,
Fehlererkennung usw.
Stefan U. schrieb:> Wenn man die bisherigen Antworten hier betrachtet, scheinen mir> Protothreads dennoch nicht empfehlenswert zu sein.
Ich habe mich schon vor Jahren über diesen Unfug ausgeworfen. Wer
Multitasking wirklich benötigt, soll es auch dediziert machen oder
es eben bleiben lassen. Ansonsten sag ich, daß es sinnvoller ist, sich
einen nicht blockierenden Code anzugewöhnen, als sich auf solche
Präprozessor-Kapriolen zu verlegen. Es geht ja, wenn man
ereignisorientiert programmiert. Dann sind Wartezeiten einfach passé.
W.S.
Arduino F. schrieb:>> grenzwertig kriminellen Makro-Konstrukten> Es gibt in meiner Schublade noch eine Variante, welche das switch-case> nicht vergewaltigt, dafür allerdings fleißig gotos verwendet.
Hab mir mittlerweile zum Spaß grad auch mal was gebastelt,
unter Verwendung von computed goto (gcc only)
Ist meiner Meinung nach einfacher zu schlucken und zu verdauen als der
vergewaltigte switch:
Arduino F. schrieb:> TaskMacro.zip
Naja, das sieht ganz nett aus. Coroutinen bringen viele moderne Sprachen
ja auch mit. Aber in einem Punkt halte ich es für sehr gefährlich und
irreführend:
Durch ein TaskSwitch (und alle Macros, die dieses aufrufen, wie das
taskPause) werden lokale Variablen ungültig.
Das ist nicht offensichtlich und es ist gefährlich.
Das ist auch genau der Punkt, den Coroutinen richtig machen: Der Stack
ändert sich nicht plötzlich.
In C könnte man sowas vielleicht mit setjmp machen.
Bernd K. schrieb:> Hab mir mittlerweile zum Spaß grad auch mal was gebastelt,> unter Verwendung von computed goto (gcc only)
Auch da wird der Stack bei einem Task switch ungültig.
Außerdem funktioniert die Präemption ja nur aus der Task-Hauptroutine
heraus.
Das mag bei den trivialen LED-Blink-Beispielen OK sein, aber für ein
größeres Programm kann das doch keine Lösung sein.
Stefan U. schrieb:> Aber ich würde es nicht Protothreads nennen, der Name ist schon> vergeben.
Ist ein allgemeiner Begriff, sowohl die Vorsilbe "proto" als auch der
Begriff Protothread aus der Informatik, es gibt bereits mehrere
Implementationen: https://de.wikipedia.org/wiki/Protothread
WaMin schrieb:> Auch da wird der Stack bei einem Task switch ungültig.
Es wird überhaupt kein Stack benutzt, alle lokalen Variablen sind
static.
> Außerdem funktioniert die Präemption ja nur aus der Task-Hauptroutine> heraus.
Ja, deshalb (und auch zur Verwendung lokaler Variablen) müsste man eine
deutliche Warnung für den zukünftigen Leser voranstellen, zusammen mit
Literaturhinweisen.
> Das mag bei den trivialen LED-Blink-Beispielen OK sein, aber für ein größeres
Programm kann das doch keine Lösung sein.
Das Putty ssh.c Beispiel hab ich ja oben schon gepostet. Das geht
sicherlich weit über LED-Blinken hinaus.
Boost bietet übrigens auch ne Implementation davon an.
Bernd K. schrieb:> Putty ist voll davon:
In einer Datei, die 10244 Zeilen hat.
Was dort produziert wurde, ist doch kaum noch wartbar. Nicht zuletzt
durch diese Coroutinenfunktionalität.
Bernd K. schrieb:> Es wird überhaupt kein Stack benutzt, alle lokalen Variablen sind> static.
Ja eben. Und das ist eine Besonderheit, die man beachten muss. Es ist
aber keineswegs offensichtlich, dass hier der Stack über diesen
scheinbaren Pause-Funktionsaufruf ungültig wird, weil es eben kein
Aufruf, sondern ein verstecktes return/goto ist.
Bernd K. schrieb:> Ja, deshalb (und auch zur Verwendung lokaler Variablen) müsste man eine> deutliche Warnung für den zukünftigen Leser voranstellen, zusammen mit> Literaturhinweisen.
Man verrenkt sich hier, um etwas zu erreichen, was ganz einfach offen
kodiert (z.B. als normale Statemachine mit normalen returns) viel
lesbarer und wartbarer ist.
Bernd K. schrieb:> Boost bietet übrigens auch ne Implementation davon an.
Mit Sicherung des Stacks?
Denn wenn der Stack gesichert wird, dann fände ich diese Art von
Coroutinen ziemlich gut. Aber so halt nicht.
In Sprachen, die Coroutinen vernünftig implementieren, verwende ich sie
ja selbst gerne.
WaMin schrieb:> Man verrenkt sich hier, um etwas zu erreichen, was ganz einfach offen> kodiert (z.B. als normale Statemachine mit normalen returns) viel> lesbarer und wartbarer ist.
Nicht unbedingt. Der Code wird auf jeden fall um den Faktor 2 kürzer und
der Kontrollfluss durch die einzelnen States ist in normalem lesbaren C
hingeschrieben, nicht außeinandergerissen in zig losgelöste Zustände
deren Reihenfolge und Übergänge man nicht mehr direkt sehen kann.
Es hat schon Vorteile, wenn nur nicht diese switch-Vergewaltigung drin
wär. Deshalb gefällt mir die goto-Variante auch wesentlich besser, die
find ich klarer, unverhohlener und daher einfacher zu vermitteln.
Bernd K. schrieb:> der Kontrollfluss durch die einzelnen States ist in normalem lesbaren C> hingeschrieben,
Eben genau nicht. Der Stack verschwindet plötzlich mit dem scheinbaren
Aufruf einer Funktion.
Deshalb ist der Code hier an einer Stelle komplett geteilt, die nicht
offensichtlich für einen C-Programmierer ist.
Wenn man das switch/case explizit hinschreibt, können diese zwei
Codeteile auch aufeinander folgen.
Nur die Trennung an der Pause-Stelle sieht man dann explizit, weil der
C-Block endet (oder mindestens der case). Das ist nichts neues für einen
C-Programmierer.
Bernd K. schrieb:> Der Code wird auf jeden fall um den Faktor 2 kürzer
Und das ist natürlich auch falsch. Das gilt nur für das triviale
LED-Blink-Beispiel, das nur 1-2 Befehle zwischen den Pausen hat.
Bernd K. schrieb:> unter Verwendung von computed goto (gcc only)
Im Falle von AVR, d.h. avr-gcc ist zu beachten, dass dort Computed Goto
nicht unterstützt wird.
Johann L. schrieb:> Bernd K. schrieb:>> unter Verwendung von computed goto (gcc only)>> Im Falle von AVR, d.h. avr-gcc ist zu beachten, dass dort Computed Goto> nicht unterstützt wird.
Also, dieses zuckt ganz gut in meiner Arduino IDE:
1
#pragma once // include guard
2
3
4
typedefvoidTask;// Task Type
5
6
typedefvoid*TaskMark;
7
8
9
// grundlegene Worte um einen Task Bereich einzugrenzen
10
#define taskBegin() \
11
static TaskMark taskMark = &&TaskLableStart; \
12
static unsigned long __attribute__((unused)) taskTimeStamp = 0; \
13
goto *taskMark ; \
14
TaskLableStart:
15
16
17
#define taskEnd() \
18
for(;;) \
19
{ \
20
taskSwitch(); \
21
}
22
//;}
23
24
25
#define LC_CONCAT2(s1, s2) s1##s2
26
#define LC_CONCAT(s1, s2) LC_CONCAT2(s1, s2)
27
28
29
30
// Task Kontrol Worte, diese werden Taskwechsel einleiten
Arduino F. schrieb:> Johann L. schrieb:>> Bernd K. schrieb:>>> unter Verwendung von computed goto (gcc only)>>>> Im Falle von AVR, d.h. avr-gcc ist zu beachten, dass dort Computed Goto>> nicht unterstützt wird.>> Also, dieses zuckt ganz gut in meiner Arduino IDE:
Und was sagt das?
Es gibt Computed Goto, für welche avr-gcc falschen Code erzeugt.
Und (dein) Code kann Anwesenheit von Fehlern zeigen, aber nicht deren
Abwesenheit.
ich finde die Mechanismen genial und die Disskussion darüber gut! Es
erhellt die Verständnisschwierigkeiten, die einige mit der Umwandlung
von Tasks in SPS-Loops haben. Es beleuchtet mehrere Aspekte und kann
wirklich helfen, den Taskianern die Möglichkeiten der SPS-Loop zu
vermitteln.
Ich hätte nichtmal was dagegen, wenn jemand sowas in überschaubarem Code
anwendet. Dann könnte man nämlich sehr einfach mal Loopcode daneben
stellen.
Johann L. schrieb:> Und was sagt das?>> Es gibt Computed Goto, für welche avr-gcc falschen Code erzeugt.>> Und (dein) Code kann Anwesenheit von Fehlern zeigen, aber nicht deren> Abwesenheit.
Ich sehe den Unterschied von "nicht unterstützt" und "falschem Code".
"falschem Code" ist mir bisher nicht bekannt gewesen und auch noch nicht
aufgefallen.
Werde mich aber kundig machen...
WaMin schrieb:> Eben genau nicht. Der Stack verschwindet plötzlich mit dem scheinbaren> Aufruf einer Funktion.> Deshalb ist der Code hier an einer Stelle komplett geteilt, die nicht> offensichtlich für einen C-Programmierer ist.
Ich habe volles Verständnis dafür, dass sich dir dabei die Fußnägel
aufrollen. Glaub mir, da durfte ich auch durch.
Es ist eine andere Sicht auf die Dinge!
Besser: Eine Projektion.
Als Erkennungsmerkmal setze ich den Datentype "Task" davor. Einen
typischen c-Krieger sollte das zumindest misstrauisch machen.
Hmm...
Man(ich) prägt diesem dummen AVR seine Sicht der Dinge auf.
Der gcc spielt mit.
Die Kehrseite:
Man(ich) muss die Kröte mit den lokalen Variablen schlucken.
S. R. schrieb:> Johann L. schrieb:>>> unter Verwendung von computed goto (gcc only)>> Im Falle von AVR, d.h. avr-gcc ist zu beachten, dass dort Computed Goto>> nicht unterstützt wird.>> Das ist in der Form falsch:> https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html>> Die hier gezeigte Nutzung funktioniert auch auf AVRs.
Es ist nunmal so dass es mehr als 1 Testfall für Computed Goto in der
GCC Testsuite gibt, für den avr-gcc falschen Code erzeugt und crasht.
Ich wollte nur darauf hingewiesen haben.
Wenn ich das richtig verstanden habe, tritt das nur bei der
Differenzbildung von Lables auf.
Den Fall haben wir hier nicht.
Ist auch nicht nötig das hier zu verwenden.
Oder habe ich was übersehen?
Ich bin am Überlegen.
- einmal das Prinzip gefressen
- 2 Include-Dateien mit je ca 20 Zeilen Codes
- 2 Überlebens-Regeln
- don't use switch-case
- don't rely on local variables
Eigentlich ein niedriger Preis, um die Segnungen des Konzeptes
"strukturierte Programmierung" wieder nutzen.
siehe
http://dunkels.com/adam/pt/examples.html
"Radio dirver" mit dem Vergleich beider Ansätze.
Imho ist die State Machine schon ein bißchen Rückkehr zum "guten alten
Spaghetti-Code", oder?
Funktioniert, kann effizient sein, fordert Disziplin und begleitende
Erläuterung.
Wenn man Erfahrung hat, kein Problem.
Sieht man an den Glaubenskriegen hier und anderswo.
Ich bin grad' dabei, mir eine "Werzeugkiste" für verschiedene Projekte
zusammenzustellen, wie sie wahrscheinlich jeder von Euch Profis im Lauf
der Jahre angesammelt hat.
Ein typisches Beispiel braucht:
- 4 Servo-Controller mit je ADC und PWM, PID dazwischen
- Tasten, Quad-Encoder und LCD
- evtl. CAN
- evtl. UART-Debug
- evtl. IP-Netz
Da werde ich um die Nebenläufigkeit nicht rum kommen.
Bin Hobbyist, hab vor 30 Jahren 6502 auf Karo-Pepier assembliert und
seitdem mit wechselnder Intensität Hochsprachen, zuletzt meist auf
Linux, gemacht.
Bin grad durch die Blink-tutorials mit den Delay-Loops durch und stelle
nun fest, daß es so für komplexere Aufgaben nicht gehen kann.
Wolfgang R. schrieb:> Da werde ich um die Nebenläufigkeit nicht rum kommen.
Für Nebenläufigkeit sind diese Tasks aber m.E. weniger geeignet als eine
SPS-Loop. Für Protokolle sind die Prototasks hingegen ideal. Wenn 1000
Byte zu verarbeiten sind ... egal. Dann warten die anderen Threads.
Wobei die eigentliche Nebenläufigkeit (Tasten-Entprellen, Uart, Encoder)
meist ja auch ohne RTOS nebenläufig und priorisiert sind ... durch
Interrupts.
In ein paar Projekten habe ich so was auch schon mal verwendet.
Allerdings wurden die einzelnen "Threads" in C++ Klassen gepackt. Damit
kann man die nötigen Variablen in der Klasse lassen und hat damit das
ganze räumlich zusammen. Ist ja nun auch nicht so ein Hexenwerk, dass
man das nicht verstehen könnte. Auch das Debuggen nach etwas Gewöhnung
geht ganz gut.
Am gefährlichsten sehe ich noch das PtWaitUntil bzw. taskWaitFor im Code
von oben. Solchen Funktionen sollte man immer irgend eine maximale Zeit
o.ä. mitgeben damit verhindert wird, dass nur noch der Watchdog hilft
wenn's mal hängt. Aber das ist nicht nur bei dieser Art Implementierung
so.
Ich benutze das hier auf AVR und selbst angepasst auch auf ARM.
https://github.com/joe7575/Arduino-MOS
Funktioniert ausgesprochen gut. Ich finde der Code ist lesbarer, da er
eher linear runter geschrieben werden kann.
Einzigen Punkt, den man beachten muss, ist eben, dass lokale Variable
ihrem Wert verlieren bei einem "Kontextswitch". Kann ich aber mit leben.
Mit den Protothreads hab ich vor Jahren auch mal ein "grösseren" Projekt
im Job gemacht. Das gefiel mir nicht so gut wegen dem Verzicht auf
switch.
Huch ja, da werden Makros auf "böse" Art verwendet. Das finde ich
genauso eine unsinnige Diskussion, wie goto ist verboten. In meinen
Augen Blödsinn. Alles mit Bedacht und der nötigen Sorgfalt eingesetzt
ist das alles kein Problem finde ich.
In der Vergangenheit hatte ich für kleinere Projekte mit Atmega & Co.
sehr oft und gerne Protothread eingesetzt.
Seit ich aber komplett auf STM32 umgestiegen bin, setzte ich vermehrt
CMSIS-RTX ein. Protothread kommt nur noch selten zum Zug.
Das ist ja komisch, plötzlich melden sich ganz viele Leute, die
Protothreads gerne verwendet haben. Davor gab es fast nur Ablehnung.
Geht hier noch alles mit Rechten Dingen zu?
900ss D. schrieb:> Mit den Protothreads hab ich vor Jahren auch mal ein "grösseren" Projekt> im Job gemacht. Das gefiel mir nicht so gut wegen dem Verzicht auf> switch.
Falls das zur Verwirrung führt, ich meinte die Adam Dunkels
"Original-Protothreads". Dort kann man kein switch verwenden. Bei dem
von mir oben aufgeführten "MOS" geht das schon.
Stefan U. schrieb:> Geht hier noch alles mit Rechten Dingen zu?
Magie?
Ach...
Ich glaube, dass hat eher mit dem üblichen "Sozialverhalten" hier im
Forum zu tun.
Als ich deine Frage gelesen habe, musste ich entscheiden, Antwort oder
nicht.
Zu dem Zeitpunkt war mir klar, dass einige "Urteiler" aus den Büschen
gesprungen kommen.
Angst vor Haue!
Aber, wie man sieht, manchmal lohnt es sich, da durch zu gehen.
Und mir gefallen die Protothreads, dann stehe ich auch dazu.
Ist ja auch ein heißes Eisen, mit dem krummen Switch oder dem gerne
verfluchten GoTo.
Konfliktpotential genug...
Wie auch immer....
Eine drohende Eskalation, ist zu einem konstruktiven Dialog geworden.
Ganz ehrlich:
Da habe ich so kaum mit gerechnet.
Ja, das Ganze hat sich gelohnt.
Danke für deine Eröffnung, und einen Dank an die Anderen, denn aus den
Codestrecken/Texten, kann ich für meine TaskMakros einiges mitnehmen.
Auf Dauer, werden sie eine Renovierung bekommen.
z.B. im Bereich Task Synchronisierung (bei mir quasi noch nicht
vorhanden)
Auch, denke ich, dass so mancher stumme Mitleser eine andere Sicht auf
die Dinge vorgeführt bekommen hat.
Weiter so!
900ss D. schrieb:> Falls das zur Verwirrung führt, ich meinte die Adam Dunkels> "Original-Protothreads". Dort kann man kein switch verwenden. Bei dem> von mir oben aufgeführten "MOS" geht das schon.
Dem Dunkel hat auch eine Goto Variante im Ordner.
Zumindest in der Arduino Lib ist die mit drin.
Arduino F. schrieb:> Zumindest in der Arduino Lib ist die mit drin.
Deshalb hab ich die dann später verwendet. Bin gespannt wann es auf
einem AVR das erste Mal knallt da es auf AVR ja ein Problem im GCC gibt.
Ist bei mir bisher nicht aufgetreten.
Arduino F. schrieb:> Stefan U. schrieb:>> Geht hier noch alles mit Rechten Dingen zu?> Magie?>> Ach...> Ich glaube, dass hat eher mit dem üblichen "Sozialverhalten" hier im> Forum zu tun.
(...)
> Eine drohende Eskalation, ist zu einem konstruktiven Dialog geworden.
:-)))))
Jungs, den Profi erkennt man daran, daß er drüber steht!
Es ist doch immer wieder überraschend, wie Menschen, von denen man
eigentlich von Berufs wegen Rationalität im Überdruss erwarten würde, in
die animalischen Grundmuster verfallen, sobald sie mehr als eine Hand
voll Bytes im Blick haben müssen.
Es freut mich, wenn ich mit meiner Anfängerfrage ein Stück Vernunft aus
dem Versteck locken konnte.
Wer sich mal richtig an der Irrationalität der eigenen Zunft erfreuen
möchte, kann sich diesen Thread (den ganzen, nicht nur den verlinkten
Einsprung) zu Gemüte führen, den Meister Dunkels selber verlinkt hat:
http://www.8052.com/forum/read/91275
Das ist definitv mehr Soziologie als Programmieren.
Aber offensichtlich nicht off-topic.
Und, ja, danke an die Befürworter.
Ich werd's probieren.