Vector - CAPL - 检测报文周期

CAN作为当前车上最重要的通信协议之一,总线上报文的周期状态可以说对于各个ECU之间的协调工作,起到了相当重要的作用,因此无论是在网络管理测试中、还是在通信层测试中,都会涉及到总线报文的周期测试;我看到蛮多人直接使用on message CAN1.*这种方式,而且在脚本工程中大量使用同一个on message,很多时候这种方式不易维护,而且易出现调用混乱的情况;那有没有一种办法能够减少on message的使用,并且能够准确的测出报文的周期呢?答案是肯定的,今天就来介绍下报文的周期测试。

ChkStart_MsgAbsCycleTimeViolation

功能:

检查循环消息的出现情况。

如果消息发送之间的时间小于aMinCycleTime或大于aMaxCycleTime,则会生成事件。

不需要检查的限制设置为0;必须至少指定一个限制。

只能在CAPL的“启动时”部分或测量过程中启动。

参数为“slotID”的数字构造函数只能应用于FlexRay总线。

对于FlexRay,只有有效的数据帧和PDU被识别为通信,空帧和错误帧被忽略。

注意:

根据使用的参数类型,如果相应的数据库对象不明确(dbc存在同名ID报文),则只需在调用函数之前设置多总线环境中的适当总线上下文。

aObservedMessage:存在于添加到工程dbc的报文

aMinCycleTime:

0:未设置检查限制

0<x<aMaxCycleTime:报文两次出现在CAN总线的时间间隔

默认单位[ms],可通过函数ChkConfig_SetPrecision进行更改。

aMaxCycleTime:

0:未设置检查限制

aMinCycleTime < x < ∞:报文两次出现在CAN总线的时间间隔

默认单位[ms],可通过函数ChkConfig_SetPrecision进行更改。

aCallback:在模拟节点中,必须设置此参数;在测试模块中,此参数是可选的。

slotID:此数字指定特定的FlexRay插槽;其值必须介于1和2047之间。

cycleOffs:这个数字表示基本周期,该值必须小于重复因子,并且在0和63之间的范围内。该值与重复因子可在FlexRay框架的“循环复用”

cycleRep:此数字表示循环重复系数,该值必须介于1和64之间,并且是2的倍数(例如1、2、4、8、16、32或64)。该值与基本周期一起决定FlexRay帧的“循环复用”。

channelMask:标识通信控制器的FlexRay通道。值1将检查通道A上的帧,2将检查通道B上的帧以及3将检查任何通道(A/B)上的帧。

aSourceAddress:J1939参数组的源地址。

可能的值:

0–253、255:观察从该地址发送的参数组。

254:观察从任何地址发送的参数组。

-1(或0xFFFFFFFF):观察从数据库中参数组指定的源地址发送的参数组。

aDestinationAddress:J1939参数组的源地址。

可能的值:

0–253、255:观察从该地址发送的参数组。

254:观察从任何地址发送的参数组。

-1(或0xFFFFFFFF):观察从数据库中参数组指定的源地址发送的参数组。

aSendNode:J1939参数组的发送节点。

aReceiveNode:J1939参数组的接收节点。此参数仅用于目标特定参数组(PDU1格式)。

MessageId:A429的报文ID

返回值:

0:无法创建检查,且不得引用

>0:已成功创建检查,可以使用返回的(handle-)值进行引用

常见问题:

数据库中不存在消息对象

两个相对限值均为0

CAPL回调不存在

代码示例

// 检查报文周期在90ms - 100ms之间
checkId = ChkStart_MsgAbsCycleTimeViolation (MsgToObserve, 90, 110);
TestAddCondition(checkId);
// 不同动作的顺序和等待条件
TestWaitForTimeout(1000);
TestRemoveCondition(checkId);

ChkStart_MsgRelCycleTimeViolation

ChkStart_NodeMsgsRelCycleTimeViolation

功能:

检查循环消息的出现情况。

如果消息发送之间的时间小于minRelCycleTime*GenMsgCycleTime(DB属性)或大于maxRelCycleTime*GenMsg CycleTime,则会生成事件。

