I have some trouble implementing a CRC16 for can message, I followed the instructions given by this website https://barrgroup.com/embedded-systems/how-to/crc-calculation-c-code and http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html#ch5, plus other implention I have seen in here ( for example Function to Calculate a CRC16 Checksum).
I don't understand how it is processed.
My message here is in form of bytes, for example char message[4] = {0x12, 0x34, 0x56, 0x78}
. When I go through the first loop I just take the first byte, shift it by 8 and calculate the remainder
with a POLYNOME
of 16 bits
.
That means we have 0x1200
and we go through the second loop with it, which mean I do a XOR
with the POLYNOME
that I store in the remainder
but I don't quite understand why this works, especially when I look at this code, the 2nd
, 3rd
and 4th
bytes
of my message which should get XORed
by the 8 first bits
of the POLYNOME
at some points aren't going through it at all.
According to the wikipedia explanation https://en.wikipedia.org/wiki/Cyclic_redundancy_check the polynome goes through the whole message at once and not byte by byte.
I don't know how that translates to doing the CRC of 0x12345678
byte by byte.
uint16_t Compute_CRC16_Simple(char* message, int nbOfBytes)
{
uint16_t POLYNOME = 0xC599;
uint16_t remainder = 0;
for (int byte = 0;byte < nbOfBytes; byte++)
{
remainder ^= (message[byte] << 8);
for (int i = 0; i < 8; i++)
{
if (remainder & 0x8000)
{
remainder = (remainder << 1) ^ POLYNOME ;
}
else
{
remainder <<= 1;
}
}
}
return remainder;
}
I don't understand how it is processed.
Maybe it will help to describe the bit by bit operations for 8 bits of data:
crc[bit15] ^= data[bit7]
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
crc[bit15] ^= data[bit6]
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
...
crc[bit15] ^= data[bit0]
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
Note that the if statement only depends on the bit value in crc[bit15], so the fixed part of the XOR with data could be done in one step:
crc[bit15 .. bit8] ^= data[bit7 .. bit0]
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
...
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
The cycling of the CRC 8 times using those if ... then (shift + xor poly) else (just shift) could be precomputed for all 256 possible values in crc[bit15 .. bit8], and stored in a table for table lookup to cycle the CRC 8 times.