I'm doing some data transmission from a dsPIC to a PC and I'm doing an 8-bit CRC to every block of 512 bytes to make sure there are no errors. With my CRC code enabled I get about 33KB/s, without it I get 67KB/s.

What are some alternative error detection algorithms to check out that would be faster?

How is the CRC itself implemented? Bitwise? Then switch to a table-based method. Bytewise? Consider the space, complexity, and time tradeoff involved in increasing the table size to, say, 16 bits (which would operate on two bytes at once, but would take 64KB of table storage).
–
Aidan CullyJul 26 '11 at 21:56

I only have 16KB on RAM and 128KB of ROM, so a 64KB table isn't an option.
–
FigBugJul 26 '11 at 21:58

1

So you're using a 256-byte table? or bitwise CRC? If you're doing bitwise, bytewise (with a 256-byte table) would be 8 times faster.
–
Aidan CullyJul 26 '11 at 22:01

67kb/s to 33kb/s? I'm not sure what your other processing involves, but that sounds like quite a bit of overhead, even for a PIC. Maybe there are some other problems impeding your performance?
–
Rei MiyasakaJul 26 '11 at 23:13

7 Answers
7

While there may be faster options than CRC, if you use them then you are likely to end up sacrificing some degree of error detection capability. An alternative may be to use CRC code optimised to your application instead.

One option to help with this is pycrc which is a tool (written in python1) which can generate C source code for dozens of combinations of crc model and algorithm. This allows you to optimise speed and size for your own application by selecting and benchmarking different combinations. 1: Requires Python 2.6 or later.

It supports the crc-8model, but also supports crc-5, crc-16 and crc-32 amongst others. As for algorithms, it supports bit-by-bit, bit-by-bit-fast and table-driven.

Crikey! That is pretty sex. Upvote just for the awesome, also, bookmarked!
–
Paul NathanJul 27 '11 at 15:54

I don't believe most people writing things for the PIC are using C, but this might work if so.
–
Billy ONealJul 27 '11 at 16:47

3

@Billy - Really? I don't think I've come across anyone developing for PIC commercially who wasn't using C. I certainly don't have the patience for assembler these days and well structured C can end up pretty compact.
–
Mark BoothJul 27 '11 at 17:12

I looked into this a while ago. I believe that summing instead of xor actually works a little better. (normally, sum everything, and then transmit the 2's complement of the sum as the checksum. On the receiver, sum everything including that received checksum. The result is 0 if its all good, and non-0 otherwise.)
–
quickly_nowJul 27 '11 at 1:10

@quickly: I don't think there's a significant difference between those two -- neither method provides all that good an assurance that things have not been corrupted. If add is faster on the target architecture by all means use that instead.
–
Billy ONealJul 27 '11 at 1:20

5

I remembered: The major difference between ADD and XOR is that there is less detectability of multiple bit errors. In the case of a stream of bytes, errors in the same bit position are cancelled out using XOR. When using ADD, the propagation of bits up through a checksum byte means that this case is more detectable. (However, multiple bit errors in different bits spread through the stream of bytes is likely to be less detectable - depending on the circumstances at the time). Any checksum arrangement like this is TERRIBLE for multiple-bit errors, so its a fairly minor argument.
–
quickly_nowJul 27 '11 at 6:52

The Adler checksum should be sufficient for checking for transmission distortions. It's used by the Zlib compression library, and was adopted by the Java 3D Mobile Graphics Standard to provide a fast but effective data integrity check.

An Adler-32 checksum is obtained by calculating two 16-bit checksums A and B and concatenating their bits into a 32-bit integer. A is the sum of all bytes in the string plus one, and B is the sum of the individual values of A from each step.

At the beginning of an Adler-32 run, A is initialized to 1, B to 0. The sums are done modulo 65521 (the largest prime number smaller than 216). The bytes are stored in network order (big endian), B occupying the two most significant bytes.

If computation cost is very constrained

The Fletcher checksum has lower computational cost than the Adler checksum
and, contrary to popular belief, is also more effective in most situations.

and

There is generally no reason to continue the common practice of using an XOR checksum in new designs, because it has the same software computational cost as an addition-based checksum but is only about half as effective at detecting errors.