www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik globale Variable in mehreren C-Files


Autor: CManiac (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich nutze den C30-Compiler von Microchip und programmiere auf einem PIC 
24 FJ
(16 Bit) uController.

Ich habe folgendes Problem:

Ich brauche feste Adressen für den RAM Bereich.

z.B.:
int var_test  __attribute__ ((address(0x8000)));  

Jetzt soll diese Variable allen C-Files bekannt sein.

z.B.:
main.c
uart.c
eeprom.c

etc....

ich habe gedacht, dass ich die Deklaration in eine Headerfile legen kann 
und dann dieses Headerfile in den C-Files einbinde.

Dies geht leider nicht, dann kommt ein Multiple Deklaration Error...

Wie kann ich das Lösen?

- globale Variable deklarieren mit fester Adressierung und dann von 
allen C-Files darauf zugreifen können?!

Danke vielmals

Gruß
CManiac

Autor: Namtam (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zwei Möglichkeiten:
Du erzeugst ein weiteres C-File, schreibst dort die Deklarationen 
hinein. Dann fügst du jeweils bei den anderen C-Files, bei welchen du 
die Variablen benötigst, die Deklaration ein weiteres Mal auf, jedoch 
mit dem Zusatz "extern" vorab.

Oder aber du erzeugst ein weiteres C-File mit den Deklarationen und 
schreibst nun in das Header-File die Deklarationen mit dem Zusatz 
"extern". Dann bindest du diesen Header in die weiteren C-Files ein.
// Code in C-File:
int var_test  __attribute__ ((address(0x8000)));
// Code in Header, bzw. weiteren C-Files:
extern int var_test __attribute__ ((address(0x8000)));

Das Problem bei deiner Variante ist, dass du mit der Einbindung via 
Header-File mehrere Versionen deiner Variable bekommst, die dann 
unabhängig voneinander bearbeitet werden. Sprich: für jedes C-File, in 
welches du den Header einbindest, wird eine eigene Variable mit diesem 
Namen erstellt (so ungefähr).

Ich denke, so sollte es dann klappen :)

Autor: CManiac (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

danke für deine Antwort,

also klingt irgendwie recht schwierig mein Vorhaben umzusetzen.

Also ist es nicht ohne weiteres möglich eine Variable an einer Stelle zu 
deklarieren, und in anderen Quelldateien darauf zuzugreifen, ohne sie 
erneut zu deklarieren?!

Bin gerade etwas verwirrt :-)

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Oder aber du erzeugst ein weiteres C-File mit den Deklarationen und
> schreibst nun in das Header-File die Deklarationen mit dem Zusatz
> "extern". Dann bindest du diesen Header in die weiteren C-Files ein.

Ich nehme an, daß bei der Deklaration das attribute entfallen kann, 
da es nur den Linker betrifft, also nur bei der Definition relevant sein 
sollte.

Das hier kommt in exakt ein C-Source-File, nennen wir es der 
einfachheit halber mal global.c
int var_test  __attribute__ ((address(0x8000)));

Und das hier kommt in eine Headerdatei, die passenderweise global.h 
genannt werden sollte:
extern int var_test;

Die ist dann in jedem Sourcefile (*.c) mit #include "global.h" 
einzubinden, in dem auf die Variable var_test zugegriffen werden soll.

Das sollte es schon sein, was ist daran jetzt kompliziert?

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schreib an den Anfang deines Header-Files folgendes:

#ifdef MAIN
#define EXT
#else
#define EXT extern
#endif

EXT int var_test


In deinem Hauptrogramm wo du dein main() hast, da schreibst du
gleich als allererstes noch folgendes bevor du die Headerdatei
includiert:

#define MAIN

So wird deine Variable nur im Hauptprogramm deklariert und
in allen anderen Source wird sie extern deklariert.

Olaf

Autor: CManiac (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na jetzt hab ichs kapiert,

hatte auch das extern vergessen, so hat der Compiler weiterhin 
gemeckert....

Danke dir vielmals :-)

Autor: Namtam (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ginge es natürlich noch einfacher :)
Werde ich gleich auch bei mir mal umsetzen, um Platz zu sparen :P

Autor: holdon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo.

ich habe 2 c-files.

in dem rufe ich eine funktion "test()" auf.diese funktion befindet sich 
in meinem anderen c-file.dort wird ein wert aufgenommen und in eine 
variable gelegt.dieser wert soll dann zur weiterverarbeitung dem 
1.c-file zur verfügung stehen.
wenn ich die variable in dem 1. c-file auslesen will steht da nichts.
hier mein grober code:

1. C-file:

extern int16_t tilt_x;
void test();

void Task1()
{
 int16_t tilt;
 uint8_t variable8bit;
 DDRC = 0xff;

 switch(a) {
    case AKTIV: test();          // aufruf test()-funktion in 2. C-file
                tilt = tilt_x;
                variable8bit = (uint8_t)tilt_x;// LOW-Byte in variable
                PORTC = variable8bit; //ausgabe auf PORTC
                break;
    //usw.
 }
}

2. C-file:


void test()
{ int16_t tilt_x;
 //....
  tilt_x = 0x1102; // dieser Wert soll 1. C-file zur Verfügung stehen
}


kann mir jemand einen tipp geben?danke

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tilt_x darf nicht innerhalb einer Funktion definiert werden, das aber 
tust Du im 2. C-File in void test().

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

Bewertung
0 lesenswert
nicht lesenswert
holdon wrote:

> void test()
> { int16_t tilt_x;

Das hier ist eine lokale Variable.
Da magst zwar noch eine globale Variable gleichen Namens haben, die wird 
allerdings nicht benutzt weil sie von der lokalen Variablen verdeckt 
wird.

> kann mir jemand einen tipp geben?danke

Wenn eine Funktion nur einen Wert zurückgeben kann, benutz doch bitte 
den Mechanismus, der für sowas vorgesehen ist: den Return Wert

int test()
{
    ....

    return 0x1102;
}

...
 switch(a) {
    case AKTIV: tilt = test();          // aufruf test()-funktion in 2. C-
            ....


Autor: Der Lars (vhdl-neuling)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weiß jetzt nicht genau was du mit dem "dann steht da nichts meinst", 
aber falls du die Funktion nicht aufrufen kannst, versuch es doch mal 
so:

Schreib eine Header-Datei und deklariere dort alle Funktionen, z.B. eine 
"routines.h".
Die bindest du dann mit #include "routines.h" in beide C-Dateien ein und 
schon fluppts ;)

Gruß,
derLars

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

Bewertung
0 lesenswert
nicht lesenswert
Der Lars wrote:
> weiß jetzt nicht genau was du mit dem "dann steht da nichts meinst",
> aber falls du die Funktion nicht aufrufen kannst, versuch es doch mal
> so:
>
> Schreib eine Header-Datei und deklariere dort alle Funktionen, z.B. eine
> "routines.h".
> Die bindest du dann mit #include "routines.h" in beide C-Dateien ein und
> schon fluppts ;)
>

Der Vorschlag ist zwar gut, hat aber nichts mir dem Problem an sich zu 
tun.

Autor: holdon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielen dank.hat prima geklappt. :)

