I have a structure which contains memory for an EEPROM:
#pragma pack(push,1)
struct EEPROM_Memory
{
char Device_ID[8];
uint8_t Version_No;
otherRandomVariables...
};
#pragma pack(pop)
I then create an instance, populate the struct and calculate it's CRC using:
CRC32::calculate(reinterpret_cast<uint8_t*>(&(memory)), sizeof(EEPROM_Memory));
I have been going crazy trying to figure out why the CRC check returns different values.
My best guess is pragma pack
is not working therefore there is still some padding. This padding is volatile thus resulting in different CRC values.
What would be a nice solution (i.e not manually checking each value in the struct for their CRC)?
Any suggestions much appreciated!
P.S. I have looked at this question but sadly it does not give many suggestions on what to do. Surely this is a common problem!
P.P.S I am using an ESP32 microcontroller, unsure which compiler. The CRC library I am using is CRC32 by Christopher Baker.
CodePudding user response:
Pretty sure the pack
is working as it should and you are using it wrong.
Note that pack is not recursive. So if your any of your otherRandomVariables is a struct then that struct may contain padding.
What you should do is static_assert
the size of the struct. Then you know if it has the expected size or some padding. If it contains any structs assert the size of those structs first.
CodePudding user response:
I have a suspicion that memory
is a pointer, and you're taking its address, thereby calculating the checksum of the pointer and following bytes rather than the data it points to.
The reinterpret_cast
is wholly unnecessary, the calculate
function you are using is templated. And like all the cast keywords, reinterpret_cast
cripples compiler type-checking and disables a whole lot of useful warnings and errors, so you really should consider it a last resort.
Try this:
auto result = CRC32::calculate(memory, 1);
If and only if you have tried that and it fails to compile because memory
is not actually a pointer, then
auto result = CRC32::calculate(&memory, 1);