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
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.
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
Ich würde mir an deiner Stelle ein
global.c machen
global.c
********
1
#define EXTERN
2
#include"global.h"
dann in main.c
1
#include"global.h"
2
3
intmain()
4
{
5
...
6
}
und in lern.c
1
#include<stdint.h>
2
#include<avr\eeprom.h>
3
#include"Anlernvorgang.h"
4
#include"global.h"
5
6
voidlernen(void)
7
{
8
eeprom_write_word(&ee_Sense_1,0xa4CD);
9
eeprom_write_word(&ee_Sense_2,0xa99A);
10
eeprom_write_word(&ee_Sense_3,0xaE66);
11
}
> ../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 ....
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.
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
1
voidlernen(void)
2
{
3
4
uint16_tee_Sense_1EEMEM;
5
uint16_tee_Sense_2EEMEM;
6
uint16_tee_Sense_3EEMEM;
7
8
eeprom_write_word(&ee_Sense_1,0xa4CD);
9
eeprom_write_word(&ee_Sense_2,0xa99A);
10
eeprom_write_word(&ee_Sense_3,0xaE66);
11
}
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
1
voidfoo()
2
{
3
inti;
4
5
for(i=0;i<irgendwas;++i)
6
...
7
}
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#Globale_Variablen_.C3.BCber_mehrere_Dateien
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