Frage

Ich bin versucht, die Mitglieder einer Struktur, die eine Mischung von ints, Chars und Arrays von Zeichen in einen Byte-Array zu kopieren, um eine serielle Leitung zu senden. Bisher habe ich

struct msg_on_send
{
    char descriptor_msg[5];
    int  address;
    char space;
    char cmdmsg[5];
    char CR;
    char LF;
};

void switch_output_on()
{
    int member;
    struct msg_on_send SendMsg_on[sizeof member] =
     {

    };
    unsigned char buffer [ sizeof SendMsg_on[0] ];
    showbytes(buffer, serialize(buffer, SendMsg_on));
}

/*************************************************************************** 
*   Function:   ArrayBuild                                                 *
*   Purpose:    Uses memcopy to transfer the struct members sequentially   *
*               into an array of char                                      *
*   Arguments:                                                             *
*   Returns:    size_t i = a count of the number of bytes in the array     *
***************************************************************************/    

size_t ArrayBuild(unsigned char *dst, const struct msg_on_send *object)
{
    size_t i = 0;

    memcpy(&dst[i], &object->descriptor_msg, sizeof object->descriptor_msg);
    i += sizeof object->descriptor_msg;

    memcpy(&dst[i], &object->address, sizeof object->address);
    i += sizeof object->address;

    memcpy(&dst[i], &object->space, sizeof object->space);
    i += sizeof object->space;

    memcpy(&dst[i], &object->cmdmsg, sizeof object->cmdmsg);
    i += sizeof object->cmdmsg;

    memcpy(&dst[i], &object->CR, sizeof object->CR);
    i += sizeof object->CR;

    memcpy(&dst[i], &object->LF, sizeof object->LF);
    i += sizeof object->LF;

    return i;
}

/*********************************************************************** 
*   Function:   USARTWrite                                             *
*   Purpose:    Writes the array data to the USART data register       *
*   Arguments:  void *object = struct member                           *
*               size_t size =  size of array remaining                 *
*   Returns:    None                                                   *
***********************************************************************/

void USARTWrite(const void *object, size_t size)        
{
    const unsigned char *byte;
    for ( byte = object; size--; ++byte )
    {
        printf("%02X", *byte);
    }
    putchar('\n');
}

Als ich diesen Code erhalten, ich verstehe nicht ganz, wie es funktioniert. Ich kann sehen, dass das Memcpy jedes Element der Struktur nimmt und macht es zu einem seriellen durch das ‚i‘ Variable indiziert Strom, aber ich weiß nicht, wie die USARTWrite Funktion diese in einen String paketiert, oder wie das Array zu laden mit meine struct Initialisierung.

Leider Dieser Beitrag ist ein bisschen lang, aber ich beginne gerade diese Programmierung Lerche, und versuche, meinen Kopf, um dieses Konzept zu erhalten.

Danke Dave

EDIT:

wow, viele gute Antworten schnell -. Danke Jungs

Slaz: Das scheint mir logisch, ich hatte nicht wirklich darüber nachgedacht, diesen Ansatz, wie ich wirklich nicht meinen Kopf noch um Zeiger bekam, aber ich fange an zu sehen, dass sie ein wesentlicher Bestandteil von C sind, so dass ich ordnungsgemäß wird einen Blick.

  • Diese Codezeile sendet die Daten an meine UART, was würde ich das Array ersetzen mit dem Nachrichteninhalt enthalten? Es scheint, als ob ich einen logischen Schritt bin hier fehlt, wo ich eine Variable haben mir zu sagen, wo meine Struktur beginnt und wie groß es ist, aber kein Array senden

    USART_SendData(USART1, message_on_contents[array_count]);
    

Harper Shelby: Vielen Dank für diese Beschreibung, es es viel klarer in meinem Kopf macht

.

rgds

Dave

War es hilfreich?

Lösung

Sehen Sie Ihren Kommentar

Sorry, ich habe nicht nur jetzt, bis. Der folgende Code kompiliert unter Linux ganz gut, so dass ich hoffe, dass es für Sie arbeitet.
printf () in Hex drucken, werden Sie für jedes Byte 2 Zeichen erhalten.

#include <stdio.h>

struct msg_on_send
{
char descriptor_msg[5];
int  address;
char space;
char cmdmsg[5];
char CR; 
char LF; 
};

void USARTWrite(const void *object, size_t size)    
{
    const unsigned char *byte;
      for ( byte = object; size--; ++byte )                                     
      {   
          printf("%02X", *byte);
      }   
      putchar('\n');
}

