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检测到故障,进入安全状态");
}
}
运行与验证
- 在CANalyzer中新建工程,加载包含目标信号定义的DBC文件。
- 将上述CAPL代码添加到Measurement Setup中的CAPL Program节点。
- 配置CAN通道为对应接口卡通道,波特率设为500kbps。
- 启动测量,观察Write窗口中的故障注入日志。
- 使用CANalyzer的Graphics窗口监控
EngineSpeed信号波形,确认越界值是否被注入。 - 在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)与实际一致,并检查总线负载和终端电阻。