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

寫了一個小程序,主要用於驗證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*16 typedef 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算法,值得收藏。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章