CAN Interaction Layer (谈谈我对交互层的理解)
Posted 蚂蚁小兵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CAN Interaction Layer (谈谈我对交互层的理解)相关的知识,希望对你有一定的参考价值。
前言
- CAN 报文层交互层的内容呢全网的资源基本上都是对Help文档的直译,对于没接触过的同学理解起来可能比较吃力,这一节我就结合脚本一步一步的阐述下交互层
概念理解
1,下面的图是Help文档的首页。这张图我们能得到哪些信息呢?
- IL层在message发送到总线上之前,默认情况下,IL层的参数是在DBC文件中定义的。
- IL层定义message 和signal的行为方式,比如什么时候发,发送周期是多少。
信号发送的基本类型
1,下图定义了 信号的行为,是周期的发送还是信号又变化的时候发送,又或者只要对信号设置了,不管值又改变否都要发送,下面结合实例一个一个看下
2,这里博主用的是官方的一个工程C:\\Users\\Public\\Documents\\Vector\\CANoe\\Sample Configurations 11.0.81\\CAN\\Easy
,如下图,博主这样排列了四个子面板,待会用得到。
3,这里一定要明白DBC文件中定义了message和signals, 在DBC文件中通过属性定义了他们的发送行为(怎么定义,这里就不展开讲述DBC Editor的编辑操作了),下图我们观察下,节点的属性只有两个,用于说明支持IL层,并且给出引用的Dll.
4,下面是Light node下的 LightState (message)和FlashLight (signal)的发送属性,这些属性都是什么意思,在下面内容会展开讲
5,如下图。我们打开 IL Configration 面板 ,找到 LightState (message)和FlashLight (signal)的发送属性,看的到是和上面DBC文件中定义的相吻合的。
1,周期发送(cycle)
- Cyclic - The message is sent at a fixed cycle time independent of signal values.
1,请看上面的那张图,LightState 报文的发送方式没定义(not_used),但是LightState 信号的发送方式是cycle,所以这整个信号的发送行为就是周期发送
结论:某个message下只要有一个信号的发送方式是cycle,则这个message的发送方式就是cycle
2,信号值有变化了才发送(OnChange)
- OnChange-The message is sent when a changed signal value is written
to the message.
2,根据下图的步骤改变信号的值,发现只有值每次改变才会发送一帧
3,只要设置了信号值就发送(OnWrite)
- OnWrite - The message is sent when the value of a signal is rewritten to the message.
3,根据下图,我连续三次设置了FlashLight==1 ,所以Trace上打印了三帧报文
4,设置了信号值且不等于默认值(IfActive)
- IfActive: The message is sent at a fast cycle time if a signal of the message is set to an active value. As soon as all values are inactive, the message is no longer sent.
这段话可以理解为信号值有变化,而且值不等于默认值,才视为有效值
4,看下FlashLight的默认值是0,设置成IFActive之后,开始Trace中是没报文的,当我将值设置为1之后,立马100ms的周期发送报文,当再设置为0之后,报文立马停发。
5,只要设置了信号值就发送n次(OnWriteWithRepetions)
这个Help中没说,根据理解就是 在OnWrite的基础上,连续以fast cycle time发送 n 次,n的数值由Repetitionsc参数请确定
6,不指定发送方式,(NoSigSendType)
如果signal的发送方式 是不指定发送方式,那么这个信号的发送方式取决于message的发送方式
- 如果message 的发送方式 not_used ,则报文不发送
- 如果message 的发送方式 cycle,则报文发送
message发送的属性
1,下图呢,help中说明了一些message 的常用属性,那么接下来我们就借助IL Configration 说明下这些属性
1,是否支持交互层,(GenMsgILSupport)
这个必须打勾的,不打勾,下面定义的属性全都没用的
2,message发送类型,(GenMsgSendType)
支持以下四种类型
- Cyclic
- NotUsed
- IfActive
- NoMsgSendType
如果message设置为cycle,即使signal 设置为 NoSigSendType ,则报文还是会以cycle发送的
如果message设置为NoMsgSendType 或者NotUsed ,但是signal 设置为 Cyclic ,则报文还是会以cycle发送的
总而言之,message 和signal的发送方式有点取或 的意思,signal发送类型在mesage的属性上进一步定义了报文的发送方式,再比如
如果message设置为cycle,signal 设置为 OnWriteWithRepetions,则报文不仅以cycle发送,还能响应 OnWriteWithRepetions的发送方式。
3,message快速发送周期,(GenMsgCycleTimeFast)
这个参数,在signal 的发送方式者只为 ifactive的时候 有用 ,
4,message连续发送N帧当条件触发的时候,(GenMsgNrOfRepetition)
这个参数,在signal 的发送方式者只为xxxxwithRepetition的时候 有用 ,就是以fast cycle time 连续发送 n帧报文,n就是这个参数定义的内容
5,message延迟多久再发,(GenMsgStartDelayTime)
这个参数,比如这只为10s,则当start Run之后,Trace中10s后你才能看到这个第一帧报文。
IL CAPL Functions
IL CAPL Functions 给了很多的API函数可以用的,下面我就选取一些比较实用的函数讲解下。
1,下图 IL 启动和停止的一个状态机和函数
2,`long ILControlInit () :初始化 IL
这个函数只能在 on preStart中使用 ,目的是阻止 IL自动启动( IL 是默认生效的)
我们在light.can里面添加如下代码
On preStart
{
long ret;
ret = ILControlInit ();
write("****ILControlInit trolinit:%d",ret);
}
测试结果来看,Trace没输出,说明禁止IL成功了。
3,`long ILControlStart() 和 ILControlStop () :开始和停止
我们在light.can里面添加如下代码:
//On preStart
//{
// long ret;
// ret = ILControlInit ();
// write("****ILControlInit trolinit:%d",ret);
//}
on key 'a'
{
long ret;
ret = ILControlStop ();
write("****ILControlStop :%d",ret);
}
on key 'b'
{
long ret;
ret = ILControlStart ();
write("****ILControlStart :%d",ret);
}
测试结果:在4s的时候按下’a‘,Trace中停发了, 然后又按下’b‘ 报文又继续发送
4,`long ILSetMsgEvent (dbMessage msg) :直接向总线上发送一帧报文
我们在light.can里面添加如下代码:
on key 'c'
{
long ret;
ret = ILSetMsgEvent (LightState);
write("****ILSetMsgEvent :%d",ret);
}
测试结果:
5,故障注入
我们在light.can里面添加如下代码:
on key 'd'
{
long ret;
ret = ILFaultInjectionDisableMsg(LightState);
write("****ILFaultInjectionDisableMsg:%d",ret);
}
on key 'e'
{
long ret;
ret = ILFaultInjectionEnableMsg(LightState);
write("****ILFaultInjectionEnableMsg:%d",ret);
}
on key 'f'
{
long ret;
ret = ILFaultInjectionSetMsgCycleTime (LightState,200);
write("****ILFaultInjectionSetMsgCycleTime :%d",ret);
}
on key 'g'
{
long ret;
ret = ILFaultInjectionResetMsgCycleTime (LightState);
write("****ILFaultInjectionResetMsgCycleTime :%d",ret);
}
分别以此按下键盘的,d,e,f,g 测试结果如下:
5,节点的函数我们选择节点开始和停发
因为我们的工程Light 节点只有一个 message ,不能很好的体现对节点的操作,所以我们按照下图添加一个message,
我们在light.can里面添加如下代码:
on key 'h'
{
long ret;
ret = ILNodeControlStop ("Light");
write("****ILNodeControlStop :%d",ret);
}
on key 'i'
{
long ret;
ret = ILNodeControlStart ("Light");
write("****ILNodeControlStart :%d",ret);
}
分别以此按下键盘的,h,i 测试结果如下:
计算 Counter 和CheckSun
IL 层最常用的应该就是计算Counter和 CheckSum了,上面新建的message中包含了counter和checkSum信号的目的就在这一步。
dword applILTxPending(long aId, dword aDlc, byte data[]);这个函数是个回调函数,当前节点又message发出,就会调用这个函数
我们在light.can里面添加如下代码:
dword applILTxPending (long aId, dword aDlc, byte data[])
{
dword i;
byte xor;
if(aId == 0x322)
{
// calculate counter
i = data[1] & 0x0F;
i++;
i = i % 16;
data[1] = i & 0x0F;
// calculate checksum
xor = 0xff;
for(i = 1; i < aDlc; ++i) {
xor = xor ^ data[i];
}
data[0] = xor;
}
return 1; // don't prevent sending of the message
}
从测试结果来看,我们成功的计算了counter 和 check sum
总结
- 回顾下本章节讲述了的知识点,主要还是要对DBC文件对node,message,signal定义的属性要了解,其次IL层的函数用很多,我们选择了一些长得漂亮的函数测试;最重要的是我们可以在IL层就完成对message 的counter和checksum的计算。
- 本博客谢绝转载
- 要有最朴素的生活,最遥远的梦想,即使明天天寒地冻,路遥马亡!
- 如果这篇博客对你有帮助,请 “点赞” “评论”“收藏”一键三连 哦!码字不易,大家的支持就是我坚持下去的动力。当然执意选择白嫖也常来哈。
相关文章
从零开始学习CANoe(一)—— 新建工程
从零开始学习CANoe(二)—— CANdb++ 创建 dbc文件
从零开始学习CANoe(三)—— 系统变量的创建和使用
从零开始学习CANoe(四)—— 设计panel
从零开始学习CANoe(五)—— CAPL 测试节点
从零开始学习CANoe(六)—— XML 测试节点
从零开始学习CANoe(七)—— .NET 测试节点
从零开始学习CANoe(八)—— IG 模块
从零开始学习CANoe(九)—— 断点调试(Debug)
从零开始学习CANoe(十)—— 信号发生器(Signal Generator)
从零开始学习CANoe(十一)—— Statistics Window
从零开始学习CANoe(十二)—— Trace Window
从零开始学习CANoe(十三)—— Logging Window
从零开始学习CANoe(十四)—— 关于Html测试报告
从零开始学习CANoe(十五)—— Graphics
从零开始学习CANoe(十六)—— Canoe的 I/O功能
从零开始学习CANoe(十七)—— Diagnostics
从零开始学习CANoe(十八)—— Python和CANoe的数据交互(1)
从零开始学习CANoe(十九)—— Python和CANoe的数据交互(2)
从零开始学习CANoe(二十)—— Python和CANoe的数据交互(3)
以上是关于CAN Interaction Layer (谈谈我对交互层的理解)的主要内容,如果未能解决你的问题,请参考以下文章