全然理解してないわけではないけど、
シリアルインタフェースでCRCが出てきてもパッと計算できず、
結局は人様が作ったツールに頼り切ってしまう。(よく使うのは以下)
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
自作ツールを作りがてら、再勉強する。
Contents
多項式
まずは、CRC-8演算で使用される多項式は複数あるので、
以下を参考に整理。
https://en.wikipedia.org/wiki/Cyclic_redundancy_check
| CRC-8-ATM CRC-8/ITU | X^8 + X^2 + X + 1 | (0x07) | ATM |
| CRC-8-CCITT | X^8 + X^7 + X^3 + X^2 + 1 | (0x8D) | シリアルバス |
| CRC-8-Dallas/Maxim | X^8 + X^5 + X^4 + 1 | (0x31) | シリアルバス |
| CRC-8 | X^8 + X^7 + X^6 + X^4 + X^2 +1 | (0xD5) | 汎用 |
| CRC-8-SAE J1850 | X^8 + X^4 + X^3 + X^2 + 1 | (0x1D) | SAE J1850 |
| CRC-8-AUTOSAR | X^8 + X^5 + X^3 + X^2 + X + 1 | (0x2F) | Automotive |
| CRC-8-Bluetooth | X^8 + X^7 + X^5 + X^2 + X + 1 | (0xA7) | 無線通信 |
| CRC-8-GSM-B | X^8 + X^6 + X^3 + 1 | (0x49) | モバイル通信 |
| CRC-8-WCDMA | X^8 + X^7 + X^4 + X^3 + X + 1 | (0x9B) | モバイル通信 |
| CRC-8-DRAC | X^8 + X^5 + X^4 + X^3 + 1 | (0x39) | Radio Channel |
ただ、実際は通信規格によって、初期値・入力反転・出力反転・XOR出力などの設定があり、単純に多項式だけでは決まらない。
が、全部調べきれてないので、まずは以下を基本としてC言語でアプリを作成。
- Polynominal : 設定可変
- 初期値:設定可変
- 左送り
- 入力反転:無し
- 出力反転:無し
- XOR出力:無し
アプリ作成
実際に作成したソースは以下。
|
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 |
#include <stdio.h> #include <stdint.h> #include <unistd.h> #include <limits.h> void usage(); static unsigned char calcCRC8(const void *buff, size_t size, uint8_t poly, uint8_t init) { unsigned char *p = (unsigned char *)buff; unsigned char crc8; for (crc8 = init; size != 0; size--) { crc8 ^= *p++; printf("0x%02X\n", crc8); for (int i = 0; i < CHAR_BIT; i++) { if (crc8 & 0x80) { crc8 <<= 1; crc8 ^= poly; } else { crc8 <<= 1; } } } return crc8; } int main(int argc, char* argv[]) { int i, opt; unsigned int tmp; uint8_t poly = 0x1D; uint8_t init = 0x00; uint8_t crc; uint8_t data[1024]; int j = 0; opterr = 0; // Disable error messages from getopt() while ((opt = getopt(argc, argv, "p:i:")) != -1) { switch (opt) { case 'p': sscanf(optarg, "%x", &tmp); poly = tmp & 0xFF; break; case 'i': sscanf(optarg, "%x", &tmp); init = tmp & 0xFF; break; default: usage(argv[0]); return 1; } } for (i = optind; i < argc; i++) { sscanf(argv[i], "%x", &tmp); data[j] = tmp & 0xFF; j++; } if(j > 0) { printf("------------------------------------\n"); printf("Polynominal : 0x%02X\n", poly); printf("Initialization : 0x%02X\n", init); printf("Input Data :"); for(i = 0; i < j; i++) { if((i !=0) && (i % 8 == 0)) { printf("\n "); } printf(" 0x%02X", data[i]); } } else { usage(argv[0]); return 1; } printf("\n------------------------------------\n"); crc = calcCRC8(data, j, poly, init); printf("------------------------------------\n"); printf("Calculated CRC : 0x%02X\n", crc); printf("\n"); return 0; } void usage(char* prg) { printf("\n"); printf("Usage: %s [-p Polynominal] [-i Initialization] data1 ...\n", prg); printf(" Polynominal:\n"); printf(" CRC-8 : 0xD5 (X^8+X^7+X^6+X^5+X^2+1)\n"); printf(" CRC-8-ATM : 0x07 (X^8+X^2+X+1)\n"); printf(" CRC-8-ITU : 0x07 (X^8+X^2+X+1)\n"); printf(" CRC-8-CCITT : 0x8D (X^8+X^7+X^3+X^2+1)\n"); printf(" CRC-8-Dallas/Maxim : 0x31 (X^8+X^5+X^4+1)\n"); printf(" CRC-8-SAE J1850 : 0x1D (X^8+X^4+X^3+X^2+1) (default)\n"); printf(" CRC-8-AUTOSAR : 0x2F (X^8+X^5+X^3+X^2+X+1)\n"); printf(" CRC-8-Bluetooth : 0xA7 (X^8+X^7+X^5+X^2+X+1)\n"); printf(" CRC-8-GSM-B : 0x49 (X^8+X^6+X^3+1)\n"); printf(" CRC-8-WCDMA : 0x9B (X^8+X^7+X^4+X^3+X+1)\n"); printf(" CRC-8-DRAC : 0x39 (X^8+X^5+X^4+X^3+1)\n"); printf("\n"); printf(" Initialization: 0x00 (default) or 0xFF\n"); printf(" CRC-8 : 0x00\n"); printf(" CRC-8-SAE J1850 : 0x00 or 0xFF\n"); printf("\n"); } |
使用方法
以下のオプションを指定して、スペース区切りで入力データをインプット
”-p”オプション:多項式
”-i”オプション :初期値
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
./calcCRC8 -p 0x07 -i 0x00 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 ------------------------------------ Polynominal : 0x07 Initialization : 0x00 Input Data : 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 ------------------------------------ 0x31 0xA5 0x41 0xF4 0xF7 0xFD 0xCA 0x40 0xFE ------------------------------------ Calculated CRC : 0xF4 |