Wert aus Array an eine Union übergeben

Gast #4819617
Hallo Leute,

ich habe dieses Problem vor einiger Zeit mit der Funktion
memcpy((BYTE*)&OUTPacket,&receivedDataBuffer,sizeof(receivedDataBuffer))
lösen können. Diese Funktion scheint mir während der Laufzeit im µC 
Probleme zu machen. Vielleicht gibt es eine andere sichere oder 
einfachere Methode? Bei mir ist eine struct und union so definiert 
worden.

typedef     struct CMD_HEADER
{
    BYTE CMD;  // Kennung des Kommandos
    BYTE LEN;  // Gesamtlänge
    BYTE STA;  // Rückmeldeparameter
}t_CMD_HEADER;

typedef union DATA_PACKET
{
    t_CMD_HEADER      CMD_HEADER;
    t_CMD_ERROR        CMD_ERROR;
    t_CMD_VERSION_EX            CMD_VERSION_EX;
    t_CMD_FRG        CMD_FRG;
    t_CMD_DREHSIG      CMD_DREHSIG;
} t_DATA_PACKET;

t_DATA_PACKET OUTPacket;

Eine Statemachine soll später im Programm auf folgendes Element der 
Union zugreifen.

switch(OUTPacket.CMD_HEADER.CMD)

im Moment existiert ein Array mit den diese Statemachine auf gleicher 
weise arbeitet.

switch(receivedDataBuffer[0])

wie könnte man den Wert des Arrays "receivedDataBuffer[0]" in das 
Element der Union "OUTPacket.CMD_HEADER.CMD" schieben? Vielleicht mit 
Hilfe von Zeigern?

Mit freundlichen Grüßen
Gast
Hallo,

das Array ist so definiert.

/* Receive data buffer */
uint8_t receivedDataBuffer[APP_READ_BUFFER_SIZE] 
APP_MAKE_BUFFER_DMA_READY;

#define APP_READ_BUFFER_SIZE 512

/* Fulfill USB DMA transfer criteria */
#define APP_MAKE_BUFFER_DMA_READY  __attribute__((coherent)) 
__attribute__((aligned(4)))

Dem Array werden Daten (Kommandos) einer USB-Schnittstelle zugeweisen 
die dann über eine Statemachine verabeitet werden.

switch(receivedDataBuffer[0])
{
case 0x80:
        /* This is the toggle LED command */
       BSP_LEDToggle( APP_USB_LED_1 );
break;

case 0x81:
        /* This is the toggle LED command */
       BSP_LEDToggle( APP_USB_LED_2 );
break;

default:
break;
}
Gast
Rumburak schrieb:
> memcpy((BYTE*)&OUTPacket,&receivedDataBuffer,sizeof(receivedDataBuffer))

Du kopierst 512 Bytes in einen wenige Bytes großen Buffer? Ja, das macht 
wohl Probleme. Es sei denn, eines der übrigen Elemente der Union ist 
mindestens 512 Bytes groß.

Rumburak schrieb:
> wie könnte man den Wert des Arrays "receivedDataBuffer[0]" in das
> Element der Union "OUTPacket.CMD_HEADER.CMD" schieben?
1
Outpacket.CMD_HEADER.CMD = receivedDataBuffer[0];

Das schiebt das erste Byte rüber.
Gast
Nop schrieb:
> Du kopierst 512 Bytes in einen wenige Bytes großen Buffer? Ja, das macht
> wohl Probleme. Es sei denn, eines der übrigen Elemente der Union ist
> mindestens 512 Bytes groß.

Oh ja, Sie haben Recht. CMD ist nur ein BYTE groß. Vielen Dank.
Gast
Hallo ms,

ms schrieb:
> t_DATA_PACKET *OUTPacket = (t_DATA_PACKET *) receivedDataBuffer;

ich hab deinen Vorschlag ausprobiert und es funktioniert.
Danke nochmal dafür.
Was ich mich noch frage ist, woher kennt der Kompiler den Bezug bei der 
Deklaration
t_DATA_PACKET *OUTPacket = (t_DATA_PACKET *) receivedDataBuffer;

dass das nullte Element des Arrays receivedDataBuffer[0] genau dem 
Element CMD der Struktur bzw. der Union zugeweisen wird?

Mit freundlichen Grüßen
ms schrieb:
> Hallo,
>
> müsste auch so gehen
>
>
1
> t_DATA_PACKET *OUTPacket = (t_DATA_PACKET *) receivedDataBuffer;
2
> switch(OUTPacket->CMD_HEADER.CMD)
3
>
>
> ms

Das muss aber nicht klappen.
Wenn das Alignement von receivedDataBuffer nicht zu dem von OUTPacket 
passt, kann es krachen.
Rumburak schrieb:
> Hallo ms,
>
> ms schrieb:
>> t_DATA_PACKET *OUTPacket = (t_DATA_PACKET *) receivedDataBuffer;
>
> ich hab deinen Vorschlag ausprobiert und es funktioniert.
> Danke nochmal dafür.
> Was ich mich noch frage ist, woher kennt der Kompiler den Bezug bei der
> Deklaration
> t_DATA_PACKET *OUTPacket = (t_DATA_PACKET *) receivedDataBuffer;
>
> dass das nullte Element des Arrays receivedDataBuffer[0] genau dem
> Element CMD der Struktur bzw. der Union zugeweisen wird?
>
> Mit freundlichen Grüßen

receivedDataBuffer ist die Anfangsadresse vom Array. Also 
&receivedDataBuffer[0]

Du tust also so, als ob receivedDataBuffer die Strucktur wäre.
Und da ist an erster Stelle CMD
Gast
Hallo Dirk,

Dirk B. schrieb:
> Wenn das Alignement von receivedDataBuffer nicht zu dem von OUTPacket
> passt, kann es krachen.

Ich sehe da keine Probleme. In der Union sind ja noch mehr struct eine 
wird ja zum Buffer passen. Es ist ja nur ein Zeiger auf. Sicher sollt 
man wissen zu welchen Zeitpunkt man das verwendet.

ms
Gast
Hallo Rumbrurak,

Rumburak schrieb:
> dass das nullte Element des Arrays receivedDataBuffer[0] genau dem
> Element CMD der Struktur bzw. der Union zugeweisen wird?

man könnte es auch so schreiben.
1
 t_DATA_PACKET *OUTPacket = (t_DATA_PACKET *) &receivedDataBuffer[0];

Zeiger sind was tolles.

ms

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.