Forum: Compiler & IDEs AVR ATMega - Zugriff auf Struct im Speicher mittels Offset


von Wolfgang H. (wolfgang_h51)


Lesenswert?

Hallo,
ich habe folgendes Problem...
1
typedef struct {
2
  uint16_t Wert1;
3
  uint8_t Wert2;
4
  uint8_t Wert3;
5
} MyStruct;

Kann auf das oben stehende Struct auch über ein Offset (Byte-Schritte) 
zugreifen, so in dieser Art: Gebe mir ein Byte an Offset 2 zurück. Das 
wäre hier Wert2.

Soviel ich weiss wird der Inhalt eines Structs im Speicher gepackt und 
verteilt. Wie kann ich an diese Problematik rangehen ?

Danke und Gruss,
Wolfgang

von Hmm (Gast)


Lesenswert?

Grundsätzlich geht das. Es ist nicht vom Sprachstandard gedeckt, wird 
aber so oft verwendet das fast alle Compiler das selbe machen, bzw. mit
1
#pragma pack

dazu gezwungen werden können keine Lücken zwischen den Elementen zu 
lassen.

von Wolfgang H. (wolfgang_h51)


Lesenswert?

Ok, da hab ich einen Ansatz um mich einzulesen...

Etwas Beispielcode wie der Zugriff aussieht hast Du auch evtl ? ;-)

Danke!

von Stefan R. (srand)


Lesenswert?

Das ist natürlich das einfachste.

Er kann natürlich auch eine eigene Getter-Funktion basteln, die aus 
"Byte n" einen Zugriff in "Element X" macht.

von Hmm (Gast)


Lesenswert?

Meister, das Kapitel über Strukturen kommt hinter dem über Zeiger.

Aber gut:
1
#pragma pack
2
3
typedef struct {
4
  uint16_t Wert1;
5
  uint8_t Wert2;
6
  uint8_t Wert3;
7
} MyStruct;
8
9
MyStruct a;
10
char * b = (char * ) & a;
11
12
char c = *b;

von Karl H. (kbuchegg)


Lesenswert?

Wolfgang Huse schrieb:
> Ok, da hab ich einen Ansatz um mich einzulesen...
>
> Etwas Beispielcode wie der Zugriff aussieht hast Du auch evtl ? ;-)

Es gibt im wesentlichen 2 Möglichkeiten.
Beide sind in dem Sinne nicht koscher, als beide zu undefiniertem 
Verhalten führen, wenn man streng nach dem Buchstaben des Gesetztes 
geht.

Der erste Weg führt über eine entsprechende union mit einem entsprechend 
großen Array aus unsigned char.

Der zweite Weg führt über einen profanen Cast eines Pointers. Pointer 
auf die Struktur bilden, auf einen Pointer nach unsigned char umcasten 
und ... zugreifen.

von troll (Gast)


Lesenswert?

Hmm schrieb:
>
1
> #pragma pack
2
>
heisst das beim GCC nicht
1
__attribute__((__packed__))
?

von Hmm (Gast)


Lesenswert?

>heisst das beim GCC nicht
1
__attribute__((__packed__))
?

Meine Güte. Bei der einen Frau heisst es: "Du hast schöne Augen." bei 
der anderen "Du hast wundervolles Haar." Der Zweck ist immer der 
gleiche.

von Hmm (Gast)


Lesenswert?

Zugegeben meine letzte Antwort ist ein wenig schnurzig.

Aber irgendwie verschwimmen die Compiler im Laufe der Jahre und kenne 
halt einige auswendig und bei anderen schlage ich nach.

http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html#Structure_002dPacking-Pragmas

von Wolfgang H. (wolfgang_h51)


Lesenswert?

Und meine Dame hat kein Interesse an Komplimenten... *g

"ignoring #pragma pack"

von Hmm (Gast)


Lesenswert?

>Und meine Dame hat kein Interesse an Komplimenten... *g
Jedenfalls nicht an meinen und das ist gut so. :-)

Schau halt mal in der Doku zu Deinem Compiler nach.

von Stefan R. (srand)


Lesenswert?

Seine Herzensdame kommt mit Doku? So eine Dame will ich auch. :-)

von Hmm (Gast)


Lesenswert?

Au weia. Wie chauvinistisch sich meine Anwort liest!

von Stefan E. (sternst)


Lesenswert?

Hmm schrieb:
>>heisst das beim GCC nicht
>
>
1
> __attribute__((__packed__))
2
>
> ?
>
> Meine Güte. Bei der einen Frau heisst es: "Du hast schöne Augen." bei
> der anderen "Du hast wundervolles Haar." Der Zweck ist immer der
> gleiche.

Und da es hier um avr-gcc geht, ist es eh irrelevant, da eh alles 
byteorientiert ist.

von Wolfgang H. (wolfgang_h51)


Lesenswert?

Also, nach einer Runde Doku heisst es:
1
typedef struct {
2
  uint16_t Wert1;
3
  uint8_t Wert2;
4
  uint8_t Wert3;
5
} __attribute__((packed, aligned(1))) MyStruct;

Das funktioniert auch wie gewünscht....

@stefan
Das heisst ich kann mir das sparen und direkt das Offset zum Zeiger 
addieren ?  Was ist mit den verschiedenen Aussagen dazu das ein Struct 
im Speicher optimiert abgelegt wird ?

In der Tat klappt es bei meinem kleinen Beispiel auch.. Aber wie ist das 
wenn die Struct später um einiges größer ist ?

/Edit: Tippfehler beseitigt...

von Hmm (Gast)


Lesenswert?

Sh... Da hast recht. Habs glatt übersehen, das es um ATMega geht. 
Tschuldigung.

von Hmm (Gast)


Lesenswert?

>Was ist mit den verschiedenen Aussagen dazu das ein Struct
>im Speicher optimiert abgelegt wird ?

Die sind dem Grunde nach richtig. Nur das bei dem AVR die optimierung 
halt heisst: Byte-Aligned. Daher hat packed keinen Effekt, wenn der 
Parameter 1 ist.

>Aber wie ist das wenn die Struct später um einiges größer ist ?
Mit der Gesamtgrösse der Struktur hat das nichts zu tun. Es geht um die 
einzelnen Elemente.

von Stefan E. (sternst)


Lesenswert?

Wolfgang Huse schrieb:
> Was ist mit den verschiedenen Aussagen dazu das ein Struct
> im Speicher optimiert abgelegt wird ?

Beim avr-gcc lautet diese "Optimierung" eben "auf Byte-Grenzen legen".

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.