I'm trying to understand (and subsequently implement) the crc16 verification employed by the clean flight quadrocopter firmware for the srxl package verification.
SRXL is a simple Serial Protocol for transmitting servo values via a single serial line.
the package structure is like this:
the crc16 is verified by the following function:
//srxlFrameLength is the package length
//srxlFrame is the received package buffer
uint16_t crc_calc = 0;
for (i = 0; i < srxlFrameLength; i++) {
crc_calc = crc16_CCITT(crc_calc, srxlFrame[i]);
}
if(crcCalc == 0){ //package is valid }
I don't understand how this works. If I were to implement this, I would calculate the crc iterativly for all bytes of the package until I reach the saved crc and then compare with the saved crc. why does this implementation work aswell?
I'd also like to implement a package generator code for the sender side. Would it be possible to implement the crc generation like this:
uint16_t crc_calc = 0;
for(int i = 0; i < packetLength; ++i){
crc_calc = crc16_CCITT(crc_calc, packet[i]);
}
//concat calculated crc16 to packet here.
Thanks in advance,
malte
If a CRC is stored properly at the end of a message, it has the property that the CRC of the message and the concatenated CRC is a constant, assuming no errors. Depending on the definition of the CRC, that constant can be zero.
The reason is that a CRC is essentially the remainder of a polynomial division of the message times xn, where n is the CRC length in bits. So when you add the CRC to the message, you are replacing those last n zeros with the remainder, resulting in the division of the whole thing having no remainder. (Note that the negative of a binary polynomial is that polynomial, since the exclusive-or of something with itself is zero.)
Yes, if you like you can instead compute the CRC on just the message, and then compare the result to the CRC appended to the message.