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
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.
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.
>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.
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.
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).
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.
@ 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.
> 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! ;)
@ 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:
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
intfoo()
2
{
3
externinti;
4
returni;
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
>> 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.
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
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 nichtvolatile sein. volatile ist nur dann
erforderlich, wenn die Variable im Interrupt Handler und in anderen
Funktionen verwendet werden soll!
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.
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?
>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.
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! ^^