I'm writing an embedded application on an ARM7 processor and I need some form of checksum for data that I'm sending over a serial link as well for data that I'm storing in the flash. I was wondering which of the two CRCs would be better suited for the purpose. The main trade-off are code speed versus robustness. Should I consider another CRC? Do you have a link to an efficient implementation for ARM?
views:
743answers:
5Take the best checksum you can afford in the situation. Flashing might not be done often, so the flash-checksum can be more sophisticated than the one for the serial communication.
Additional checksums I have in mind:
- CRC32
- MD5
- SHA1
but this depends entirely on the application you are doing and the harm that can be done if you don't detect an error.
Take a look here for more input: http://en.wikipedia.org/wiki/List_of_checksum_algorithms
CRC32 is relatively cheap and quick to implement. There's a reputable and efficient implementation in the PNG sample code on W3C's website (cost=1Kbyte RAM for table & it can be generated easily w/o needing EEPROM resources). You can tradeoff table memory size for calculation time if you look out there for other CRC implementations.
Flash data is likely something you don't want to be corrupted, so crc is good. The other part is a serial protocol. Given the slow speed of serial link, you should go with a crc. ARM7 chip can handle ethernet checksuming at speed much higher than the speed of a serial link, so code speed should not be a problem, and you will get a huge increase in robustness.
RFC1071 is a simple 16-bit sum of pairs of bytes. As such, it's possible that two errors could "cancel out", and still give a "pass" checksum. E.g. a bit error flips a bit from 1 to 0. Then another bit error 16 bits later flips a bit from 0 to 1. RFC1071 will not detect this. But the same double-bit-flip error, if being checked with a CRC, would be detected.
This sort of double-bit-flip error is possible in a serial transmission. (It is much more likely on a parallel cable especially if one wire is "noisy" but who uses parallel these days?) It's also possible in a Flash chip, especially if the PCB has a bad solder joint between micro and Flash chip. Overall, a CRC is statistically more robust at detecting errors because a single bit change in the input affects multiple bits in the CRC shift register.
In practice the other thing that's likely, that you want to detect, is an incomplete Flash upload, so a large chunk of the code is simply missing. For that, statistically a checksum is probably fine but I've always favoured a CRC in projects I've worked on. With a table-based CRC algorithm, we've been able to get the calculation speeds required.
For things like flash memory or (especially) OTP, it's often good to have both something like a CRC which will do a good job of catching random combinations of errors, and a one's-complement checksum which is long enough not to overflow. The latter will have the advantage that any combination of errors which includes only erroneously-set bits or includes only erroneously-cleared bits will be detected.