C Structure Question

Hi All,

Quick brainstorm question.

I have an array sent by serial port to an embedded chip.
the data is passed on reception to an ARRAY, in my case a ‘char’ ARRAY.
the format is fixed, uses only ASCII data, its a simple message protocol.

char start (‘v’)
char address (‘1’)
char serial number (‘0’ to ‘9’)
char[2] message type (an array of 2 characters)
char[20] payload (an array of up to 20 char)

this all lives in ARRAY of 26 char in size, 25 data plus 1 for string terminator.

what I just cant get working is taking this ARRAY data and ‘pouring’ it into a STRUCTURE that is formatted exactly as shown above.

it seems to me I need some UNION to align the array and structure, but I just cant get it to work out! it should be very straight forward.

Any ideas?, Thanks!

Maybe you need a way to tell the compiler to align the data as is excluding paddings, like:

#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */

struct MyMessage // Packed
{
    char start;
    char address;
    char serialNumber;
    char message[2];
    char payload[21]; // 20 + terminator
};

#pragma pack(pop)   /* restore original alignment from stack */

assuming there is NO alignment padding you should be able to use a PTR to a structure

     struct mystruct *startStart ;
     
     startStart = struct mystruct *(&arrayoffset of start of data) 

or something like that

thanks Rick

I did not give enough info.
the C compiler is XC8 used in MPLABX by Microchip, my issue is not of alignment (I have not got to the point where anything could be misaligned)

the structure is no issue, I have the as you typed in code and can allocated data to all elements individually no issue.

but I can not take my ARRAY and make the first address of the array and the char ‘start’ have the same address and then that structure be able to reference the elements of the array (their memory location not array)

so simply:-

struct MyMessage = &array
for instance, or in xojo I would have used:-

MyMessage.StringValue(false)=data

yes, I thought that too, maybe I mucked up the syntax, too late now to try, job for tomorrow.

this should be so easy!

ptr’s :slight_smile:

yeah to use the &array the destination HAS to be a PTR to a struct not a struct itself

and after that you have to use → to access members not .

yes, I did try the too, but again its not worked out with the syntax I used, I blame the batteries in the keyboard getting low.

I know all the characters are there, but just not in the right order…

tomorrows job now, thanks

A ‘random’ order, ‘off by one’ , or ‘reversed’?

Could this be an Endianess issue?

Not if each thing is a char (byte)
It would be relevant if the bytes were being interpreted as long integere

Well, my question was in which “endianness” the bits of each byte arrive over the serial port.

Hi everyone,

thanks for the replies, but I think I have not explained the problem I wish to solve in a clear way.

my comment “just not in the right order…” was a joke reference to a Morcambe and Wise sketch with the composer André Previn, link here:-

it is so funny, even now, and my quote is referenced to this…

1 Like

there is no issue in serial port, no issue in me receiving the data, all that is not where I am having the issue.

I have an array of data, it is all ASCII data, CHAR
it is 26 char in size, it is sent from a structure and all elements are fixed in position, with the final element being of variable length.
none of this is really important.

what I want to do is take this linear memory (assume it is packed and consecutive)
and make it somehow appear in my structure :-

struct MyMessage
{
    char start;
    char address;
    char serialNumber;
    char message[2];
    char payload[21]; // 20 + terminator
};

it should be simple, but I can not make it happen.

char start needs the same address as my char array[0] and then I access the array data by reference to the structure.

I have tried union, pointers and I just do not know where the syntax is failing.

the C compiler I am using is supposed to be C99, but it is really strict in casting so I have to do a lot of this in code and it gets stupid complex for what in theory should be some simple referencing exercise.

Well, you wrote:

… but did not indicate what you exactly mean by that.

ok, to be totally clear and painfully obvious to anyone not following my jovial comments and taking the written words out of context:

“yes, I did try the too, but again its not worked out with the syntax I used, I blame the batteries in the keyboard getting low.”

in this phrase I create a reference, one that is absolutely nothing to do with the thread context, ‘keyboard’ being the reference.

“I know all the characters are there, but just not in the right order…”

2 references here, one is the context of that message (which I thought obvious, but seemingly not by some readers), the ‘keyboard’ and its ‘characters’, the ones typed, nothing to do with CHAR or the code in previous portions of the thread.

the second reference was somewhat specific, to a UK audience or an aficionado of historic UK comedic shows that is obviously lost entirely on a wider audience.

I will try to stick to actual labeled facts in the future and never imply anything!

I blame myself entirely for moving this thread off topic.

MyMessage *ptr = (MyMessage *)(&array[0]) ;
try this


#include <stdio.h>

typedef struct

{

char start;

char address;

char serialNumber;

char message[2];

char** payload[21]; // 20 + terminator

} MyMessage;

int main(int argc, const char * argv[]) {

char array[] = { 'a','b', 'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','i','v','w','x','y','z'} ;

MyMessage *ptr = (MyMessage *)(&array) ;

printf("start %c\n", ptr->start) ;
printf("address %c\n", ptr->address);
printf("serialNumber %c\n", ptr->serialNumber);
printf("message %c%c\n", ptr->message[0], ptr->message[1]) ;
printf("payload %s\n", ptr->payload) ; // 20 + terminator

return 0;

}

It would be helpful, if you told what exactly goes wrong. An example would be great.

This works, assuming that both arrays (message and payload) end with a null:

   struct MyMessage {
        char start;          // v
        char address;        // 1
        char serialNumber;   // 0
        char message[2];     // a\0
        char payload[21];    // ABCDEFGHIJKLMNOP\0
    };

    char input[26] = "v10a\0ABCDEFGHIJKLMNOP\0";

    struct MyMessage *message = input;

    printf(message->message);
    printf(message->payload);
1 Like

Hi Eli,

your understanding of what I expected to do is 100% and the code is what I thought should work, but I have tries so many variations that I can not remember them.

using the code you posted exactly produces this error in my compiler:-

g_messages_rx.c:130:23: warning: incompatible pointer types initializing ‘struct MyMessage *’ with an expression of type ‘char [26]’ [-Wincompatible-pointer-types]
struct MyMessage *message = input;

now I am going to try Norms code to see what it does.