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?
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.
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
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.
Was verleitet Dich zur Annahme, es würde Speicher sparen, statt vier uint8_t einen uint32_t zu verwenden?
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?!
>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
> 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.
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.
> 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.
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.