PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Multitasking für den Asuro



Giwo
31.05.2005, 14:35
Hallo!

Ich habe ein sehr einfaches cooperatives Multitasking für den Asuro geschrieben. Es ist noch unvollständig (man kann z.B. noch keine Tasks beenden) und vermutlich voller Fehler (also bitte damit rechnen, das der Asuro unverhofft irgentwas macht und z.B. vom Tisch fährt!).

In der Task.zip ist ein Verzeichniss, dass dem "FirstTry" entspricht. Die asuro.c habe ich etwas verändert, so dass sie sich mit meinem task.c verträgt. Außerdem nutzt die Sleep-Funktion nun einen 32Bit Zähler, damit man auch länger als 3ms warten kann.

Die test.c startet 3 Tasks die alle unterschiedliche Leuchtdioden Blinken lassen. Zum anschauen stelle ich sie hier mal rein:


/************************************************** *************************

* *

* This program is free software; you can redistribute it and/or modify *

* it under the terms of the GNU General Public License as published by *

* the Free Software Foundation; either version 2 of the License, or *

* any later version. *

************************************************** *************************/

#include "asuro.h"
#include "task.h"

#define STACK_SIZE 256 /* Groesse der Stacks fuer die Tasks */

unsigned char stackStatus[STACK_SIZE]; /* Stack fuer taskStatus */
unsigned char stackFront[STACK_SIZE]; /* Stack fuer taskFront */

/* taskStatus - Laesst die Status-LED rot und grueb blinken. */
void taskStatus(void) {
while (1) {
StatusLED(RED);
Sleep(72UL*500); /* eine halbe Sekunde warten */
StatusLED(GREEN);
Sleep(72UL*500); /* eine halbe Sekunde warten */
}
}

/* taskFront - Dimmt die Front-LED hell und dunkel, indem sie schnell ein- und ausgeschaltet wird. */
void taskFront(void) {
int i;
while (1) {
for (i=0; i<200; i++) { /* von dunkel nach hell */
FrontLED(ON);
Sleep(i);
FrontLED(OFF);
Sleep(200-i);
}
for (i=0; i<200; i++) { /* von hell nach dunkel */
FrontLED(ON);
Sleep(200-i);
FrontLED(OFF);
Sleep(i);
}
}

}


int main(void)

{

Init(); /* Asuro initialisieren */
initTask(); /* Task initialisieren */
addTask(taskFront, &stackFront[STACK_SIZE-1]); /* taskFront starten */
addTask(taskStatus, &stackStatus[STACK_SIZE-1]); /* taskStatus starten */

while (1) { /* Back-LEDs blinken lassen */
BackLED(ON,OFF);
Sleep(72UL*1000);
BackLED(OFF,ON);
Sleep(72UL*1000);
}


while(1);

return 0;

}



Ich hoffe, trotz fehlender Dokumentation reicht das, um erste spielereien zu machen!

Über Kritik, Kommentare, Verbesserungsvorschläge und natürlich Fehlerbereichte würde ich mich sehr freuen!

Archi
01.06.2005, 23:07
Cool, ist ja ne saugeile Idee!

Ich muss mir das Teil demnächst noch genauer anschauen! Was passiert eigentlich, wenn eine Fuktion, die als Task aufgerufen wurde mit "return" endet?

CU, Robin

Giwo
02.06.2005, 13:03
Cool, ist ja ne saugeile Idee!
Danke!


Was passiert eigentlich, wenn eine Fuktion, die als Task aufgerufen wurde mit "return" endet?
Es wird keine Rückprungadresse auf dem Stack gespeichert, d.h. er macht irgendwas. Einen Neustart oder andere komische Sachen.

Ich habe eben bemerkt, dass man das Attachment nur sehen kann, wenn man hier angemeldet ist! Deswegen hier nochmal für alle anderen:
http://stud.fh-wedel.de/~ii4984/Task.zip

Archi
02.06.2005, 20:56
Wenn man das Status-Register beim Taskwechsel noch mitspeichert, könnte man den Taskwechsel doch auch noch zusätzlich von einem Timer vornehmen lassen, oder? Das muss ja nicht ungedingt der 72kHz-Timer sein, auch der Overflow vom INT1, der auch die Motoren mit PWM versorgt, würde sich eignen.

CU, Robin

linux_80
02.06.2005, 21:04
Hallo,

hab mir mal erlaubt, ein paar gedanken in Sachen "Task loswerden" gemacht:
es bräuchte sowas wie eine removeTask function,
die anfangs so handelt wie die switchTask,
dann aber den alten Task entsorgt, entweder alle nachfolgenden Tasks in der Liste nach unten schieben, oder den letzten Task in der Liste an diesen Platz, dann stimmt halt die Reihenfolge nicht mehr (falls das wichtig sein sollte)

