Hallo,
ich versuche gerade mein AVR Projekt möglichst modular und elegant
aufzubaun. Leider ist das nicht immer ganz leicht. So auch jetzt wieder.
Beispiel: Ich schreibe ein Modul zur Benutzung des USARTS. Über eine
Headerdatei werden einer Applikationssoftware Schnittstellen zum Zugriff
auf das Modul zur Verfügung gestellt, etwa PutChar oder PutString.
Die Kommunikation zwischen den Modulen in die andere Richtung könnte zB
über Callbacks laufen. Das Modul kann zB einer Applikation mitteilen,
dass ein Char empfangen wurde. Die Applikation kann den Char dann
auswerten oder in einen Puffer schreiben.
Leider birgt der Aufruf einer Funktion, von der man nur den Prototyp
kennt, innerhalb einer ISR einige Tücken. Der Compiler weis nicht, was
in der Funktion genau passiert und muss alle Register sichern. Das sieht
dann zB so aus:
1 | 00000760 <__vector_20>:
|
2 | 760: 1f 92 push r1
|
3 | 762: 0f 92 push r0
|
4 | 764: 0f b6 in r0, 0x3f ; 63
|
5 | 766: 0f 92 push r0
|
6 | 768: 0b b6 in r0, 0x3b ; 59
|
7 | 76a: 0f 92 push r0
|
8 | 76c: 11 24 eor r1, r1
|
9 | 76e: 2f 93 push r18
|
10 | 770: 3f 93 push r19
|
11 | 772: 4f 93 push r20
|
12 | 774: 5f 93 push r21
|
13 | 776: 6f 93 push r22
|
14 | 778: 7f 93 push r23
|
15 | 77a: 8f 93 push r24
|
16 | 77c: 9f 93 push r25
|
17 | 77e: af 93 push r26
|
18 | 780: bf 93 push r27
|
19 | 782: ef 93 push r30
|
20 | 784: ff 93 push r31
|
21 | 786: 0e 94 aa 03 call 0x754 ; 0x754 <Char_ReceiveClbk>
|
22 | 78a: ff 91 pop r31
|
23 | 78c: ef 91 pop r30
|
24 | 78e: bf 91 pop r27
|
25 | 790: af 91 pop r26
|
26 | 792: 9f 91 pop r25
|
27 | 794: 8f 91 pop r24
|
28 | 796: 7f 91 pop r23
|
29 | 798: 6f 91 pop r22
|
30 | 79a: 5f 91 pop r21
|
31 | 79c: 4f 91 pop r20
|
32 | 79e: 3f 91 pop r19
|
33 | 7a0: 2f 91 pop r18
|
34 | 7a2: 0f 90 pop r0
|
35 | 7a4: 0b be out 0x3b, r0 ; 59
|
36 | 7a6: 0f 90 pop r0
|
37 | 7a8: 0f be out 0x3f, r0 ; 63
|
38 | 7aa: 0f 90 pop r0
|
39 | 7ac: 1f 90 pop r1
|
40 | 7ae: 18 95 reti
|
Neben der Speicherplatzverschwendung fällt natürlich vor allem die
Ausführungszeit ins Gewicht. Ein Rx Interrupt kann unter Umständen ja
sehr oft auftreten. Ich verschenke also massig Zeit, das Sichern und
Wiederherstellen der Register dauert länger als das Sichern des
empfangenen Zeichens...
Wie löst man nun sowas am elegantesten?
Alles in eine C Datei hauen erscheint mir wenig sinnvoll. Der Compiler
könnte sich zwar dadurch nach Belieben austoben, aber zu welchem Preis?
Kann man irgendwie über inline tricksen?
Ich bin ja mit Sicherheit nicht der erste mit diesem Problem. Hat sich
in der Praxis dafür vielleicht eine Vorgehensweise etabliert?
Danke & Viele Grüße,
Rudi