不需要检查的限制设置为0;必须至少指定一个限制。

只能在CAPL的“启动时”部分或测量过程中启动。

参数为“slotID”的数字构造函数只能应用于FlexRay总线。

对于FlexRay,只有有效的数据帧和PDU被识别为通信,空帧和错误帧被忽略。

说明:根据所使用的参数类型,如果相应的数据库对象不明确,则只需在调用函数之前设置多总线环境中的适当总线上下文。

aObservedMessage:存在于添加到工程dbc的报文

aMinRelCycleTime:

0:未设置检查限制

0<x<1:限制检查条件

aMaxRelCycleTime:

0:未设置检查限制

1 < x < ∞:限制检查条件

aCallback:在模拟节点中,必须设置此参数;在测试模块中,此参数是可选的。

slotID:此数字指定特定的FlexRay插槽;其值必须介于1和2047之间。

cycleOffs:这个数字表示基本周期,该值必须小于重复因子,并且在0和63之间的范围内。该值与重复因子可在FlexRay框架的“循环复用”

cycleRep:此数字表示循环重复系数,该值必须介于1和64之间,并且是2的倍数(例如1、2、4、8、16、32或64)。该值与基本周期一起决定FlexRay帧的“循环复用”。

channelMask:标识通信控制器的FlexRay通道。值1将检查通道A上的帧,2将检查通道B上的帧以及3将检查任何通道(A/B)上的帧。

aSourceAddress:J1939参数组的源地址。

可能的值:

0–253、255:观察从该地址发送的参数组。

254:观察从任何地址发送的参数组。

0xFFFFFFFF:观察从数据库中参数组指定的源地址发送的参数组。

aDestinationAddress:J1939参数组的源地址。

可能的值:

0–253、255:观察从该地址发送的参数组。

254:观察从任何地址发送的参数组。

-0xFFFFFFFF:观察从数据库中参数组指定的源地址发送的参数组。

aSendNode:J1939参数组的发送节点。

aReceiveNode:J1939参数组的接收节点。此参数仅用于目标特定参数组(PDU1格式)。

返回值:

0:无法创建检查,且不得引用

>0:已成功创建检查,可以使用返回的(handle-)值进行引用

常见问题:

数据库中不存在消息对象

两个相对限值均为0

CAPL回调不存在

报文不是周期报文

代码示例:

// 检查周期报文的状态
checkId = ChkStart_MsgRelCycleTimeViolation (MsgToObserve, 0.9, 1.1);
TestAddCondition(checkId);
// 检查报文周期的时间
TestWaitForTimeout(1000);
TestRemoveCondition(checkId);

TestAddCondition

功能:添加事件对象或事件文本作为条件。测试服务库中的检查适合作为事件对象。

此功能可以在测试用例中使用,也可以在主测试级别上使用。

aAuxHandle:事件对象,例如来自测试服务库的检查,指定的是创建检查时返回的句柄。

aEventText:应监视其发生的事件的文本名称,此事件可以通过函数TestSupplyTextEvent触发

aBehavior:通常情况下,在条件损伤的情况下,只在测试报告中进行相应的输入,并且将活动测试用例的判决设置为“失败”。在特殊情况下,可以以其他方式设置此行为:

0

默认行为、测试报告中的条目以及将判决设置为“失败”

1

只在测试报告中输入一个条目,结果保持不变

2, 3

保留值

返回值:

0:已成功添加条件

<0:无法添加条件

代码示例

添加检查作为条件

dword checkId;
dword numCheckEvents;

// 开始“错误帧”观测
checkId = ChkStart_ErrorFramesOccured();
//添加检查作为条件,
//这意味着违反检查规定的行为会被报告
//测试用例的判决被设置为“失败”
TestAddCondition(checkId);
//不同动作的顺序和等待条件
TestWaitForTimeout(1000);
//删除检查作为条件
TestRemoveCondition(checkId);

