Forum: Compiler & IDEs static volatile und Interrupts


von KeDaiv (Gast)


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

von (prx) A. K. (prx)


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.

von Ahem (Gast)


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.

von KeDaiv (Gast)


Lesenswert?

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

von Ahem (Gast)


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.

von (prx) A. K. (prx)


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.

von Ahem (Gast)


Lesenswert?

Entschuldigung: Ersetze in meiner Antwort "deklariert" durch 
"definiert".

von (prx) A. K. (prx)


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).

von KeDaiv (Gast)


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.

von Ahem (Gast)


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.

von Ahem (Gast)


Lesenswert?

Da war ja A.K. Hinweis gerade richtig.
Deine Anwendung wäre gerade so ein Fall, wie er ihn noch genannt hat.
1
static char x;
2
3
interrupt // habe die syntax jetzt nicht parat
4
{
5
   x = irgendwas;
6
}
7
8
main () // oder welche Funktion auch immer
9
{
10
   // mach was mit x
11
}

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

von KeDaiv (Gast)


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! ;)

von (prx) A. K. (prx)


Lesenswert?

@Ahem: Das static ist so richtig, jetzt fehlt aber das volatile.

von Ahem (Gast)


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:
1
static volatile char x;
2
3
interrupt // habe die syntax jetzt nicht parat
4
{
5
   x = irgendwas;
6
}
7
8
main () // oder welche Funktion auch immer
9
{
10
   // mach was mit x
11
}

von Johann L. (gjlayde) Benutzerseite


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
1
int foo()
2
{
3
    extern int i;
4
    return i;
5
}

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

von Ahem (Gast)


Lesenswert?

Kommt davon wenn man nebenbei arbeitet und 007 guckt.

von (prx) A. K. (prx)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

Ahem wrote:

> Kommt davon wenn man nebenbei arbeitet und 007 guckt.

Sowas gibt's? Professioneller Fernsehgucker von alten Schinken?

von Ahem (Gast)


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.

von Johann L. (gjlayde) Benutzerseite


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

von Johannes M. (johnny-m)


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!

von Simon K. (simon) Benutzerseite


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.

von KeDaiv (Gast)


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?

von STK500-Besitzer (Gast)


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.

von KeDaiv (Gast)


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! ^^

von KeDaiv (Gast)


Lesenswert?

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

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.