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


von Martin W. (wassertropfen)


Lesenswert?

Enwicklungsumgebung Keil uVision 5.10 Stm32F030

Der Compiler bringt keine Fehlermeldung, aber das Verhalten entspricht 
nicht dem Erwarteten.

//global Variables.h
extern volatile uint16_t g_u16_ADCresults[NUMBEROFREGULARADCHANNELS];
//global Variables.c
#include "global Variables.h"
volatile uint16_t g_u16_ADCresults[NUMBEROFREGULARADCHANNELS];

//main.c
#include "global Variables.h"

a=g_u16_ADCresults[0]; <------liefert richtiges Ergebnis
// Aufruf von der Funktion aus fcn.c, die das Gleiche macht

//fcn.c
#include "global Variables.h"

b=g_u16_ADCresults[0];<-------- liefert 0, also falsch

Der Zugriff auf die globale Variable in main.c funktioniert einwandfrei, 
in fcn.c aber nicht.

Jemand eine Idee ?

von Peter II (Gast)


Lesenswert?

lass dir mal die Adresse von den Variabel anzeigen

printf("%p", g_u16_ADCresults );

von Falk B. (falk)


Lesenswert?

@ Martin W. (wassertropfen)


>//global Variables.h
>extern volatile uint16_t g_u16_ADCresults[NUMBEROFREGULARADCHANNELS];

ein paar Uunderlines wären nicht schlecht.

g_u16_ADCresults[NUMBER_OF_REGULAR_AD_CHANNELS]

>//global Variables.c
>#include "global Variables.h"
>volatile uint16_t g_u16_ADCresults[NUMBEROFREGULARADCHANNELS];

>//main.c
>#include "global Variables.h"

>a=g_u16_ADCresults[0]; <------liefert richtiges Ergebnis
>// Aufruf von der Funktion aus fcn.c, die das Gleiche macht

//fcn.c
>#include "global Variables.h"

>b=g_u16_ADCresults[0];<-------- liefert 0, also falsch

>Der Zugriff auf die globale Variable in main.c funktioniert einwandfrei,
>in fcn.c aber nicht.

Makefile falsch?

von Martin W. (wassertropfen)


Lesenswert?

ok, ich hab folgendes versucht

//main.c
#include "stdio.h"

...
a1=printf("%p",g_u16_ADCresults);
...

Dabei liegt in a1 der Wert 0. Allerdings sehe ich das die IRQs nicht 
mehr aufgerufen werden. Irgendwas stimmt nicht. Variablen schaue ich 
über STMstudio an.

Vermutung, dass für g_u16_ADCresults zwei verschiedene Adressen 
hinterlegt sind ? Pro File ? wie ist das möglich ?

von Falk B. (falk)


Lesenswert?

Falsches makefile, Linker macht Unsinn.

Aber wenn schon, dann eher so.

printf("%p", &g_u16_ADCresults );

von Peter II (Gast)


Lesenswert?

Falk Brunner schrieb:
> Aber wenn schon, dann eher so.
>
> printf("%p", &g_u16_ADCresults );

bin jetzt etwas verwirrt warum &?
maximal so:

&g_u16_ADCresults[0]

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> Falk Brunner schrieb:
>> Aber wenn schon, dann eher so.
>>
>> printf("%p", &g_u16_ADCresults );
>
> bin jetzt etwas verwirrt warum &?

Weil Falk wissen will, ob sich der TO irgendwo in seinem System noch ein 
2-tes Array mit gleichem Namen eingefangen hat.

Wenn die Start-Adresse des Array in main.c sich von der in fcn.c 
unterscheidet, dann hat er es. Bei den kryptischen und unlesbaren 
Bezeichnern würde mich das nicht weiter wundern.

von Peter II (Gast)


Lesenswert?

Karl Heinz schrieb:
> Weil Falk wissen will, ob sich der TO irgendwo in seinem System noch ein
> 2-tes Array mit gleichem Namen eingefangen hat.
>
> Wenn die Start-Adresse des Array in main.c sich von der in fcn.c
> unterscheidet, dann hat er es. Bei den kryptischen und unlesbaren
> Bezeichnern würde mich das nicht weiter wundern.

es ging mit um das & beim printf. Die Idee mit der startadresse hatte 
ich. Und ich hatte es ohne & geschrieben.

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> Karl Heinz schrieb:
>> Weil Falk wissen will, ob sich der TO irgendwo in seinem System noch ein
>> 2-tes Array mit gleichem Namen eingefangen hat.
>>
>> Wenn die Start-Adresse des Array in main.c sich von der in fcn.c
>> unterscheidet, dann hat er es. Bei den kryptischen und unlesbaren
>> Bezeichnern würde mich das nicht weiter wundern.
>
> es ging mit um das & beim printf. Die Idee mit der startadresse hatte
> ich. Und ich hatte es ohne & geschrieben.

