www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik globale Variable in externer header-datei


Autor: Balesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich programmiere einen ATTiny in C mit WinAVR.
Es ist ein größeres Programm und ich habe einige Funktionen in separaten 
c-files ausgelagert. Ich benutze aber teilweise VAriablen, die global 
angelegt werden sollen und von allen Files zugänglich sein sollen, u.a. 
auch für EEPROM

Ich habe mir schon diverse Beträge angesehen, u.a. diesen hier: 
Beitrag "Globale Variablen, mehrere Dateien", der sehr aufschlussreich 
war.

Leider habe ich aber dennoch Probleme und bekomme Fehlermeldungen. Hier 
ein Auszug aus meinen Dateien:
global.h
/******************************************************************************/
/****************************** globale Variablen *****************************/
/******************************************************************************/
#ifndef EXTERN
#define EXTERN extern
#endif

EXTERN uint8_t  ee_Fehlermode EEMEM; //Variablen EEPROM
EXTERN uint16_t ee_Sense_1 EEMEM;
EXTERN uint16_t ee_Sense_2 EEMEM;
EXTERN uint16_t ee_Sense_3 EEMEM;

EXTERN unsigned char messageBuf[2];
EXTERN volatile uint8_t v_sek;// v_sek = viertel sekunde -->wird in ISR hochgezählt

main.c
#include "global.h"
uint8_t stamp=0, sekunde = 0, Blinkcode =0xFF;

lern.c
#include "global.h"

void lernen(void)
{
  eeprom_write_word(&ee_Sense_1, 0xa4CD); 
  eeprom_write_word(&ee_Sense_2, 0xa99A); 
  eeprom_write_word(&ee_Sense_3, 0xaE66); 
}

eine der Fehlermeldungen:
../global.h:14: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'v_sek'

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <stdint.h> vergessen?

Autor: Balesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, habe ich sowohl in der main.c, als auch in der lern.c eingebaut

