IT

crc16 bit .....

뚱냐리 2018. 1. 4. 18:35
반응형

데이터값을 기존 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
반응형