PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Multithread in Basic?



Sommer
16.04.2005, 09:14
Hi Leute,

wie macht man zwei Schleifen unter Basic die "gleichzeitig" laufen?

So nen art Multithread mach ich momentan so.

Thread:
gosub A
gosub B
gosub B
goto Thread


A:
xxxxxxxx
Code..
RETURN


B:
xxxxxxxx
Code..
RETURN


C:
xxxxxxxx
Code..
RETURN


ich müsste aber zwei Schleifen (Zähler) gleichzeitig laufen lassen.
Schleife in Schelife geht leider nicht da die Schleife Start und Return bedingung hat wenn ein Pin High b.z.w Low wird, ich zähle damit meine
Radimpulse aus 0 --> 200ms.
Das bremst natürlich mein Programm :-(

Da ich aber schon mal gehört habe das manche einen Multihread in Basic
Programmiert haben (AVR) könnte es ja sein das es geht?!

Technisch kann ich mir des leider net vorstellen da ich mit Basic nur springen kann und ja dann der Code ausgeführt wird und er erst wieder
zurückspringt wenn er fertig ist und nicht nach Maschienenzyklen?!

Danke an alle

By Ulli

BlueNature
16.04.2005, 11:34
Hallo!

1. Parallel geht mal gar nichts!
2. Man kann nur quasi parall, also abwechslend nacheinander sehr schnell die einzelnen Tasks bedienen

Wenn du das machen willst mußt die selber eine Zeischeibe aufbauen die deinen Anforderungen enstspricht. Darfst keine Zeiten vernichten durch Pause-Befehle und mußt eine IDLE-Loop aufbauen als zentrales Hauptpgramm. Das ist aber alles selbst zu schreiben und dem jeweiligen Fall entsprechend!

Im einfachsten Fall geht man her und schreibt sich eine Hauptschleife in der einfach die Tasks (Unterporogramme 1...n) aufgerufen werden. Das Durchlaufen der Unterprogramme muß entweder permanent so schnell wie möglich erfolgen oder wenn es zeitgenau sein muß immer gewartet werden auf ein Ereigniss das die ganzen Tasks nacheinander ablaufen läßt (z.B. einem Timer-Interrupt).

Zudem darf in keinem Unterprogramm zu viel Code stehen weil es in der Summe dann zuviel Zeit brauchen würde. Mußt also genau ausknobeln.

Weiterhin mußt zusehen das jedes Unterprogram wenn es länger braucht auch mehrfach wie eine Art Schrittkette funktioniert. Also nur einen kleinen Teil seiner Aufgabe erledigt und dann erst beim nächsten Aufruf gleich in den nächsten Aufgabenteil springt und somit nach vielen Aufrufen dann ein komplexes Programm (Einzeltask) abgearbeitet hat.

Man kann das Ganze noch weiter treiben und so eine Art Flags als Bitvariablen zuwischen Hauptprogramm (Taskmanager) und Unterprogrammen (Tasks) austauschen die anzeigen ob die Abarbeitung nötig ist, oder ob Zeit gespart werden kann.

Grpße Wolfgang

recycle
16.04.2005, 12:02
Technisch kann ich mir des leider net vorstellen da ich mit Basic nur springen kann und ja dann der Code ausgeführt wird und er erst wieder
zurückspringt wenn er fertig ist und nicht nach Maschienenzyklen?!


Wenn du die einzelnen Routinen über einen Timer aufrufst, kannst du erreichen, dass er nach eine von dir definierten Zeit zur nächsten Routine springt und nicht erst wenn er mit der einen fertig ist.

Das ergibt natürlich noch lange kein richtiges Multithreading, aber oft reicht es, wenn man nur wenige wirklich zeitkritische Routinen über einen Timer aufruft und den Rest in einer Schleife (so wie deine Sprungliste oben) nacheinander abarbeiten lässt.

So ein µC ist ja ziemlich flott und bei der Abfrage von Sensoren und vielen anderen Dingen kommt es meist nicht auf ein paar mS an.
Wenn der Controller da per Timer regelmässig zwischendurch rausspringt um einen Radencoder abzufragen oder einen Schritt auf den Schrittmotor zu geben stört das meist nicht.



Radimpulse aus 0 --> 200ms.
Das bremst natürlich mein Programm
Radencoder würde ich an einen externen Interrupt anschliessen und in der entsprechenden Interrupt-Routine jedesmal eine Zählervariable um 1 hochzählen, wenn ein neuer Interrupt kommt.
Auf diese Zählkervariable kannst du dann in deiner normalen Routine zugreifen und hast (mehr oder weniger) automatisch immer den aktuellen Stand.

PS: ich sehe gerade, BlueNature war schneller und hat deine Frage schon beantwortet.

BlueNature
16.04.2005, 12:08
Servus Recycle!

Das mit dem Interrupt ist für schnelle Impulse eh unabdinglich. Da muß ich dir recht geben. Aber das wollte ich ncith alles schreiben weil es ein recht kompliziertes Thema ist bei dem ich am liebsten einen Test-Pin toggle um daran die Flanken der Tasks real zu messen.

Wenn ich externe Interrupts mit einem Increment auswerte um damit eine globale Variable hochzuzählen setze ich noch im Interrupt nach dem Incrementieren sofort ein Flag das ich mit definiert habe. Das erleichtert den betroffenen Tasks dann zu entscheiden ob die Zählvariable sinnvoll ist neu zu berechnen oder ob es unterschlagen werden kann. Ist das Flag da, wird eben in der folgenden Zeit eiene neue Berechnung durchgeführt und ist diese erledigt wird das Flag wieder zurückgesetzt um das Ganze wieder "scharf" zu schalten. So kann man mit Interrupts sehr effektiv arbeiten.

Grüße Wolfgang

uli88
27.12.2005, 14:50
Mein Vorschlag kommt zwar spät, aber vielleicht hilft es dem Ein oder Anderen weiter der ein ähnliches Problem mit der "Gleichzeitigkeit" von Abläufen hat.

Will man auf Timergeschichten und Threads verzichten, eignet sich folgende Logik:

Aufg1=“start“
Aufg2=“start“

Do While Aufg1<>”Ende” Or Aufg2 <>”Ende”
Select Case Aufg1
Case “start”: tu irgendwas, setze Aufg1=”Action1”
Case “Action1”: tu irgendwas, setze Aufg1=”Action2”
Case “Action2”: tu irgendwas, setze Aufg1=”Verlasse”
Case “Verlasse” tu irgendwas, setze Aufg1="Ende"
End Select

Select Case Aufg2
Case “start”: tu irgendwas, setze Aufg2=”Action1”
Case “Action1”: tu irgendwas, setze Aufg2=”Action2”
Case “Action2”: tu irgendwas, setze Aufg2=”Verlasse”
Case “Verlasse” tu irgendwas setze Aufg2="Ende"
End Select
Loop

Zur Erklärung, die Do While-Schleife wird solange durchlaufen bis Aufgabe1 und Aufgabe2 ihre Endebedingung zugewiesen bekommen.

Die Variable Aufg1 und Aufg2 wird verwendet um innerhalb der zugehörigen Select Case-Anwiesung eien Logischen Ablauf zu steuern.

Zugegeben, man muß sich mit dieser Art der Logik wirklich auseinandersetzen um den gewünschten Ablauf zu erreichen, aber es funktioniert und ist eine oft angewandte Programmiertechnik!

MfG Uli88