mikrocontroller.net

Forum: Compiler & IDEs static volatile und Interrupts


Autor: KeDaiv (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey,

Wenn eine Variable in einem Interrupt verwendet werden soll, dann sollte 
man diese ja als volatile deklariert werden. Jedoch muss dies ja global 
sein. ich wollte fragen, ob es auch geht, das man in einer Funktion eine 
Variable als static volatile deklariert und diese dann auch in dem 
Interrupt verwenden kann?
Also, ich meine das nun so in der Art: http://rafb.net/p/R3bITd90.html
Gibt es dort irgendeine Möglichkeit?

Thx und mfg
KeDaiv

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Global ist nicht nötig, volatile und static sind unabhängig voneinander. 
File scope, also "static volatile ..." ausserhalb einer Funktion geht 
auch.

Aber das was der Link zeigt sind zwei völlig getrennte Variablen.

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier vermischst Du verschiedene Dinge.

Volatile sollte eine Variable deswegen deklariert sein, damit der 
Compiler nicht aus dem Kontrollfluss allein schliesst, ob oder das eine 
Varible nicht oder doch verändert worden sein kann. Da ein Interrupt den 
Kontrollfluss unterbricht und eine Variable ändern kann obwohl dies 
normalerweise nicht möglich wäre, muss der Compiler eine volatile 
Variable immer wieder neu laden, da ja der Interrupt inzwischen 
zugeschlagen haben könnte.

Du sagst aber ganz richtig, das diese Variable global sein muss.

Wozu sie also static deklarieren?

Das Codebeispiel, das Du angegeben hast, muss entweder eine 
Don't-Do-That Absicht haben oder bezieht sich auf etwas anderes. Hier 
fehlt der Kontext.

Jedenfalls kann aus der main-Routine nicht auf foo aus dem Interrupt 
zugegriffen werden. Das sind zwei völlig verschiedene Variablen.

Static ist eigentlich nur innerhalb von Funktionen sinnvoll, da globale 
Variablen sozusagen von sich aus static sind. Aber bei globalen 
Variablen macht das keinen Sinn. Ihr Wert bleibt erhalten solange da 
Programm läuft.
Innerhalb einer Funktion bewirkt static das ein Variablenwert auch nach 
Verlassen der Funktion erhalten bleibt und bei erneutem Aufruf der 
Funktion wieder zur Verfügung steht.

>ich wollte fragen, ob es auch geht, das man in einer Funktion eine
>Variable als static volatile deklariert und diese dann auch in dem
>Interrupt verwenden kann?
Das ist bei Variablen die in Interrupts gesetzt werden garnicht die 
Frage. Sie sollten global volatile deklariert werden. Eine static 
deklaration macht überhaupt keinen Sinn.

Autor: KeDaiv (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, mit den 2 verschiedenen Variablen hast du wohl recht! ^^
Aber wie definiere ich diese dann nicht als global?

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Aber wie definiere ich diese dann nicht als global?

Vielleicht verstehe ich Dich nicht.

Eine Variable ist dann global wenn sie ausserhalb jeder Funktion 
deklariert ist.
Sie ist dann nicht global wenn sie innerhalb einer Funktion deklariert 
ist.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahem wrote:

> Sie sollten global volatile deklariert werden. Eine static
> deklaration macht überhaupt keinen Sinn.

Sie ergibt durchaus Sinn. Nämlich dann, wenn die Variable nicht 
ausserhalb des betreffenden Quellfiles sichtbar sein muss (neudeutsch: 
file scope). Was bei "static" Deklaration ausserhalb einer Funktion der 
Fall ist. Global ist sie dann nicht, lokal aber auch nicht.

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entschuldigung: Ersetze in meiner Antwort "deklariert" durch 
"definiert".

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahem wrote:

> Eine Variable ist dann global wenn sie ausserhalb jeder Funktion
> deklariert ist.
> Sie ist dann nicht global wenn sie innerhalb einer Funktion deklariert
> ist.

Tertium Datur. Global ist sie nur, wenn sie nicht innerhalb einer 
Funktion deklariert und nicht static ist.

Deutsch hab ich es nicht parat, aber es gibt es 3 Gültigkeitsbereiche:
- local scope (innerhalb Funktion),
- file scope (ausserhalb mit static),
- global scope (ausserhalb ohne static).

Autor: KeDaiv (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gut! ^^
War eben gerade zu schnell gewesen mit dem lesen und wohl zu langsam mit 
dem schreiben.
Es geht hier um einen kleinen Puffer. Der von außen eigentlich nicht 
sichtbar sein soll. Die Daten sollen zu erst in einen Puffer geschrieben 
werden. Ein Interrupt soll sich dann darum kümmern, das diese Werte aus 
den Puffer in den EEPROM kommen. also, von daher wäre es schon schön, 
wenn die Variable nicht global verfügbar wäre. Da es eine kleine lib 
werden soll.

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ A.K.

>> Sie sollten global volatile deklariert werden. Eine static
>> deklaration macht überhaupt keinen Sinn.

>Sie ergibt durchaus Sinn. Nämlich dann, wenn die Variable nicht
>ausserhalb des betreffenden Quellfiles sichtbar sein muss (neudeutsch:
>file scope). Was bei "static" Deklaration ausserhalb einer Funktion der
>Fall ist. Global ist sie dann nicht, lokal aber auch nicht.
Ja. Du hast recht. Das habe ich unrichtig dargestellt.

Wenn also die Variable ausserhalb einer Funktion, aber dennoch static 
deklariert ist, dann ist sie nur Funktionen (und Interrupts) die 
innerhalb der selben Datei definiert sind, sichtbar.

Danke für den Hinweis.

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da war ja A.K. Hinweis gerade richtig.
Deine Anwendung wäre gerade so ein Fall, wie er ihn noch genannt hat.
static char x;

interrupt // habe die syntax jetzt nicht parat
{
   x = irgendwas;
}

main () // oder welche Funktion auch immer
{
   // mach was mit x
}


mit diesem code wäre x nur innerhalb der Datei sichtbar.
Nicht aber in anderen Dateien.

Autor: KeDaiv (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn also die Variable ausserhalb einer Funktion, aber dennoch static
> deklariert ist, dann ist sie nur Funktionen (und Interrupts) die
> innerhalb der selben Datei definiert sind, sichtbar.

Danke, das wusste ich noch nicht. Also, werde ich sie denn als static 
volatile deklarieren. Danke euch allen! ;)

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ahem: Das static ist so richtig, jetzt fehlt aber das volatile.

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ A.K.
>Das static ist so richtig, jetzt fehlt aber das volatile.
Hrrmpf.
Du hast schon wieder recht und KeDaiv hat sich von meinem Fehler nicht 
verwirren lassen.

Es muss heissen:
static volatile char x;

interrupt // habe die syntax jetzt nicht parat
{
   x = irgendwas;
}

main () // oder welche Funktion auch immer
{
   // mach was mit x
}


Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. wrote:
> Ahem wrote:
>
>> Eine Variable ist dann global wenn sie ausserhalb jeder Funktion
>> deklariert ist.
>> Sie ist dann nicht global wenn sie innerhalb einer Funktion deklariert
>> ist.
>
> Tertium Datur. Global ist sie nur, wenn sie nicht innerhalb einer
> Funktion deklariert und nicht static ist.

Ob ein Objekt global ist, bestimmt ihre Definition, nicht ihre 
Deklaration. Das zugehörige Symbol wird bei der Definition erzeugt.

In
int foo()
{
    extern int i;
    return i;
}

referenziert i eine globale Variable, die aber nur innerhalb von foo -- 
also nur lokal -- sichtbar ist (sofern sie nicht schon vorher im Modul 
ausserhalb aller Funktionen Deklariert wurde.

Johann

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kommt davon wenn man nebenbei arbeitet und 007 guckt.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann, ich fürchte mit solchen Spielchen stiften wir hier mehr 
Verwirrung als nötig. Ist ausserdem schlechter Stil.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahem wrote:

> Kommt davon wenn man nebenbei arbeitet und 007 guckt.

Sowas gibt's? Professioneller Fernsehgucker von alten Schinken?

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Kommt davon wenn man nebenbei arbeitet und 007 guckt.

>Sowas gibt's? Professioneller Fernsehgucker von alten Schinken?
Nun, fernsehgucken tue ich nicht professionell. Aber Programme schreiben 
und Hardware entwickeln. Und ich bin halt selbst ein alter Schinken.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. wrote:
> Johann, ich fürchte mit solchen Spielchen stiften wir hier mehr
> Verwirrung als nötig. Ist ausserdem schlechter Stil.

Da stimme ich dir voll und ganz zu.

Johann

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
KeDaiv wrote:
> Wenn eine Variable in einem Interrupt verwendet werden soll, dann sollte
> man diese ja als volatile deklariert werden.
Nein, wenn die Variable nur in dem Interrupt Handler verwendet wird, 
dann muss sie nicht volatile sein. volatile ist nur dann 
erforderlich, wenn die Variable im Interrupt Handler und in anderen 
Funktionen verwendet werden soll!

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, anders gesagt: Volatile ist nur nötig wenn über die Variable Daten 
zwischen Hauptprogramm und ISR ausgetauscht werden sollen.
Bei größeren als 8 Bit Variablen muss zusätzlich der Zugriff atomar von 
statten gehen.

Autor: KeDaiv (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heißt atomar, das ich mir zwar ein uit16_t definieren kann, als statisch 
in der Quelldatei, diesen jedoch erst als 2x uint8_t auseinander nehmen 
muss um diesen dann wieder zusammen zu führen?
Wenn ja, wie mache ich das?

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Heißt atomar, das ich mir zwar ein uit16_t definieren kann, als statisch
>in der Quelldatei,
ja.
>diesen jedoch erst als 2x uint8_t auseinander nehmen
>muss um diesen dann wieder zusammen zu führen?

Das erledigt der Compiler für dich.
Du mußt nur beim Bearbeiten dieser Variablen dafür sorgen, dass sie 
nicht "gleichzeitig" durch eine Interrupt-Routine verändert wird.
Dazu "umzingelt" man die Bearbeitung einfach mit CLI(); und SEI();
Blockiert also vor der Bearbeitung die Interrupts und gibt sie danach 
wieder frei. Sie gehen dadurch ja nicht verloren.

Autor: KeDaiv (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gut, wunderbar, das hab ich schon erledigt! ^^

Aber ich muss mal sagen, großes Lob an das Forum, das man so schnell an 
Antworten kommt, hätte ich nicht gedacht! ;)
Thx an alle! ^^

Autor: KeDaiv (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sry, und natürlich an alle die hier schreiben und helfen auch nen großes 
Lob! ;)

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.