Forum: Compiler & IDEs Wert aus Array an eine Union übergeben


von Rumburak (Gast)


Lesenswert?

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

von Dirk B. (dirkb2)


Lesenswert?

Was ist receivedDataBuffer und wie ist es dort definiert, wo du das 
memcpy benutzt.

von Rumburak (Gast)


Lesenswert?

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;
}

von Nop (Gast)


Lesenswert?

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.

von Rumburak (Gast)


Lesenswert?

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.

von ms (Gast)


Lesenswert?

Hallo,

müsste auch so gehen
1
t_DATA_PACKET *OUTPacket = (t_DATA_PACKET *) receivedDataBuffer;
2
switch(OUTPacket->CMD_HEADER.CMD)

ms

von Rumburak (Gast)


Lesenswert?

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

von Dirk B. (dirkb2)


Lesenswert?

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.

von Dirk B. (dirkb2)


Lesenswert?

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

von ms (Gast)


Lesenswert?

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

von ms (Gast)


Lesenswert?

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

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.