// 停止检查
ChkControl_Stop(checkId);
// 重置检查的存储值
ChkControl_Reset(checkId);
//在不添加作为条件的情况下再次开始检查,
//这意味着观察到错误帧,但违反了
//未报告,也未将测试案例的判决设置为“失败”
ChkControl_Start(checkId);
//不同动作的顺序和等待条件
TestWaitForTimeout(1000);
// 停止检查
ChkControl_Stop(checkId);

// 分析数据
numCheckEvents = ChkQuery_NumEvents(checkId);
if (numCheckEvents > 0)
TestStepFail("Error Frame occurred!");
// 删除检查数据
ChkControl_Destroy(checkId);

添加文本事件作为条件

// 用于检查是否出现错误帧的测试用例
testcase CheckErrorFrameReceived ()
{
   TestAddCondition("ErrorFrameReceived");
   // 不同动作的顺序和等待条件
   TestWaitForTimeout(1000);
   TestRemoveCondition("ErrorFrameReceived");
}

// 提供文本事件的处理程序
on errorFrame
{
   TestSupplyTextEvent("ErrorFrameReceived");
}

TestRemoveCondition

功能:删除作为条件添加的事件对象或事件文本。

此功能既可以在测试用例中使用,也可以在测试模块级别上使用。

注意:条件只能在测试用例中或在添加了条件的测试模块级别上删除。如果一个测试用例被放弃,那么在这个测试用例中创建的约束将被自动删除。类似地,随着测试模块的结束,所有约束都会自动删除。

aAuxHandle:事件对象,例如来自测试服务库的检查。指定的是创建检查时返回的句柄。

aEventText:应监视其发生的事件的文本名称。此事件可以通过函数TestSupplyTextEvent触发。

返回值:

0:已成功移除条件

<0:无法移除条件

代码示例

同上

以上即为检查报文周期的函数,通常来说,如果是知道报文的周期,我们可以使用ChkStart_MsgAbsCycleTimeViolation函数将待检查报文加入进去,然后把周期检查范围作为参数输入,然后通过函数TestAddCondition将句柄加入,等待检查时间,通过函数TestRemoveCondition移除检查条件;最终输出测试结果。

如果是不知道报文周期,那使用函数ChkStart_MsgRelCycleTimeViolation加入检查事件,更方便点;特别是在网络管理或者通信层的测试中,我们一般要求报文周期偏差在10%或者20%以内,通过这种方法最是方便,然后同样通过函数TestAddCondition、TestWaitForTimeout、TestRemoveCondition共同使用,最省事的输出测试结果。

  • 2
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
是的,您可以使用CAPL编写脚本来实现全程检测报文周期的功能。以下是一个示例代码,可以帮助您实现这个功能: ```CAPL variables { int messageCounter = 0; // 报文计数器 float messagePeriod = -1; // 报文周期 float messageFrequency = -1; // 报文频率 dword lastMessageTime = 0; // 上一次接收到报文的时间戳 } on message * // 监听所有CAN报文 { if (this.ext == 0) // 只处理标准帧 { messageCounter++; // 计数器加1 dword currentTime = timeNow(); // 获取当前时间戳 if (lastMessageTime != 0) // 如果不是第一次接收到报文 { float timeDiff = (currentTime - lastMessageTime) / 1000000.0; // 计算时间差,单位为秒 if (messagePeriod < 0) // 如果是第一次计算报文周期 { messagePeriod = timeDiff; } else { messagePeriod = 0.9 * messagePeriod + 0.1 * timeDiff; // 采用滑动平均法计算报文周期 } messageFrequency = 1.0 / messagePeriod; // 计算报文频率 } lastMessageTime = currentTime; // 更新上一次接收到报文的时间戳 } } on timer event 1 // 定时器事件,定时输出报文周期和频率 { write("Message period: %.3f s, frequency: %.3f Hz\n", messagePeriod, messageFrequency); setTimer(1, 1000); // 重新设置定时器,每隔1秒输出一次 } ``` 在上面的代码中,我们使用 `on message *` 监听所有的CAN报文,并通过计数器和时间戳计算出报文周期和频率。每隔1秒,我们使用 `write()` 函数输出报文周期和频率。您可以根据需要修改代码中的参数和输出格式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

车载网络测试

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值