Forum: Compiler & IDEs Multitasking mit AVR


von chris (Gast)


Lesenswert?

Zur Übung würde ich gerne ein sehr kleines Multitasking System bauen. Es 
soll nichts weiter tun, außer zwischen 3 Tasks im Millisekundentakt 
wechseln.

Wie kann man in einer Timer ISR den Kontext-Switch realisieren?

von Marius W. (mw1987)


Lesenswert?

Klar geht das...

Jeder Task bekommt seinen eigenen Stack und dann gehts los:
1. Alle Register in zu Anfang der ISR auf den Stack sichern: SREG, 
R0-R31
2. Dann den Stackpointer sichern
3. Den Stackpointer auf den nächsten Task ändern
4. Alle Register zurücksichern
5. Rücksprung mit reti

Schau dir mal den FreeRTOS-Port an, da solltest du fündig werden.

MfG
Marius

von Mark .. (mork)


Lesenswert?

Eine Möglichkeit wäre z.B. folgendes:

Du hast eine Sturktur, in der Platz für alle 32 Register, SP und PC ist. 
Diese stellt den Zustand eines Threds dar. Dann gibt es eine Liste von 
Zeigern auf diese Sturkturen, mit in deinem Fall 3 elementen, so wie 
einen Index, der immer auf das momentan verwendete Element zeigt.

In der ISR liest du den Index aus und speicherst alle Register, SP und 
PC in den aktuellen Eintrag. Dann wird der Index erhöht (FIFO-Prinzip) 
und zeigt auf den nächsten auszuführenden Thread. es werden dann alle 
Register aus der Sturktur gelesen, der SP gesetz sowie der gespicherte 
PC als letzes auf den Stack gelegt. Mit einem reti wird dann "zurück" in 
den nächste Task gesprungen. usw...

Jeder Thread muss natürlich einen eigenen Stack haben.

MfG Mark

von Ralf G. (ralg)


Lesenswert?

Wieviel Multitasking solls denn sein?
Alle 1ms umschalten, da langweilt der µC sich ziemlich. Da in dieser 
Zeit jede Menge Befehle abgearbeitet werden können, reicht vielleicht 
auch so ein 'Multitasking für arme'. Gibt's einige Vorschläge hier im 
Forum.

von Falk B. (falk)


Lesenswert?

chris schrieb:
> Zur Übung würde ich gerne ein sehr kleines Multitasking System bauen. Es
> soll nichts weiter tun, außer zwischen 3 Tasks im Millisekundentakt
> wechseln.
>
> Wie kann man in einer Timer ISR den Kontext-Switch realisieren?

Multitasking heisst noch lange nicht Kontext-Switch. Kooperation ist 
nicht nur im Leben sondern auch bei kleinen uCs besser, siehe Artikel 
Multitasking

von chris (Gast)


Lesenswert?

Vielen Dank erst mal für eure Antworten.
>Jeder Task bekommt seinen eigenen Stack und dann gehts los:
1
// neuen Stack erzeugen 
2
// aber wie?
3
4
  task1(); // task1 mit neuen Stack starten
5
6
7
void task1()
8
{
9
 while(1)
10
 {
11
  tuewas();
12
 }
13
}

Bei machen C-Kompilern gibt es einen Parameter und einen Call-Stack.

von Antwortender (Gast)


Lesenswert?

Hallo,

in einer älteren c't (vor zwei Jahren?) wurde das Thema schön erläutert 
mit Beispielen .

von Uwe (de0508)


Lesenswert?

Hallo Chris,

ich habe damit gearbeitet

http://www.cocoos.net/

Anregungen sollten für dich zu finden sein.

Sehr elegant ist das

Beitrag "Wartezeiten effektiv (Scheduler)"

von Peter Dannegger.

Wenn man das Beisiel verstanden hat, eröffnet sich eine andere Sicht 
einer Problemlösung.

von chris (Gast)


Lesenswert?

Danke für die Links. Leider bin ich mit der Beantwortung der Frage, wie 
man vor dem Call einer Funktion einen neuen Stack-Bereich anlegen kann, 
nicht weitergekommen. Vielleicht weiß von euch jemand, wie man so etwas 
macht.

von 900ss (900ss)


Lesenswert?

Es wird z.B. im Sourcecode von FreeRTOS und auch uc/OS-II gut gezeigt.
Es wird in den anderen vielen kleineren RTOS sicher auch zum "Nachlesen" 
drinstehen.
Einfach nur versuchen das nachzuvollziehen.
Hier im Thread wurden auch schon Lösungen gezeigt. Ach ja, ohne 
Assembler wird es nicht gehen.

von chris (Gast)


Lesenswert?

>Hier im Thread wurden auch schon Lösungen gezeigt.

Wo wurde hier im Thread gezeigt, wie man einen neuen Stack-Bereich für 
einen Task erzeugt?

von 900ss (900ss)


Lesenswert?

chris schrieb:
>>Hier im Thread wurden auch schon Lösungen gezeigt.
>
> Wo wurde hier im Thread gezeigt, wie man einen neuen Stack-Bereich für
> einen Task erzeugt?

Hier:
Beitrag "Re: Multitasking mit AVR"
Beitrag "Re: Multitasking mit AVR"

Wie gesagt, etwas (oder pur) Assemblercode ist nötig.

von Uwe (de0508)


Lesenswert?

Chris,

dieser Beitrag

Beitrag "Re: Multitasking mit AVR"

ist bestimmt direkt gemeint und alle aufgezeigten Taskswitscher liegen 
im Quellcode vor, da müsste man dann auch hinein schauen.

Die Frage ist nur_
wir kompliziert und bzgl. Speicherverbrauch, Task-Verhalten muss es für 
eine Problemlösung sein ?

von 900ss (900ss)


Lesenswert?

Bei FreeRTOS findest du das erzeugen des Stacks
in der Datei port.c in einem AVR-Port directory.
Z.B: FreeRTOS\Source\portabe\GCC\ATMegaxxx\port.c

pxPortInitialiseStack heißt die Funktion, die z.B. von 
xTaskGenericCreate() in tasks.c aufgerufen wird.

Der Context-Switch selber findet in vPortYieldFromTick() in port.c 
statt.

von chris (Gast)


Angehängte Dateien:

Lesenswert?

>Z.B: FreeRTOS\Source\portabe\GCC\ATMegaxxx\port.c

Danke, das scheint genau die Stelle zu sein, die man braucht. Ich hänge 
die Datei mal als Referenz zur weiteren Diskussion an den Thread.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.