Autor: def (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du neben der Deklaration auch an eine globale Definition in einem 
der *.c files gedacht (z.B. in main.c)?!?

Autor: def (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sry für Doppelpost!!

Aber mit der global.h, sagst du dem Compiler ja nur, dass es irgendwo in 
einer anderen Datei die beschriebenen Variablen gibt. Anlegen musst die 
aber trotzdem noch.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Balesi schrieb:
> Nein, habe ich sowohl in der main.c, als auch in der lern.c eingebaut

Ich hätte es auch in die global.h mit aufgenommen, denn dort werden 
diese Datentypen ja auch verwendet
#ifndef GLOBAL_H_INCLUDED
#define GLOBAL_H_INCLUDED

#include <stdint.h>

/******************************************************************************/
/****************************** globale Variablen *****************************/
/******************************************************************************/
#ifndef EXTERN
#define EXTERN extern
#endif

EXTERN uint8_t  ee_Fehlermode EEMEM; //Variablen EEPROM
EXTERN uint16_t ee_Sense_1 EEMEM;
EXTERN uint16_t ee_Sense_2 EEMEM;
EXTERN uint16_t ee_Sense_3 EEMEM;

EXTERN unsigned char messageBuf[2];
EXTERN volatile uint8_t v_sek;// v_sek = viertel sekunde -->wird in ISR hochgezählt
 
#endif


Abgesehen davon:
Bitte poste kompletten, compilierbaren Code. Dann können wird den durch 
unsere Compiler jagen und selbst probieren.

Autor: Balesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für Eure Tipps, habe meinen Code folgendermaßen abgeändert:
global.h
/******************************************************************************/
/****************************** globale Variablen *****************************/
/******************************************************************************/
#ifndef EXTERN
#define EXTERN extern
#endif
#include <stdint.h>
#include <avr\eeprom.h>

EXTERN uint8_t  ee_Fehlermode EEMEM;//Variablen EEPROM
EXTERN uint16_t ee_Sense_1 EEMEM;
EXTERN uint16_t ee_Sense_2 EEMEM;
EXTERN uint16_t ee_Sense_3 EEMEM;

EXTERN unsigned char messageBuf[2];
EXTERN volatile uint8_t v_sek;// v_sek = viertel sekunde -->wird in ISR hochgezählt
main.c:
#include "global.h"
uint8_t  ee_Fehlermode EEMEM;
unsigned char messageBuf[2];
volatile uint8_t v_sek;// v_sek = viertel sekunde -->wird in ISR hochgezählt
lern.c
#include <stdint.h>
#include <avr\eeprom.h>
#include "Anlernvorgang.h"
#include "global.h"

void lernen(void)
{

uint16_t ee_Sense_1 EEMEM;
uint16_t ee_Sense_2 EEMEM;
uint16_t ee_Sense_3 EEMEM;

  eeprom_write_word(&ee_Sense_1, 0xa4CD); 
  eeprom_write_word(&ee_Sense_2, 0xa99A); 
  eeprom_write_word(&ee_Sense_3, 0xaE66); 
}

Jetzt habe ich folgende Fehlermeldung:
../lern.c: error: section attribute cannot be specified for local variables
Ich weiß nicht wie ich bei einer Auslagerung mit den Variablen fürs 
EEPROM umgehen muss

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mir an deiner Stelle ein
global.c machen

global.c
********
#define EXTERN
#include "global.h"

dann in main.c
#include "global.h"

int main()
{
  ...
}

und in lern.c
#include <stdint.h>
#include <avr\eeprom.h>
#include "Anlernvorgang.h"
#include "global.h"

void lernen(void)
{
  eeprom_write_word(&ee_Sense_1, 0xa4CD); 
  eeprom_write_word(&ee_Sense_2, 0xa99A); 
  eeprom_write_word(&ee_Sense_3, 0xaE66); 
}


> ../lern.c: error: section attribute cannot be specified for local
> variables

Ist ja wohl ziemlich eindeutig.
Die section attributes von denen dein Compiler spricht, ist das EEMEM. 
Und die einzigen lokalen Variablen, auf die das zutrifft, sind ....

Autor: Balesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Karl heinz für deinen Tipp

Karl heinz Buchegger schrieb:
> Ist ja wohl ziemlich eindeutig.
> Die section attributes von denen dein Compiler spricht, ist das EEMEM.
> Und die einzigen lokalen Variablen, auf die das zutrifft, sind ....

Das habe ich auch vermutet, aber wie gesagt, wich wusste nicht wie ich 
damit umzugehen habe. Muss ich das Attribut nur einmalig benutzen, wenn 
ja an welcher Stelle, usw.

Ich habe zunächst die Funktion lernen, wie von dir vorgschlagen 
abgeändert, ohne erneute deklaration (oder definition). Da kam dann 
wieder eine Fehlermeldung. Nachdem ich dann eine global.c angelegt habe 
war diese verschwunden und es hat funktioniert.

Kannst du mir hierzu eine Erklärung geben? Ich möchte es gerne 
verstehen.

Das Problem scheint erledigt zu sein.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Balesi schrieb:
> Danke Karl heinz für deinen Tipp
>
> Karl heinz Buchegger schrieb:
>> Ist ja wohl ziemlich eindeutig.
>> Die section attributes von denen dein Compiler spricht, ist das EEMEM.
>> Und die einzigen lokalen Variablen, auf die das zutrifft, sind ....
>
> Das habe ich auch vermutet, aber wie gesagt, wich wusste nicht wie ich
> damit umzugehen habe. Muss ich das Attribut nur einmalig benutzen, wenn
> ja an welcher Stelle, usw.


2 Paar Schuhe.
Du hattest
void lernen(void)
{

uint16_t ee_Sense_1 EEMEM;
uint16_t ee_Sense_2 EEMEM;
uint16_t ee_Sense_3 EEMEM;

  eeprom_write_word(&ee_Sense_1, 0xa4CD); 
  eeprom_write_word(&ee_Sense_2, 0xa99A); 
  eeprom_write_word(&ee_Sense_3, 0xaE66); 
}

Diese Variablen ee_Sense_1 etc. haben nichts mit deinen globalen 
Variablen zu tun. Das sind zunächst einfach nur stink normale 
funktionslokale Variablen, so wie in
void foo()
{
  int i;

  for( i = 0; i < irgendwas; ++i )
    ...
}

Jetzt hast du deinen funktionslokalen Variablen aber das EEMEM Attribut 
verpasst. D.h. du wolltest sie in das EEPROM verlgen. Das geht aber 
nicht. Funktionslokale Variablen können nicht im EEPROM liegen. 
Funktionslokale Variablen werden beim Betreten einer Funktion erzeugt 
und verschwinden wieder beim Verlassen einer Funktion. Bei einem EEPROM 
wäre das aber ziemlich kontraproduktiv. Gerade bei denen möchte ja man, 
dass sie überleben. Sie sollen sogar einen Stromausfall überleben :-)

> Ich habe zunächst die Funktion lernen, wie von dir vorgschlagen
> abgeändert, ohne erneute deklaration (oder definition). Da kam dann
> wieder eine Fehlermeldung.

Merk dir bitte eines:
Eine Aussage  "Da kam dann eine Fehlermeldung" ist genausoviel wert, wie 
wenn du zum Arzt gehst und sagst: Es tut weh

Höchst wahrscheinlich lautete die Fehlermeldung (und die wird vom Linker 
gewesen sein), dass du eine 'undefined reference' hast.

Logisch. Du hast jetzt zwar haufenweise extern Variablen aber keine 
Definition. extern sagt ja nur: irgendwo anders existiert die Variable. 
Aber wo? Wo ist sie denn? Man kann nicht immer nur sagen: irgendwo 
anders. Irgendwann muss man auch Farbe bekennen und sagen: Hier!

> Nachdem ich dann eine global.c angelegt habe

und genau diese global.c sorgt dafür, dass die Variablen dann auch 
tatsächlich angelegt werden, indem global.h durch das vorhergehende 
#define so manipuliert wird, dass es die Variablen ohne das vorangehende 
"extern" compiliert.
Ohne "extern": Dadurch werden die Variablen dann auch tatsächlich 
angelegt und damit gibt es dann genau die eine Stelle von der vorher 
gesagt wurde: Irgendwo existieren diese Variablen. Das global.c ist 
quasi der Teil in deinem Programm, der das geforderte "Hier!" enthält.

http://www.mikrocontroller.net/articles/FAQ#Global...

Autor: Balesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für deine Zeit und deine Hilfe. Ich habe nun einiges gelernt 
und hoffentlich soweit verstanden, dass ich diese Hürden in Zukunft 
leichter nehmen kann.

Karl heinz Buchegger schrieb:
>> Ich habe zunächst die Funktion lernen, wie von dir vorgschlagen
>> abgeändert, ohne erneute deklaration (oder definition). Da kam dann
>> wieder eine Fehlermeldung.
>
> Merk dir bitte eines:
> Eine Aussage  "Da kam dann eine Fehlermeldung" ist genausoviel wert, wie
> wenn du zum Arzt gehst und sagst: Es tut weh

Ich weiß, konnte mich nicht mehr an den Wortlaut erinnern und hatte die 
global.c vergessen anzulegen, danach kam die Fehlermeldung dann nicht 
mehr

> Höchst wahrscheinlich lautete die Fehlermeldung (und die wird vom Linker
> gewesen sein), dass du eine 'undefined reference' hast)
So war es glaube ich auch

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.