1. 基于CANalyzer的CAN信号故障注入

任务目标

使用CANalyzer的CAPL编程接口,向CAN总线注入指定信号故障(信号值越界、信号缺失、校验错误),验证ECU能否正确识别故障并进入安全状态。本案例聚焦于CAPL故障注入脚本的编写与验证方法。

环境依赖

  • Vector CANalyzer 12.0或更高版本(需包含CAPL编译器)
  • VN1610/VN1640等Vector接口卡,或兼容的CANoe硬件
  • 被测ECU通过CAN总线连接至接口卡,总线波特率500kbps
  • DBC文件(包含目标信号定义,如EngineSpeed、Checksum)

实现方案

通过CAPL程序在CANalyzer中实现三类故障注入:信号值越界(将EngineSpeed设为超出物理范围的值)、信号缺失(抑制包含目标信号的报文发送)、校验错误(篡改Checksum字节)。每类故障通过定时器控制注入时长,并在注入期间记录ECU的响应帧。

关键完整代码

/* CAPL脚本:CAN信号故障注入 */
variables
{
  msTimer tInject;
  int injectType = 0;  // 0=无故障, 1=越界, 2=缺失, 3=校验错误
  int injectActive = 0;
  message 0x123 gMsg;  // 假设目标报文ID为0x123
}

on start
{
  setTimerCyclic(tInject, 1000);  // 每秒触发一次注入控制
}

on timer tInject
{
  // 注入序列:每5秒切换一次故障类型
  injectType = (injectType + 1) % 4;
  if (injectType == 0) {
    injectActive = 0;
    write("故障注入停止");
  } else {
    injectActive = 1;
    write("注入故障类型: %d", injectType);
  }
}

on message 0x123
{
  if (injectActive == 0) return;

  gMsg = this;

  switch (injectType)
  {
    case 1:  // 信号值越界:EngineSpeed设为最大值+100
      gMsg.EngineSpeed = 10000;  // 假设DBC中物理最大值为8000rpm
      break;

    case 2:  // 信号缺失:不发送该报文
      return;  // 直接丢弃,不发送

    case 3:  // 校验错误:篡改Checksum字节
      gMsg.Checksum = (gMsg.Checksum + 0x5A) & 0xFF;
      break;
  }

  output(gMsg);  // 发送篡改后的报文
}

on message 0x200  // 监听ECU响应帧(假设ID为0x200)
{
  if (this.ErrorCode == 0x01) {
    write("ECU检测到故障,进入安全状态");
  }
}

运行与验证

  1. 在CANalyzer中新建工程,加载包含目标信号定义的DBC文件。
  2. 将上述CAPL代码添加到Measurement Setup中的CAPL Program节点。
  3. 配置CAN通道为对应接口卡通道,波特率设为500kbps。
  4. 启动测量,观察Write窗口中的故障注入日志。
  5. 使用CANalyzer的Graphics窗口监控EngineSpeed信号波形,确认越界值是否被注入。
  6. 在Trace窗口检查0x123报文的发送间隔,验证信号缺失期间报文是否被抑制。

通过判定标准

  • Write窗口按预期每秒输出一次故障类型切换日志,无CAPL编译错误。
  • 注入越界故障时,Trace窗口显示0x123报文中EngineSpeed值为10000,且ECU在1秒内发出0x200响应帧(ErrorCode=0x01)。
  • 注入缺失故障时,Trace窗口在1秒内无0x123报文出现,ECU发出0x200响应帧。
  • 注入校验错误时,ECU能识别Checksum错误并发出0x200响应帧。
  • 停止注入后,ECU恢复正常通信,不再发送0x200故障帧。

常见问题

  • 信号无法赋值:确认DBC中信号已正确映射至报文0x123,且CAPL中信号名与DBC完全一致。
  • 报文未发送:检查output()函数是否被调用,以及on message处理器是否被正确触发。
  • ECU无响应:确认ECU的故障响应ID(本案例假设为0x200)与实际一致,并检查总线负载和终端电阻。