Forum: Mikrocontroller und Digitale Elektronik Struct mit payload zwischen size und crc


von Holger K. (holgerkraehe)


Lesenswert?

Hallo zusammen

Ich würde gerne Daten mittels eines Strukts verarbeiten.
1
struct ALDP_t_class
2
{
3
  uint8_t  aldp_hdr_byte_1;
4
  uint8_t aldp_hdr_byte_2;
5
  uint8_t aldp_payload[];
6
};
7
8
struct SLDP_t_class
9
{
10
  uint8_t    sldp_size;
11
  uint8_t    *sldp_payload;
12
  uint8_t    sldp_crc8;
13
};

Dazu habe ich folgende Strukte.
Nun ist mein Problem folgendes:
Beim sldp Strukt ist die Payload in der Mitte, dies ist ungünstig, da 
ich dadurch sowas nicht machen kann:
1
SLDP_Paket = (struct SLDP_t_class *)&BufferPointer[0];
Denn die Länge der Payload von SLDP kann variabel sein.

Natürlich müsste ich für obige Zuweisung sldp_payload von * zu 
sldp_payload[] ändern. Jedoch ändert dies ja nichts daran, dass der 
Compiler nicht mehr weiss, wo die sldp_crc8 kommt.

Eine Möglichkeit wäre die payload ans Ende zu setzen, und die crc8 nach 
sldp_size anzugliedern. Dies erschwert dann aber die crc8 kalkulation 
etwas.

Gibt es hier einen "Trick77" womit man sowas elegant lösen kann?

Danke schonmal

von Dr. Sommer (Gast)


Lesenswert?

Holger K. schrieb:
> SLDP_Paket = (struct SLDP_t_class *)&BufferPointer[0];

Pointer auf irgendwas nach Pointer-Auf-Struct casten ist in C verboten 
("Strict Aliasing").

So geht es sauber:
1
struct SLDP_t_class
2
{
3
  uint8_t    sldp_size;
4
  uint8_t    sldp_crc8;
5
  const uint8_t    *sldp_payload;
6
};
7
8
void receive (struct* SLDP_t_class r, const uint8_t* BufferPointer) {
9
  r->sldp_size = BufferPointer[0];
10
  r->sldp_payload = BufferPointer+1;
11
  if (r->sldp_size > MaxBufSize-2) error ();
12
  r->sldp_crc8 = BufferPointer[r->sldp_size+1];
13
  checkCrc (r->sldp_payload, r->sldp_size, r->sldp_crc8);
14
}

von K. S. (the_yrr)


Lesenswert?

Du hast also einen Buffer der entweder variable Länge hat oder Daten 
variabler Länge enthält? und diese Daten willst du zu deiner Struct 
casten?

Egal wie rum du die Variablen in der Struct anordnest, du kannst das 
nicht direkt casten. denn du brauchst folgendes:
    1 Byte Länge
    1-2Byte Pointer
    1 byte CRC
Du hast aber:
    1 Byte Länge
    viele bytes Daten
    1 Byte CRC

mit einer einfachen Funktion kannst du das zuweisen, aber dann kopierst 
du die Daten nicht aus dem Buffer.
oder du holst dir mit malloc oder Ähnlich genug Speicher um die Date nzu 
Kopieren.

Alternativ pack nen Array statt nem Pointer in die Struct. Nur hat die 
Struct dann eine feste Länge, mit folgenden Konsequenzen:

Buffer > Struct => Daten gehen verloren
Buffer < Struct => Du liest/schreibst in völlig zufällige 
Speicherbereiche, außer du Begrenzt den Zugriff auf die echte Länge 
Daten, ist aber so oder so nicht wirklich schön

Buffer >= Struct, aber Daten in Buffer < Struct => selbes Problem, nur 
jetzt nicht völlig zufällige Speicherbereiche, sondern welche in deinem 
Buffer.

Hast du einen Ringbuffer oder Ähnliches bei dem die Daten nicht immer 
bei 0 beginnen geht das sowieso nicht mehr.

: Bearbeitet durch User
von Pandur S. (jetztnicht)


Lesenswert?

Ganz sicher nicht mit malloc() oder sonstige dynamische Dinger. Mach 
feste statische Buffer mit maximaler Groesse, sodass sie Meldung sicher 
reinpasst.

von A. S. (Gast)


Lesenswert?

Holger K. schrieb:
> Dies erschwert dann aber die crc8 kalkulation etwas.

Nein.

Beim Senden kommt sie ans Ende, beim Empfang ist sie implizit (hat am 
Ende einen festen wert)

Eine CRC wird nicht "verglichen"

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.