Forum: Mikrocontroller und Digitale Elektronik externe Funktionen in Interrupts


von Rudi (Gast)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@  Rudi (Gast)

>Alles in eine C Datei hauen erscheint mir wenig sinnvoll. Der Compiler
>könnte sich zwar dadurch nach Belieben austoben, aber zu welchem Preis?

Zum Preis, dass eben nich alles super perfekt wiederverwendbar 
lehrbuchartig modularisiert ist. Ich könnte damit leben.

von Strickwettbewerbgewinner (Gast)


Lesenswert?

Oder eben schon alles in einzelne .c Dateien, und dann diese 
#include'n... Das ist zwar so böse, dass da nie jemand drüber redet, 
geht aber... Hat halt den Nachteil, dass bei jeder Änderung alles neu 
kompiliert wird.

von Gebhard R. (Firma: Raich Gerätebau & Entwicklung) (geb)


Lesenswert?

Es erscheint mir grundsätzlich keine gute Idee, in einer 
Interruptroutine Funktionen aufzurufen.Die Interruptroutine soll so kurz 
wie irgendwie möglich sein, d.h. sie ist in der Regel übersichtlich, 
auch wenns Spaghetti-Code ist.

Grüsse

von Rudi (Gast)


Lesenswert?

Schon klar, ich versuch auch Funktionen in Interrupts zu vermeiden.
Man kann auch nicht alles streng nach Schulbuch machen, auch klar.

Aber ein bischen Gedanken machen schadet ja wohl nicht. Über das 
Includen von .C Dateien werd ich mir in einer ruhigen Minute mal den 
Kopf zerbrechen...

Hatte gedacht es gäbe hier vielleicht eoch eine elegantere Lösung...

Danke bisher & Viele Grüße!

von Andreas (Gast)


Lesenswert?

Gebhard Raich schrieb:
> auch wenns Spaghetti-Code ist

Für Spaghetti-Code gibt es heutzutage keine Entschuldigung mehr. Auch 
kleine MCUs sind heute so schnell, dass das Sichern vieler Register oder 
der Aufruf kurzer Funktionen bei jedem empfangenen Zeichen schnell genug 
geht. Wenn es tatsächlich einmal eng werden sollte, kann man bequem auf 
die nächst schnellere MCU ausweichen. Das ist immer preiswerter als der 
- oft vergebliche - Versuch Spaghetti Code zu pflegen.
In den vom Compiler generierten Assembler-Code sollte man nur reinsehen, 
wenn es irgendwelche Probleme gibt. Wenn nicht, ignoriert man ihn 
einfach, auch wenn viele Stellen für das menschliche Auge umständlich 
oder unnötig langsam erscheinen.

von holger (Gast)


Lesenswert?

>In den vom Compiler generierten Assembler-Code sollte man nur reinsehen,
>wenn es irgendwelche Probleme gibt. Wenn nicht, ignoriert man ihn
>einfach, auch wenn viele Stellen für das menschliche Auge umständlich
>oder unnötig langsam erscheinen.

Genau. Für unbenutzte Rechenzeit gibt es auch kein Geld vom
Hersteller zurück;)

von Strickwettbewerbgewinner (Gast)


Lesenswert?

holger schrieb:
> Genau. Für unbenutzte Rechenzeit gibt es auch kein Geld vom
> Hersteller zurück;)

Aber mehr Leben aus dem Akku, falls aus einem solchen betrieben :-P

von Rudi (Gast)


Lesenswert?

Ok dann werd ichs mal so beibehalten wie ichs momentan habe. Ich hab ja 
momentan nix zeitkritisches vor, weswegen ich auch nicht optimieren 
muss.

Aber man macht sich halt so seine Gedanken,

Wenn jemandem noch was einfällt, gerne her damit :-)

Viele Grüße!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.