• 前言
  • 一、VH6501 基本配置
  • 二、busoff干扰方式(Demo版)
  • 三、短路干扰(Demo版)
  • 四、CAPL函数干扰
  • 五、采样点测试(Demo版和CAPL函数)
    基于14229+15765的UDS或Bootloader培训
    一、培训内容:14229服务含义,功能应用场景,正响应,负响应,优先级等;15765传输层测试;Capl help常用的函数讲解,最后用CAPL函数做一个完整的UDS自动化测试或Bootloader刷写测试,也可指定培训内容。
    二、收费标准:按课时收费+测试用例收费(也可只线上培训不买测试用例,只按课时收费,一般培训周期一周)。
    三、培训时间:时间为晚上或周末,线上远程讲解。
    四、培训方案:如果你懂协议,看你是否需要买用例,按照用例讲解或者边写边讲函数搭建;如果你不懂协议,先培训协议了解服务,在培训用例编写。
    五、其他培训:Autosar网络管理,Osek网络管理,通信测试等。
    下面是我搭配的CANoe CAPL脚本,无diva也能做的UDS自动化测试脚本。
    前言
    新的一年,新的开始,新的征程;虽说天天大鱼大肉补人,也不能少了知识养分。
    今天带来的是用CAPL如何发送节点报文来实现节点DTC的丢失与恢复自动化测试
    ————————————————
前言

请输入公众号:总线网络。关注我,获取汽车网络开发及测试方面资料,更新干货!
技术支持来自Vector,旨在更多人学习。
总结一下VH6501的使用方式:
在这里插入图片描述

一、VH6501 基本配置

包含驱动安装、硬件连接、通道配置及 CANoe 软件中的基本配置
1、驱动安装:驱动下载地址,https://download.vector.com/drivers/Vector_Driver_Setup.zip
在这里插入图片描述
2、硬件连接
在这里插入图片描述
CH1 的两个 D-SUB9 接口用法

  1. 若将 VH6501 当作硬件接口卡使用(即:用于通信),则接任意一个接口即可;
  2. 若将 VH6501 用于干扰总线,则通常情况下接任意一个接口即可,以下两种情况例外;
    • 情况一:如需外接电源,则必须接公头(母头可不接);
    • 情况二:如需作 CANH 和 CANL 反接测试,则至少要接上母头,
  • 若总线上只接一个被测节点,接母头即可(公头可不接);
  • 若总线上接了多个被测节点,可通过两个接口将 VH6501 串联到总线上。

3、通道配置
在这里插入图片描述
4、干扰功能激活
在这里插入图片描述

二、busoff干扰方式

使用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 反接
在这里插入图片描述

四、CAPL函数干扰

此项是自我摸索总结,参考就好。不一定适应你们的项目。
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测试用例等
一起来学习,进步,交流吧!
在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