ISR Vektor nur wenn init-Funktion aufgerufen wird

Persönliche Seite #4414847
Lesenswert?

Hallo Forum,

wie immer eine spezielle Frage von mir:

Ich habe hier einen AVR der verschiedene Hardwareteile hat, bei dem 
jeder eine oder mehrere Interrupts besitzt.
Dadurch dass die dazugehörigen Vektoren nicht durch das Programm, 
sondern durch die Hardware aufgerufen wird, muss im Linkerfile ein 
KEEP(vectors) (oder so ähnlich) stehen. Dadurch erzeugt jeder Vektor der 
im Programm definiert ist einen Eintrag im Output-File. Das ist ja 
generell auch richtig und wichtig.

Aber nun kann es sein, dass z.B. ein AVR mehrere UARTs hat und nur einer 
davon benutzt wird. Somit wären die restlichen ISRs zwar enthalten, 
bleiben aber immer ungenutzt.

Bei mir hat jeder Hardware-Teile seine eigene init-Funktion. Könnte man 
dem Linker irgendwie beibringen, dass er die Vektoren nur behalten soll, 
wenn die dazugehörige init-Funktion aufgerufen wird?

Ein einfaches Nein genügt ;)

mit freundlichen Grüßen
N.G.
Persönliche Seite #4415225
Lesenswert?

N. G. schrieb:
> Bei mir hat jeder Hardware-Teile seine eigene init-Funktion. Könnte man
> dem Linker irgendwie beibringen, dass er die Vektoren nur behalten soll,
> wenn die dazugehörige init-Funktion aufgerufen wird?

Ja, die entsprechenden Module (i.d.R. nur eines) werden einfach nicht 
hinzugelingt.

Dazu wird die init nicht explizit, z.B. von main, aufgerufen, sondern 
die Initialisierung geschieht durch einen Konstruktor per Modul:
1
__attribute__((__constructor__,__used__,__unused__))
2
static void module_init (void) { ... }
Persönliche Seite #4415231
Lesenswert?

anbei mal ein Beispiel was ich meine:

(Gebaut für einen ATmega2560 - ja ein schlechtes Beispiel, weil Platz 
hat der genug, aber um das "Problem" zu verdeutlichen ist es perfekt)

Abgesehen vom Startup-Code, der Vektortabelle, der (leeren) 
main-Funktion und dem exit-Code ist nichts da, ist ja auch klar, der 
Controller soll ja nichts machen.
Aber: ein bischen mehr ist halt doch da: 9 nicht ganz kleine Vektoren

macht schon mal über 1200 byte Code, bei dem ich den größten Teil gar 
nicht will...

Johann L. schrieb:
> N. G. schrieb:
>> Bei mir hat jeder Hardware-Teile seine eigene init-Funktion. Könnte man
>> dem Linker irgendwie beibringen, dass er die Vektoren nur behalten soll,
>> wenn die dazugehörige init-Funktion aufgerufen wird?
>
> Ja, die entsprechenden Module (i.d.R. nur eines) werden einfach nicht
> hinzugelingt.
>
> Dazu wird die init nicht explizit, z.B. von main, aufgerufen, sondern
> die Initialisierung geschieht durch einen Konstruktor per
> Modul:__attribute__((_constructor_,__used__,__unused__))
> static void module_init (void) { ... }

Okay, das sieht schon mal interessant aus. Aber darf ein Kontruktor 
static sein? Und warum _used_,__unused__?
Angehängte Dateien:
Persönliche Seite #4415241
Lesenswert?

N. G. schrieb:
> Johann L. schrieb:
>> N. G. schrieb:
>>> Bei mir hat jeder Hardware-Teile seine eigene init-Funktion. Könnte man
>>> dem Linker irgendwie beibringen, dass er die Vektoren nur behalten soll,
>>> wenn die dazugehörige init-Funktion aufgerufen wird?
>>
>> Ja, die entsprechenden Module (i.d.R. nur eines) werden einfach nicht
>> hinzugelingt.
>>
>> Dazu wird die init nicht explizit, z.B. von main, aufgerufen, sondern
>> die Initialisierung geschieht durch einen Konstruktor per
>> Modul:__attribute__((_constructor_,__used__,__unused__))
>> static void module_init (void) { ... }
>
> Okay, das sieht schon mal interessant aus. Aber darf ein Kontruktor
> static sein?

Ja. I'm not joking :-)

> Und warum _used_,__unused__?

used: Selbst wenn kein Aufruf existiert, wird die (static) Funktion 
nicht vom Compiler entsprgt.  Kann aber gut sein, dass das für 
Konstruktoren eh der Fall ist, weil die i.d.R. ja nicht aufgerufen 
werden. Aber used schadet nicht.

unused: Es gibt keine Warnung, obwohl eine static nicht-inline Funktion 
nie verwendet wird.  Ditto was gcc-Wissen bzgl. Konstruktor angeht.
Persönliche Seite #4415251
Lesenswert?

Johann L. schrieb:
> Ja. I'm not joking :-)

Hätte ich von dir auch nicht erwartet ;)

>> Und warum used,__unused__?
>
> used: Selbst wenn kein Aufruf existiert, wird die (static) Funktion
> nicht vom Compiler entsprgt.  Kann aber gut sein, dass das für
> Konstruktoren eh der Fall ist, weil die i.d.R. ja nicht aufgerufen
> werden. Aber used schadet nicht.
>
> unused: Es gibt keine Warnung, obwohl eine static nicht-inline Funktion
> nie verwendet wird.  Ditto was gcc-Wissen bzgl. Konstruktor angeht.

Okay, mit der Erklärung logisch, auf den ersten Blick aber paradox.
#4415416
Lesenswert?

N. G. schrieb:
> Aber nun kann es sein, dass z.B. ein AVR mehrere UARTs hat und nur einer
> davon benutzt wird. Somit wären die restlichen ISRs zwar enthalten,
> bleiben aber immer ungenutzt.

Wo ist das Problem?
Du weißt doch schon zur Compilezeit, ob und welche UART Du benutzt:
1
#ifdef UART0_RX_BUFF_SIZE
2
// code
3
#endif
4
#ifdef UART1_RX_BUFF_SIZE
5
// code
6
#endif
7
#ifdef UART2_RX_BUFF_SIZE
8
// code
9
#endif
10
#ifdef UART3_RX_BUFF_SIZE
11
// code
12
#endif
#4425066
Lesenswert?

N. G. schrieb:
> Im Prinzip mache ich das meist auch so, nur dachte ich, dass es vllt.
> eine Trickreichere, elegantere Lösung gibt.

Ich sag mal, ein Funktionsaufruf kann keinen Code erzeugen. Und wenn man 
eine Funktion nicht aufruft, ist ja auch ihr Code überflüssig.
Man könnte natürlich ein Macro schreiben, was Code enthält und nach 
außen hin wie ein Funktionsaufruf aussieht.

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