CRC-15-CANを計算するプログラムを書いた


はじめに

仕事でCAN通信のプログラムを書いているんだけど、CRCエラーの表示が出る。
デバッグのために、CRCの変換プログラムが必要になっった。
CANのCRCはCRC-15という特殊なフォーマットでネット上に資料が少ない。
ソースや調べたことをまとめておくことにした。

実装例

言語はcを使用。
(追記)コメントでint_to_binstr()の終端処理等の記述が抜けていたという指摘があり、修正した。


#include <stdio.h>
#include <stdint.h>

//  int to bin
char* int_to_binstr(char buff[], int bin, int len)
{
    int i;

    for (i = 0; i < len; i++) {
        if (bin & (1UL << (len - i - 1))) {
            buff[i] = '1';
        }
        else {
            buff[i] = '0';
        }
    }
    buff[len] = '\0';
    return buff;
}

uint16_t can_crc_next(uint16_t crc, uint8_t data)
{
    uint8_t i;
    crc ^= (uint16_t)data << 7;

    for (i = 0; i < 8; i++) {
        crc <<= 1;
        if (crc & 0x8000) {
            crc ^= 0xc599;
        }
    }
    return crc & 0x7fff;
}

void cal_crc15(unsigned char* buff, int len) {
    uint16_t crc;
    crc = 0;

    printf("crc15 0x");
    for (int i = 0; i < len; i++) {
        printf("%02X ", buff[i]);
    }

    printf("\n-> "); 

    for (int i = 0; i < len; i++) {
        crc = can_crc_next(crc, buff[i]);
    }
    char binstr[16];
    printf("0x%04X(%s)\n", crc, int_to_binstr(binstr, (int)crc, 15));
}

int main()
{
    uint8_t data[] = { 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    cal_crc15(data, 11);
}

CRC元データについて

CRCの元データはSOFからデータまで。スタッフビットは除く。
バイナリはHEXにする。
SOF側が半端なビットになるようにする。

uint8_t data[] = { 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

プログラムの動作

CRCの初期値は0。


crc = 0;

データをHEXごとに取り出して7ビット左シフトしてCRCと排他的論理和をとる。


crc ^= (uint16_t)data << 7;

CRCを1ビット左シフト


crc <<= 1;

CRCの最上位ビットが1なら、CRC15の生成多項式x^15 + x^14 + x^10 + x^8 + x^7 + x^4 + x^3 + 1(=0xc599)との排他的論理和を取る。


        if (crc & 0x8000) {
            crc ^= 0xc599;
        }

15ビットなので16ビットの最上位ビットを省く。


return crc & 0x7fff;

注意

CANコントローラ(MCP2515)の吐き出した値と一致することは確認できているが、CAN15の仕様と完全に一致しているかは確認できていない。
おそらく大丈夫だとは思うが。

参考URL

http://forum.easyelectronics.ru/viewtopic.php?f=49&t=34508
https://qiita.com/niQSun/items/5bf1d8d9ceea16d83951
https://qiita.com/dearblue/items/669e2ce2fae57baf1e90
https://ja.wikipedia.org/wiki/%E5%B7%A1%E5%9B%9E%E5%86%97%E9%95%B7%E6%A4%9C%E6%9F%BB
https://reveng.sourceforge.io/crc-catalogue/1-15.htm#crc.cat-bits.15