計算CRC32和CRC16的小工具(主要用於驗證FLASH燒錄的正確性)

来源:互联网 发布:mac安装iphone应用 编辑:程序博客网 时间:2024/06/05 06:31

寫了一個小程序,主要用於驗證FLASH是否燒錄成功。應用場景是這樣的,工廠會將MCU的Firmware直接燒到Flash里,通常這個固件小於Flash的大小,燒錄進去的時候,空白區域會被填充“0xFF”,這個小工具就是驗證燒錄進去的Flash是否正確的。

代碼中使用了他人開源的CRC表生成算法,請參見這篇文章。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <fcntl.h>#include <libgen.h>#define P_16 0xA001#define P_32 0xEDB88320L#define FILE_SIZE 1024*1024*16typedef enum{CRC32=0,CRC16}CRCTYPE;static uint8_t crcbuf[16384];static uint16_t crc_tab16[256];static uint32_t crc_tab32[256];static void init_crc16_tab(void);static void init_crc32_tab(void);uint32_t get_crc16(uint32_t crcinit, uint8_t * bs, uint32_t bssize);uint32_t get_crc32(uint32_t crcinit, uint8_t * bs, uint32_t bssize);uint32_t GetFileCRC(int fd,int type);static void init_crc16_tab(void){    int i, j;    unsigned short crc, c;    for (i=0; i<256; i++)    {        crc = 0;        c   = (unsigned short) i;        for (j=0; j<8; j++)        {            if ((crc ^ c) & 0x0001)            crc = ( crc >> 1 ) ^ P_16;            else            crc = crc >> 1;            c = c >> 1;        }        crc_tab16[i] = crc;    }}  /* init_crc16_tab */static void init_crc32_tab( void ) {    int i, j;    unsigned long crc;    for (i=0; i<256; i++)    {        crc = (unsigned long)i;        for (j=0; j<8; j++)         {            if ( crc & 0x00000001L )            crc = ( crc >> 1 ) ^ P_32;            else                  crc = crc >> 1;        }        crc_tab32[i] = crc;    }}  /* init_crc32_tab */uint32_t get_crc16(uint32_t crcinit, uint8_t * bs, uint32_t bssize){uint32_t crc = 0;init_crc16_tab();while(bssize--){crc=(crc >> 8)^crc_tab16[(crc & 0xff) ^ *bs++];}return crc;}uint32_t get_crc32(uint32_t crcinit, uint8_t * bs, uint32_t bssize){uint32_t crc = crcinit^0xffffffff;init_crc32_tab();while(bssize--){crc=(crc >> 8)^crc_tab32[(crc & 0xff) ^ *bs++];}return crc^0xffffffff;}uint32_t GetFileCRC(int fd,int type){uint32_t rdlen;uint32_t crc = 0;uint32_t (*get_crc)(uint32_t crcinit, uint8_t * bs, uint32_t bssize);switch(type){case CRC32:get_crc=get_crc32;break;case CRC16:get_crc=get_crc16;break;default:get_crc=get_crc32;break;}while((rdlen = read(fd, crcbuf, 4096)) > 0){crc = get_crc(crc, crcbuf, rdlen);}return crc;}int main(int argc,char **argv){int fd;unsigned int value=0;int bytes_read=0,bin_size=0;unsigned char *buf;if(argc<3){printf("Usage: %s file 32/16\n",basename(argv[0]));exit(1);}if((fd=open(argv[1],O_RDONLY))==-1){perror("Error:");exit(1);}if(argc>3){bin_size=atoi(argv[3]);bin_size=(bin_size>FILE_SIZE?FILE_SIZE:bin_size);}buf=malloc(FILE_SIZE);memset(buf,0xFF,FILE_SIZE);bytes_read=read(fd,buf,FILE_SIZE);printf("File length: %d\n",bytes_read);if(strncmp(argv[2],"32",2)==0){value=get_crc32(0,buf,(bytes_read>bin_size?bytes_read:bin_size));/* crc32 *//* value=GetFileCRC(fd,CRC32); */}else{value=get_crc16(0,buf,(bytes_read>bin_size?bytes_read:bin_size));/* crc16 *//* value=GetFileCRC(fd,CRC16); */}printf("CRC: %X\n",value);if(buf!=NULL)free(buf);close(fd);return 0;}

這篇文章提供的代碼中還包含其它類型的CRC算法,值得收藏。


原创粉丝点击