请输入公众号:总线网络。关注我,获取汽车网络开发及测试方面资料,更新干货!
技术支持来自Vector,旨在更多人学习。
总结一下VH6501的使用方式:
包含驱动安装、硬件连接、通道配置及 CANoe 软件中的基本配置
1、驱动安装:驱动下载地址,https://download.vector.com/drivers/Vector_Driver_Setup.zip
2、硬件连接
CH1 的两个 D-SUB9 接口用法:
使用CANoe自带的demo“CANDisturbanceMain”干扰CAN报文
版本:CANoe11.0
Demo路径:C:\Users\Public\Documents\Vector\CANoe\Sample Configurations 11.0.81\CAN\MoreExamples\CANDisturbanceInterface\CANDisturbanceMain(参考)
打开如下图:
主界面:
1、产生位错误(bit error);
2、产生格式错误(form error);
3、干扰ACK Delimeter位,产生格式错误;
4、干扰ACK位,产生no ACK错误;
5、产生填充错误(stuff error)。
Demo路径:C:\Users\Public\Documents\Vector\CANoe\Sample Configurations 11.0.81\CAN\MoreExamples\CANDisturbanceInterface\CANDisturbanceMain(参考)
打开如下图:
1、CAN_H 或 CAN_L 短接到地
2、CAN_H 和 CAN_L 短接
3、CAN_H 或 CAN_L 短接到电源
4、CAN_H 和 CAN_L 反接
此项是自我摸索总结,参考就好。不一定适应你们的项目。
1、新建工程,连接好VH6501,激活。
2、打开C:\Users\Public\Documents\Vector\CANoe\11.0 (x64)_2\Reusable\CAPL_Includes\CANDisturbanceCaplLibs\CANdisturbance.cin,并将此文件移到新工程目录下。
3、capl里加载CANdisturbance.cin文件
includes { #include "CANDisturbanceCaplLibs\\CANdisturbance.cin"//干扰的代码 }
4、我常用的有以下三种干扰函数,CANdisturbance.cin里是有的。
on key '1'
{
// CommonCANDisturbanceLibrary_BusOff_ID_Independed(deviceID);//干扰所有报文,不推荐用来干扰发送的报文,CANoe容易卡掉
// CommonCANDisturbanceLibrary_DisturbAllECUMessageswithoutNMH(deviceID,0x200,0x3ff);//干扰0x200-0x3ff之间报文
// CommonCANDisturbanceLibrary_BusOff_ID(deviceID,0x314,8);//干扰0x314报文
}
5、函数主要参数解析,以CommonCANDisturbanceLibrary_BusOff_ID函数为例
①干扰次数等设置
canDisturbanceTriggerRepetitions reps;//help搜canDisturbanceTriggerRepetitions
busoffDTCDisturb_n = 10;//连续干扰次数
reps.Cycles = 2;//连续干扰10次,2个10次
reps.HoldOffCycles = 0;//周期间隔时间0ms
reps.Repetitions = 32*busoffDTCDisturb_n;//干扰帧数32*10
reps.HoldOffRepetitions = 0;//每帧之间,间隔时间0ms
canDisturbanceSequence rawSequence;//help搜canDisturbanceSequence
ret = rawSequence.AppendToSequence(ticksPerBit, 'd');//显性位
canDisturbanceFrameTrigger frameTrigger;//help搜canDisturbanceFrameTrigger::SetMessage
frameTrigger.TriggerFieldType = @CanDisturbance::Enums::FieldType::DataByte1;//DataByte1
long flags;//help搜canDisturbanceFrameTrigger(CAPL)
flags = @sysvar::CanDisturbance::Enums::ValidityMaskFlags::IDBase
| @sysvar::CanDisturbance::Enums::ValidityMaskFlags::IDExtended
| @sysvar::CanDisturbance::Enums::ValidityMaskFlags::IDE
| @sysvar::CanDisturbance::Enums::ValidityMaskFlags::FDF;
ret = frameTrigger.SetMessage(msg, deviceID, flags);
原理
假设 DUT 会以 10ms 为周期向总线发送 ID 为 0x100 的 CAN 报文。 VH6501 将在程序启动后,在 DUT 发送报文的总线空闲间隙发送 ID 为 0x0 的干扰报文。 VH6501 发送的所有报文,其【ACKSlot】位都为显性位“0”,为系统默认,无需额外特殊设置。每次干扰循环发送结束,微调干扰报文的【CRC Delimiter】位长度,使其逐次缩短,并将后一位【ACK Slot】的长度增加。导致的结果为,后一位【ACK Slot = 0】前移。而一旦显性位电平由后往前,前移至 DUT 采样点位置,被 DUT 采到判定为高电平,则出现 Form Error,DUT 随即发送错误帧,并被 CANoe 捕获到(RxErr)。故 CANoe 测试逻辑通道(VH6501 所在通道)采样点须选取靠前位置(e.g. 50%),从而避免被 VH6501 本身先干扰到。另, 每次干扰循环结束, VH6501 将发送 30 次 ID 为 0x1 的正常报文,从而使 DUT 始终保持 Error Active 状态,因其主动错误帧容易辨认。
1、运用Demo
版本:CANoe11.0
路径:C:\Users\Public\Documents\Vector\CANoe\Sample Configurations 11.0.96\CAN\MoreExamples\CANDisturbanceInterface\CANDisturbanceSamplePointTest
填好panel即可测试。
打开如下图:
2、编写CAPL自动化测试
(1)新建工程,通道 1(VH6501 通道)配置如下图所示, 请确保各处设置与下图一致:
(2)建立Test Module
代码如下:
/*@!Encoding:936*/
includes
{
}
variables
{
CanDisturbanceFrameTrigger frameTrigger;
CanDisturbanceFrameSequence frameSequence;
CanDisturbanceSequence sequence;
CanDisturbanceTriggerRepetitions repetitions;
const int repetition_times_in_one_cycle = 10;
//Number of disturbance repetitions in a cycle
long result;
long errfrmcount; //The error frame count in one cycle
long first_err_bit_length,first_error_occur, ten_error_occur;
long validityMask;
long cycleFlag;
message 0x100 triggerMessage = {FDF = 1}; //The triggermessage.(ID is not important.)
message 0x0 spTestMsg = {FDF = 1}; //The disturbance frame sequence which CRC DEL need to be shorten.
message 0x1 Keep_DUT_ErrorActive = {FDF = 1};
const long CountMsgKeepErrorActive = 30;
long MsgCntKeepErrorActive = 0;
char spTestDone[33] = "SPDone";
}
on errorFrame
{
if(this.msgChannel == @sysvar::CANDisturbanceInterface1::ChannelNo)
{
errfrmcount++;
if((errfrmcount == 1) && (first_error_occur == 0))
{
first_err_bit_length = frameSequence.CRCDelimiter.BitSequence[0].segmentLength[0];
first_error_occur = 1;
write("+++++++++First error frame occurs+++++++++++.");
}
if(errfrmcount == repetition_times_in_one_cycle)
{
ten_error_occur = 1;
testSupplyTextEvent(spTestDone);
}
}
}
on message 0x1
{
if(MsgCntKeepErrorActive <= CountMsgKeepErrorActive)
{
++MsgCntKeepErrorActive;
output(Keep_DUT_ErrorActive);
}
else
{
ActivateTriggerAgain();
}
}
void ActivateTriggerAgain()
{
if(ten_error_occur == 0)
{
errfrmcount = 0;
//CRC Delimiter is shorten with 6.25ns per cycle.
--frameSequence.CRCDelimiter.BitSequence[0].segmentLength[0];
++frameSequence.AckSlot.BitSequence[0].segmentLength[0];
result = canDisturbanceTriggerEnable(@sysvar::CANDisturbanceInterface1::DeviceNo,frameTrigger, frameSequence, repetitions);
if(result == 1)
{
write("Trigger is enabled,frameSequence.CRCDelimiter.BitSequence[0].segmentLength[0] = %d",frameSequence.CRCDelimiter.BitSequence[0].segmentLength[0]);
}
else
{
write("Enable trigger error Result = %d", result);
}
}
}
on sysvar sysvar::CANDisturbanceInterface1::Trigger::State
{
//6501 is Idle after repetition_times_in_one_cycle finish
if(@sysvar::CANDisturbanceInterface1::Trigger::State == 0)
{
//At the end of each disturbance cycle, the VH6501 need to output some normal message to prevent the DUT from being in a passive error state
// because the passive error frame is not easily to be observed and identified.
MsgCntKeepErrorActive = 0;
output(Keep_DUT_ErrorActive);
}
}
testcase SamplePointTest_forVH6501()
{
first_error_occur = 0;
ten_error_occur = 0;
errfrmcount = 0;
cycleFlag = 1;
frameSequence.SetMessage(@sysvar::CANDisturbanceInterface1::DeviceNo,spTestMsg);
validityMask = 0; //trigger on any CAN messages
frameTrigger.SetMessage(triggerMessage,@sysvar::CANDisturbanceInterface1::DeviceNo, validityMask);
frameTrigger.TriggerFieldType = @sysvar::CanDisturbance::Enums::FieldType::EndOfFrame;
frameTrigger.TriggerFieldOffset = 9; //Trigger position is the third bit of IFS.
write("CRC Delimiter Bit Length = %d",frameSequence.CRCDelimiter.BitSequence[0].segmentLength[0]);
repetitions.Cycles = 1;
repetitions.HoldOffCycles = 0;
repetitions.HoldOffRepetitions = 0;
repetitions.Repetitions = repetition_times_in_one_cycle;
result = canDisturbanceTriggerEnable(@sysvar::CANDisturbanceInterface1::DeviceNo,frameTrigger,frameSequence,repetitions);
if(result == 1)
{
write("Trigger is enabled.");
}
else
{
write("Enable trigger error Result = %d", result);
}
result = testWaitForTextEvent(spTestDone, 10000);
if(result == 1)
{
write("frameSequence.CRCDelimiter.BitSequence[0].segmentLength[0] = %d, sample point lies in %f%%~%f%%",
frameSequence.CRCDelimiter.BitSequence[0].segmentLength[0],
(frameSequence.CRCDelimiter.BitSequence[0].segmentLength[0] * 100.00) /
frameSequence.DLC.BitSequence[1].segmentLength[0], (first_err_bit_length *100.00) / frameSequence.DLC.BitSequence[1].segmentLength[0]);
}
}
void maintest()
{
SamplePointTest_forVH6501();
}
(3)执行,最后将以下程序放置于 CAPL Test Module 节点当中,并通过 Test Module 执行:
选择合适自己的写脚本的方式,能事半功倍!祝福各位学习CANoe的同学能早日毕业!
有不完善的地方欢迎留言或加我vx补充。
请输入公众号:总线网络。关注我,获取汽车网络开发及测试方面资料,更新干货!
分享总线开发知识
分享CAN/CANFDLIN/ETH等网络资料
分享CANoe/TSMaster/PCAN等设备工具使用
分享UDS/NM/Bootloader测试用例等
一起来学习,进步,交流吧!