最近开始使用CANoe来模拟CAN节点,碰到了rolling count 自增和checksum自动计算的问题。rolling cnt的实现还是简单的,例如使用on message实现:
on message IPB1
{
$IPB1_Rolling_counter ++;
}
但是checksum的逻辑在这里面怎么做不是非预期的,根本原因是on message的触发意味着CAN报文已经被发出来了,而不是我们以为的"提前算好"checksum再随报文发送出去。
网上查到了applILTxPending 这个函数就是专门为这个需求存在的,只是网上教程没有解释的很清楚,导致我调试花了一些时间,现在就就来讲讲如何使用的总结结论吧。
一、首先要会导入dbc,会新增节点并配置成自己想要的模拟节点
二、右键ECU节点后选择Open IL Configuration,对要操作的报文进行使能,默认是全部使能的
三、打开capl脚本,编写.can文件里的脚本
1 请注意避免直接操作信号名
2 checksum的算法按照自己的需要进行修改
3 按照需要再增加if(aId == XXXX)逻辑段增加不同的帧上的信号值设置,按需增加全局变量进行数值的"记忆"
4 applILTxPending函数被定义在capl中就会被有条件地执行,不需要开发人员特地考虑它的调用位置。
如下是我的产品功能需要编写的逻辑,可以参考我的注释,写得很详细了
/*@!Encoding:936*/
includes
{
}
variables
{
byte g_IPB1_Rolling_counter; //定义变量
}
//! 注意直接使用信号名是非预期的
dword applILTxPending (long aId, dword aDlc, byte data[])
{
dword i;
byte xor;
if(aId == IPB1.id)// 或者使用指定的message ID例如:0x200
{
// set the new crolling_cnt (在第6个字节高4位)
data[6] = (data[6] & 0x0f) | (g_IPB1_Rolling_counter<<4);
// calculate checksum
xor = 0x00;
for(i = 0; i < 7; ++i) {
xor += data[i];
}
xor ^= 0xFF;
// set the new checksum (在第7个字节)
data[7] = xor;//$IPB1_CheckSum_0D5 = xor;直接使用信号名会延迟一帧
// prepare the next crolling_cnt
if(g_IPB1_Rolling_counter++ >=15) //发送每一帧cntr都会加1;
{
g_IPB1_Rolling_counter = 0;
}
}
return 1; // don't prevent sending of the message
}
运行CANoe查看结果:
希望对你有所帮助!其它细节可以查找help文档进行更详细的学习。