2018. 1. 4. 18:35ㆍIT
데이터값을 기존 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"
가 있네?
들어가면 소스 다운받을수있음. ㅋ
이건데... 여기 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] = { 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 }; #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 != NULL) for (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.)
'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 |