Guten Abend,
ich versuche mich grade an einem RTOS für Cortex M (nur zum Spaß, ich
weiß es gibt viele Fertige). Mein Problem ist zur Zeit der Kontext
wechsel von einem Task zu einem anderen.
1 | void Task1(void)
|
2 | {
|
3 | int x = 123;
|
4 | while(1)
|
5 | {
|
6 | debug_printf("%d\n", x);
|
7 | }
|
8 | }
|
9 |
|
10 | void Task2(void)
|
11 | {
|
12 | int x = 321;
|
13 | while(1)
|
14 | {
|
15 | }
|
16 | }
|
Als erstes Läuft Task1 und dann wird gewechselt (im Systick Handler).
Wenn Task1 dannach wieder laufen soll wird aber 321 statt 123
ausgegeben, weshalb ich befürchte, dass die Stacks durcheinander kommen.
Ich könnte mir auch gut vorstellen, dass das mit dem Software Stacking
zu tun hat, bei dem die Register R4 - R11 auf dem Stack gesichtert
werden. Die anderen Register sichert die Hardware automatisch beim
Eintritt in den Interrupt.
1 | void SaveTask(void)
|
2 | {
|
3 | CurrentTask->State = WAITING;
|
4 |
|
5 | msp = __get_MSP();
|
6 | __set_MSP(__get_PSP());
|
7 | __ISB();
|
8 |
|
9 | asm("push {r4}");
|
10 | asm("push {r5}");
|
11 | asm("push {r6}");
|
12 | asm("push {r7}");
|
13 | asm("push {r8}");
|
14 | asm("push {r9}");
|
15 | asm("push {r10}");
|
16 | asm("push {r11}");
|
17 |
|
18 | CurrentTask->StackPointer = __get_MSP();
|
19 |
|
20 | __set_MSP(msp);
|
21 | __ISB();
|
22 | }
|
23 |
|
24 | void LoadTask(Task_t *task)
|
25 | {
|
26 | if(task->State == READY)
|
27 | {
|
28 | CurrentTask = task;
|
29 | CurrentTask->State = RUNNING;
|
30 |
|
31 | __set_PSP(CurrentTask->StackPointer);
|
32 | __ISB();
|
33 | }
|
34 | else if(task->State == WAITING)
|
35 | {
|
36 | CurrentTask = task;
|
37 | CurrentTask->State = RUNNING;
|
38 |
|
39 | msp = __get_MSP();
|
40 | __set_MSP(CurrentTask->StackPointer);
|
41 | __ISB();
|
42 |
|
43 | asm("pop {r11}");
|
44 | asm("pop {r10}");
|
45 | asm("pop {r9}");
|
46 | asm("pop {r8}");
|
47 | asm("pop {r7}");
|
48 | asm("pop {r6}");
|
49 | asm("pop {r5}");
|
50 | asm("pop {r4}");
|
51 |
|
52 | CurrentTask->StackPointer = __get_MSP();
|
53 |
|
54 | __set_MSP(msp);
|
55 | __ISB();
|
56 |
|
57 | __set_PSP(CurrentTask->StackPointer);
|
58 | __ISB();
|
59 | }
|
60 | }
|
Die Stacks sind auch außreichen groß (128 Words nur für Daten) Der
Zustand READY sagt nur aus, das der Task neu ist. WAITING bedeutet, das
der Task schonmal aktiv war.
Vielleicht hat hier jemand Ahnung von RTOSs und kennt die Lösung. Per
Debugging und Step by Step konnte ich leider nicht raus finden wie die
Daten von Task2 in Task1 gelangen.
mfg Moritz