www.mikrocontroller.net

Forum: Compiler & IDEs Struktur mit Pointer "durchlaufen"


Autor: Richard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe eine Struktur:
typedef struct {
byte a; // 1Byte
word b; // 2Bytes
byte c; // 1Byte
typ_irgendwas d; // 5Bytes
byte e[3]; // 3Bytes
} tStrukt;
tStrukt Strukt;

diese möchte ich genau in dieser Reihenfolge im Eeprom ablegen. (Falls
der Compiler die Struktur umsortieren würde, wäre das nicht schlimm, da
die Daten genauso wieder nach dem Powerup in die Struktur kopiert
werden sollen). Für das Eepromablegen habe ich eine funktionierende
Funktion Eep_write16Bytes(Adr, *daten16);

Ich habe mir gedacht einen Pointer über die Struktur laufen zu lassen
und das 16er Array "daten16" (byte daten16[16];) mit diesen Daten zu
befüllen.

for(i=0;i<sizeof(Strukt);i++)
{
  ...
  daten16[i]= ...;
}

1.) Ist meine Idee prinzipiell korrekt?
2.) Wie sind die "..." zu befüllen?
3.) Wie kann ich grundsätzlich auf das erste Element einer Struktur
zugreifen, wenn ich den Namen des Elements nicht kenne? (Grund: Ich
habe mehrere dieser Strukturen abzulegen und wieder zu restaurieren und
würde das gerne universell halten).

Gruß Richard.

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was spricht gegen die Verwendung von
eeprom_read_block()/eeprom_write_block()?

Autor: Richard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab ich da nicht auch das Problem, daß ich zuerst einen Puffer füllen
muß, der geschrieben werden soll?
Mir gings weniger um die Verwendung einer speziellen
Eeprom-Schreibroutine, sondern darum, wie ich das erste Element einer
Struktur "angreifen" kann, ohne den genauen Namen zu wissen.

Mit folgender Zuweisung (daraufhin zielte auch meine Frage 2 ab) habe
ich erfolgreich die Daten wegschreiben können:
for (i=0;i<16;i++)
  Daten16[i]=*(&Struktur.a+i);

Ich will aber zukünftig vermeiden (und darauf zielte Frage 3 ab :)),
daß das Element "a" explizit genannt werden muß. Sympatischer wäre
mir folgende (leider fehlerhafte) Zuweisung:
Daten16[i]=*(&Struktur+i);

(Meine Schwäche beim Verständnis von Zeigern usw. läßt sich natürlich
nicht verleugnen).
Wie wäre die korrekte Syntax?

Gruß Richard.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ohne mir jetzt 100% sicher zu sein:

Daten16[i]=*((unsigned char *)(&Struktur+i));

Matthias

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hab ich da nicht auch das Problem, daß ich zuerst einen Puffer
> füllen muß, der geschrieben werden soll?

Nein, aber Du brauchst eine typgleiche Variable im RAM von/zu der Du
kopieren kannst.

> ... wie ich das erste Element einer Struktur "angreifen" kann,
ohne
> den genauen Namen zu wissen.

Gar nicht.

> Ich will aber zukünftig vermeiden (und darauf zielte Frage 3 ab :)),
> daß das Element "a" explizit genannt werden muß. Sympatischer wäre
> mir folgende (leider fehlerhafte) Zuweisung:
> Daten16[i]=*(&Struktur+i);

Ich sehe nicht, was daran fehlerhaft sein sollte.

Autor: Richard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte eher das Problem für ein AnsiC-Problem gehalten und deswegen
im GCC-Forum gepostet (und nicht unter allgemein), da ja der GCC auch
ein strenger AnsiC-Vertreter ist.

Ich verwende den Metrowerks Compiler für Motorola. Dieser meldet bei:
>  Daten16[i]=*(&Struktur+i);
Type mismatch (expected 'unsigned char ', given 'tStruktur ')

Aber inzw. hab ichs hinbekommen:
Daten16[i]=*((unsigned char *)(&Struktur)+i);
Sieht jetzt so ähnlich aus wie Matthias' Vorschlag, allerdings wird
jetzt nur noch die "Struktur" selbst gecastet (und nicht noch "+i"
gleich mit).

Kann jetzt leider nicht mit nem GCC vergleichen, dieser sollte(???)
aber doch den gleichen Fehler melden?

Vielen Dank für die Hilfen,
Gruß Richard.

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
welcher puffer muss warum gefüllt werden???

gib doch einfach dem eeprom-beschreib-befehl (char *)&structur als
pointer und sizeof(strukturdings) als bytelänge an... das funktioniert
prima und ohne gross herumtrixn zu müssn...


ich hab da z.b diese zeile bei mir verbastlt...

eeprom_read_block(&g_InputDevices[nCounter],(uint16_t *)
EEPROM_STRUCTURE_START+nCounter*INPUT_DEVICE_STRUCT_SIZE,
INPUT_DEVICE_STRUCT_SIZE);

ist zwar ein bisserl komisch aber wirst schon durchsteign ;)

73 de oe6jwf

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mglw. hilft auch eine "union", z.B.

struct Mystruct {
 unsigned short a;
 unsigned char b;
 unsigned char c[3];
};

union {
 Mystruct s;
 unsigned char arr[sizeof(Mystruct)];
} gConv;

void struct_to_eeprom(Mystruct *ps, unsigned int eeadr)
{
 gConv.s=*ps;
 eeprom_write_block(gConv.arr,&eeadr,sizeof(Mystruct));
}

Im Code mag der ein oder andere Syntaxfehler sein, aber im Prinzip
muesste es klappen (nicht getestet) und erscheint mir klarer. Methode
braucht etwas RAM, nicht zuletzte wg. der globalen "union", vermeidet
aber Probleme mit lokalen "Konverter-Unions" und deren zur Laufzeit
schlecht abschaetzbarem Platzbedarf.

Autor: Richard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> welcher puffer muss warum gefüllt werden???
gute Frage, eigentlich liegen die Daten ja schon im Speicher perfekt
bereit... (und die Daten ändern sich auch nicht während des Schreibens
- also eigentlich kein Problem).

Und die Sache mit der Union an sich ist auch ein guter Gedanke.

Ich werde meiner Eeprom-Schreibroutine einen Zeiger direkt auf die
Struktur übergeben - ganz ohne Puffer befüllen.

Danke für die Anregungen.
Gruß Richard.

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.