Hallo,
ich habe ein Programm, welches im wesentlichen aus einer Sleep-Zeit
besteht und mehreren Anweisungen, die sporadisch auftreten können.
Die Hauptfunktion sieht also wie folgt aus:
1 | if(Taskregister==FLAG_IDLE)
|
2 | {
|
3 | LPM3;
|
4 | }
|
5 |
|
6 | else
|
7 | {
|
8 | Taskmanager();
|
9 | }
|
und der eigentliche Taskmanager wie folgt:
1 | int32_t Taskmanager()
|
2 | {
|
3 | switch(Taskregister)
|
4 | {
|
5 | case FLAG_MEASURE: // in Timer ISR gesetzt
|
6 | Measure(&Messergebnisse);
|
7 | set(&Taskregister, FLAG_EVALUATE);
|
8 | reset(&Taskregister, FLAG_MEASURE);
|
9 | set (&Taskregister, FLAG_TEMP_START);
|
10 | //no break Fallthrough
|
11 |
|
12 | case FLAG_EVALUATE:
|
13 | reset(&Taskregister, FLAG_EVALUATE);
|
14 | my_itoa_4digit(Messergebnisse.Wert, string_array);
|
15 | add_string_to_uart_tx_buffer(&TX_Ringbuffer, Wert);
|
16 |
|
17 | case FLAG_TEMP_START:
|
18 | uart_transmit();
|
19 | Measure_Temp();
|
20 | reset(&Taskregister, FLAG_TEMP_START);
|
21 | break;
|
22 | ...
|
23 | weitere cases
|
Hinter dem Flag-Register verbirgt sich:
1 | #define FLAG_IDLE 0x0000
|
2 | #define FLAG_MEASURE 0x0001
|
3 | #define FLAG_EVALUATE 0x0002
|
4 | #define FLAG_UART 0x0004
|
5 |
|
6 | ... weitere Flags...
|
7 |
|
8 |
|
9 | volatile extern uint32_t Taskregister;
|
Nun ist die Idee dahinter natürlich, dass die einzelnen Flags an
unterschiedlichen Positionen und auch durch unterschiedliche externe
Ereignisse gesetzt werden können.
Das funktioniert auch soweit, solange nur ein einziges Flag zur Zeit
gesetzt ist.
Sobald aber aus welchen Gründen auch immer mehrere Flags gesetzt sind,
z.B. zeitgleich das 0. und 1. Bit meines Flagregisters, so ist das
Resultat dann ja dezimal "3" und die Switch-Case Anweisung findet diesen
Fall nicht mehr... bzw. fängt an einem falschen Punkt an, in die
Switch-case Anweisung hineinzulaufen
Wie kann ich dieses Problem umgehen und dabei die oben skizzierte
Strategie der Eventbehandlung beibehalten?