I'll start with a code sample
typedef struct { uint16_t len; uint16_t crc; uint8_t data[1]; } __attribute__ ((packed)) packet_t; typedef struct { uint64_t timestamp; uint8_t val1, val2, val3, val4; } __attribute__ ((packed)) msg_t; uint8_t buffer[64]; packet_t *packet = buffer; msg_t *msg = buffer + sizeof(packet_t) - sizeof(uint8_t); msg->timestamp = 0xAA;
We use packed structs for communication. The following code crashes on msg->timestamp line. It calls __aeabi_write8. Which looks like this
0x00025B80 B570 PUSH {r4-r6,lr} 0x00025B82 4604 MOV r4,r0 0x00025B84 460D MOV r5,r1 0x00025B86 2307 MOVS r3,#0x07 0x00025B88 7010 STRB r0,[r2,#0x00] 0x00025B8A 060E LSLS r6,r1,#24 0x00025B8C 0A00 LSRS r0,r0,#8 0x00025B8E 4330 ORRS r0,r0,r6 0x00025B90 0A09 LSRS r1,r1,#8 0x00025B92 1C52 ADDS r2,r2,#1 0x00025B94 1E5B SUBS r3,r3,#1 0x00025B96 D5F7 BPL 0x00025B88 0x00025B98 4620 MOV r0,r4 0x00025B9A 4629 MOV r1,r5 0x00025B9C BD70 POP {r4-r6,pc}
When the POP happens at the end, PC register is set to some odd location (0x14), then it starts executing some random code and crashes. I also experienced similar problem with memcpy/memset functions. Any help is appreciated.
We are using 32-bit ARM Cortex M0 CPU (This is nRF514xx series chip) and Armcc v5.04.0.49.
So don't do that, then!
The whole reason for packing structures is precisely to get the accesses aligned!
Instead, have proper functions to do the serialising and de-serialising...
Am I reading that right? I thought the whole reason for packing structures was to get rid of gaps that might otherwise be present to get the accesses aligned.
There seems to be a loose nut on my keyboard!
That should, of course, say "padding" - not "packing"