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.
Hmm, mit den 2 verschiedenen Variablen hast du wohl recht! ^^ Aber wie definiere ich diese dann nicht als global?
>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.
Entschuldigung: Ersetze in meiner Antwort "deklariert" durch "definiert".
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.
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.
> 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:
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 | }
|
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
Johann, ich fürchte mit solchen Spielchen stiften wir hier mehr Verwirrung als nötig. Ist ausserdem schlechter Stil.
Ahem wrote:
> Kommt davon wenn man nebenbei arbeitet und 007 guckt.
Sowas gibt's? Professioneller Fernsehgucker von alten Schinken?
>> 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 nicht volatile 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! ^^
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.