Kontextwechsel beim AVR

Gast #3341674
Lesenswert?

Hallo zusammen,

rein aus Interesse hab ich mir mal den freeRTOS - Port für den ATmega323 
angeschaut.

Leider verstehe ich da nicht genau, wie der Kontextwechsel funktioniert.

Einmal gibt es folgendes Makro:
1
#define portSAVE_CONTEXT()                  \
2
  asm volatile (  "push  r0            \n\t"  \
3
          "in    r0, __SREG__      \n\t"  \
4
          "cli              \n\t"  \
5
          "push  r0            \n\t"  \
6
          "push  r1            \n\t"  \
7
          "clr  r1            \n\t"  \
8
          "push  r2            \n\t"  \
9
          "push  r3            \n\t"  \
10
          "push  r4            \n\t"  \
11
          "push  r5            \n\t"  \
12
          "push  r6            \n\t"  \
13
          "push  r7            \n\t"  \
14
          "push  r8            \n\t"  \
15
          "push  r9            \n\t"  \
16
          "push  r10            \n\t"  \
17
          "push  r11            \n\t"  \
18
          "push  r12            \n\t"  \
19
          "push  r13            \n\t"  \
20
          "push  r14            \n\t"  \
21
          "push  r15            \n\t"  \
22
          "push  r16            \n\t"  \
23
          "push  r17            \n\t"  \
24
          "push  r18            \n\t"  \
25
          "push  r19            \n\t"  \
26
          "push  r20            \n\t"  \
27
          "push  r21            \n\t"  \
28
          "push  r22            \n\t"  \
29
          "push  r23            \n\t"  \
30
          "push  r24            \n\t"  \
31
          "push  r25            \n\t"  \
32
          "push  r26            \n\t"  \
33
          "push  r27            \n\t"  \
34
          "push  r28            \n\t"  \
35
          "push  r29            \n\t"  \
36
          "push  r30            \n\t"  \
37
          "push  r31            \n\t"  \
38
          "lds  r26, pxCurrentTCB    \n\t"  \
39
          "lds  r27, pxCurrentTCB + 1  \n\t"  \
40
          "in    r0, 0x3d        \n\t"  \
41
          "st    x+, r0          \n\t"  \
42
          "in    r0, 0x3e        \n\t"  \
43
          "st    x+, r0          \n\t"  \
44
        );
Hier wird der Kontext aber nur gesichert. Soweit ist noch alles klar.

Aufgerufen wird das Makro z.B. hier:
1
void vPortYield( void )
2
{
3
  portSAVE_CONTEXT();
4
  vTaskSwitchContext();
5
  portRESTORE_CONTEXT();
6

7
  asm volatile ( "ret" );
8
}

vTaskSwitchContext() klingt ja sehr nach dem "eigentlichen" Wechsel.
Allerdings wird hier nur der nächste TCB (= task control block; 
Konfigurationsstruktur eines jeden Tasks) aus einer Liste ausgesucht.

So wie ich das sehe habe ich zwar nach "vPortYield()" den alten Stack 
und Kontext gesichert und den neuen Stack und Kontext ausgewählt.
Aber irgendwie vermisse ich den Teil wo auch der Wechsel des 
Programmflusses stattfindet. Irgendwann muss ja mal ein "Sprung" in den 
anderen Task stattfinden.

Kennt sich jemand mit dem freeRTOS einigermasen aus und kann mir 
weiterhelfen?

Grüße,
Karlo
Gast #3341682
Lesenswert?

Alle Register auf den Stack.
StackPointer in den aktuellen TCB.
Nächsten TCB ermitteln.
StackPointer aus dem aktuellen TCB, der jetzt ein anderer als zuvor sein 
kann.
Alle Register von (potentiell anderen) Stack holen.

Jede Ta so hat ihren eigenen Stack.
BTW, FreeRTOS hat auch eine bebilderte Beschreibung des Ganzen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren