Forum: Mikrocontroller und Digitale Elektronik structs in char*


von attiny417 (Gast)


Lesenswert?

Hey hallo,

Ich benötige auf meinem Controller eine struktur. Diese strutkur wird in 
der MAIN Ständig abgepollt und es geben eben Ereignisse die getriggert 
werden, sobald sich an der Struktur was ändert. Über I2C soll aber 
zugriff auf diese Struktur möglich sein. Ich hatte jetzt gedacht ich 
caste die struct einfach mal zu einem char* aber irgendwie scheint im 
speicher einige anders zu sein. Wie serialisiert man eine strukt 
möglichst einfach?
1
typedef struct {
2
  u16 dies;
3
  u16 UndDas;
4
  struct{
5
    u8 set_blub:1;
6
    u8 test_blub:1;
7
    u8 rel_an:1;
8
    u8 rel_an2:1;
9
    u8 reserved:4;
10
  }bits;
11
  u8 blubb;
12
  u16 vol2;
13
  u16 vol1;
14
  u16 version;
15
  u8 RESERVED1[50];
16
  u8 RESERVED2[50];
17
  u8 RESERVED3[50];
18
  u8 RESERVED4[50];
19
}REGISTER;

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?


von Oliver S. (oliverso)


Lesenswert?

attiny417 schrieb:
> aber irgendwie scheint im
> speicher einige anders zu sein.

Auf einem Attiny417? Welcher Compiler, welche Version, welche 
Optimierung?

Oliver

von attiny417 (Gast)


Lesenswert?

>>Auf einem Attiny417? Welcher Compiler, welche Version, welche
>>Optimierung?
zunächste Probiere ich mit microchip studio. Später (in serien 
Produktion) wolte ich avr-gcc + avr dude nehmen.

von Oliver S. (oliverso)


Lesenswert?

attiny417 schrieb:
> zunächste Probiere ich mit microchip studio. Später (in serien
> Produktion) wolte ich avr-gcc + avr dude nehmen.

Aha...

Aber wenn du schon das Studio benutzt, schau halt mal in der Simulation 
in den Speicher, was da so steht..

Der avr-gcc 11, den ich hier habe, legt das alles so an, wie das da 
steht. Das Studio verwendet eine ältere Version. Vielleicht fehlt dem da 
ein packed, auch wenn das auf einem AVR eigentlich nicht beötigt werden 
sollte.

Oliver

von attiny417 (Gast)


Lesenswert?

Hey oliver und erlkoenig.
Vielen Dank :)

Es passt alles, ich hab die Daten nur falsch herum interpretiert :D

von A. S. (Gast)


Lesenswert?

attiny417 schrieb:
> Ich hatte jetzt gedacht ich
> caste die struct einfach mal zu einem char* aber irgendwie scheint im
> speicher einige anders zu sein.

Was passiert denn? Mit welchem Code?

Deine Struktur hat ja mindestens 224 Byte (wenn ich richtig gezählt 
hab), je nach Allignment auch an die 256. Soll das so?

Typische Probleme sind

 a) Allignment (REGISTER.Unddas fängt bei [4] an und nicht bei [2])
 b) Endianess (REGISTER.dies=3 schreibt 0,3 in den Speicher oder 3,0)
 c) Bitfelder sind ein eigenes Fass
 d) Dein Debugger ("im Speicher anders") ist wieder ein eigenes Fass
 e) Warnungen aus (und Schreibfehler, Verständnisfehler)
 f) ...

von attiny417 (Gast)


Lesenswert?

>> a) Allignment (REGISTER.Unddas fängt bei [4] an und nicht bei [2])
>> b) Endianess (REGISTER.dies=3 schreibt 0,3 in den Speicher oder 3,0)
>> c) Bitfelder sind ein eigenes Fass
>> d) Dein Debugger ("im Speicher anders") ist wieder ein eigenes Fass
>> e) Warnungen aus (und Schreibfehler, Verständnisfehler)
>> f) ...

I know :D

A) Im Beispiel oben wird man Problme mit dem Alignment bekommen, in 
meiner struct passe ich drauf auf das jede struct ein vielfaches von 4 
byte hat.
B) Endianess -> naja beide compiler die ich nutzen werde sind vom grunde 
auf gcc compiler, ich denke da springt das alignment nicht.
C) Siehe A / bzw Bitfelder nutze ich seit jahren.
d/e) -> feolgefehler durch fehlinterpretation :D

von A. S. (Gast)


Lesenswert?

attiny417 schrieb:
> I know :D

Machst Du Witze? Du schreibst, Du hast ein Problem

> aber irgendwie scheint im speicher einige anders zu sein.

schreibst nicht dazu welches, sondern erklärst stattdessen, dass Du 
keine Fehler machst.

Dass der Compiler die Endianess bestimmt ist sicher nur ein Versehen. 
Und die genaue Größe der Struktur ist relativ egal, sizeof & co 
berücksichtigen das.

von attiny417 (Gast)


Lesenswert?

>>Dass der Compiler die Endianess bestimmt ist sicher nur ein Versehen.
Es ist leider nicht festgelegt, es kann es sein das ein anderer Compiler 
die Daten anders herum Speichert.


>>Und die genaue Größe der Struktur ist relativ egal, sizeof & co
>>berücksichtigen das.
Das stimmt nicht.

