Forum: Mikrocontroller und Digitale Elektronik Wie speichere ich verschiedene Variablen in ein "Array" von Bytes


von Master S. (snowman)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich verwende den XC32 im Zusammenhang eines PIC32. Ich habe wiedermal 
Mühe, was der Compiler macht:
1
typedef struct {
2
    unsigned char timeH;
3
    unsigned char timeM;
4
    unsigned char weekdays;
5
    unsigned int W;
6
    unsigned int R;
7
    unsigned int G
8
    unsigned int B;
9
    unsigned char power;
10
} LightElement;

- "sizeof LightElement" ist ageblich 24
- jedoch 0xA00044B4 - 0xA00044A0 = 0x14 = 20 (siehe Attachment)
- LightElement hat aber nur 12 Bytes Nutzdaten

Das verstehe ich mal nicht, muss es aber so hinnehmen.


Eigentlich habe ich ein höheres Ziel: Ich habe verschiedene solcher 
strucs, die ich in einer Page (256 Bytes) eines EEPROMs abspeichern 
möchte. Ich möchte gleich eine ganze Page schreiben und nicht 
"Bytemanipulatorisch". Das heisst es wäre schön wenn ich ein 
übergeordneter "Container" hätte, der genau 256 Bytes gross ist (und 
auch 256 Bytes Nutzdaten hätte), den ich dann in einer Page ablegen 
könnte. Ich hatte an sowas gedacht, was aber (siehe oben) nicht 
funktioniert.
1
typdef struct {
2
  ...
3
} StructA; // 64 Bytes gross
4
5
typdef struct {
6
  ...
7
} StructB; // 64 Bytes gross
8
9
typdef struct {
10
  ...
11
} StructC; // 64 Bytes gross
12
13
typdef struct {
14
  ...
15
} StructD; // 64 Bytes gross
16
17
18
struct {
19
   StructA ElementA;
20
   StructB ElementB;
21
   StructC ElementC;
22
   StructD ElementD;
23
} StructAllesZusammen; // 256 Bytes gross

Frage: Wie mache ich das am besten und leserlichsten, dass ich innerhalb 
des Programms (code) auf die einzelnen Variablen zugreiffen kann und 
diese doch in einem 256 Byte grossen Array sind?

Vielen Dank für Tips

von Bitflüsterer (Gast)


Lesenswert?

#pragma packed

von Marc S. (marc_s86)


Lesenswert?

Bitflüsterer schrieb:
> #pragma packed

http://www.catb.org/esr/structure-packing/

hier noch die Erklärung dazu

es gibt noch die Möglichkeit nur einzelne structs zu packen:
1
struct my_struct { 
2
uint8_t field1; 
3
uint16_t field2; 
4
} __attribute__((packed));

http://digitalvampire.org/blog/index.php/2006/07/31/why-you-shouldnt-use-__attribute__packed/

von Master S. (snowman)


Lesenswert?

OK, vielen Dank - habe wieder was gelernt :-)

von S. R. (svenska)


Lesenswert?

Zu deinem LightElement:
- Sortiere mal die drei "unsigned char" an das Ende der Struktur. Das 
spart dir vermutlich dreimal Padding ein, ohne Tricksereien.
- Wie kommst du auf 12 Bytes Nutzdaten? Auf einer 32-Bit-Plattform 
sollte ein "unsigned int" 32 Bit = 4 Byte haben, und damit wären das 20 
Bytes Nutzdaten. Dann passt das auch mit dem sizeof von 24 Bytes (ein 
Padding-Byte hinter jedem unsigned char).

von Markus D. (mowlwurf)


Lesenswert?

Master Snowman schrieb:
> Frage: Wie mache ich das am besten und leserlichsten, dass ich innerhalb
> des Programms (code) auf die einzelnen Variablen zugreiffen kann und
> diese doch in einem 256 Byte grossen Array sind?

Ich würde es mit einer union machen:
1
typedef union
2
{
3
   unsigned char aucBuffer[256];
4
   struct {
5
     LightElement ElementA;
6
     LightElement ElementB;
7
     LightElement ElementC;
8
     LightElement ElementD;
9
   } StructAllesZusammen;
10
} MeineUnion;

Grüße,
Markus

von Master S. (snowman)


Lesenswert?

@ S. R.: ja du hast recht, ich habe int als 2 Bytes gerechnet (anstatt 4 
Bytes)
@ Markus D.: funktioniert das dann auch, wenn der struct 
zugriffsoptimiert im RAM liegt und nicht speicheroptimiert? (letzteres 
wird ja vom Compiler per default gemacht)

von Markus D. (mowlwurf)


Lesenswert?

Da ich den XC32-Compiler nicht kenne, kann ich dir die Frage leider 
nicht beantworten.
Beim GCC ist es so, dass eine globale Variable vom Typ MeineUnion in der 
.data section landet und damit zugriffsoptimiert im RAM liegt.

Ich verstehe auch nicht so ganz, was du mit "speicheroptimiert" meinst.

Grüße,
Markus

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.