[ECOS] Re: Bug in crc32 routine?

Andrew Lunn andrew.lunn@ascom.ch
Fri Oct 11 05:00:00 GMT 2002


I checked around and found a few more CRC calculations. In summary

1) zlib
2) jffs2
3) gdb stubs
4) cygmon
5) ks32c5000 net driver
6) Redboot - already using cyg_crc32()

cygmon and gdb stubs i've left alone. The code is not particularly
well commented.

jffs2 uses the same algorithm as cyg_crc32.

ks32c5000 wants the Ethernet FCS algorithm. 
zlib uses an algorithm which happens to be the FCS algorithm :-)

So, what i've done is left cyg_crc32 alone and added a new one,
cyg_ether_crc32. Another coincidence, is that it appears to use the
same table of coefficients as cyg_crc32. The only difference is that
it does some XORs at the beginning and the end. jffs2 and zlib need to
be able to run the CRC over multiple buffers, so i've added support
for this as well and some tests.

Redboot should not be affected in any way. I've removed the code from
zlib, jffs2 and the ks32c5000 net driver. Unfortunately, i don't have
the required hardware to test all this properly. It all compiles
cleanly. The zlib tests run correctly. Also the normal jffs2 test
passes. I hacked around with the jffs2 romfileio1 test on linux. It
correctly recognizes the filesystem, but fails some of the mkdir and
rename tests. This could be something to do with it running with a
ramfs not romfs?

What i would like is some volunteers to run the following test:

1) redboot flash CRC still work OK
2) redboot support for gzip images still works OK
3) Somebody with a Compaq Ipaq test that jffs2 still works OK
4) Somebody with a snds with a ks32c5000 test its still OK

Here is the patch. Once i get feedback on these i will commit the
patch.

        Andrew
-------------- next part --------------
Index: packages/devs/eth/arm/ks32c5000/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/arm/ks32c5000/current/ChangeLog,v
retrieving revision 1.5
diff -u -r1.5 ChangeLog
--- packages/devs/eth/arm/ks32c5000/current/ChangeLog	10 Jul 2002 15:42:41 -0000	1.5
+++ packages/devs/eth/arm/ks32c5000/current/ChangeLog	11 Oct 2002 11:32:31 -0000
@@ -1,3 +1,9 @@
+2002-10-10  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* cdl/ks32c5000_eth.cdl
+	* src/ks5000_ether.c (ks32c5000_eth_get_recv_buffer): Use the 
+	cyg_crc32 function in the CRC package.
+
 2002-07-10  Gary Thomas  <gary@chez-thomas.org>
 2002-07-10  Simon Sudler <sudlersn@iis.fhg.de>
 
Index: packages/devs/eth/arm/ks32c5000/current/cdl/ks32c5000_eth.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/arm/ks32c5000/current/cdl/ks32c5000_eth.cdl,v
retrieving revision 1.2
diff -u -r1.2 ks32c5000_eth.cdl
--- packages/devs/eth/arm/ks32c5000/current/cdl/ks32c5000_eth.cdl	23 May 2002 23:00:40 -0000	1.2
+++ packages/devs/eth/arm/ks32c5000/current/cdl/ks32c5000_eth.cdl	11 Oct 2002 11:32:31 -0000
@@ -58,6 +58,8 @@
 	active_if     CYGPKG_IO_ETH_DRIVERS
     implements    CYGHWR_NET_DRIVERS
     implements    CYGHWR_NET_DRIVER_ETH0
