Forum: Compiler & IDEs PC kompatible structs


von Thundernail (Gast)


Lesenswert?

Moin, moin,

zwischen einem AVR- und einem PC-Programm verschicke ich viele 
unterschidliche Nachrichtentypen (jeder Typ besteht aus einem eigenen 
Struct).
Bisher zerlege ich das Struct auf AVR-Seite in ein char-Array übertrage 
dieses und baue auf PC-Seite wieder ein Struct zusammen. Dadurch muss 
ich für jeden Nachrichtentyp zwei Funktionen schreiben, die die ganze 
Kommunikation sehr unflexibel gestalltet.
Ich würde nun gerne das Zerlegung/Zusammenbauen vereinheitlichen, dazu 
müsste aber die Speicherdastellung auf PC und AVR gleich aussehen. Gibt 
es eine Möglichkeit dies zu erreichen?

Beispiel:
1
typedef struct Tpacket {
2
  char c;
3
  int32_t i;
4
};
Speicherbelegung 8-Bit (AVR):
| c | i | i | i | i |
Speicherbelegung 32-Bit (PC):
| c |   |   |   | i | i | i | i |

von Uhu U. (uhu)


Lesenswert?

Du mußt auf dem PC das alignment für den Struct auf 1 setzen.

Bei VC++ geht das mit #pragma pack(...)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Beim GCC mit __attribute__((packed)).

von Rolf Magnus (Gast)


Lesenswert?

Ich würde lieber auf der AVR-Seite an den passenden Stellen Zusatzbytes 
einfügen bzw. die Reihenfolge der struct-Elemente geschickter wählen.
Am PC wird ein Fehlalingment nur mit langsamerem Zugriff bestraft, aber 
wenn du stattdessen mal was anderes verwendest, kann es je nach 
Plattform auch einen Crash geben. Dann bist du wieder zurück am Start.

von Philipp B. (philipp_burch)


Lesenswert?

Könnte es in dem Fall nicht sogar helfen, einfach die Member zu 
vertauschen? Sonst halt einfach zwei uint32_t verwenden, da passt ein 
char ja auch rein.
Ist aber speichermässig auf einem AVR nicht wirklich optimal.

von Martin R. (thundernail)


Lesenswert?

Moin, moin,

Danke für die Ratschläge.

__attribute__((packed)): werd ich mal ausprobieren

@Rolf und Philipp: Dazu müsste man beim erstellen der Packete immer 
mitdenken => sehr hohe Fehlerquelle, die auch noch schwer zu entdecken 
ist (Warum liefert der Sensor den falschen Wert?).

von yalu (Gast)


Lesenswert?

Du kannst ja auch beides kombinieren, also packen und die Elemente
nach absteigender Größe sortieren. Dann funktioniert's und die
Zugriffe sind maximal schnell. Machst dur beim Sortieren einen Fehler,
wird's zwar etwas langsamer, funktioniert aber auf Grund der Packerei
immer noch korrekt.

Das Ganze versagt natürlich, wenn de eines Tages auf einer der beiden
Seiten einen Prozessor mit anderer Endianness benutzt. Dann musst du
doch wieder die Strukturen elementweise in Bytearrays kopieren. Aber
wenn der AVR und der PC sozusagen ein untrennbares Gesamtsystem
bilden, ist das direkte Übertragen von Strukturen schon ok.

von Uhu U. (uhu)


Lesenswert?

Mit Verlaub, aber das Geschwindigkeitsargument ist doch ziemlich 
daneben. Die Kosten für Misalignment auf dem PC kann man sich zwar 
ausrechnen, aber im Leben nicht messen, wenn die Kiste unter Windows 
oder Linux läuft - die gehen einfach im Rauschen unter.

von Rolf Magnus (Gast)


Lesenswert?

> Die Kosten für Misalignment auf dem PC kann man sich zwar
> ausrechnen, aber im Leben nicht messen, wenn die Kiste unter Windows
> oder Linux läuft - die gehen einfach im Rauschen unter.

Vermutlich. Wenn du dann allerdings statt eines PCs jemals was 
anschließen, das Misalignment gar nicht unterstützt, kannst du das 
Protokoll grad mal in die Tonne treten und alles nochmal 
umkonfektionieren.

von Philipp B. (philipp_burch)


Lesenswert?

> @Rolf und Philipp: Dazu müsste man beim erstellen der Packete immer
> mitdenken => sehr hohe Fehlerquelle, die auch noch schwer zu entdecken
> ist (Warum liefert der Sensor den falschen Wert?).

Ich dachte eigentlich, dass man beim Programmieren grundsätzlich 
mitdenken sollte?

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.