<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Mon, 13 Jun 2011 19:27:52 +0200
From   : rick@... (Rick Murray)
Subject: Calculating CRCs

On 13/06/2011 16:32, J.G.Harston wrote:

> Argh!!! That's *exactly* the useless sort of stuff I kept finding.
>> which explains by bit, by byte, and differences in various types of CRC.
> Lots of detailed theoretical analysis of what CRCs are and the
> mathematics of how they work, but no actual real cut'n'paste usable
> code. It even starts by saying "Before writing even one line of code,
> let's first examine the mechanics of modulo-2 binary division...."
> No!!! I don't care about the theory!!! I just need the code!!!!

You *what*?!?

Did you read that page?
   "Listing 1. A naive CRC implementation in C".
   "Listing 2. A more portable but still naive CRC implementation".
   "Listing 3. Computing the CRC lookup table".
   "Listing 4. A more efficient, table-driven, CRC implementation".

I've not tried compiling them after cut'n'paste, but what I can say it 
is looks to be more complete than your example on the CRC page you've 
made (i.e. where is 'crc' defined? "int8"? does that macro to unsigned 
char or unsigned short?).

Either way, there ought to be enough to get started...


Perhaps a description of what they're doing is a good thing. Take a look 
at the complications of:
   http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/lib/crc32.c
and you'll see there are several ways to calculate a CRC.

Certainly, the CRC calculation in the Neuros UPK file creator (thingy 
that builds files for updating my PVR's firmware) uses the version with 
loads of bit shifting. I mean stuff like this:
--8<--------
  #  define DO_CRC4 crc = tab[3][(crc) & 255] ^ \
                  tab[2][(crc >> 8) & 255] ^ \
                  tab[1][(crc >> 16) & 255] ^ \
                  tab[0][(crc >> 24) & 255]
--8<--------

In the code I wrote to unpick those UPK files, I used the code I posted 
previously (due to not wanting to use GPL code) and, frankly, it is a 
HELL of a lot simpler and clearer.

In addition, I made, from the same source, versions that compile and run 
successfully on x86 Windows, x86 Ubuntu, ARM RISC OS, and the ARM based 
PVR itself.

Perhaps somebody with a better grasp of the maths could explain the GPL 
version, but it seems to me to be complicated for the sake of being 
complicated...


>> Because you were not specific enough in your search.
>>     "xmodem crc calculation code"
> Ah, yes, *now*. Try 15 years ago.

You neglected to mention 15 years ago. To be honest, the first place I'd 
have tried looking is a Unix kernel source. Try either:
   /lib/crc32.c
or:
   /libkern/crc32.c

;-)


> Yes, that's the document I finally managed to track down:
> http://mdfs.net/Docs/Comp/Comms/FTP/

Otherwise called "092792" in the version I pulled from Arcade a billion 
years ago. And, oh look, the edit history has your initials on it!


It is useful to consider some of the points made in the first document 
(the one with the lengthy description) as it discusses trade-offs 
between using a table and on-the-fly calculations.

To quote a pertinent section:
--8<--------
As you can see from the code in Listing 4, a number of fundamental 
operations (left and right shifts, XORs, lookups, and so on) still must 
be performed for each byte even with this lookup table approach. So to 
see exactly what has been saved (if anything) I compiled both crcSlow() 
and crcFast() with IAR's C compiler for the PIC family of eight-bit RISC 
processors. 1 I figured that compiling for such a low-end processor 
would give us a good worst-case comparison for the numbers of 
instructions to do these different types of CRC computations. The 
results of this experiment were as follows:

     * crcSlow(): 185 instructions per byte of message data
     * crcFast(): 36 instructions per byte of message data

So, at least on one processor family, switching to the lookup table 
approach results in a more than five-fold performance improvement. 
That's a pretty substantial gain considering that both implementations 
were written in C. A bit more could probably be done to improve the 
execution speed of this algorithm if an engineer with a good 
understanding of the target processor were assigned to hand-code or tune 
the assembly code. My somewhat-educated guess is that another two-fold 
performance improvement might be possible. Actually achieving that is, 
as they say in textbooks, left as an exercise for the curious reader.
--8<--------

This is why I say it would be best to calculate on-the-fly on a BBC 
micro (can you afford the space to store the lookup table?), while on 
more capable machines (B+, Master, SWRAM expanded) would benefit from 
the use of a lookup table to speed things up.


Best wishes,

Rick.

-- 
Rick Murray, eeePC901 & ADSL WiFI'd into it, all ETLAs!
BBC B: DNFS, 2 x 5.25" floppies, EPROM prog, Acorn TTX
E01S FileStore, A3000/A5000/RiscPC/various PCs/blahblah...
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>