Mercurial > flash_v2
changeset 365:38b5627c5569
* 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
a previous CRC calculation into a new buffer.
* tests/crc_test.c: Tests for new functions.
| author | asl |
|---|---|
| date | Mon, 14 Oct 2002 15:31:10 +0000 |
| parents | 5fb39527fe00 |
| children | 580e5f06f957 |
| files | packages/services/crc/current/ChangeLog packages/services/crc/current/doc/crc.sgml packages/services/crc/current/include/crc.h packages/services/crc/current/src/crc32.c packages/services/crc/current/tests/crc_test.c |
| diffstat | 5 files changed, 123 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/services/crc/current/ChangeLog +++ b/packages/services/crc/current/ChangeLog @@ -1,3 +1,12 @@ +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-08-07 Andrew Lunn <andrew.lunn@ascom.ch> * Created a new package from the CRC routines
--- a/packages/services/crc/current/doc/crc.sgml +++ b/packages/services/crc/current/doc/crc.sgml @@ -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 @@ CRC is returned as an unsigned long.</pa <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">
--- a/packages/services/crc/current/include/crc.h +++ b/packages/services/crc/current/include/crc.h @@ -65,6 +65,23 @@ cyg_posix_crc32(unsigned char *s, int le 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
--- a/packages/services/crc/current/src/crc32.c +++ b/packages/services/crc/current/src/crc32.c @@ -120,17 +120,49 @@ static const unsigned long crc32_tab[] = 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); +} + +
--- a/packages/services/crc/current/tests/crc_test.c +++ b/packages/services/crc/current/tests/crc_test.c @@ -73,6 +73,8 @@ your programs, too."; externC void cyg_start( void ) { + unsigned long crc1,crc2; + CYG_TEST_INIT(); CYG_TEST_INFO("Calculating CRCs"); @@ -83,12 +85,40 @@ cyg_start( void ) 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 {