+    requires      (CYGPKG_CRC || (!(CYG_HAL_CPUTYPE == \"KS32C5000A\" )))
+
     include_dir   net
     description   "Ethernet driver for Samsung KS32C5000"
     compile       -library=libextras.a ks5000_ether.c
Index: packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.c,v
retrieving revision 1.5
diff -u -r1.5 ks5000_ether.c
--- packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.c	10 Jul 2002 15:42:41 -0000	1.5
+++ packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.c	11 Oct 2002 11:32:32 -0000
@@ -110,6 +110,7 @@
 
 #if defined(CYG_HAL_CPUTYPE_KS32C5000A)
 #define SoftwareCRC 1
+#include <cyg/crc/crc.h>
 #else
 #define SoftwareCRC 0
 #endif
@@ -268,9 +269,6 @@
 static BDMA_RX_ERR BDMARxErrCnt = {0,0,0,0,0};
 
 
-#if SoftwareCRC
-static U32 crc32( unsigned char *blk_adr, unsigned blk_len);
-#endif
 static void Init_TxFrameDescriptorArray(void);
 static void Init_RxFrameDescriptorArray(void);
 
@@ -572,7 +570,7 @@
       
 #if SoftwareCRC
       crclen = (RxStatusAndLength & 0xffff) - 4;
-      crc = crc32(RxBufPtr->data+2,crclen);
+      crc = cyg_ether_crc32(RxBufPtr->data+2,crclen);
       crcOK = ((U08)(crc>>0) == RxBufPtr->data[2+crclen+0] &&
                (U08)(crc>>8) == RxBufPtr->data[2+crclen+1] &&
                (U08)(crc>>16) == RxBufPtr->data[2+crclen+2] &&
@@ -1336,92 +1334,3 @@
                 "ks32c5000", 
                 ks32c5000_eth_init, 
                 &ks32c5000_sc);
-
-
-#if SoftwareCRC
-
-static U32 crctable[256] =
-{
-0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
-0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
-0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
-0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
-0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
-0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
-0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
-0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
-0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
-0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
-0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
-0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
-0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
-0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
-0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
-0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
-0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
-0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
-0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
-0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
-0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
-0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
-0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
-0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
-0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
-0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
-0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
-0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
-0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
-0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
-0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
-0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
-0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
-0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
-0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
-0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
-0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
-0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
-0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
-0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
-0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
-0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
-0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
-0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
-0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
-0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
-0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
-0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
-0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
-0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
-0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
-0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
-0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
-0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
-0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
-0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
-0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
-0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
-0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
-0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
-0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
-0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
-0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
-0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
-};
-
-
-static U32 crc32( unsigned char *blk_adr, unsigned blk_len)
-{
-  U32 crc = 0xffffffff;
-  
-  while (blk_len--)
-    crc = crctable[(crc ^ *blk_adr++) & 0xffL] ^ (crc >> 8);
-  
-  return crc ^ 0xffffffff;
-}
-
-#endif
-
-
-
-
- 
Index: packages/fs/jffs2/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/ChangeLog,v
retrieving revision 1.2
diff -u -r1.2 ChangeLog
--- packages/fs/jffs2/current/ChangeLog	23 May 2002 23:01:38 -0000	1.2
+++ packages/fs/jffs2/current/ChangeLog	11 Oct 2002 11:32:32 -0000
@@ -1,3 +1,8 @@
+2002-10-11  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/crc32.h (crc32): Use the CRC package for crc calculation
+	* tests/romfileio1.c (main): Pass the name of the device to mount
+
 2002-05-20  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/LICENCE: New file. Contains license for JFFS2, now GPL+exception.
Index: packages/fs/jffs2/current/cdl/jffs2.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/cdl/jffs2.cdl,v
retrieving revision 1.2
diff -u -r1.2 jffs2.cdl
--- packages/fs/jffs2/current/cdl/jffs2.cdl	23 May 2002 23:01:38 -0000	1.2
+++ packages/fs/jffs2/current/cdl/jffs2.cdl	11 Oct 2002 11:32:32 -0000
@@ -58,6 +58,7 @@
     requires       CYGPKG_IO_FLASH
     requires       CYGPKG_COMPRESS_ZLIB
     requires       CYGINT_ISO_MALLOC
+    requires       CYGPKG_CRC
 
     requires       CYGPKG_ISOINFRA
     requires       CYGPKG_ERROR
@@ -67,7 +68,7 @@
     requires       CYGPKG_IO_FILEIO_INODE
 
     compile        -library=libextras.a jffs2.c
-    compile        build.c scan.c malloc-ecos.c nodelist.c crc32.c nodemgmt.c readinode.c erase.c dir-ecos.c write.c gc.c read.c compr.c compr_zlib.c compr_rtime.c compr_rubin.c file-ecos.c
+    compile        build.c scan.c malloc-ecos.c nodelist.c nodemgmt.c readinode.c erase.c dir-ecos.c write.c gc.c read.c compr.c compr_zlib.c compr_rtime.c compr_rubin.c file-ecos.c
 
     cdl_option CYGPKG_FS_JFFS2_CFLAGS_ADD {
 	display "Additional compiler flags"
Index: packages/fs/jffs2/current/src/crc32.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/crc32.h,v
retrieving revision 1.2
diff -u -r1.2 crc32.h
--- packages/fs/jffs2/current/src/crc32.h	23 May 2002 23:01:38 -0000	1.2
+++ packages/fs/jffs2/current/src/crc32.h	11 Oct 2002 11:32:32 -0000
@@ -16,10 +16,7 @@
 static inline uint32_t 
 crc32(uint32_t val, const void *ss, int len)
 {
-	const unsigned char *s = ss;
-        while (--len >= 0)
-                val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8);
-        return val;
+	return cyg_crc32_accumulate(val,(void *)ss,len);
 }
 
 #endif
Index: packages/fs/jffs2/current/src/jffs2port.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/jffs2port.h,v
retrieving revision 1.1
diff -u -r1.1 jffs2port.h
--- packages/fs/jffs2/current/src/jffs2port.h	20 May 2002 22:21:29 -0000	1.1
+++ packages/fs/jffs2/current/src/jffs2port.h	11 Oct 2002 11:32:32 -0000
@@ -27,6 +27,8 @@
 
 #include <cyg/io/flash.h>
 
+#include <cyg/crc/crc.h>
+
 #include <pkgconf/fs_jffs2.h>
 
 #include "list.h"
Index: packages/fs/jffs2/current/tests/romfileio1.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/tests/romfileio1.c,v
retrieving revision 1.2
diff -u -r1.2 romfileio1.c
--- packages/fs/jffs2/current/tests/romfileio1.c	23 May 2002 23:01:39 -0000	1.2
+++ packages/fs/jffs2/current/tests/romfileio1.c	11 Oct 2002 11:32:32 -0000
@@ -58,6 +58,7 @@
 #include <cyg/kernel/ktypes.h>         // base kernel types
 #include <cyg/infra/cyg_trac.h>        // tracing macros
 #include <cyg/infra/cyg_ass.h>         // assertion macros
+#include <cyg/io/flash.h>
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -277,14 +278,15 @@
 int main( int argc, char **argv )
 {
     int err;
-    char address[16];
+    //    char address[16];
 
     CYG_TEST_INIT();
 
     // --------------------------------------------------------------
 
-    err = mount( "", "/", "jffs2" );
-
+    err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, "/", "jffs2" );
+    if ( err != ENOERR ) SHOW_RESULT( chdir, err );
+    
     diag_printf("<INFO>: JFFS2 root follows\n");
     diag_printf("<INFO>: Note that dev cannot be stat()ed\n");
     listdir( "/", true );
@@ -315,7 +317,7 @@
 
     diag_printf("<INFO>: Mount JFFS2 again onto /mnt\n");
     //sprintf( address, "%p", (void*)CYGNUM_FS_JFFS2_BASE_ADDRESS );
-    err = mount( "", "/mnt", "jffs2" );
+    err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, "/mnt", "jffs2" );
     if( err < 0 ) SHOW_RESULT( mount, err );    
 
     comparefiles( "/etc/passwd", "/mnt/etc/passwd" );
Index: packages/services/compress/zlib/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/compress/zlib/current/ChangeLog,v
retrieving revision 1.6
diff -u -r1.6 ChangeLog
--- packages/services/compress/zlib/current/ChangeLog	9 Sep 2002 17:16:30 -0000	1.6
+++ packages/services/compress/zlib/current/ChangeLog	11 Oct 2002 11:32:32 -0000
@@ -1,3 +1,11 @@
+2002-10-10  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* include/zutil.h:
+	* include/zlib.h:
+	* src/inflate.c (inflate): Use the CRC function from the CRC
+	package.
+	* src/crc32.c: Removed.
+
 2002-09-09  Mark Salter  <msalter@redhat.com>
 
 	* inflate.c (inflate): Fix CRC calculation over multiple invocations
Index: packages/services/compress/zlib/current/cdl/compress_zlib.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/compress/zlib/current/cdl/compress_zlib.cdl,v
retrieving revision 1.4
diff -u -r1.4 compress_zlib.cdl
--- packages/services/compress/zlib/current/cdl/compress_zlib.cdl	23 May 2002 23:08:37 -0000	1.4
+++ packages/services/compress/zlib/current/cdl/compress_zlib.cdl	11 Oct 2002 11:32:32 -0000
@@ -56,9 +56,10 @@
     include_dir   cyg/compress
 
     requires      CYGPKG_ISOINFRA
+    requires      CYGPKG_CRC
 
     compile       infblock.c infcodes.c inffast.c inflate.c
-    compile       inftrees.c infutil.c adler32.c crc32.c
+    compile       inftrees.c infutil.c adler32.c 
     compile       zutil.c deflate.c trees.c compress.c uncompr.c
 
     cdl_interface CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC {
Index: packages/services/compress/zlib/current/include/zlib.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/compress/zlib/current/include/zlib.h,v
retrieving revision 1.1
diff -u -r1.1 zlib.h
--- packages/services/compress/zlib/current/include/zlib.h	6 Apr 2001 17:20:41 -0000	1.1
+++ packages/services/compress/zlib/current/include/zlib.h	11 Oct 2002 11:32:32 -0000
@@ -836,9 +836,7 @@
      if (adler != original_adler) error();
 */
 
-#if 1 // __ECOS__
-ZEXTERN uLong ZEXPORT gz_crc32   OF((uLong crc, const Bytef *buf, uInt len));
-#else
+#ifndef __ECOS__
 ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
 #endif // __ECOS__
 /*
Index: packages/services/compress/zlib/current/src/inflate.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/compress/zlib/current/src/inflate.c,v
retrieving revision 1.2
diff -u -r1.2 inflate.c
--- packages/services/compress/zlib/current/src/inflate.c	9 Sep 2002 17:16:30 -0000	1.2
+++ packages/services/compress/zlib/current/src/inflate.c	11 Oct 2002 11:32:33 -0000
@@ -392,9 +392,10 @@
         r = f;
 #ifdef __ECOS__
       if (z->state->gz_mode != DONE)
-        z->state->gz_sum = gz_crc32(z->state->gz_sum,
-				    z->state->gz_start,
-				    z->next_out - z->state->gz_start);
+        z->state->gz_sum = cyg_ether_crc32_accumulate(z->state->gz_sum,
+                                                      z->state->gz_start,
+                                                      z->next_out - 
+                                                      z->state->gz_start);
 #endif
       if (r != Z_STREAM_END)
         return r;
Index: packages/services/compress/zlib/current/src/zutil.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/compress/zlib/current/src/zutil.h,v
retrieving revision 1.1
diff -u -r1.1 zutil.h
--- packages/services/compress/zlib/current/src/zutil.h	6 Apr 2001 17:20:42 -0000	1.1
+++ packages/services/compress/zlib/current/src/zutil.h	11 Oct 2002 11:32:33 -0000
@@ -15,6 +15,7 @@
 
 #ifdef __ECOS__
 #include <cyg/compress/zlib.h>
+#include <cyg/crc/crc.h>
 #else
 #include "zlib.h"
 #endif // __ECOS__
Index: packages/services/crc/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/crc/current/ChangeLog,v
retrieving revision 1.1
diff -u -r1.1 ChangeLog
--- packages/services/crc/current/ChangeLog	9 Aug 2002 10:27:03 -0000	1.1
+++ packages/services/crc/current/ChangeLog	11 Oct 2002 11:32:33 -0000
@@ -1,3 +1,16 @@
+2002-10-11  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/crc32.c (cyg_ether_crc32):
+	* src/crc32.c (cyg_ether_crc32_accumulate): New functions for Ethernet
+	  FCS style CRC calculations.
+	* src/crc32.c (cyg_crc32_accumulate): New function. Continue
+	  an previous CRC calculation into a new buffer.
+	* tests/crc_test.c: Tests for new functions.
+
+2002-10-10  Roland Ca??ebohm  <roland.cassebohm@visionsystems.de>
+
+	* src/crc32.c (cyg_crc32) Make compatible to zlibs CRC algorithm.
+
 2002-08-07  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* Created a new package from the CRC routines
Index: packages/services/crc/current/doc/crc.sgml
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/crc/current/doc/crc.sgml,v
retrieving revision 1.1
diff -u -r1.1 crc.sgml
--- packages/services/crc/current/doc/crc.sgml	9 Aug 2002 10:27:03 -0000	1.1
+++ packages/services/crc/current/doc/crc.sgml	11 Oct 2002 11:32:33 -0000
@@ -5,7 +5,7 @@
 The CRC package provides implementation of CRC algorithms. This
 includes the POSIX CRC calculation which produces the same result as
 the cksum command on Linux, another 32 bit CRC by Gary S. Brown and a
-16bit CRC.
+16bit CRC. The CRC used for Ethernet FCS is also implemented.
 </PARA>
 </PARTINTRO>
 <CHAPTER id="crc-functions">
@@ -35,17 +35,45 @@
 <sect2 id="services-crc-api-cyg-crc32">
 <title>cyg_crc32</title>
 <para>
-This function implements a 32 bit CRC by Gary S. Brown. It uses the
+These functions implements a 32 bit CRC by Gary S. Brown. It uses the
 polynomial
 X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0.
 </para>
 <programlisting>
 unsigned long cyg_crc32(unsigned char * s, int len);
+unsigned long cyg_crc32_accumulate(unsigned long crc, unsigned char * s, int len);
 </programlisting>
 <para>
 The CRC calculation is run over the data pointed to by
 <parameter>s</parameter>, of length <parameter>len</parameter>. The
-CRC is returned as an unsigned long.</para>
+CRC is returned as an unsigned long.</para> 
+
+<para> The CRC can be calculated over data separated into multiple
+buffers by using the function <parameter> cyg_crc32_accumulate()
+</parameter>. The parameter <parameter>crc</parameter> should be the
+result from the previous CRC calculation.
+</para>
+</sect2>
+
+<sect2 id="services-crc-api-cyg-ether-crc32">
+<title>cyg_ether_crc32</title>
+<para>
+These functions implements the 32 bit CRC used by the Ethernet FCS word.
+</para>
+<programlisting>
+unsigned long cyg_ether_crc32(unsigned char * s, int len);
+unsigned long cyg_ether_crc32_accumulate(unsigned long crc, unsigned char * s, int len);
+</programlisting>
+<para>
+The CRC calculation is run over the data pointed to by
+<parameter>s</parameter>, of length <parameter>len</parameter>. The
+CRC is returned as an unsigned long.</para> 
+
+<para> The CRC can be calculated over data separated into multiple
+buffers by using the function <parameter> cyg_ether_crc32_accumulate()
+</parameter>. The parameter <parameter>crc</parameter> should be the
+result from the previous CRC calculation.
+</para>
 </sect2>
 
 <sect2 id="services-crc-api-cyg-crc16">
Index: packages/services/crc/current/include/crc.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/crc/current/include/crc.h,v
retrieving revision 1.1
diff -u -r1.1 crc.h
--- packages/services/crc/current/include/crc.h	9 Aug 2002 10:27:04 -0000	1.1
+++ packages/services/crc/current/include/crc.h	11 Oct 2002 11:32:33 -0000
@@ -65,6 +65,23 @@
 unsigned long 
 cyg_crc32(unsigned char *s, int len);
 
+// Gary S. Brown's 32 bit CRC, but accumulate the result from a
+// previous CRC calculation
+
+unsigned long 
+cyg_crc32_accumulate(unsigned long crc, unsigned char *s, int len);
+
+// Ethernet FCS Algorithm
+
+unsigned long 
+cyg_ether_crc32(unsigned char *s, int len);
+
+// Ethernet FCS algorithm, but accumulate the result from a previous
+// CRC calculation.
+
+unsigned long 
+cyg_ether_crc32_accumulate(unsigned long crc, unsigned char *s, int len);
+
 // 16 bit CRC with polynomial x^16+x^12+x^5+1
 
 unsigned short
Index: packages/services/crc/current/src/crc32.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/crc/current/src/crc32.c,v
retrieving revision 1.1
diff -u -r1.1 crc32.c
--- packages/services/crc/current/src/crc32.c	9 Aug 2002 10:27:04 -0000	1.1
+++ packages/services/crc/current/src/crc32.c	11 Oct 2002 11:32:33 -0000
@@ -120,17 +120,49 @@
       0x2d02ef8dL
    };
 
-/* Return a 32-bit CRC of the contents of the buffer. */
+/* This is the standard Gary S. Brown's 32 bit CRC algorithm, but
+   accumulate the CRC into the result of a previous CRC. */
+unsigned long 
+cyg_crc32_accumulate(unsigned long crc32val, unsigned char *s, int len)
+{
+  int i;
+
+  for (i = 0;  i < len;  i++) {
+    crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
+  }
+  return crc32val;
+}
 
+/* This is the standard Gary S. Brown's 32 bit CRC algorithm */
 unsigned long 
 cyg_crc32(unsigned char *s, int len)
 {
+  return (cyg_crc32_accumulate(0,s,len));
+}
+
+/* Return a 32-bit CRC of the contents of the buffer accumulating the
+   result from a previous CRC calculation. This uses the Ethernet FCS
+   algorithm.*/
+unsigned long 
+cyg_ether_crc32_accumulate(unsigned long crc32val, unsigned char *s, int len)
+{
   int i;
-  unsigned long crc32val;
+
+  if (s == 0) return 0L;
   
-  crc32val = 0;
+  crc32val = crc32val ^ 0xffffffff;
   for (i = 0;  i < len;  i++) {
       crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
   }
-  return crc32val;
+  return crc32val ^ 0xffffffff;
+}
+
+/* Return a 32-bit CRC of the contents of the buffer, using the
+   Ethernet FCS algorithm. */
+unsigned long 
+cyg_ether_crc32(unsigned char *s, int len)
+{
+  return cyg_ether_crc32_accumulate(0,s,len);
 }
+
+
Index: packages/services/crc/current/tests/crc_test.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/crc/current/tests/crc_test.c,v
retrieving revision 1.1
diff -u -r1.1 crc_test.c
--- packages/services/crc/current/tests/crc_test.c	9 Aug 2002 10:27:04 -0000	1.1
+++ packages/services/crc/current/tests/crc_test.c	11 Oct 2002 11:32:33 -0000
@@ -73,6 +73,8 @@
 externC void
 cyg_start( void )
 {
+  unsigned long crc1,crc2;
+   
   CYG_TEST_INIT();
   
   CYG_TEST_INFO("Calculating CRCs");
@@ -83,12 +85,40 @@
     CYG_TEST_PASS("POSIX CRC32 calculation");
   }
   
+  if (1667500021 != cyg_ether_crc32(license_txt,sizeof(license_txt)-1)) {
+    CYG_TEST_FAIL("Wrong Ethernet crc32 calculation");
+  } else {
+    CYG_TEST_PASS("Ethernet crc32 calculation");
+  }
+  
+  if (0 != cyg_ether_crc32_accumulate(0,0,0)) {
+    CYG_TEST_FAIL("Ethernet crc32 accumulate setup");
+  } else {
+    crc1= cyg_ether_crc32_accumulate(0, license_txt,sizeof(license_txt)-1);
+    crc2 = cyg_ether_crc32_accumulate(crc1, license_txt,sizeof(license_txt)-1);
+    
+    if ((1667500021 != crc1) || (3478736840u != crc2)) {
+      CYG_TEST_FAIL("Wrong Etheret crc32 accumulate");
+    } else {
+      CYG_TEST_PASS("Ethernet crc32_accumulate");
+    }
+  }
+
   if (1247800780 != cyg_crc32(license_txt,sizeof(license_txt)-1)) {
     CYG_TEST_FAIL("Wrong Gary S. Browns' crc32 calculation");
   } else {
     CYG_TEST_PASS("Gary S. Browns' crc32 calculation");
   }
 
+  crc1 = cyg_crc32_accumulate(0,license_txt,sizeof(license_txt)-1);
+  crc2 = cyg_crc32_accumulate(crc1,license_txt,sizeof(license_txt)-1);
+    
+  if ((1247800780 != crc1) || (926002294 != crc2)) {
+    CYG_TEST_FAIL("Wrong Gary S. Browns' crc32 accumulate calculation");
+  } else {
+    CYG_TEST_PASS("Gary S. Browns' crc32 accumulate calculation");
+  }
+    
   if (32256 != cyg_crc16(license_txt,sizeof(license_txt)-1)) {
     CYG_TEST_FAIL_FINISH("Wrong 16bit CRC calculation");
   } else {


More information about the Ecos-patches mailing list