mikrocontroller.net

Forum: Compiler & IDEs Unterschiedlicher Aufruf einer Funktion


Autor: Stefan (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...???.
#ifndef FOO_H
#define FOO_H

static inline void foo(...)
{
   ...
}

#endif /* FOO_H */

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.