Aufrufen entweder definiert am ende des Tasks,
oder falls man es hinbekommt, am stack den zeiger hinterlegen (in addTask), dann per return ... irgendwie ... :-k

Giwo
02.06.2005, 22:49
Wenn man das Status-Register beim Taskwechsel noch mitspeichert, könnte man den Taskwechsel doch auch noch zusätzlich von einem Timer vornehmen lassen, oder?
Ja, stimmt! Aber an soetwas habe ich mich noch nicht rangetraut, weil man sich damit eine menge Probleme einhandelt. Es ja oft Programmteile, die nicht unterbrochen werden dürfen ("kritische Abschnitte"), wenn z.B. mehrere Prozesse einen gleichen Speicherbereich nutzen (zur Kommunikation), so geht das schief,wenn mittendrin der Nächste drannkommt.

Aber auf jeden fall eine Idee, die man früher oder später umsetzten könnte!


es bräuchte sowas wie eine removeTask function, die anfangs so handelt wie die switchTask, dann aber den alten Task entsorgt, entweder alle nachfolgenden Tasks in der Liste nach unten schieben, oder den letzten Task in der Liste an diesen Platz, dann stimmt halt die Reihenfolge nicht mehr (falls das wichtig sein sollte)
Ich denke es ist nicht schlimm, wenn sich die Reihenfolge ändert. Wenn man soetwas wie Prioritäten hätte, würde sich dei Reihenfolge eh ständig ändern.


Afrufen entweder definiert am ende des Tasks,
oder falls man es hinbekommt, am stack den zeiger hinterlegen (in addTask), dann per return ... irgendwie ...
Man könnte das ijmp am ende von addTaskASM in ein icall umändern. Dann würde man nach einem "return" im Task wieder am ende von addTaskASM landen. Dort könnte man dann was zum löschen hinschreiben.

Mal sehen, am Wochenende finde ich bsetimmt nochmal Zeit, um daran weiterzumachen. Langfristig hatte ich mir überlegt, könnte man eine relativ mächtige Biliothek schreiben, nicht nur mit Multitasking, sondern z.B. auch eine fertige Odemitrieauswertung, Motoregelung, etc. kann. Da ist natürlich die Frage, ob an soetwas Interesse besteht, oder ob die Asuro-Bastler lieber ihren Asuro ganz alleine Programmieren wollen (was ich voll und ganz verstehen könnte!)

PS: Hat eigentlich jemand die Tasks mal unter Windows kompiliert? Ich benutze nur Linux, und frage mich, ob dei dem Windows-Compiler vielleicht unterschiede gibt....

linux_80
02.06.2005, 23:07
Hi,

auch wenn mein name nicht dazu passt, ich habs unter Win probiert, :-b
lief so wie sichs im Programm liest :-)

Hab u.a. festgestellt, wenn man weitere Tasks einbaut, bzw. entfernt, ändern sich die Zeiten erheblich,
bei einem dieser Tasks alleine sieht man von der blinkerei schon nix mehr,
hier gehen dann wohl die ganzen sleeps ab.

Giwo
02.06.2005, 23:31
Hab u.a. festgestellt, wenn man weitere Tasks einbaut, bzw. entfernt, ändern sich die Zeiten erheblich,
bei einem dieser Tasks alleine sieht man von der blinkerei schon nix mehr,
hier gehen dann wohl die ganzen sleeps ab.
Hmm, das könnte ja auf einen Fehler hindeuten 8-[ , obwohl ich nicht verstehe, was du genau meinst. Wird das Sleep schneller oder langsamer? Also bei mir ist z.B. das Blinken in main immer gleich schnell, egal ob ich Tasks adde oder nicht.

linux_80
05.06.2005, 02:30
Hi,

so jetzt kann ich auch wieder, mein Asuro hatte ein paar macken, jetzt hab ich es sogar geschafft mit RS232-adapter zu flashen, geht jetzt sogar besser als mit dem USB, man kann jetzt erst von flashen reden \:D/

beim letzten post meinte ich, dass wenn ich nur den Teil vom Hauptprogramm gelassen habe ging die blinkerei so schnell, da man es nicht mehr als blinken erkennen konnte.
Ich muss das jetzt aber erst nochmal überprüfen.

linux_80
05.06.2005, 03:32
ich denke jetzt weiss ich warum das zeitmässig nicht passte, ich hab da letztesmal selber rumprobiert, und hab nicht deine asuro.c verwendet, in dieser ist ja der Sleep modifiziert.
Jetzt gehts nämlich, egal wieviel Tasks ich verwende.
\:D/