问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

CAN通信基础:CRC校验在CAN通信中的应用

创作时间:
作者:
@小白创作中心

CAN通信基础:CRC校验在CAN通信中的应用

引用
CSDN
1.
https://blog.csdn.net/wendy_mooncat/article/details/144621065

CAN(Controller Area Network)总线是一种广泛应用于汽车电子和工业控制领域的串行通信协议。为了确保数据传输的可靠性,CAN协议采用了CRC(Cyclic Redundancy Check)校验机制。本文将详细介绍CRC算法的基础原理、在CAN数据链路层的具体应用,以及CAN报文中的Rolling Counter和Checksum的使用。

1 CRC算法基础

1.1 简介

CRC(循环冗余校验,Cyclic Redundancy Check)是一种常用的、基于多项式除法的校验方法,用于检测数据传输或存储过程中的错误。

基本原理

  • CRC算法将数据视为多项式,并将数据多项式除以一个收发双方约定的多项式(称为生成多项式),计算得到的余数就是CRC校验值;
  • 生成的余数(CRC校验值)会被附加至原始数据后面,随原始数据一同发送或存储;
  • 当数据被接收时,接收方会使用相同的生成多项式对数据进行CRC计算。如果计算出的CRC值与接收到的CRC值相匹配,那么数据被认为是正确的;如果不匹配,数据在传输或存储过程中可能发生了错误。

算法参数

通常,CRC算法需要明确如下参数:

  • 生成多项式:决定了CRC算法的特性,不同的多项式会产生不同的CRC算法。
  • 初始值:CRC计算开始前寄存器的初始值。
  • 输入数据反转:部分CRC算法在处理数据前会反转数据的位顺序。
  • 输出数据反转:部分CRC算法在输出CRC值前会反转CRC值的位顺序。
  • 最终XOR值:CRC计算完成后,与CRC寄存器的最终值进行XOR操作的值。

优势和应用

  • CRC校验能够检测出所有奇数个错误和几乎所有的偶数个错误,以及所有长度小于或等于生成多项式次数的突发错误。
  • CRC校验的计算效率高,适合硬件和软件实现。
  • CRC校验广泛应用于通信领域,用于确保数据的完整性和准确性。在CAN协议中,数据链路层使用CRC-15校验CAN帧的准确性;应用层也常常在重要报文中添加Checksum信号(基于CRC-8)校验CAN数据的准确性。

1.2 CRC的生成多项式

首先,对CRC校验中生成多项式进行介绍。

CRC算法的多项式可以通过二进制序列表示。如某CRC-8算法的二进制表示为1 0001 1101,最低位(右1位)是第0比特,其多项式P ( x ) = x 8 + x 4 + x 3 + x 2 + 1 P(x)=x^8+x^4+x^3+x^2+1P(x)=x8+x^4+x^3+x^2+1与二进制序列一一对应。由于CRC-8生成多项式最高位阶指数默认是8,则最高位通常不表示,则上述CRC-8生成多项式常用十六进制1Dh表示。

1.3 CRC运算示例和多项式除法(模2除法)

CRC校验方法使用多项式除法(模2除法)进行计算,下面以具体实例说明模2除法如何计算CRC校验值。

现有数据FFh(1111 1111)使用CRC-8 1Dh进行校验。其计算CRC校验码的过程如下:

  • CRC-8 1Dh算法的生成多项式为P ( x ) = x 8 + x 4 + x 3 + x 2 + 1 P(x)=x^8+x^4+x^3+x^2+1P(x)=x8+x^4+x^3+x^2+1,其对应的二进制序列为100011101;
  • 在原始数据FFh(1111 1111)补充8位的数据0,其中8是生成多项式的阶数;
  • 使用补0之后的二进制数据对生成多项式的二进制序列进行模2运算(见下图)。其实际计算方式是从数据最高位开始和生成多项式进行异或运算,不断向数据低位滑动;
  • 最终得到余数C4h(1100 0100),当不足8位时,需要高位补零得到8比特的CRC校验码。

2 CAN数据链路层的CRC Field

ISO 11898-1协议为CAN数据帧定义CRC字段:

  • 该CRC字段长度为15比特;
  • 该CRC生成多项式为P ( x ) = x 15 + x 14 + x 10 + x 8 + x 7 + x 4 + x 3 + 1 P(x)=x^{15}+x^{14}+x^{10}+x^8+x^7+x^4+x^3+1P(x)=x15+x14+x10+x8+x7+x4+x3+1;
  • 该CRC校验数据的范围是SOF(Start of Frame,帧起始)字段至Data Field(数据域)结束;
  • 若某接收节点计算的CRC字段与其接收到的CRC字段数值不一致,则会在ACK-DEL(ACK字段界定符)之后发出错误帧。