Autor: Der Lars (vhdl-neuling)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Der Vorschlag ist zwar gut, hat aber nichts mir dem Problem an sich zu
> tun.

Ok, hatte das falsch verstanden. Die letzte Diplomarbeitsnacht war doch 
zu lang :))

Autor: Tommy Tacker (tommy776)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo ich bin´s nochmal.

wie schon erwähnt hat es mit der wertrücklieferung gut geklappt.mein 
daraus resultierendes problem hat sich aber leider noch nicht gelöst:

der zurückgelieferte wert "tilt" aus
...
 switch(a) {
    case AKTIV: tilt = test();          // aufruf test()-funktion in 2. 
C-
            ....

soll auf die adresse des folgenden falles nach "AKTIV" gelegt werden.

...switch(a) {
   case AKTIV: tilt = test();
               a = SENDEN;
   case SENDEN: ...
                apsDataReq.asdu = (uint8_t *) 
&appMessageBuffer.daten.tilt;
                ...

Das ganze dient einer Funkübertragung.Als ich es so gemacht habe wie von 
euch empfohlen (also mit return-wert) war die Übertragung erstmal 
gestoppt.
Also wie kann ich es realisieren,dass der Rückgabewert auf der 
Speicherstelle "&appMessageBuffer.daten.tilt" steht???

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

Bewertung
0 lesenswert
nicht lesenswert
Tommy Tacker wrote:

> Also wie kann ich es realisieren,dass der Rückgabewert auf der
> Speicherstelle "&appMessageBuffer.daten.tilt" steht???


Ins blaue geraten (da Empfehlungen, die auf nur wenigen Codezeilen 
basieren eigentlich immer geraten werden müssen)
    appMessageBuffer.daten.tilt = tilt();
??

oder vielleicht auch:
...
  switch(a) {
    case AKTIV: tilt = test();
                a = SENDEN;
                                   // fallthrough
   case SENDEN: ...
                apsDataReq.asdu = (uint8_t *)&appMessageBuffer.daten.tilt;
                *apsDataReq.asdu = tilt;
                ...


oder vielleicht auch:
...
  switch(a) {
    case AKTIV: tilt = test();
                a = SENDEN;
                                   // fallthrough
   case SENDEN: ...
                apsDataReq.asdu = (uint8_t *)&appMessageBuffer.daten.tilt;
                appMessageBuffer.daten.tilt = tilt;
                ...

oder vielleicht auch
void foo()
{
  static int16_t tilt;

...
  switch(a) {
    case AKTIV: tilt = test();
                a = SENDEN;
                                   // fallthrough
   case SENDEN: ...
                apsDataReq.asdu = (uint8_t *)&appMessageBuffer.daten.tilt;
                appMessageBuffer.daten.tilt = tilt;
                ...


oder ....

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.