Forum: Mikrocontroller und Digitale Elektronik AVR ATMEGA static für globale Variable?


von Anton G. (antong)


Lesenswert?

Hallo,
ich muß euch mal mit static auf die Nerven gehen.
Es gibt zwar schon genug Threads dazu, aber mir ist da noch nicht ganz 
was schlüssig.

Problem:
Ich habe eine Headerdatei in der ich eine globale Variable als uint8_t 
deklariere. Diese Headerdatei binde ich in alle C Dateien die diese 
globale Variable benötigen ein.

Beispiel:
1
//Globale_Header.h
2
uint8_t Modus;  //Variable soll Global genutzt werden
3
4
5
//C_Datei1.c
6
include "Globale_Header.h"
7
8
void Test1(void)
9
{
10
 Modus = 1
11
}
12
13
//C_Datei2.c
14
include "Globale_Header.h"
15
void Test2(void)
16
{
17
 ...
18
 //hier folgt eine Ausgabe der "Modus" Variable über Uart
19
...
20
}

Die Variable "Modus" ist in der C_Datei2.c nicht 1!
Wenn ich ein static in der Headerdatei vor der Variable Modus setze, 
funktioniert das zwar (dann ist Modus in der C_Datei2.c auch 1), ich 
bekomme aber eine Compilerwarnung "Modus defined but not used".

Wie macht man das richtig?
Gruß Antong

von Peter II (Gast)


Lesenswert?

Anton G. schrieb:
> Wie macht man das richtig?

mit "extern"

und dazu muss die Variabel auch noch in einer C datei angelegt werden. 
In der Header datei steht dann nur drin das die Variable existiet.

von Thomas (Gast)


Lesenswert?

nun ja Variablen definiert man nicht in Headerdateien sondern
deklariert Sie dort. Falls du also eine Variable in allen
Files brauchst:
1
//Globale_Header.h
2
extern uint8_t Modus;  //Variable soll Global genutzt werden
3
4
//C_Datei1.c
5
include "Globale_Header.h"
6
7
uint8_t Modus;  //Variable wird nur einmal definiert
8
9
void Test1(void)
10
{
11
 Modus = 1
12
}
13
14
//C_Datei2.c
15
include "Globale_Header.h"
16
void Test2(void)
17
{
18
 ...
19
 //hier folgt eine Ausgabe der "Modus" Variable über Uart
20
...
21
}

so wie du das machst erzeugst du 2 Variablen in unterschiedliche
Files mit dem gleichen Namen das dürfte ohne Fehlermelung gar nicht
funktionieren

Thomas

von Code (Gast)


Lesenswert?

Mach es lieber mit static Deklaration, sowie Get und Set Routinen.

von Peter II (Gast)


Lesenswert?

Code schrieb:
> Mach es lieber mit static Deklaration, sowie Get und Set Routinen.

dafür muss man aber auch die Variable in einer C datei anlegen. Außerdem 
ist das ganze noch duch den funtionaufruf sehr langsam.

von Anton G. (antong)


Lesenswert?

Wenn ich das nach Thomas (Gast) Variante mache, habe ich immer noch das 
Problem, dass scheinbar zwei Variablen genutzt werden.

In C_Datei2.c ist Modus immer noch nicht 1.
Muß ich die dann noch static machen? Habe ich versucht. Ich habe in der 
Header und in der C Datei ein static davor geschrieben.
Bekomme dann aber die Compiler Meldung "multiple storage classes in 
declaration specifiers" und "static declaration of Modus follows non 
static declaration".

von Peter II (Gast)


Lesenswert?

Anton G. schrieb:
> Wenn ich das nach Thomas (Gast) Variante mache, habe ich immer noch das
> Problem, dass scheinbar zwei Variablen genutzt werden.

nein, so ist es richtig und da gibt es nicht 2 Variablen.


Wen es nur einmal die zeile (in einer C datei)

uint8_t Modus;

gibt, dann ist die Variable auch nur einmal da. Wenn ein extern davor 
steht, dann wird sie nicht angelegt.

von Coder (Gast)


Lesenswert?

Peter II schrieb:
> Außerdem
> ist das ganze noch duch den funtionaufruf sehr langsam.

Das würde pauschal nicht unterschreiben. Wenn man den Optimierer 
vewendet, wird das i.d.R. "geinlined". Das muss natürlich die Toolchain 
unterstützen.

von Peter II (Gast)


Lesenswert?

Coder schrieb:
> Das würde pauschal nicht unterschreiben. Wenn man den Optimierer
> vewendet, wird das i.d.R. "geinlined". Das muss natürlich die Toolchain
> unterstützen.

er kann es aber nicht geinlined, weil die Set und Get funktionen ja in 
einer Extra C datei stehen müssen, sonst kann man nicht auf die Static 
variable zugreifen. Und wenn die Variabel als extern definiert ist, kann 
man auch die Set und Get sachen weglassen.

