E2E CANFD信号矩阵计算实例
计算CANFD上传输的一帧数据的E2E校验,CRC-8-SAE J1850 - 0x1D (x8 + x4 + x3 + x2 + 1),但具有不同的起始值和 XOR 值(起始值和 XOR 值均为 0x00)。
背景
计算CANFD上传输的一帧数据的E2E校验,CRC-8-SAE J1850 - 0x1D (x8 + x4 + x3 + x2 + 1),但具有不同的起始值和 XOR 值(起始值和 XOR 值均为 0x00)。
CANFD数据帧结构
CANFD 数据场总共有DLC 64字节,一般包括 比如(0x100 帧)
时间戳+传输数据 + counter +checkSum +信号更新状态位 等
每一帧数据有一个唯一的Dataid(0x0001,项目前期会定义好),数据长度在如下链接有说明
[PRS_E2E_00085] In E2E Profile 1, with E2E_P01DataIDMode equal to
E2E_P01_DATAID_BOTH or E2E_P01_DATAID_ALT the length of the Data ID shall
be 16 bits (i.e. 2 byte).
《AUTOSAR_PRS_E2EProtocol》入门1 (持续更新)-CSDN博客
数据排序方式
一般有motorola 格式和intel 格式,数据排序方式有点不太一样。在取数据的时候,bit位会不一样。
- Intel 格式:同小端 (Little-endian),低字节在前
- Motorola 格式:同大端 (Big-endian),高字节在前
E2E校验实例
CRC 算法 1
byte Crc_CalculateCRC8(byte data[],int dataLen,byte Crc_StartValue8)
{
int i,j;
byte polynomial;
byte initValue;
polynomial = 0x1d;
initValue = Crc_StartValue8^0X00;
for(i=0;i<dataLen;i++)
{
initValue = initValue ^ data[i];
for(j=0;j<8;j++)
{
if(initValue & 0x80)
{
initValue = ((initValue << 1) & 0xff);
initValue = initValue ^ polynomial;
}
else
{
initValue = ((initValue << 1) & 0xff);
}
}
}
initValue = initValue ^ 0x00;
return(initValue);
}
CRC 算法2
#include <stdint.h>
// 假设CRC-8多项式为0x07
const uint8_t crc8_table[256] = {
0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
};
// 使用查找表计算CRC-8
uint8_t crc8_table_compute(uint8_t *data, size_t length, uint8_t crc) {
for (size_t i = 0; i < length; ++i) {
crc = crc8_table[crc ^ data[i]];
}
return crc;
}
// 使用示例
int main() {
uint8_t data[] = {0x12, 0x34, 0x56, 0x78};
uint8_t crc = crc8_table_compute(data, sizeof(data), 0x00); // 初始CRC通常为0
// 使用计算出的CRC进行后续操作
return 0;
}
两种算法的优缺点在《AUTOSAR_PRS_E2EProtocol》中有说明
实时计算CRC值
优点:
- 灵活性:实时计算CRC值的方法不受限于预定义的查找表,因此可以适用于任何CRC多项式。这意味着它可以轻松适应不同的通信协议和数据格式。
- 内存占用:对于某些应用,尤其是内存受限的环境,实时计算CRC值可能更为合适,因为它不需要存储大量的查找表数据。
缺点:
- 计算速度:实时计算CRC值通常涉及复杂的位操作和多项式除法,这可能会比查找表方法慢,特别是在需要频繁计算CRC的场景中。
- 资源消耗:对于某些处理器来说,实时计算CRC值可能需要更多的CPU周期,从而增加能源消耗。
查找表(查找数组)方法
优点:
- 计算速度:查找表方法通过预先计算并存储所有可能的CRC值,可以显著减少实时计算的需求。因此,它在计算CRC时通常更快,适用于需要高速数据传输的场景。
- 简化代码:查找表方法简化了CRC计算的代码逻辑,使得实现更为简单和直接。
缺点:
- 内存占用:查找表方法需要存储大量的预计算CRC值,因此会占用更多的内存空间。这可能在内存受限的应用中成为问题。
- 灵活性:查找表方法通常针对特定的CRC多项式进行预计算,因此可能不适用于所有通信协议和数据格式。如果需要适应不同的CRC多项式,可能需要重新生成查找表。
附录1:CRC计算原理
CRC(Cyclic Redundancy Check),即循环冗余检验,是基于数据计算一组校验码码,用于核对数据传输过程中是否被更改或传输错误。假设有一组原始数据:1101011011,如何获取其CRC?见下图右方:
第1步:选取CRC算法,即生成多项式,也就是E2E profiles就采用了CRC-8,CRC-16, CRC-32。像E2E profile 1采用x8 + x4 + x3 + x2 + 1,即1 0001 1101。此处选用4位CRC算法,x4 + x1 + 1,即1 0011。
第2步:因此选用4位CRC算法,1 0011,注意宽度是4位,不是5位,这时原始数据需要在右边填充4位,0000,后面用来存放4位CRC,变为:1101011011 0000。
第3步,使用XOR运算,计算CRC,过程如下图左方:
第4步:将CRC更新到原始数据的右4位,则数据变为:11010110111110。这个数据将发送给其他控制器。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)