Forum: Compiler & IDEs Unterschiedlicher Aufruf einer Funktion


von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!


Anbei ein kleine Projekt von mir, in welchem eine Funktion test() einmal 
in einer ISR und einmal in einer Anderen "normalen"Funktion "InitRtc()" 
aufgerufen wird. test() wird in einer anderen Datei definiert.

was mich konkret wundert ist das er in der ISR so viele Register sichert 
und bei der normalen Funktion nicht.

Ich weis das er in interrupts die Register die er nutzt sichern muss, 
aber warum nicht in der normalen funktion? ich weiß das mann das umgehen 
kann, indem mann die Funktion mit in das File Programmiert, in der sie 
aufgerufen wird. nur eine Erklärung für das Verhalten finde ich nicht.

Kennt die jemand???


Gruß

Stefan

von Stefan E. (sternst)


Lesenswert?

Das sind die "Call-Clobbered-Register". Diese können von einer Funktion 
verändert werden, ohne das sie sie sichern und wiederherstellen muss. Da 
die Definition von test in einer anderen Datei ist, weiß der Compiler 
nicht, welche dieser Register von der Funktion tatsächlich verändert 
werden, und er weiß natürlich auch nicht, welche andere Funktion durch 
die ISR unterbrochen wurde. Also bleibt ihm nichts anderes übrig, als 
sie in der ISR alle zu sichern. In einer "normalen" Funktion weiß der 
Compiler dagegen, welche Register in der aufrufenden Funktion verwendet 
werden und daher gesichert werden müssen.

von Stefan (Gast)


Lesenswert?

Hallo Stefan!


Danke für die Antwort.

Habe auch noch ein bisschen im Testprojekt rumgespielt und nun ist es 
mir klar das er es nicht anders machen kann.

Gruß

Stefan

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Eine möglichkeit, dem COmpiler zu sagen, was in der Funktion abgeht, 
wäre zB sie in einem Header als static inline zu definierern. Dann weiß 
gcc genau, welche Register sie braucht. Das bringt allerdings nur was, 
wenn die Funktion ein Blatt ist, also ihrerseits keine anderen 
Fnuktionen als Black-Box aufruft.

von Falk B. (falk)


Lesenswert?

@  Stefan (Gast)

>Anbei ein kleine Projekt von mir, in welchem eine Funktion test() einmal
>in einer ISR und einmal in einer Anderen "normalen"Funktion "InitRtc()"
>aufgerufen wird. test() wird in einer anderen Datei definiert.

Sowas ist sehr gefählich und sollte möglichst vermieden werden, siehe 
Interrupt. Nimm lieber zwei Einzelfunktionen.

MFG
Falk

von Stefan (Gast)


Lesenswert?

Hallo Falk!!


Mir geht es nicht darum das ich die Funktion 2 mal aufrufen sollte, mir 
ging es nur darum, das sie vom gcc unterschiedlich aufgerufen wird. ich 
habe nicht vor das so zu lösen.

Gruß Stefan

von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Johann!

Wenn ich versuche die test() als static inline in main.h zu definieren, 
bringt mir der linker eine

undefined reference to `test'

bedeutet static nicht, das diese Funktion nur für main.c "sichtbar"  ist


oder wolltest du das anders lösen.

anbei das Projekt mit static, welche den linker Fehler bringt


Gruß


Stefan

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Der entsprechende Header muss in allen Modulen includet werden, welche 
die Funktion verwenden. Ähnlich wie du ein Makro definieren würdest, das 
in mehreren Modulen verwendet wird. Es wird ja nicht mehr gegen die 
Funktion gelinkt (der Fehler isn Linkerfehler) sondern die Funktion wird 
direkt ins Programm eingefügt. Daher genügt nicht der Prototyp der 
Funktion, sondern die Implementierung muss vorliegen.

Wenn zwei Funktionen genau das selbe machen und man braucht die 
Funktionalität sowohl in einer ISR als auch im normalen Code ist es 
nicht "unsicher", die gleiche Funktion zu verwenden. Natürlich muss man 
alles beachten, was man bei ISR-Programmierung beachten muss, zB den 
richtigen (atomaren) Zugriff auf Objekte größer als 1 Byte. Und man muss 
bei Verwendung globaler/statischer Variablen darauf auchten, daß die 
Funktion reentrant bleibt, der Code also mehrfach betreten werden kann.

Aber wozu sollte man den Code doppelt hinschreiben/pflegen, wenn er 
mehrfach gebraucht wird...???.
1
#ifndef FOO_H
2
#define FOO_H
3
4
static inline void foo(...)
5
{
6
   ...
7
}
8
9
#endif /* FOO_H */

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.