von Rolf Magnus (Gast)


Lesenswert?

Coder schrieb:
> Peter II schrieb:
>> Außerdem
>> ist das ganze noch duch den funtionaufruf sehr langsam.
>
> Das würde pauschal nicht unterschreiben. Wenn man den Optimierer
> vewendet, wird das i.d.R. "geinlined". Das muss natürlich die Toolchain
> unterstützen.

Und die Funktion muß im Header definiert und inline sein.

Anton G. schrieb:
> Wenn ich das nach Thomas (Gast) Variante mache, habe ich immer noch das
> Problem, dass scheinbar zwei Variablen genutzt werden.

Woran erkennst du das denn? Die von ihm angegebene Variante ist korrekt. 
Entweder interpretierst du das beobachtete Verhalten falsch, oder der 
Fehler steckt in dem Teil des Code, den du verheimlicht hast. Deshalb 
ist es auch immer besser, nicht irgendwelchen für's Posting 
zusammengetippten Pseudo-Code zu zeigen, sondern ein minimales, aber 
vollständiges echtes Programm, das auf dem Prozessor den angegebenen 
Fehler hat.

> Muß ich die dann noch static machen?

Nein. Static bewirkt ja genau, daß die Variable dann zweimal vorhanden 
ist.

von Anton G. (antong)


Lesenswert?

Peter II schrieb:
> Anton G. schrieb:
>> Wenn ich das nach Thomas (Gast) Variante mache, habe ich immer noch das
>> Problem, dass scheinbar zwei Variablen genutzt werden.
>
> nein, so ist es richtig und da gibt es nicht 2 Variablen.
>
>
> Wen es nur einmal die zeile (in einer C datei)
>
> uint8_t Modus;
>
> gibt, dann ist die Variable auch nur einmal da. Wenn ein extern davor
> steht, dann wird sie nicht angelegt.

Ich gebe dir recht. Das funktioniert doch. Allerdings nur, wenn ich in 
der C Datei "Modus" nicht definiere, sondern initialisiere mit z.B.
"uint8_t Modus = HAND" (Hand ist definiert in der "Globale_Header.h" als 
0.

Ich hatte das auch nur definiert und dann direkt in der Main von der 
C_Datei1.c mit "Modus = 1" zugewiesen. Das klappt nicht.
Wenn ich aber wie oben geschrieben z.B. erst mal einen Wert mit 
initialisiere (kann auch ruhig eine 0 sein), dann funktioniert das 
einwandfrei und in der C_Datei2.c ist Modus = 1

Komisch, oder gibt es da eine logische Erklärung.
Vielen Dank erst einmal euch allen.

von Coder (Gast)


Lesenswert?

Peter II schrieb:
> Coder schrieb:
>> Das würde pauschal nicht unterschreiben. Wenn man den Optimierer
>> vewendet, wird das i.d.R. "geinlined". Das muss natürlich die Toolchain
>> unterstützen.
>
> er kann es aber nicht geinlined, weil die Set und Get funktionen ja in
> einer Extra C datei stehen müssen, sonst kann man nicht auf die Static
> variable zugreifen. Und wenn die Variabel als extern definiert ist, kann
> man auch die Set und Get sachen weglassen.

Nicht umsonst schrieb ich, Wenn es die Toolchain unterstützt. TI's Code 
Composer Toolchain kann das zum Beispiel; ist natürlich nicht für den 
AVR :-).

von Rolf Magnus (Gast)


Lesenswert?

Anton G. schrieb:
> Ich gebe dir recht. Das funktioniert doch. Allerdings nur, wenn ich in
> der C Datei "Modus" nicht definiere, sondern initialisiere mit z.B.
> "uint8_t Modus = HAND" (Hand ist definiert in der "Globale_Header.h" als
> 0.

Das ist genauso eine Definition. Außer daß du die Variable explizit mit 
0 initialisierst anstatt implizit, ist da kein Unterschied.

> Ich hatte das auch nur definiert und dann direkt in der Main von der
> C_Datei1.c mit "Modus = 1" zugewiesen. Das klappt nicht.
> Wenn ich aber wie oben geschrieben z.B. erst mal einen Wert mit
> initialisiere (kann auch ruhig eine 0 sein), dann funktioniert das
> einwandfrei und in der C_Datei2.c ist Modus = 1
>
> Komisch, oder gibt es da eine logische Erklärung.

Nein, aber ich habe das Gefühl, daß irgendein wichtiger Teil der 
Information fehlt.

von Anton G. (antong)


Lesenswert?

Ich suche noch mal weiter, den ganzen Code darf ich leider nicht 
einstellen (rechtliche Gründe). Sorry. Vielen Dank erst mal für die 
Hilfe.

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.