1

I'm working with a microprocessor (PIC32MX250) and I created a struct that stores various members:

typedef struct {
    char element1[20];
    unsigned char element2;
    unsigned char element3[2];
    unsigned char element4[2];
    unsigned char element5[2];
    unsigned char element6[2];
    unsigned char element7;
    unsigned char element8;
    unsigned char element9[2];
    unsigned char element10;
    unsigned char element11[2];
    unsigned char element12;
    char element13[7];
    unsigned char service_day;
    unsigned char service_month;
    unsigned char service_year;
    unsigned char service_hour;
    unsigned char service_minute;
    unsigned char service_status[2];
} usb_service_t;

Then I call a function that reads the elements inside a flash memory and transfers them to the struct, like this:

usb_service_t g_service_container;
void read_service (unsigned int memory_address)
{
    byte loop_idx = 0;
    byte buf[64] = { 0 };

    (void) Flash_Read(memory_address, buf, 64, 0);

    g_service_container.service_day= buf[0]; // <<< PROBLEM HERE

    g_service_container.service_month= buf[1];
    g_service_container.service_year= buf[2];
    g_service_container.service_hour= buf[3];
    g_service_container.service_minute= buf[4];
    for (loop_idx = 0; loop_idx < 20; loop_idx++)
    {
        g_service_container.targa[loop_idx] = buf[5 + loop_idx];   
        if (g_service_container.element1[loop_idx] == 0x8e)
        {
            g_service_container.element1[loop_idx] = 'A';
        }
        else if (g_service_container.element1[loop_idx] == 0x99)
        {
            g_service_container.element1[loop_idx] = 'O';
        }
        else if (g_service_container.element1[loop_idx] == 0x9a)
        {
            g_service_container.element1[loop_idx] = 'U';
        }
    }
    g_service_container.element1[20] = '\0';
    g_service_container.element2= buf[25];
    for (loop_idx = 0; loop_idx < 2; loop_idx++)
    {
        g_service_container.element3[loop_idx] = buf[26 + 1 - loop_idx];
        g_service_container.element4[loop_idx] = buf[28 + 1 - loop_idx];
        g_service_container.element5[loop_idx] =
                                                    buf[30 + 1 - loop_idx];
        g_service_container.element6[loop_idx] = buf[32 + 1 - loop_idx];
        g_service_container.element9[loop_idx] = buf[36 + 1 - loop_idx];
        g_service_container.service_status[loop_idx] = buf[38 + 1 - loop_idx];
        g_service_container.element11[loop_idx] =
                                                    buf[41 + 1 - loop_idx];
    }
    g_service_container.element7= buf[34];
    g_service_container.element8= buf[35];
    g_service_container.element10= buf[40];
    g_service_container.element12= buf[43];
    for (loop_idx = 0; loop_idx < 7; loop_idx++)
    {
        g_service_container.element13[loop_idx] = buf[44 + loop_idx];
    }
    g_service_container.element13[7] = '\0';

}

When I assign the elements from the buffer to the member of the struct, I can see with the MPLAB debugger, that g_service_container.service_day is always 0, in particular buf[0] is not zero (the others read the buffer value instead).

I tried to force the value of the member writing a constant value and it accepts it.

However writing the struct in a different way, as shown below, it works:

typedef struct {
    char element1[20];
    unsigned char element2;
    unsigned char element3[2];
    unsigned char element4[2];
    unsigned char element5[2];
    unsigned char element6[2];
    unsigned char element7;
    unsigned char element8;
    unsigned char element9[2];
    unsigned char element10;
    unsigned char element11[2];
    unsigned char element12;
    char element13[7];
    unsigned char service_status[2];  // NOW I CHANGE THE ORDER OF THIS MEMBER
    unsigned char service_day;
    unsigned char service_month;
    unsigned char service_year;
    unsigned char service_hour;
    unsigned char service_minute;
} usb_service_t;
Filippo
  • 126
  • 1
  • 12
  • 2
    Please provide a [mre] with emphasis on _complete_. – the busybee Feb 23 '22 at 14:17
  • 6
    Most likely, you are successfully setting the `service_day` member, and then later overwriting it by overrunning the bounds of an earlier member, maybe `element13`. But you haven't given us enough information to confirm that. This sort of thing is why we ask for a [mre]. – John Bollinger Feb 23 '22 at 14:22
  • I've just added the complete code of my function. I hope it will be more understandable. – Filippo Feb 23 '22 at 14:32
  • but how do you **write** the structure to the flash ? – Guillaume Petitjean Feb 23 '22 at 14:35
  • it's not very clear, it looks like you are not reading the whole struct from the flash but start reading it in the middle. – Guillaume Petitjean Feb 23 '22 at 14:35
  • 1
    mmm I think I relied too much on the debugger. In the last line I'm writing on a memory field of the struct that overlaps the following member!! The fact I didn't notice it is because when I stopped the debugger on the firsts lines it was already zero! – Filippo Feb 23 '22 at 14:38

1 Answers1

0

Sounds like the compiler is padding the struct. See this post on how this works: https://stackoverflow.com/a/40642888/9766462