Multitasking mit AVR

#2399756
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
#2399760
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
#2399776
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
Gast #2399811
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.
Gast #2400098
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.
#2400105
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.
#2400153
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.