CRC 16サイクル冗長検査RTU-MODBUS標準Linux C
1、概要
CRC 16サイクル冗長検査は、メッセージの整合性を検査するためにMODBUSプロトコルでよく使用される.CRC 16検査値uint 16_t符号なし整形2バイト、MODBUSプロトコルでは、低検査バイトが前、高校検査バイトが後、例えば検査結果crc 16=0 x 1788であれば、MODBUSにおける検査順序は...0x88 0x17.
以下は自分で書いたlinux Cコードで、直接使えます.
2、Cプログラム
3、コンパイル
4、使用
CRC 16サイクル冗長検査は、メッセージの整合性を検査するためにMODBUSプロトコルでよく使用される.CRC 16検査値uint 16_t符号なし整形2バイト、MODBUSプロトコルでは、低検査バイトが前、高校検査バイトが後、例えば検査結果crc 16=0 x 1788であれば、MODBUSにおける検査順序は...0x88 0x17.
以下は自分で書いたlinux Cコードで、直接使えます.
2、Cプログラム
/*******************************************************************************
_____ ___ ____ ___ _____ _ _ _
| ____|_ _| _ \|_ _| |_ _|__(_)_ __ __ _| | | |_ _ __ _
| _| | || |_) || | | |/ __| | '_ \ / _` | |_| | | | |/ _` |
| |___ | || _ < | | | |\__ \ | | | | (_| | _ | |_| | (_| |
|_____|___|_| \_\___| |_||___/_|_| |_|\__, |_| |_|\__,_|\__,_|
* File Name : main.c
* Description : This file provides code for crc16 caculation in linuxc.
* Author : jackwang by [email protected]
* Date : 2018-07-15
*******************************************************************************/
/*! -------------------------------------------------------------------------- */
/*! Include headers */
#include
#include
#include
/*! -------------------------------------------------------------------------- */
/*! Private function declarations */
static unsigned char Char2Int(char chr,bool *isOK);/*! convert char to int type*/
static unsigned char HexStr2Int(char *str, bool *isOK);/*!convert hexstr to int*/
/*! caculate crc16 of buff-input:arr_buff and length: len */
static unsigned short GenerateCRC16(unsigned char *arr_buff, unsigned short len);
/*! -------------------------------------------------------------------------- */
/*! main function defination */
int main(int argc, char* argv[])
{
/*! variable define */
int ret = 0;
int numByte = argc;
unsigned char bccVal = 0x00;
char inPutbuff[10];
unsigned char databuff[1000];
unsigned short buffsize = 0;
unsigned short crcVal;
bool isOK;
int Nibb;
if(argc == 1){
printf("[note] no params to caculate, please input hex string,
splite by space!\r
");
}
else{
printf("[note] input %d byte: ",numByte-1);
for(int i = 1; i < numByte; i++){
printf("%s ",argv[i]);
}
printf("\r
");
for(int i = 1; i < numByte; i++){
memcpy(inPutbuff,argv[i],2);
Nibb = HexStr2Int(inPutbuff,&isOK);
if(isOK){
databuff[i-1] = Nibb;
buffsize++;
}
}
crcVal = GenerateCRC16(databuff,buffsize);
printf("[note] crc16 value: 0x%04X\r
",crcVal);
}
return 0;
}
/*! -------------------------------------------------------------------------- */
/*! Private function definations */
/*! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
static unsigned char Char2Int(char chr,bool *isOK)
{
unsigned char nibb1;
if(chr >= '0' && chr <= '9'){ nibb1 = chr - '0'; *isOK = true;}
else if(chr >= 'a' && chr <= 'f'){ nibb1 = chr - 'a' + 10; *isOK = true;}
else if(chr >= 'A' && chr <= 'F'){ nibb1 = chr -'A' + 10; *isOK = true; }
else{ printf("[error] invalid hex str input: %c \r
",chr); *isOK = false; }
return nibb1;
}
/*! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
static unsigned char HexStr2Int(char *str, bool *isOK)
{
unsigned char nibb1,nibb2;
bool isOK1,isOK2;
nibb1 = Char2Int(*str, &isOK1);
nibb2 = Char2Int(*(str+1),&isOK2);
if(isOK1 && isOK2){
*isOK = true;
return nibb1*16 + nibb2;
}
else{
*isOK = false;
return 0;
}
}
/*! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
static unsigned short GenerateCRC16(unsigned char *arr_buff, unsigned short len)
{
unsigned short crc=0xFFFF;
unsigned char i, j;
for ( j=0; j < len;j++){
crc=crc ^*arr_buff++;
for ( i=0; i<8; i++) {
if( ( crc&0x0001) >0){
crc=crc>>1;
crc=crc^ 0xa001;
}
else{ crc=crc>>1;}
}
}
return crc;
}
3、コンパイル
~$ gcc main.c -o getcrc16
4、使用
~$ ./getcrc16 01 03 00 04 00 04
~$ [note] input 6 byte: 01 03 00 04 00 04
~$ [note] crc16 value: 0xC805