Forum: Compiler & IDEs Struct


von AVRKiller (Gast)


Lesenswert?

Hi


Für eine CAN Message hatte ich zwei Datastrukturen gesehen:

typedef struct {
  uint32_t ID;
  uint32_t DLC;
  uint32_t RTS;
  uint32_t data[8];
} CAN_struct;

und

typedef struct {
  uint32_t ID;
  uint32_t DLC;
  uint32_t RTS;
  uint32_t data1;
  uint32_t data2;
  uint32_t data3;
  uint32_t data4;
  uint32_t data5;
  uint32_t data6;
  uint32_t data7;
  uint32_t data8;
} CAN_struct;



angesprochen wird die erste über z.B.

pdata->data[3]

und die zweite:

pdata.data3



Wo ist denn hier mal ein qualitativer Unterschied?
Beide funktionieren aber welche ist besser?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die erste wirkt ernstgemeinter; ansonsten hängt das ganze davon ab, auf 
welche Art und Weise auf die Nutzdaten der Struktur zugegriffen werden 
soll. Wenn das Array data[] als Array betrachtet wird, dann ist die 
erste Schreibweise sicherlich die sinnvollere, wenn die Variablen nur 
rein willkürlich mit data1..8 benannt worden sind, kann auch die zweite 
Variante sinnvoll sein.

Das alles hängt wie gesagt von der Anwendung der ganzen Chose ab; werden 
denn mit diesen Strukturen nur 32-Bit-Werte transportiert oder könnte 
das ganze auch eine Sammlung von Bytes sein? In letzterem Falle würde 
ich data[] als entsprechende dimensioniertes Byte-Array deklarieren und 
-je nach Auswertung- per Typecast in den für den entsprechenden Pakettyp 
sinnvollen Datentyp umwandeln.

von Stefan K. (_sk_)


Lesenswert?

Mit der ersten Lösung verbaust Du Dir nichts.

Mit der zweiten Lösung hast Du ein Problem, wenn zusammenhängende Daten 
drin stehen. Oder wenn Du die Daten woanders hin kopieren musst, darfst 
Du jedes Byte separat anpacken und kannst keine Schleife benutzen. Oder 
...

Im übrigen bestehen die CAN-Nutzdaten aus 8 Bytes, und nicht aus 8 
32-Bit-Werten. Natürlich kannst Du das so machen, was aber zur Folge 
hat, dass Du sehr schnell den verfügbaren Speicher Deines AVR Killst.

Gruß Stefan

von AVRKiller (Gast)


Lesenswert?

ok. also ich habe eine 32 Bit MCU, deswegen die 32-Bit Speicherbreite.

Um Speicher zu sparen könnte ich die Daten immer als 4er Kette in einen 
32-Bit legen.
Frage:
Ist der Aufwand für die CPU groß wenn ich die Bitverschiebung anwende?
Data[0] = (Byte1<<24)|(Byte2<<16)|(Byte3<<8)|Byte4;

Diese Anwendung würde nämlich in einer ISR liegen und darf nicht zu lang 
dauern.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Was verleitet Dich zur Annahme, es würde Speicher sparen, statt vier 
uint8_t einen uint32_t zu verwenden?

von AVRKiller (Gast)


Lesenswert?

4x uint8 ?

wenn ich jedes Datenbyte mit uint8_t definiere, so bleiben die 
restlichen 24 Bit ja auch frei.
Ist halt ne 32 Bit breite Archirektur.

Is doch so?!

von Stefan K. (_sk_)


Lesenswert?

>wenn ich jedes Datenbyte mit uint8_t definiere, so bleiben die
>restlichen 24 Bit ja auch frei.
>Ist halt ne 32 Bit breite Archirektur.

Also selbst wenn das so wäre (was wir nicht wissen können, warum?), dann 
macht es trotzdem Sinn, die Werte mit uint8_t anzugeben. Gesetzt den 
Fall, Du willst den Code mal wiederverwenden auf einer anderen Maschine, 
die sparsamer mit ihrem Speicher umgeht.

Stefan

von A.K. (Gast)


Lesenswert?

> wenn ich jedes Datenbyte mit uint8_t definiere, so bleiben die
> restlichen 24 Bit ja auch frei.

Nö. Soviel Intelligenz kannst du dem Compiler durchaus zutrauen.

von Ronny (Gast)


Lesenswert?

Naja,in einem Punkt ist die Verwendung von uint8_t auf manchen 
32-Bittern schon ineffektiv,nämlich dann wenn das Byte nicht richtig 
ausgerichtet ist.Einige 32-Bitter mögen ihre Daten gerne an geraden 
Addressen (oder durch 4 teilbaren Addressen) angeordnet haben.Und dann 
liegt bei einem Byte-Array logischerweise immer nur jedes 2 (oder jedes 
vierte) Byte an einer günstig erreichbaren Stelle im Speicher.

Übrigens gibt es durchaus auch z.b im Header bei Dateiformaten auf PCs 
(32 oder 64 Bit-Architektur!) 8-Bit Werte,die wären dann nicht mehr so 
einfach zu verarbeiten wenn jeder C-Compiler eigenmächtig die kleinen 
Datentypen derart aufbläst.

von A.K. (Gast)


Lesenswert?

> Einige 32-Bitter mögen ihre Daten gerne an geraden
> Addressen (oder durch 4 teilbaren Addressen) angeordnet haben.

Yep. 32bit-Daten an 32bit-Grenzen, 16bit-Daten an 16bit-Grenzen und 
8bit-Daten an 8bit-Grenzen. So isses allgemein üblich seit 
wortadressierende Maschinen aus der Mode kamen. Spezialarchitekturen 
(z.B. DSPs und Grafikcontroller) mal ausgenommen.

Also: Ein Compiler weiss nicht alles, aber über die Zugriffs- und 
Alignment-Anforderungen der Datentypen ist er gewöhnlich ausgesprochen 
gut informiert.

von A.K. (Gast)


Lesenswert?

> Naja,in einem Punkt ist die Verwendung von uint8_t auf
> manchen 32-Bittern schon ineffektiv,nämlich dann wenn
> das Byte nicht richtig ausgerichtet ist.

Beispiel? Jenseits von Crays Schöpfungen fällt mir da nur die erste 
Version von DEC Alpha ein, und denen haben die Kunden derart die Leviten 
gelesen, dass es schon in der zweiten Release wieder ging.

Erst in neuerer Zeit hat es ein Hersteller tatsächlich geschafft, diese 
Kuh wieder auf's Eis zu manövrieren: Maxim mit MAXQ2000.

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.