Ja, habs zu spät gesehen.
Mein Fehler.

von Daniel A. (daniel-a)


Lesenswert?

Martin W. schrieb:
> b=g_u16_ADCresults[0];<-------- liefert 0, also falsch
g_u16_ADCresults[0] ist kein pointer, also ist 0 ein gültiger wert
>
> Der Zugriff auf die globale Variable in main.c funktioniert einwandfrei,
> in fcn.c aber nicht.
>
> Jemand eine Idee ?

A) ungültiges linkerskript
B) g_u16_ADCresults[0] noch nicht gesetzt zu dem zeitpunkt / 
überschrieben

C) segmentation fault/bufferoverflow, das programm macht, was es will

Ich vermute B

Tipp: verwende die optionen -Wall -pedantic Und verwende tools wie 
cppcheck

von Falk B. (falk)


Lesenswert?

@ Karl Heinz (kbuchegg) (Moderator)

>> bin jetzt etwas verwirrt warum &?

>Weil Falk wissen will, ob sich der TO irgendwo in seinem System noch ein
>2-tes Array mit gleichem Namen eingefangen hat.

Nee, der Falk hatte vergessen, dass das ja ein Array ist und bei damit 
Name = Anfangsadresse. :-0

von Martin W. (wassertropfen)


Lesenswert?

printf("%p",g_u16_ADCresults) in main.c und fcn.c liefert beides mal 
2000004 als Speicheradresse.

Interessanterweise funktionierte der anschließende Zugriff auf die 
globale Variable in beiden Files einwandfrei. ???

Martin W. schrieb:
> //main.c
> #include "global Variables.h"
>
> a=g_u16_ADCresults[0]; <------liefert richtiges Ergebnis
> // Aufruf von der Funktion aus fcn.c, die das Gleiche macht
>
> //fcn.c
> #include "global Variables.h"
>
> b=g_u16_ADCresults[0];<-------- liefert 0, also falsch

Kann jemand mit diesem Verhalten etwas anfangen ? Das kann doch 
eigentlich nicht sein ? Hat die Funktion Printf() eine Querverbindung 
zwischen den Files hergestellt ? Ein anschließendes Herausnehmen von 
printf änderte nichts.

von Karl H. (kbuchegg)


Lesenswert?

Martin W. schrieb:

> eigentlich nicht sein ? Hat die Funktion Printf() eine Querverbindung
> zwischen den Files hergestellt ?

Nein.
Du bellst den falschen Baum an.

Irgendwas hast du falsch gemacht. Das kann von hier aber keiner sehen.

Bau dir ein minmiales Testprogramm (oder specke deines soweit ab, dass 
es nur noch wenige Zeilen pro File umfasst) und teste das nochmal. Wenn 
sich der Effekt immer noch zeigt und du nicht dahinter kommst, dann 
poste das.

von Daniel A. (daniel-a)


Lesenswert?

Martin W. schrieb:
> Printf() eine Querverbindung zwischen den Files hergestellt ? Ein
> anschließendes Herausnehmen von printf änderte nichts.

Wenn du damit sagen willst das der fehler dauerhaft verschwunden ist, 
dann ist klar, dass du einen fehler beim compilieren/linken machst, 
zumindest wenn das printf die einzige änderung war.

Wie kompilierst du? Makefile, automake, in den compiler per komandozeile 
direkt ausfügren, (ahnungslos in der ide auf compilieren klicken) ?
Du musst sicherstellen, dass jede .c datei nach einer änderung 
derselbigen oder einer dessen header files neu kompilierst, und dass du 
keine veralteten .o dateien verlinkst.

Wenn du mit Ändert nichts, problem bleibt meinst, dann ist es vermutlich 
ein segmentation fault/bufferoverflow. Viel spass beim suchen, die 
können überall und minimal 1 byte gross sein :))

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Martin W. schrieb:
> ... anfangen ? Das ... sein ? Hat ... hergestellt ? Ein ...
Bitte nicht plenken, da zerreißt es die ganze Formatierung. Oder lernt 
man diese Art der Zeichensetzung heute in der Schule?

Ich tippe hier auf einen amoklaufenden Pointer. Was ist denn vor dem 
fraglichen Struct definiert? Und was passiert zwischen den beiden 
Zugriffen?

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.