Hallo,
ich habe mir einen kleinen Scheduler in ASM geschrieben, siehe Anhang.
Gedacht ist er für nicht zeitkritisches quasi Multitasking und in seiner
späteren Anwendung auch für Powermanagement.
Der Scheduler wird im MAIN loop aufgerufen und ist daher nicht all zu
genau, kann aber ohne großen Aufwand auch auf Interruptsteuerung
umgebaut werden.
Das ganze ist im Moment für ein mega164 mit dementsprechenden
Registerpositionen gedacht, aber kritische Passage sind im Quelltext
markiert.
Geplant ist eventuell noch eine Routine um Tasks zu löschen, im Moment
besteht dazu aber keine Notwendigkeit.
Wenn Ihr Fragen oder Anregungen habt, immer her damit.
flex schrieb im Beitrag #4839561:
> phpJEsxV7
Wenn das ANSI ist, hast du es zumindest gut versteckt - nu' aber nochmal
richtig mit ordentlicher Dateierweiterung. Das hier lädt sich keiner auf
seinen Rechner.
Ähm kurze Frage zu diesen beiden Befehlen gibs die wirklich beim Mega164
? Finde die im InstructionSet nicht
STO SDLR_TIME, tmp
LOD tmp, TIFR2
Kommt mir eher von ner älteren Plattform bekannt vor
S. Landolt schrieb:> an Chris:> Ist im Textblock erklärt; allerdings hätte ich das Zeigen des konkreten> Macros für sinnvoller gehalten.
H. d. das obige Konstrukt lässt sich ohne die Makros nicht übersetzen?
Danke alles gut habs überlesen :D
ne das kein Makro, ich kanns nachvollziehen wenn man es zum Beispiel auf
nen Controller packt wo z.B das TIFR2 ausserhalb des IO-Bereiches(>$3F)
liegt dann muss man LDS/STS nutzen statt IN/OUT.
Hab nicht geschrieben das man keine Macros schreiben kann. Nur in seiner
Beschreibung hab ichs überlesen für was sto/lod steht und nein es müssen
nicht zwingend Macros sein. Naja jetzt wird wieder getrollt....
MaWin schrieb:> chris schrieb:>> Darum gehts jetzt nicht!>> Warum nicht? Das ist halt meine Frage und ich würde das gerne wissen.
Bist du der Psychopath?
Donny schrieb:> Bist du der Psychopath?
Ich bin MaWin und ich würde gerne wissen, wo der Threadersteller seine
Motivation hernimmt das in ASM zu implementieren. Wo ist da jetzt das
Problem? Die Antwort kann auch lauten: "Weil es mir in ASM mehr Spaß
macht." Das wäre natürlich völlig OK. Ich würde es halt nur gerne
wissen.
Könnten wir jetzt mit der Trollerei aufhören?
Mich würde die Motivation auch interessieren. Multithreading hat wohl
wenig Sinn mit 2K RAM, genauso wenig Sinn macht es einen Scheduler in
ASM zu schreiben, bis auf den Contextswitch. Für die AVRs sind wohl
Statemachinen besser.
Karl M. schrieb:> Hallo,>> also mein AVR Assembler kennt keine AVR Befehle: STO und LOD also müssen> es Macros sein.
Zu meinen Assemblerzeiten hatte ich Macros die XOUT bzw. XIN genannt für
eXtended IN/OUT.
Hallo,
wieso Assembler? Weil ich uCs eigentlich nur in Assembler programmiere.
Das hat verschiedenen Gründe.
Die LOD / STO Befehle sind wie schon vermutet einerseits Macros, aber
andererseits auch Gedankenstützen um es von Hand an verschiedenen AVRs
anpassen zu können, falls man nicht die Macrosammlung aus AVR001
benützt.
http://read.pudn.com/downloads169/sourcecode/math/777464/macros.inc__.htm
Ob Multitasking in kleinen 8bittern sinnvoll ist, steht hier nicht zur
Diskussion, das muss jeder für sich selbst und seine Anwendung
entscheiden. Als Beispiel könnten lange aber nicht rechenintensive
Routinen, die auf Peripherie warten, genannt werden.
Wenn sich die Diskussion aber einfach nur um den Code selbst drehen
könnte, wäre ich dankbar.
Frohe Weihnachten!
flex schrieb:> Ob Multitasking in kleinen 8bittern sinnvoll ist, steht hier nicht zur> Diskussion, das muss jeder für sich selbst und seine Anwendung> entscheiden.
Das, was du gepostet hast, ist aber kein Multitasking, es sind ganz
einfach Routinen, die hintereinander aufgerufen werden.
Sollte nur eine davon blockieren, bzw. auf irgendeine Eingabe warten,
wartet dein Scheduler auch vergebens.
> Als Beispiel könnten lange aber nicht rechenintensive> Routinen, die auf Peripherie warten, genannt werden.
Und genau da ist dein Scheduler, welcher in Main sitzt, nutzlos.
Der wartet geduldig darauf, dass die Routine endet und zurückkehrt.
> Wenn sich die Diskussion aber einfach nur um den Code selbst drehen> könnte, wäre ich dankbar.
Warum ?
So, wie es jetzt aussieht, ist es absolut nutzlos.
Genauso kann man die Routinen auch aufrufen.
So als Idee: Weiß eine Routine, dass sie Wartezeiten hat oder zu lange
rechnet, aber die Operation nicht Zeitkritisch ist, könnte sie sich eine
Task einrichten (der die Wartezeit abschätzt) und dann den Prozessor
freigeben. Nennt sich Kooperatives Multitasking.
Daran arbeite ich gerade und es funktioniert wunderbar, insofern ist
deine Aussage schlichtweg falsch.
Zusätzlich ist ein recht gutes Powermanagement möglich, da wartende
Prozesse Tasks einrichten können und zwischen den Task der uC schlafen
geht.
Da der Scheduler sehr einfach auf Interruptmodus umgebaut werden kann,
könnte man übrigens auch Präemptives Multitasking implementieren.
Z.B. prüft der Scheduler bei einem neuen anstehend Task ob der PC beim
Aufruf innerhalb eines bestimmten Bereichs war, der Subroutinen enthält
die unterbrochen werden können. Ist dem der Fall wird ein neuer Task
angelegt, der dorthin zurück springt und die Register wieder herstellt.
Der anstehende Task wird abgearbeitet und der ursprüngliche darf seine
Aufgabe erledigen wenn sein Timeslot gekommen ist.
flex schrieb:> So als Idee: Weiß eine Routine, dass sie Wartezeiten hat oder zu lange> rechnet, aber die Operation nicht Zeitkritisch ist, könnte sie sich eine> Task einrichten (der die Wartezeit abschätzt) und dann den Prozessor> freigeben. Nennt sich Kooperatives Multitasking.> Daran arbeite ich gerade und es funktioniert wunderbar, insofern ist> deine Aussage schlichtweg falsch.
Nein.
Dein Problem ist, dass alles ohne Timer-Interrupt über main geht.
Praktisch eine Statemachine, nur fehleranfälliger und komplizierter.
Wenn schon aus main und ohne Timer, dann geht das Ganze mit Flags und
Statemachine viel besser.
Vorteil:
a) Dein Programm weiss immer welche Tasks ausgeführt und welche noch
auszuführen sind.
b) Dein Programm ist viel leichter zu debuggen und zu verstehen, auch
noch nach ein paar Wochen.
Ohne Timer-ISR bringt das Ganze überhaupt keine Vorteile, da jeder neue
Task erst die anderen Tasks abwarten muss, aber nicht im Voraus wissen
kann, wieviele Tasks noch vor ihm auf Abarbeitung warten und wie lange
dessen Ausführung überhaupt dauert.
Wenn es keiner oder nur einer ist, kann das u. U. zu schnell sein,
wenn es aber mehrere sind, kann es schon zu spät sein.
Oder es wird als besonders geniale Idee mit Task-Stack rum hantiert,
Anzahl der Tasks rausgefunden, die benötigte Gesammtzeit erechnet und
am Ende ist dann doch nicht genug Zeit vorhanden.
Was dann ?
Einen Flag setzen und wieder zurückkehren oder in der Routine warten?
Falls Flag - genauso gut geht es mit Statemachine.
Falls warten - nix mit Multitasking...
Einen Sinn macht das Ganze nur mit Interrupts und TimeSlice, das aber
ist eine ganz andere Liga.
Zeig uns doch jetzt mal, wie man jetzt z.B. zwei Tasks einbindet, von
denen eine einen Piepser an irgendeinem Port quäken lässt und eine einen
Taster abfragt, die den Piepser startet und meinetwegen 2 Sekunden
quäken lässt.
Ich vermisse übrigens die .def für deine Register.
Hallo und allen noch ein gesundes Neues Jahr 2017!
Falls es den einen oder anderen interessiert:
Ich habe mal zwei Bibliotheken erstellt, die auf AVR den Umgang mit Code
vereinfachen sollen.
U.a. die CPU abstrahieren fuer z.B. cooperatives Multitasking...
Fuer konstruktive Anmerkungen, Forks oder Sternchen bin ich dankbar :-)
https://github.com/dumpsite/avr-contexts
MfG Stephan