3 CAN报文的Rolling Counter和Checksum

为了提高CAN通信传输的可靠性,重要的CAN报文通常需要包含Rolling Counter和Checksum两个信号。如下图,是常见的Rolling Counter和Checksum的在一帧CAN报文中的布局。

3.1 Rolling Counter

Rolling Counter是CAN报文的滚动计数器,用于跟踪报文的序列,确保报文按预期顺序接收。它是一个简单的递增计数器,范围为0-15之间递增循环。通常以一个4比特长度Singal的形式体现。Rolling Counter可以帮助接收方应用软件判断:报文传输过程中是否出现丢帧和乱序。

3.2 Checksum

Checksum是一种CAN报文的数据校验码,用于检查通信数据的完整性。Checksum在CAN报文中通常以一个8比特长度信号的形式体现,常用CRC-8算法。Checksum信号中是发送方按照算法计算出的校验码,其校验范围是本条CAN报文中的其他信号。接收方收到CAN报文后,会根据同样的算法计算校验码,并与Checksum信号进行对比,若两者一致,则认为报文传输过程未出现错误。

在CAN通信设计中,需要约定系统中所有CAN控制器使用的Checksum校验算法,供应商按照此算法实现控制器。下表是CRCH1D算法的参数,以此算法为例介绍发送方和接收方需要约定的CRC8算法参数。

算法参数
数值
解释
宽度 Width
8 Bits
CRC-8算法计算结果的宽度是8比特
生成多项式 Polynomial
1Dh
发送、接收双方约定的计算CRC校验值的多项式
初始值 Initial Value
FFh
CRC寄存器的初始值
输入数据反转 Input Data Reflected
NO
输入数据是否进行反转
输出数据反转 Output Data Reflected
NO
输出数据是否进行反转
异或值 XOR Value
FFh
输出数据与此值进行异或计算
校验值 Check
4Bh
用户在指定一段数据,此段数据进入校验后的数值。
魔术校验值 Magic Check
C4h
详见解释

解释

  • 生成多项式:CRC-8算法的多项式可以通过十六进制表示。如1Dh的二进制表示为0001 1101,CRC-8第一位默认隐藏,故实际多项式二进制序列为(1) 0001 1101。按照二进制序列对应x xx的指数,则生成多项式P ( x ) = x 8 + x 4 + x 3 + x 2 + 1 P(x)=x^8+x^4+x^3+x^2+1P(x)=x8+x^4+x^3+x^2+1;
  • 初始值:初始值是在开始CRC计算之前,CRC寄存器被设置的值;
  • 输入数据反转:在进行CRC计算之前,输入数据的位不会被反转。该反转指位反转,即1101位反转后为1011;
  • 输出数据反转:在进行CRC计算之后,输出数据的位不会被反转;
  • 异或值:XOR值是在CRC计算完成后,与CRC寄存器的最终值进行XOR(异或)操作的值;
  • 校验值:用户指定一段输入数据,经过此CRC算法校验后的输出值。如使用ASCII值’1’,‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, '9’作为输入数据,输出得到的校验值;
  • 魔术校验值:任意一段数据经过CRC校验后,得到CRC校验值。将CRC校验值附加于原数据后形成新的输入数据,并进行CRC校验,得到的校验值与异或值(XOR Value)异或,最终输出魔术校验值(Magic Check)。此数值不受原始数据影响,任意数据经过此过程后可得到唯一的魔术校验值。

4 CRC算法代码实现

def crc8h1d(ptr, length):  
    crc = 0xFF          # [参数]初始值 Initial Value : 0xFF
    polynomial = 0x1D   # [参数]生成多项式  Polynomial = P(x)=x^4+x^3+x^2+1  
    for i in range(length):     # 读入数据  
        crc ^= ptr[i]           # 数据与当前CRC寄存器中的数值进行异或  
        for j in range(8):      # 逐位处理 模拟模2除法  
            if (crc & 0x80):    # 当前高位是1,则左移1位并异或生成多项式(模2除法):左移1位的原因是当前生成多项式表达式不包含最高次幂  
                crc = ((crc << 1) ^ polynomial) & 0xFF  
            else:               # 当前高位是0,则左移1位  
                crc = (crc << 1) & 0xFF  
            crc &= 0xFF         # [参数]宽度  Width : 8 bits  
    return crc ^ 0xFF           # [参数]最终异或值 XOR Value : 0xFF  
  
ptr = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]  # 输入数据(此输入数据为计算Check值的输入)
length = 9  # 输入数据长度  
  
crc_value = crc8h1d(ptr, length)                # 计算CRCH1D校验值  
print(f"The CRC value is: {crc_value:#04x}")    # The CRC value is: 0x4b

本文原文来自CSDN

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号