Hallo, ich habe Daten in einer Union / Struktur auf einem Controller angelegt. Diese möchte ich byteweise über die serielle Schnittstelle senden und am PC wieder in die gleiche Union / Struktur einlesen und damit arbeiten. Ich programmiere den AVR mit dem GCC und unter Windows in c++ mit Visual Studio .net. Das senden und empfangen der Struktur ist kein Problem... Ich habe mal mit sizeof überprüft, ob die Struktur unter Windows und auf dem Controller gleich groß ist. Auf dem Controller ist es korrekt (byte-genau), aber auf dem PC wird's scheinbar immer in 4Byte Blöcken gehandhabt. Wie kann ich sicher stellen, dass meine Strukturen auf dem Controller und auf dem PC exakt übereinstimmen, sodass ich wirklich Byte für Byte die Struktur übertragen kann? Oder gibt's einfache alternativen? Ich hoffe, ich habe das Problem klar geschildert. domi
Achja, damit das überhaupt funktioniert, müssen doch beide Systeme mit Big oder beide mit Little Endian arbeiten... Womit arbeitet der AVR-GCC? domi
Das Phänomen unterschiedlich großer Strukturen liegt am sogenannten Alignment. Aus Performancegründen werden auf 32-Bit-Prozessoren Strukturelemente so ausgerichtet, daß auf sie mit einem 32-Bit-Zugriff zugegriffen werden kann. Liegt ein WORD oder DWORD aber auch nur um ein Byte daneben, muss der Prozessor nacheinander zwei Zugriffe durchführen und die Daten zusammensetzen. Das macht auf einem PC zwar die Hardware (also nicht das vom Compiler erzeugte Programm!), aber langsam ist's trotzdem. Bei Microsoft-C-Compilern kann diese Strukturausrichtung mit #pragma pack(1) abgeschaltet werden. Damit der Rest (Strukturen des OS etc.) nicht davon beeinflusst werden, solltest Du so vorgehen:
1 | #pragma pack(push) // alte Einstellung merken
|
2 | #pragma pack(1) // Alignment auf Bytegrenzen
|
3 | struct meinestruktur |
4 | {
|
5 | // etc.
|
6 | };
|
7 | #pragma pack(pop) // alte Einstellungen wiederherstellen
|
Das sieht bei anderen Compilern anders aus, sollte aber in deren Dokumentation beschrieben werden.
Danke Rufus! Bin mal gespannt, ob das so mit der Übertragung funktioniert. Domi
wegen den von rufus erwähnten gründen (alignment und padding) sollte man immer vermeiden, structs etc. zwischen verschieden gearteten systemen auszutauschen. das geht nur wirklich zuverlässig mit byte arrays. auch sollte man vorher festlegen, in welchem format multibyte werte übertragen werden (low-byte zuerst oder anders)...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.