int main (int argc, char**argv)
{
    struct msg_on_send myMsg;
    unsigned char* ptr= (unsigned char*)&myMsg;

    USARTWrite(ptr, sizeof(myMsg));

    return 0;
}

Ich hoffe, das hilft.

~
~

Andere Tipps

Sie haben nicht wirklich die Struktur in ein Array von Bytes zu kopieren. Man könnte dies gegebenenfalls tun:

struct msg_on_send myMessage;

// code to set myMessage to whatever values...

// get a byte pointer that points to the beginning of the struct    
uint8_t *bytePtr = (uint8_t*)&myMessage;

// pass that into the write function, and it will write the amount of bytes passed in
USARTWrite(bytePtr, sizeof(myMessage));

Die Macht des Zeigers! :)

Wenn ich eine Struktur als ein Array von Bytes behandeln möchte ich eine Vereinigung der Regel verwenden, um kombinierte die Struktur mit einem Byte-Array. Zum Beispiel:

typedef union
{
    struct
    { 
        char descriptor_msg[5]; 
        int  address; 
        char space; 
        char cmdmsg[5]; 
        char CR; 
        char LF; 
    };
    BYTE bytes[];
} msg_on_send;

hier Ihre struct von Bytes nur Array ist, es enthält keine Hinweise, die davon hinweisen.

Mitglied zu Mitglied Kopie wird höchstwahrscheinlich durchgeführt mit Ausrichtung gerecht zu werden, wie (char*) &address wahrscheinlich größer sein wird als ((char*) &descriptor_msg) + 5.

USARTWrite sendet HEX Codes des Bytes Ihrer Struktur stdout, sondern verwirft Ausrichtung. Das Kompilieren dieses Codes mit unterschiedlichen Ausrichtung Strategien zu verschiedenen Ausgängen führen.

Schliessen Sie Ihre Strukturdeklaration in #pragma pack(push, n) und #pragma pack(pop) Ausrichtung zu zwingen, und kopieren Sie einfach Ihre Struktur Byte-to-Byte.

Es ist ziemlich einfach: 1. ArrayBuild nimmt einen Zeiger auf eine msg_on_send Struktur und für jedes Mitglied in dort verwendet Memcpy das Bytes in ein char Array zu kopieren, die in etwa so übergeben wurde -

char byteArray[17]; // This assumes 4-byte ints
                    // be careful though, the length *must* be long enough, or 
                    // Bad Things will happen
size_t msgSize; // Holds the size of the message built by ArrayBuild,
                // passed to USARTWrite
struct msg_on_send myMessage;
// Code to fill up myMessage appropriately

msgSize = ArrayBuild(byteArray, &myMessage); // need the & to pass a pointer as required

USARTWrite(myMessage, msgSize);

USARTWrite ist nur ein char-Array und eine Größe gegeben - es packt jedes Zeichen wiederum und druckt sie auf dem Bildschirm als Hex-Wert mit printf ()

.

Die ‚Magie‘ ist in der ArrayBuild - Memcpy hat eine wörtliche Kopie von Bytes von der Quelle zum Ziel, ohne Übersetzung. Unter der Annahme, 4-Byte-Ints, das Array von der Funktion aufgebaut wird, wie so aussehen:

                     1 1 1 1 1 1 1 
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
|   A     |   B   |C|    D    |E|F|

A = descriptor_msg (char[5])
B = address (int)
C = space (char)
D = cmdmsg (char[5])
E = CR (char)
F = LF (char)

ich davon ausgehen, dass würde in der ‚realen‘ Anwendung, die printf () Anruf von einem Anruf an eine serielle Schnittstelle Schreib ersetzt werden würde.

Voll vollständiges Beispiel. Perfekt funktioniert. Getestet unter X-CODE 9 Objective-C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Person
{
    char name[20];
    int age;
};

int main()
{
    //structure variable declaratio with initialisation
    struct Person person={"Deniss Ritchie", 60};
    //declare character buffer (byte array)
    unsigned char *buffer=(char*)malloc(sizeof(person));
    int i;

    //copying....
    memcpy(buffer,(const unsigned char*)&person,sizeof(person));

    //printing..
    printf("Copied byte array is:\n");
    for(i=0;i<sizeof(person);i++)
        printf("%02X ",buffer[i]);
    printf("\n");

    //freeing memory..
    free(buffer);
    return 0;
}

Ausgabe:

Copied byte array is:
44 65 6E 69 73 73 20 52 69 74 63 68 69 65 00 00 00 00 00 00 3C 00 00 00
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top