PIC32/XC32: Attribute 'Packed'

OP #4937437
Lesenswert?

Hallo zusammen

Ich habe structs, die genau 32Bytes sein sollen, weil ich die in 
32Byte-EEPROM-Blocks abspeichere. Verwenden tue ich einen PIC32 mit dem 
XC32.

typedef struct {
   char cA;    // 8 bit
   char cB;    // 8 bit
   char cC;    // 8 bit
   short sA;   // 16 bit
   ...         // restliche Bytes
} __attribute__((packed)) StructElement1;

typedef struct {
   char cA;    // 8 bit
   char cB;    // 8 bit
   char cC;    // 8 bit
   char cD;    // 8 bit
   short sA;   // 16 bit
   ...         // restliche Bytes
} __attribute__((packed)) StructElement2;

StructElement1 E1;
StructElement2 E2;

void TestFunction(short *i) {...}

Wenn ich nun "TestFunction(&E1.sA);" verwende verabschiedet sich das 
Programm ins Nirvana, bei "TestFunction(&E2.sA);" jedoch nicht.

Lösung:
a) Sehe ich das richtig, dass der XC32 die shorts immer auf einer 
geraden(?) Adresse braucht; ich also im gemischten Struct zuvor eine 
gerade Anzhal Char-Variablen brauche? Uhhh, gefällt mir gar nicht sowas, 
ich möchte mich nicht auf Zufall-Compilierung verlassen.
b) Meine 32Byte-Structs nur mit Short-Variablen machen. Wie kann ich da 
sicher sein, dass mir der Compiler aus Laufzeitoptimierung, diese Shorts 
als 16bit und nicht als 32bit im Struct abspeichert? Resp. das Struct 
dann je nach Compilerverfassung 64Byte gross ist, resp. dann nicht mehr 
in ein EEPROM-Block passt.
c) ... ?

Was würded ihr vorschlagen?

Vielen Dank für Ratschläge! :-)
Gast #4937476
Lesenswert?

Master S. schrieb:
> a) Sehe ich das richtig, dass der XC32 die shorts immer auf einer
> geraden(?) Adresse braucht;

Nein, nicht direkt der XC32, sondern der ARM-Core Deines PIC32, der kann 
16-Bit Zugriffe nur auf graden Adressen.

Master S. schrieb:
> b) Meine 32Byte-Structs nur mit Short-Variablen machen. Wie kann ich da
> sicher sein, dass mir der Compiler aus Laufzeitoptimierung, diese Shorts
> als 16bit und nicht als 32bit im Struct abspeichert?

Dann nimm "uint16_t", das ist exakt 16Bit breit (oder der Compiler, 
repektive die Standardlibrary ist Schrott)
#4937491
Lesenswert?

Master S. schrieb:
> Wenn ich nun "TestFunction(&E1.sA);" verwende verabschiedet sich das
> Programm ins Nirvana, bei "TestFunction(&E2.sA);" jedoch nicht.

Das kann nicht funktionieren, wenn die zugrundeliegende Maschine 
Zugriffe nur mit passendem Alignment durchführen kann. Der Compiler kann 
zwar Zugriffe der Form
  ... = E1.sA;
entsprechend umständlich byteweise durchführen, weil er weiss, dass die 
Struct packed ist. Aber wenn du die Adresse eines solchen Objekts einem 
Pointer zuweist, dann geht diese Information verloren.
#4937518
Lesenswert?

guest schrieb:
> Ooops, bei ARM taucht das Problem aber auch auf.

Teils. Manche ARMe können misaligned accesses. Während aber die meisten 
CPUs, die es nicht können, darauf unubersehbar mit einem Trap antworten, 
liefern die klassischen ARMe einfach das ab, was bei der Adressierung in 
Verbindung mit dem von den untersten 2 Bits gesteuerten 
Barrel/Bytelane-Shifter rauskommt.
Gast #4937532
Lesenswert?

Master S. schrieb:
> einfach innerhalb
> eines Structs den gleichen Variablen-Typ verwenden

Wenn dann nur bei 'packed' Structs. Wenn man auf das Alignment achtet 
muß das  aber da auch nicht sein.
Ich würd die Structs allerdings nicht packen sondern die Werte Byteweise 
aus dem EEPROM holen und passend zusammenbauen.
OP #4937554
Lesenswert?

guest schrieb:
> Ich würd die Structs allerdings nicht packen sondern die Werte Byteweise
> aus dem EEPROM holen und passend zusammenbauen

Naja, das wären dann total 512 Bytes, die ich beim EEPROM schreiben und 
lesen rumschubsen muss. Und wie mache ich das mit 32bit-Floats?

Da scheint mir auf Aligment zu achten einfacher. Wie sage ich aber dem 
Compiler, dass er den "Beginn" eines solchen Structs immer schön auf den 
Start seiner hanbaren 32bit-Adresse legt?
Gast #4937595
Lesenswert?

Master S. schrieb:
> Wie sage ich aber dem
> Compiler, dass er den "Beginn" eines solchen Structs immer schön auf den
> Start seiner hanbaren 32bit-Adresse legt?

Das macht der sowieso so daß es passt (es sei denn Du sagst ihm explizit 
was anderes).
Ansonsten RTFM, da findest Du dann z.B. was über "__align(alignment) 
specifier".
OP #4937610
Lesenswert?

Ich mache mir da weniger Sorgen um Ressourcen/Zeit sondern um meine 
Faulheit, das explizit auszucoden, wenn es eventuell einfacher ginge - 
ich lerne lieber von anderen als mühselig aus eigenen Fehlern ;-)

RTFM: Ja... Wieviel RTFM sollte man betreiben und wieviel sollte man tun 
und Hilfe in einem Forum erwarten und geben?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren