crc16 bit .....

2018. 1. 4. 18:35IT

반응형

데이터값을 기존 crc16 소스로 (check sum) 계산하니 mismatch 값이였다. 


*** STX = Start flag / ETX = End flag, C/S = 16bit의 Check Sum 으로, Type부터 Data 까지를 포함하며 CRC16방식이다.


Data = 02 30 4b 45 55 4b 44 4f 4e 47 42 00 b2 71 03


Data에서 맨 앞에 있는 Start flag를 제외한 Type ~ LEN까지의 data로 crc16 check sum 값을 계산한다. 위의 Data로 계산하자면...

(Online으로 계산함)



이제... 원래 나와야하는 값이 CRC16 방식이라는데... (그냥 Basic) 우리가 쓰는 CRC코드는 XModem crc였던것. 


그래서 CRC공부를 또 했는데... 이게 설명 제일 잘되어있음. 

https://ko.wikipedia.org/wiki/%EC%88%9C%ED%99%98_%EC%A4%91%EB%B3%B5_%EA%B2%80%EC%82%AC

(위키피디아)


그으래서 ...... 자 이제 소스를 구해볼까..했는데 저기 위에 계산해주는 사이트에 떡하니 


"Free CRC calculation routines for download"


가 있네?

들어가면 소스 다운받을수있음. ㅋ


libcrc-2.0.zip



이건데... 여기 main 이랑 해당 CRC 방법 연결해서 쓰면됨.


테스트 소스는 이런식으로. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdio.h>
#include <stdint.h>
#define POLYNOMIAL 0x8005
#define CRC_TABLE_SIZE 256
#define RCV_BUF_SIZE 4
 
#define USE_CRC_TABLE
#ifndef USE_CRC_TABLE
#else
 
// use this 
#define CRC_POLY_16 0xA001
#define CRC_START_16 0x0000
static void init_crc16_tab(void);
static bool crc_tab16_init = false;
static uint16_t crc_tab16[256];
 
#if 0
static uint16_t crc_tab16[CRC_TABLE_SIZE] = {
    0x00000x80050x800f0x000a0x801b0x001e0x00140x8011,
    0x80330x00360x003c0x80390x00280x802d0x80270x0022,
    0x80630x00660x006c0x80690x00780x807d0x80770x0072
    0x00500x80550x805f0x005a0x804b0x004e0x00440x8041,
    0x80c30x00c60x00cc0x80c90x00d80x80dd0x80d70x00d2
    0x00f00x80f50x80ff0x00fa0x80eb0x00ee0x00e40x80e1,
    0x00a00x80a50x80af0x00aa0x80bb0x00be0x00b40x80b1,
    0x80930x00960x009c0x80990x00880x808d0x80870x0082,
    0x81830x01860x018c0x81890x01980x819d0x81970x0192,
    0x01b00x81b50x81bf0x01ba0x81ab0x01ae0x01a40x81a1,
    0x01e00x81e50x81ef0x01ea0x81fb0x01fe0x01f40x81f1,
    0x81d30x01d60x01dc0x81d90x01c80x81cd0x81c70x01c2,
    0x01400x81450x814f0x014a0x815b0x015e0x01540x8151,
    0x81730x01760x017c0x81790x01680x816d0x81670x0162,
    0x81230x01260x012c0x81290x01380x813d0x81370x0132,
    0x01100x81150x811f0x011a0x810b0x010e0x01040x8101,
    0x83030x03060x030c0x83090x03180x831d0x83170x0312,
    0x03300x83350x833f0x033a0x832b0x032e0x03240x8321,
    0x03600x83650x836f0x036a0x837b0x037e0x03740x8371,
    0x83530x03560x035c0x83590x03480x834d0x83470x0342,
    0x03c00x83c50x83cf0x03ca0x83db0x03de0x03d40x83d1,
    0x83f30x03f60x03fc0x83f90x03e80x83ed0x83e70x03e2,
    0x83a30x03a60x03ac0x83a90x03b80x83bd0x83b70x03b2,
    0x03900x83950x839f0x039a0x838b0x038e0x03840x8381,
    0x02800x82850x828f0x028a0x829b0x029e0x02940x8291,
    0x82b30x02b60x02bc0x82b90x02a80x82ad0x82a70x02a2,
    0x82e30x02e60x02ec0x82e90x02f80x82fd0x82f70x02f2,
    0x02d00x82d50x82df0x02da0x82cb0x02ce0x02c40x82c1,
    0x82430x02460x024c0x82490x02580x825d0x82570x0252,
    0x02700x82750x827f0x027a0x826b0x026e0x02640x8261,
    0x02200x82250x822f0x022a0x823b0x023e0x02340x8231,
    0x82130x02160x021c0x82190x02080x820d0x82070x0202
};
#endif
#endif
 