[code]
typedef struct {
    ui8 blub;
}test1;


typedef struct {
    ui8 blub;
    ui8 blub2;
}test2;
[/code}

soizeof(test2) wird 2 oder 4 ausgeben, genauso wie soizeof(test1). Es 
sei denn man "packt" mit #pragma push/pop

Daher ist es sehr sinnvoll darauf zu achten das man die size immer bei 
einem vielfachen von 4 hält, wenn man strukturen serialisieren möchte.

von A. S. (Gast)


Lesenswert?

attiny417 schrieb:
> es kann es sein das ein anderer Compiler
> die Daten anders herum Speichert.

natürlich. Nur kommt der Compiler in Teufels-Küche, wenn er sich da 
nicht am µC und seinen Fähigkeiten orientiert. Und z.B. bei Deinem 
Nick-uC hätte ich jetzt nicht erwartet, dass er da flexibel ist.

attiny417 schrieb:
> Daher ist es sehr sinnvoll darauf zu achten das man die size immer bei
> einem vielfachen von 4 hält, wenn man strukturen serialisieren möchte.

Kann man so sehen. Man kann es auch anders rum sehen, dass nämlich der 
Compiler schon dafür sorgt, dass nichts schief geht. Er "macht" Deine 
Strukturen so groß, dass es passt. Probleme gibt es nur, wenn Du 
irgendwelche Dinge selbst ausrechnest (ohne sizeof oder []), vor allem 
wenn es um Arrays von Strukturen geht.

Aber wenn bei Dir doch alles funktioniert, dann OK, freut mich!

von Gerald K. (geku)


Lesenswert?

Für Telegramm, die seriell übertragen werden, dürfen keine Lücken in der 
Struktur vorhanden sein.

Abhilfe:
1
struct my_struct {
2
   char a;
3
   int b;
4
} __attribute__ ((packed));

Bei unterschiedlichen Prozessorfamilien kann die Reihenfolge von Low und 
High vertauscht sein. Diese müssen dann im Empfänger gedreht werden.

char* speichert in der Struktur nur einen Zeiger vom Typ char !

von Rolf M. (rmagnus)


Lesenswert?

attiny417 schrieb:
> B) Endianess -> naja beide compiler die ich nutzen werde sind vom grunde
> auf gcc compiler, ich denke da springt das alignment nicht.

Das hat mehr mit der Zielplattform als mit dem Compiler zu tun. Daher 
kommt es stark darauf an, wer über I²C zugreifen will:

attiny417 schrieb:
> Über I2C soll aber zugriff auf diese Struktur möglich sein.

Wenn das auch ein AVR mit gcc ist, brauchst du dir keine Sorgen machen. 
Ansonsten musst du da genauer aufpassen.

Gerald K. schrieb:
> Für Telegramm, die seriell übertragen werden, dürfen keine Lücken in der
> Struktur vorhanden sein.

Die dürfen schon vorhanden sein. Sie müssen nur beidseitig gleich sein 
(und zwar unabhängig davon, wie sie übertragen werden). Das kann man 
z.B. auch erreichen, indem man zum Alignment Dummy-Elemente einfügt. Und 
man sollte ausschließlich die uint*_t-Datentypen oder vergleichbare mit 
genau definierter Breite nutzen.

> Abhilfe:
> struct my_struct {
>    char a;
>    int b;
> } _attribute_ ((packed));

Das kann fehlschlagen, wenn der Prozessor bestimmte Alignments zwingend 
voraussetzt. Und int kann auch auf Sender- und Empfänger-Seite 
unterschiedlich groß sein.

> Bei unterschiedlichen Prozessorfamilien kann die Reihenfolge von Low und
> High vertauscht sein. Diese müssen dann im Empfänger gedreht werden.

Oder im Sender. Man muss sich halt auf eine gemeinsame Byteoder einigen 
oder diese beim Start aushandeln.

von A. S. (Gast)


Lesenswert?

Rolf M. schrieb:
> Gerald K. schrieb:
>> Für Telegramm, die seriell übertragen werden, dürfen keine Lücken in der
>> Struktur vorhanden sein.
>
> Die dürfen schon vorhanden sein. Sie müssen nur beidseitig gleich sein
> (und zwar unabhängig davon, wie sie übertragen werden).

Genau.

Ein Problem ergibt sich vielleicht, wenn man solche Strukturen 
vergleicht, z.B. mit memcmp.

von mh (Gast)


Lesenswert?

A. S. schrieb:
> Rolf M. schrieb:
>> Gerald K. schrieb:
>>> Für Telegramm, die seriell übertragen werden, dürfen keine Lücken in der
>>> Struktur vorhanden sein.
>>
>> Die dürfen schon vorhanden sein. Sie müssen nur beidseitig gleich sein
>> (und zwar unabhängig davon, wie sie übertragen werden).
>
> Genau.
>
> Ein Problem ergibt sich vielleicht, wenn man solche Strukturen
> vergleicht, z.B. mit memcmp.

Das hat aber nichts mit der Übertragung zu tun.

von A. S. (Gast)


Lesenswert?

mh schrieb:
> Das hat aber nichts mit der Übertragung zu tun.

natürlich nicht. Darum schrieb ich ja:

A. S. schrieb:
> die genaue Größe der Struktur ist relativ egal,

mir ging es nur um Geralds Aussage, vielleicht hat er das verwechselt.

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.