Wenn die Aufrufzeiten für die Module ganzzahlige Vielfache voneinander
sind, dann einen gemeinsamen Timer ("Systemtimer für die Module meiner
Library", z.B. 10ms Timer) so schnell laufen lassen, dass Ticks für
beide Aktionen erreicht werden (grösster gemeinsamer Teiler). Über einen
Softwarezähler dann die Ereignisse abpassen.
Interrupt-driven
(do_UHR() und do_PIR() haben kurze Laufzeit, d.h. können mit gesperrten
Interrupts laufen)
1 | ISR(Timer...)
|
2 | {
|
3 | static uint8_t prescaler_PIR = PRESCALER_PIR;
|
4 | static uint8_t prescaler_UHR = PRESCALER_UHR;
|
5 |
|
6 | if ( --prescaler_PIR == 0 )
|
7 | {
|
8 | prescaler_PIR = PRESCALER_PIR;
|
9 | do_PIR();
|
10 | }
|
11 |
|
12 | if ( --prescaler_UHR == 0 )
|
13 | {
|
14 | prescaler_UHR = PRESCALER_UHR;
|
15 | do_UHR();
|
16 | }
|
17 | }
|
Event-driven
(do_UHR() und do_PIR() dauern lang, d.h. Interrupts sollen weiterlaufen)
1 | #define PRESCALER_PIR 23
|
2 | #define PRESCALER_UHR 42
|
3 |
|
4 | volatile uint8_t event_PIR;
|
5 | volatile uint8_t event_UHR;
|
6 |
|
7 | ISR(Timer...)
|
8 | {
|
9 | static uint8_t prescaler_PIR = PRESCALER_PIR;
|
10 | static uint8_t prescaler_UHR = PRESCALER_UHR;
|
11 |
|
12 | if ( --prescaler_PIR == 0 )
|
13 | {
|
14 | prescaler_PIR = PRESCALER_PIR;
|
15 | event_PIR = 1;
|
16 | }
|
17 |
|
18 | if ( --prescaler_UHR == 0 )
|
19 | {
|
20 | prescaler_UHR = PRESCALER_UHR;
|
21 | event_UHR = 1;
|
22 | }
|
23 | }
|
24 |
|
25 | int main(void)
|
26 | {
|
27 | while(1)
|
28 | {
|
29 | if ( event_PIR )
|
30 | {
|
31 | event_PIR = 0;
|
32 | do_PIR();
|
33 | }
|
34 |
|
35 | if ( event_UHR )
|
36 | {
|
37 | event_UHR = 0;
|
38 | do_UHR();
|
39 | }
|
40 | }
|
41 | }
|
Für eine Library kann man die Abarbeitung der Funktionen flexibel
halten, wenn man eine Liste führt, in die neue Module/Funktionen sich
mit Funktionspointer, Eventflagpointer und Prescaler eintragen.
Stichwort: Scheduler