static void init_crc16_tab(void) {
    uint16_t i;
    uint16_t j;
    uint16_t crc;
    uint16_t c;
 
    for(i = 0; i < 256; i++) {
        crc = 0;
        c   = i;
 
        for(j = 0; j < 8; j++) {
            if((crc^c)&0x0001) crc = (crc >> 1) ^ CRC_POLY_16;
            else               crc = crc >> 1;
 
            c = c >> 1;
        }
        crc_tab16[i] = crc;
    }
    crc_tab16_init = true;
}
 
uint16_t crc_16(const int8_t *input_str, size_t num_bytes) {
    uint16_t crc;
    uint16_t tmp;
    uint16_t short_c;
    const int8_t *ptr;
    size_t a;
 
    if(!crc_tab16_init) init_crc16_tab();
 
    crc = CRC_START_16;
    ptr = input_str;
 
    if(ptr != NULLfor (a=0; a<num_bytes; a++) {
        short_c = 0x00ff & (uint16_t) *ptr;
        tmp     = crc ^ short_c;
        crc     = (crc >> 8) ^ crc_tab16[tmp & 0xff];
 
        ptr++;
    }
    return crc;
}
 
int main() {
    int a, i;
    uint8_t tx_frame[20];
    uint8_t len = 0;
    const unsigned char *ptr;
    uint16_t crc16;
 
    tx_frame[len] = 0x02; len++;
    tx_frame[len] = 0x10; len++;
    tx_frame[len] = 0x4B; len++;
    tx_frame[len] = 0x45; len++;
    tx_frame[len] = 0x55; len++;
    tx_frame[len] = 0x4B; len++;
    tx_frame[len] = 0x44; len++;
    tx_frame[len] = 0x4F; len++;
    tx_frame[len] = 0x4E; len++;
    tx_frame[len] = 0x47; len++;
    tx_frame[len] = 0x01; len++;
    tx_frame[len] = 0x06; len++;
 
    crc16 = crc_16((const int8_t *)&tx_frame[1], len-1);
    printf("crc = %04x\n",crc16);
 
    tx_frame[len] = (uint8_t)((crc16 >> 8& 0xFF); len++;
    tx_frame[len] = (uint8_t)((crc16 >> 0& 0xFF); len++;
 
    for(i = 0; i < len; i++) {
        printf("%02x ", tx_frame[i]);
    }
    printf("\n");
}
cs


ㅇㅇ

 소스분석 아직안함 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ


저 위에 첨부파일한 소스 목록에  crc16, crc_modbus, xmodem, ccitt, 32bit 등등... 구분되어있는데 그것만 바꿔주면서 사용하면됨. 


main 도 같이 참고해서 반영하도록 함.. 참고로 C++ 이니까 Ubuntu 에서 


Compile은 


g++ [파일이름]


이렇게 해야함 ㅎㅎ (gcc는 c file.)



728x90
반응형

'IT' 카테고리의 다른 글

Linux 에서 GPIO 컨트롤하기  (2) 2018.01.26
Fedora install  (0) 2018.01.26
Ubuntu install in HPE Proliant Server  (0) 2017.12.13
Shell script  (0) 2017.12.06
(16.04LTS)The System Network Services are not compatible with this version  (0) 2017.11.29