1. 诊断请求发送基础
任务目标
编写一个CAPL脚本,通过CAN总线向ECU发送UDS诊断请求(读取VIN码,服务ID 0x22,DID 0xF190),并验证是否收到正确的肯定响应。
环境依赖
需要Vector CANoe/CANalyzer环境,并配置好CAN通道(本文以CAN1为例)。诊断请求通过CAPL的diag函数库或原始CAN帧发送均可,本案例采用原始CAN帧方式,不依赖诊断数据库(CDD),便于独立运行。
关键完整代码
/* 诊断请求发送基础 - 读取VIN码 */
variables
{
const int CAN_CHANNEL = 1; // CAN通道
const long ARB_ID_REQ = 0x7E0; // 物理请求ID(诊断仪->ECU)
const long ARB_ID_RESP = 0x7E8; // 物理响应ID(ECU->诊断仪)
// 诊断请求报文:0x22(读取DID) + 0xF1 0x90(VIN DID)
const byte REQ_DATA[4] = {0x02, 0x22, 0xF1, 0x90};
message CAN1_MSG_REQ = { dlc = 8 }; // 请求报文对象
message CAN1_MSG_RESP = { dlc = 8 }; // 响应报文对象
byte respData[8]; // 存储响应数据
int respCount = 0; // 响应计数器
timer tTimeout; // 超时定时器
}
on start
{
// 配置请求报文
CAN1_MSG_REQ.id = ARB_ID_REQ;
CAN1_MSG_REQ.can = CAN_CHANNEL;
CAN1_MSG_REQ.byte(0) = REQ_DATA[0]; // PCI:单帧,2字节数据
CAN1_MSG_REQ.byte(1) = REQ_DATA[1]; // SID:0x22
CAN1_MSG_REQ.byte(2) = REQ_DATA[2]; // DID高字节:0xF1
CAN1_MSG_REQ.byte(3) = REQ_DATA[3]; // DID低字节:0x90
// 其余字节默认填充0xCC或0x00,不影响诊断解析
// 发送请求
output(CAN1_MSG_REQ);
write("诊断请求已发送:读取VIN (DID 0xF190)");
// 启动500ms超时定时器
settimer(tTimeout, 500);
}
on message CAN1_MSG_RESP
{
int i;
respCount++;
canceltimer(tTimeout);
// 复制响应数据
for (i = 0; i < 8; i++)
{
respData[i] = this.byte(i);
}
// 验证响应:检查SID是否为0x62(肯定响应)
if ((this.byte(1) & 0x3F) == 0x22) // 0x62 & 0x3F = 0x22
{
write("收到肯定响应!响应帧数:%d", respCount);
write("响应数据:%02x %02x %02x %02x %02x %02x %02x %02x",
respData[0], respData[1], respData[2], respData[3],
respData[4], respData[5], respData[6], respData[7]);
// 检查VIN数据长度(PCI字节指示数据长度)
if (respData[0] > 0x03)
{
write("VIN数据长度:%d 字节", respData[0] - 2);
write("VIN内容(ASCII):");
for (i = 3; i < respData[0] + 1 && i < 8; i++)
{
write(" [%d] 0x%02X = '%c'", i, respData[i], respData[i]);
}
}
}
else
{
write("收到否定响应或错误SID:0x%02X", this.byte(1));
}
}
on timer tTimeout
{
write("错误:等待响应超时(500ms),未收到ECU响应");
}
运行与验证方法
运行步骤:
- 在CANoe中新建工程,配置CAN1通道连接仿真总线或真实ECU。
- 将上述代码粘贴到CAPL Browser中,关联到CAN1网络节点。
- 点击“编译”确保无语法错误,然后点击“运行”启动测量。
验证通过条件:
- 在Write窗口看到“诊断请求已发送”日志。
- 若ECU正常响应,应看到“收到肯定响应”及响应数据,其中VIN的ASCII字符可读。
- 若ECU无响应或响应错误,Write窗口会显示超时或否定响应提示。
预期输出(以仿真ECU返回VIN“12345678901234567”为例):
诊断请求已发送:读取VIN (DID 0xF190)
收到肯定响应!响应帧数:1
响应数据:12 62 f1 90 31 32 33 34
VIN数据长度:17 字节
VIN内容(ASCII):
[3] 0x31 = '1'
[4] 0x32 = '2'
...
注意:实际VIN内容取决于ECU实现,上述仅为格式示例。若VIN超过4字节(单帧最多传6字节数据),ECU会发送多帧响应,本案例仅验证首帧正确性,完整VIN拼接需扩展处理多帧逻辑。