CAPL内置CRC函数Crc_CalculateCRC8概述

目录

0 前言

1 CRC函数简介

2 抛出问题

3 解决问题

3.1 firstCall中初次调用(1)和后续调用(0)的区别:

3.2 函数Crc_CalculateCRC8定义的多项式


0 前言

        因为之前喜欢偷懒直接用CAPL的内置CRC函数来做计算,但是最近发现这个函数有些鸡肋的地方,拿出来记录一下,分享给大家。

CRC函数简介

        在CAPL中,有以下的CRC函数可以选择,每个函数具体根据的是哪个多项式在Help文档中都可以看到。

比如说Crc_CalculateCRC8()函数用的是AUTOSAR Profile1的多项式来进行计算的,实际根据项目自行选择所需要的函数。

2 抛出问题

        以Crc_CalculateCRC8()为例,其语法主要如下所示:

long Crc_CalculateCRC8 (byte data[], dword dataSize, dword dataOffset, dword crcLength, dword crcStartValue, dword firstCall, dword& crcCalculated);

        使用CAPL的内置函数Crc_CalculateCRC8做计算,为什么算出来的结果和我直接使用AUTOSAR Profile 1里的算法结果算出来是不一样的,代码及结果如下图所示

从图中可以看到CRC和CRC1的结果并不一样,需要提前说明的是0x37是正确的结果。 而是用Crc_CalculateCRC8函数算出来的0x4B是错误的。这是为什么呢?

3 解决问题

这是因为在Autosar Proile1中CRC有两种算法,分别是CRC-8-SAE J1850 CRC-8-SAE J1850 zero,来源如下图:两者的初始值与异或值是不同的。为了分辨,将初始值和异或值为0x00的多式定义为CRC-8-SAE J1850 zero。Crc_CalculateCRC8()一般默认为CRC-8-SAE J1850的多项式。

如果想使用Crc_CalculateCRC8()来实现CRC-8-SAE J1850 zero的多项式,需要设置参数crcStartValue0xFFfirstCallfalse,最后再和0xFF进行异或。如果感兴趣为什么要这么做的朋友可以直接调到3.2节。按照这个方法生成的CRC就是0x37了。

on key 'c'
{
  long retval;
  dword crc;
  byte data[9] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
  const dword firstcall =1;
  const dword subsequentcall =0;
  
  retval = Crc_CalculateCRC8(data, elcount (data), 0, elcount (data) , 0xff, subsequentcall, crc);
  crc = crc^0xff;
  write("CRC of data: 0x%X", crc);
}

函数主要参数如下图所示:

data

Payload data for which the checksum is to be calculated.

dataSize

Length of data block to be calculated in bytes.

dataOffset

Start index for the calculation of the CRC in the payload data.

crcLength

The length of the data for the CRC is calculated.

crcStartValue

CRC initial value depending on whether it is the first call or a subsequent call. Value is ignored if firstCall is 1.

firstCall

Flag for first call or a subsequent call. Possible values are 0 (subsequent call) or 1 (first call).

crcCalculated

Calculated CRC8 value.

上述的 firstCallcrcStartValue含义需要做重点了解,因为这是转换多项式的关键。

3.1 firstCall中初次调用(1)和后续调用(0)的区别:

二者的区别演示如下图所示:

First call分为first call和subsequent call两种模式

First Call:

- CRC计算从初始值开始,通常由正在使用的CRC标准指定(例如,0x00或0xFF)。

- 对输入的数据进行处理,并根据初始值计算CRC值。

Subsequent Calls:

- 如果继续使用新数据进行CRC计算,该函数将使用上一次计算的CRC值作为起点。

- 这允许CRC积累多个数据块,确保连续性的CRC计算。。

- 本质上,First Call:用初始化CRC计算,而Subsequent Calls根据先前的结果累积CRC值

参数crcStartValue是否作为初始值生效取决于First cal,如果是subsequent_call,就生效,如果是first call,start value默认是0:

3.2 函数Crc_CalculateCRC8定义的多项式

        它的初始值和异或值都是0xFF,如果想实现CRC-8-SAE J1850 zero的多项式,就需要将初始值和异或值都变为0x00,就不能将frist call参数设置为1,因为这样的话初始值0xFF就会被使用,因此frist call应该被设置为0。crcStartValue 参数这时派上用场。crcStartValue 设置为0xFF, firstCall = false,得到新的初始值0x00。然后对crc的结果与0xFF进行异或,以取消之前的0xFF异或,使最终结果为0x00的异或。

简单来说:

1.firstCall = false和crcStartValue=0xFF,以便获得0x00的实际初始值

2.对函数调用的结果应用0xFF异或,以撤销CRC_Calculate8的最终异或

如果有那里不足还请各位大佬多多指正,最后打个广告,如果有需要加入HIL自动化测试群的小伙伴们欢迎评论或私信我,大家一起多多交流多多进步。

### CAPL语言中的CRC8算法实现 CAPLCAN Access Programming Language)是一种用于开发和测试基于CAN网络的应用程序的语言。它广泛应用于Vector公司的工具链中,例如CANoeCANalyzer。 在CAPL中,`Crc_CalculateCRC8` 是一种内置函数,可以用来计算CRC8校验值[^2]。然而,由于不同的参数设置以及初始条件的不同,可能会导致其结果与其他标准算法的结果不一致。以下是使用CAPL语言手动实现CRC8算法的一个示例: #### 手动实现CRC8算法CAPL代码 下面是一个简单的CAPL脚本,展示了如何通过循环移位的方式手动实现CRC8算法: ```capl variables { byte poly = 0x31; // 多项式定义 (通常为0x31或0x9B) } byte calculateCRC8(byte data[], dword length) { byte crc = 0xFF; // 初始值设为0xFF dword i; for(i = 0; i < length; ++i){ crc ^= data[i]; dword j; for(j = 0; j < 8; ++j){ if((crc & 0x80) != 0){ crc = (crc << 1) ^ poly; } else{ crc <<= 1; } } } return crc; } ``` 此代码片段实现了基本的CRC8算法逻辑,其中多项式的默认值设定为 `0x31`,这是许多应用中最常用的值之一。如果需要调整到其他特定的标准(如AUTOSAR Profile),可以根据具体需求修改多项式、初始值以及其他配置参数[^3]。 当调用该函数时,传入待处理的数据数组及其长度即可获得对应的CRC8校验值。需要注意的是,不同场景下可能还需要考虑数据偏移量 (`dataOffset`) 和起始值 (`crcStartValue`) 的影响。 对于更复杂的环境或者更高版本的支持情况,则可以直接利用 CANoe 提供的功能强大的内置函数来简化操作过程。 ### 结果差异的原因分析 造成上述提到的手工计算与自动计算之间存在差别的主要原因在于以下几个方面: - **初始化向量**:某些情况下,默认使用的启动值可能是零或者其他固定数值而不是全一状态(即0xFF)[^1]; - **反射输入/输出比特顺序**:部分协议规定需反转每一位后再参与运算最后再恢复原样; - **最终异或掩码**:结束阶段会对整个累加器执行额外的一次XOR操作以改变最终形式; 这些因素共同决定了即使采用相同的多項式也可能得到完全不一样的結果。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IAMeee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值