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