ISR effizient verteilen

#4972729
Lesenswert?

Hi,

ich spiele derzeit mit einem USB-fähigen AVR (Atmega32U4) herum und 
möchte daraus ein Composite Device (cdc-acm und msc) bauen. Die 
Verwaltung des Gesamtdevices (Endpoint 0, Descriptoren) muss zentral 
geschehen, alles weitere soll aber jeder Treiber (nach Möglichkeit) für 
sich behandeln.

Alle Endpoints teilen sich einen Interruptvektor, also hatte ich da eine 
Tabelle im Kopf, wo die Endpoint-spezifischen Handler vermerkt sind und 
verzweige dann nach Bedarf. Ich arbeite mit C (avr-gcc).

Kann ich diese spezifischen Handler in die ISR inlinen, auch über 
Dateigrenzen hinweg? Was muss ich dem gcc dafür mitteilen?

Oder muss ich den Preis eines indirekten Funktionsaufrufs in der ISR 
bezahlen, wenn ich getrennte Treiber möchte?

Eine fertige Bibliothek möchte ich (vorerst) nicht nutzen. Im Augenblick 
orientiere ich mich an einem kleinen Teensy-Beispiel für cdc und den 
originalen Datenblättern, Lufa ist mir ein bisschen zu wirr.

Gruß,
svenska
#4972756
Lesenswert?

Du kannst keine ISR mehrfach definieren. Der eigentliche Funktionsaufruf 
aus der ISR heraus ist ja noch nicht mal das Problem, der kostet selbst 
mit Parameterübergabe nur ein paar Zyklen. Unschöner ist, daß der gcc 
zum ISR-Begin alle Register retten, und am Ende wieder herstellen muß, 
sobald er da einen Funtionsaufruf findet, bei dem er die Sourcecode 
nicht kennt.

Da die ISR aber auch nur eine C-Funktion ist, kannst du da Funktionen so 
inlinen, wie sich in C Funktionen halt so inlinen lassen.
Also entweder alle Funktionen in einem Sourcefile, oder zumindest per 
include darin eingebunden. Die dann noch static und inline, dann machts 
der gcc vielleicht sogar.

Oliver
#4973318
Lesenswert?

wenn man eine C-Funktion möglichst immer und ausschließlich auch über 
Übersetzungseinheiten hinweg ge-inlined haben möchte, schreibt man sie 
nicht in eine .c-Datei, sondern in die entsprechende Header-Datei und 
definiert sie
1
static inline f(...) { ... };

Allerdings muß der Compiler sie selbst dann nicht unbedingt inlinen, 
wenn er nicht will (weil man z.B. nicht optimiert compiliert). Bei gcc 
kann man in dem Fall noch extra nachhelfen:
1
__attribute__((always_inline))

Dann geht das auch ohne -flto
#4973380
Lesenswert?

MaWin schrieb:
> Ja. Mit Link Time Optimization (LTO) geht das ganz automatisch.

Auch, wenn man das indirekt über einen Funktionspointer in einer (lokal 
const static deklarierten) Tabelle macht?

Also von:
1
    switch(whatever) {
2
    case 0: tab[0](); break;
3
    case 1: tab[1](); break;
4
    default: break;
5
    }

zu:
1
    if(whatever == 0) {
2
        /* die funktion, auf die tab[0] zeigt */
3
    } elsif(whatever == 1) {
4
        /* die funktion, auf die tab[1] zeigt */
5
    }

automatisch? Denn das kann ich mir nicht vorstellen.
#4973394
Lesenswert?

S. R. schrieb:
> MaWin schrieb:
>> Ja. Mit Link Time Optimization (LTO) geht das ganz automatisch.
.
> Auch, wenn man das indirekt über einen Funktionspointer in einer (lokal
> const static deklarierten) Tabelle macht?
>
> Also von:
>
1
>     switch(whatever) {
2
>     case 0: tab[0](); break;
3
>     case 1: tab[1](); break;
4
>     default: break;
5
>     }
6
>
.
> zu:
>
1
>     if(whatever == 0) {
2
>         /* die funktion, auf die tab[0] zeigt */
3
>     } elsif(whatever == 1) {
4
>         /* die funktion, auf die tab[1] zeigt */
5
>     }
6
>
>
> automatisch? Denn das kann ich mir nicht vorstellen.

Bei LTO wird die komplette interne Darstellung einer "C-Datei" oder 
korrekt Übersetzungseinheit an den Linker übergeben, d.h. die 
Optimierung kann dort mit der gesammelten Info über alle Code-Schnipsel 
stattfinden.
Gast #4973420
Lesenswert?

S. R. schrieb:
> automatisch? Denn das kann ich mir nicht vorstellen.

Ich weiß nicht, ob der gcc das tut. Aber ich halte es nicht für 
unmöglich. Es müss(t)en halt mehrere Optimierungen zusammenarbeiten.

Ich denke aber, dass eher das switch rausfliegen wird und Arithmetik auf 
die Tabelle angewendet wird.

Am Ende ist das aber auch ein Spezialfall. Nimm halt keine Tabelle.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren