Forum: Mikrocontroller und Digitale Elektronik Externer struct zugriff


von Moot S. (mootseeker)


Lesenswert?

Hallo Zusammen,

mein Stand ist wie folgt:
ich habe in einem eeprom.h File eine Struktur definiert:
1
typedef struct
2
{
3
  uint8_t eeDataPage[EEPROM_PAGE_SIZE];
4
}struct_eeprom_data_type;

Im eeprom.c kann ich drauf zu greifen schreiben/lesen, das funktioniert 
und kann ich auch mit dem Debugger kontrollieren.

In einem dritten File data.c habe ich eeprom.h eingebunden und möchte 
nun die struktur auslesen wie folgt:
1
struct_eeprom_data_type struct_eeprom_data;

Die Struktur kann ich mit dem Debugger kontrollieren und ich finde die 
Daten, leider aber nicht an der selben stelle wie ich sie im eeprom.c 
geschrieben habe. Wenn ich im eeprom.c z.B. "Hallo Welt!" schriebe mit
1
 memcpy(struct_eeprom_data, "Hallo Welt!", sizeof("Hallo Welt!");
 (Mit dem Debugger kontrolliert ist das "Hallo Welt!" auf der stelle 0 
wie es auch sein sollte) sehe ich im data.c zwar das "Hallo Welt!" aber 
nicht an der selben stelle sonder um 32 Stellen verschoben.

Habe ich die struktur im data.c falsch definiert? Ich stehe gerade vor 
einer Wand...

von OMG (Gast)


Lesenswert?

Welcher Controller?

Moot S. schrieb:
> Habe ich die struktur im data.c falsch definiert?

Ich sehe keine Datei data.c

Moot S. schrieb:
> Ich stehe gerade vor einer Wand...

Ich auch.

Muss man den Leuten die Popel immer einzeln aus der Nase ziehen?

Bitte soviele Details dass man auch was nachvollziehen kann.

von Moot S. (mootseeker)


Lesenswert?

OMG schrieb:
> Welcher Controller?

Warum spielt das eine Rolle? sollte ja allgemein in C gleich sein. ich 
verwende einen STM32F446RET6

> Moot S. schrieb:
>> Habe ich die struktur im data.c falsch definiert?
>
> Ich sehe keine Datei data.c

Im data.c steht:
1
#include "data.h"
2
#include "eeprom.h"
3
4
void data_merge(void)
5
{
6
  properties_factory_data_type factoryData;
7
  struct_eeprom_data_type struct_eeprom_data;
8
9
  //memcpy(factory_data, eedata, EEPROM_DATA_FACTORY_SIZE);
10
}

Mein Problem ist, dass wenn ich aus einem anderen File (data.c) auf die 
struktur von eeprom.h zugreifen möchte, die daten nicht gleich sind, 
sondern um 32 Stellen verschoben.

Was ist an dieser definition
1
struct_eeprom_data_type struct_eeprom_data;
 falsch, dass sich das ganze verschiebt?

von zitter_ned_aso (Gast)


Lesenswert?

Also ich kenne das so, dass man eine struct-Variable in einem File 
global definiert (und nicht in einer Funktion) und dann macht man sie 
per "extern ...." in einer anderen Datei bekannt.

Moot S. schrieb:
> In einem dritten File data.c habe ich eeprom.h eingebunden und möchte
> nun die struktur auslesen wie folgt:
>struct_eeprom_data_type struct_eeprom_data;

es wird doch eine neue Variable erzeugt?

von OMG (Gast)


Lesenswert?

Moot S. schrieb:
> Warum spielt das eine Rolle?

Weil es sehr viele verschiedene Controller gibt und das EEPROM
Handling ganz grundsätzlich anders sein kann (wenn du mal über
deinen STM32 Tellerrand hinausschaust)

Im Übrigen geht das hier weiter:

OMG schrieb:
> Muss man den Leuten die Popel immer einzeln aus der Nase ziehen?

In deinem Fall ist noch nicht mal bekannt wo die EEPROM Daten
herkommen. Im Controller können sie jedenfalls nicht sein.

von Moot S. (mootseeker)


Lesenswert?

zitter_ned_aso schrieb:
> Also ich kenne das so, dass man eine struct-Variable in einem File
> global definiert (und nicht in einer Funktion) und dann macht man sie
> per "extern ...." in einer anderen Datei bekannt.

Ich habe nun im data.c global mit extern definiert:
1
 extern struct_eeprom_data_type struct_eeprom_data;

Jetzt bekomme ich folgende Fehler Meldung:
./Core/Src/_Configuration/properties.c:104: undefined reference to 
`struct_eeprom_data'

von MaWin (Gast)


Lesenswert?

Das typedef
Moot S. schrieb:
> typedef struct
> {
>   uint8_t eeDataPage[EEPROM_PAGE_SIZE];
> }struct_eeprom_data_type;

und die extern Deklaration in den header xyz.h
Moot S. schrieb:
> extern struct_eeprom_data_type struct_eeprom_data;

In den .c Dateien den header xyz.h einbinden und nur in einer .c Datei 
die Variable definieren.
Moot S. schrieb:
> struct_eeprom_data_type struct_eeprom_data;

von Moot S. (mootseeker)


Lesenswert?

@OMG Es geht aber garnicht um das EEPROM...

Mein Problem ist, das ich beim Zugriff auf eine Struktur, welche im im 
eeprom.h ist (Auf dem Kontroller) irgendwo einen Fehler habe den ich 
nicht finde.

Als Test habe ich mit:
1
memcpy(struct_eeprom_data, "Hallo Welt!", sizeof("Hallo Welt!");

Versucht einen String zu kopieren und diesen dann aus dem anderen File 
zu lesen mit dem Debugger. Das hat nichts mit der Ansteuerung vom EEPROM 
zu tun. Es hat auch nichts mit dem Kontroller zu tun, sondern ist ein 
unabhängiges C Problem.

Dieses Problem hätte ich wahrscheinlich auch in einer Windows Konsolen 
Anwendung.

von Moot S. (mootseeker)


Lesenswert?

Vielen Danke @MaWin!

Es Funktioniert nun!

Beitrag #6095694 wurde von einem Moderator gelöscht.
von Theor (Gast)


Lesenswert?

@  Moot S. (mootseeker)

Aus Deiner Beschreibung und den Codeteilen lässt sich m.M.n. kein 
Anhaltspunkt dafür ableiten, dass beim lesen eine Verschiebung der Daten 
um 32 Byte eintritt.

Wichtig sind die Eigenschaften von Definition und Deklaration sowie 
von Geltungsbereichen. Diese müssen für Dich (und nun für uns, da Du 
uns fragst) nachvollziehbar sein. Sie sind es aber im Moment nicht.

Du hast die Möglichkeit, ein minimales, aber compilierbares und 
lauffähiges  Codebeispiel zu erstellen, dass den Effekt demonstriert. 
Weiter könntest Du noch den Compiler angeben.

von Theor (Gast)


Lesenswert?

Ah, Schön. Hat sich erledigt.

von Moot S. (mootseeker)


Lesenswert?

Theor schrieb:
> @  Moot S. (mootseeker)
>
> Aus Deiner Beschreibung und den Codeteilen lässt sich m.M.n. _kein_
> Anhaltspunkt dafür ableiten, dass beim lesen eine Verschiebung der Daten
> um 32 Byte eintritt.
>
> Wichtig sind die Eigenschaften von Definition und Deklaration sowie
> von Geltungsbereichen. Diese müssen für Dich (und nun für uns, da Du
> uns fragst) nachvollziehbar sein. Sie sind es aber im Moment nicht.
>
> Du hast die Möglichkeit, ein minimales, aber compilierbares und
> lauffähiges  Codebeispiel zu erstellen, dass den Effekt demonstriert.
> Weiter könntest Du noch den Compiler angeben.

Danke für deine Antwort, ich versuch es beim nächsten mal etwas klarer 
zu definieren.

von mh (Gast)


Lesenswert?

Theor schrieb:
> Aus Deiner Beschreibung und den Codeteilen lässt sich m.M.n. kein
> Anhaltspunkt dafür ableiten, dass beim lesen eine Verschiebung der Daten
> um 32 Byte eintritt.

Naja, die 32 Bytes lassen sich nicht ablesen, dafür aber das 
Grundprinzip.
Es werden uninitialisierte lokale Variablen von dem im header 
definierten struct-Typ auf dem Stack angelegt (z.B. in data_merge). Je 
nachdem, was sonst so passiert im Programm, kann zufälligerweise die 
neue Instanz deckungsleich mit der alten sein ("Es funktioniert nun!") 
oder eben nicht (z.B. 32 Byte Versatz).

Das Grundproblem ist die Verwechslung von Typ-Definition mit 
Variablen-Definition.

von MaWin (Gast)


Lesenswert?

mh schrieb:
> zufälligerweise die
> neue Instanz deckungsleich mit der alten sein

???
Alle Module greifen auf die gleiche globale Variable zu. Dafür gibt es 
den extern Zirkus.

Das ist zwar schlechter Stil, aber einfach möglich.

von Moot S. (mootseeker)


Lesenswert?

Wie würdest du es den anderst lösen @MaWin?

von Wilhelm M. (wimalopaan)


Lesenswert?

Moot S. schrieb:
> Warum spielt das eine Rolle? sollte ja allgemein in C gleich sein. ich
> verwende einen STM32F446RET6

Spielt es auch nicht, sofern Du nicht wirklich etwas ins EEPROM 
schreiben willst (das tust Du ja noch nicht).

Warum versuchen so viele Leute, eine Programmiersprache wie C (oder auch 
C++) auf einem µC zu erlernen? Hier geht es doch um absolute Grundlagen 
wie lokale und globale Variablen.

Die Antwort ist wohl eher ein C-Buch oder Kurs.

von MaWin (Gast)


Lesenswert?

Die Daten kapseln und über Zugriffsfunktionen lesen und ggf. schreiben 
lassen.

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.