ISR effizient verteilen

OP #4972729
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
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
Gast
S. R. schrieb:
> Die Frage ist, ob das über Dateigrenzen hinweg machbar ist.

Ja. Mit Link Time Optimization (LTO) geht das ganz automatisch. Wenn es 
nur einen Aufrufer einer Funktion gibt, wird diese automatisch 
ge-inlined. Ganz ohne inline und/oder static keywords.
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
OP
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.
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
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

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.