Canoe E2E校验自定义Checksum算法

发布于:2024-12-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

当E2E的 CRC算法非常规算法,则需要自己编写代码计算,可参考如下:

一、添加 DBC文件

在这里插入图片描述

在这里插入图片描述
导入DBC时, AddImport Wizaid 的区别

当已经通过 Add 添加DBC后,也可以选择导入 ECU Node
在这里插入图片描述

二、导入要仿真的ECU节点

将需要的仿真节点添加进来
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、编写 CAPL脚本

1. 创建 .can 文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 设置counter递增

/*@!Encoding:936*/
includes
{
  
}

variables
{
  byte VCU_To_Veh_Info_counter = 0;
  byte VCU_Charging_Info_counter = 0;
}

// Calculation of a checksum and a message counter 示例:
dword applILTxPending (long aId, dword aDlc, byte data[]) // 在CANoe交互层(CANoe IL)向总线发送消息之前,调用此回调。
{
  dword i;
  if(aId == 0x15D)  // 方法一:直接写 message ID
  {
    // she counter 0-14
    VCU_To_Veh_Info_counter++;
    VCU_To_Veh_Info_counter %= 15;    
    if(VCU_To_Veh_Info_counter == 15) {
      data[1] = (data[1] & 0xF0) | (0x00 & 0x0f);  // data[1]的低半字节表示counter
    } else {
      data[1] = (data[1] & 0xF0) | (VCU_To_Veh_Info_counter & 0x0f);  // data[1]的低半字节表示counter
    }
    
    // set the new checksum
    
  }
    
  if(aId == VCU_Charging_Info.id) // 方法二:message名.id
  {
    // she counter 0-14
    VCU_Charging_Info_counter++;
    VCU_Charging_Info_counter %= 15;    
    if(VCU_Charging_Info_counter == 15) {
      data[1] = (data[1] & 0xF0) | (0x00 & 0x0f);  // data[1]的低半字节表示counter
    } else {
      data[1] = (data[1] & 0xF0) | (VCU_Charging_Info_counter & 0x0f);  data[1]的低半字节表示counter
    }
    // set the new checksum
    
  } 
  return 1; // don't prevent sending of the message
}

3. 设置 CRC 算法,以profile01 8-bit SAE J1850 CRC校验为例

通过 data 修改待发送的数据,如果通过 $信号 可能存在未知问题,导致实际发送的值不是预期的值
需要注意的是,自定义函数定义的变量 不是局部变量

/*@!Encoding:936*/
includes
{
  
}

variables
{
  byte VCU_To_Veh_Info_counter = 0;
}

// Calculation of a checksum and a message counter 示例:
dword applILTxPending (long aId, dword aDlc, byte data[]) // 在CANoe交互层(CANoe IL)向总线发送消息之前,调用此回调。
{
  dword i;
  byte data_Rec[64];
  byte result_crc;
  if(aId == 0x15D)  // 方法一:直接写 message ID
  {
    // she counter 0-14
    VCU_To_Veh_Info_counter++;
    VCU_To_Veh_Info_counter %= 15;    
    if(VCU_To_Veh_Info_counter == 15) {
      data[1] = (data[1] & 0xF0) | (0x00 & 0x0f);  // data[1]的低半字节表示counter
    } else {
      data[1] = (data[1] & 0xF0) | (VCU_To_Veh_Info_counter & 0x0f);  // data[1]的低半字节表示counter
    }
    
    // set the new checksum
    data_Rec[0] = (aId & 0xff); // 将CANID 添加进待校验的数组  
    data_Rec[1] = (aId & 0xff00) >> 8;
    for(i = 1; i < 8; i++) {
      data_Rec[i + 1] = data[i];  // 将前7个Byte添加进待校验的数组 
    }
    
    data[0]  = CRC8_SAEJ1850_CAL(data_Rec, aDlc+1);  // 要校验的数据为 DataID + CRC外的7个Byte    
  }
  return 1; // don't prevent sending of the message
}

// 自定义 checksum 算法
byte CRC8_SAEJ1850_CAL(byte buf[], byte len)
{
    byte CRC_POLY = 0x1D; 
    byte crc = 0xFF; /* 计算的初始crc值: 0 - 输入值, 1 - 输入翻转 */ 
    byte i,j,load_crc;
    load_crc = crc;

    for(i = 0; i < len; i++) {
    load_crc ^= buf[i];  /* 每次先与需要计算的数据异或,计算完指向下一数据 */  
    for (j=8; j>0; --j)   /* 下面这段计算过程与计算一个字节crc一样 */  
    { 
        if (load_crc & 0x80)
                load_crc = (load_crc << 1) ^ CRC_POLY;
            else
                load_crc = (load_crc << 1);
        }
    }
    return (load_crc ^ 0xFF);
}

四、开始仿真

点击闪电按钮(Start)会弹出让我们选择所用硬件通道,如有硬件,选择与产品相连的CAN通道即可,没有硬件的话也可以使用虚拟通道(Virtual CAN BUS):
在这里插入图片描述

选择完成之后点击OK即可启动工程。

考虑到不是每个读者都有硬件,以下暂时以无硬件仿真进行讲解。

在home目录下,点击Real Bus旁边的小箭头,切换到SimulationBus模式进行离线仿真
在这里插入图片描述

五、运行结果

counter:
在这里插入图片描述
在这里插入图片描述
再使用在线网页验证:
在这里插入图片描述

CRC在线校验