不知道大家有没有遇到过这个问题?
当我们在学习如何测试网络管理时,难题不在于如何编写测试脚本,而是编写完测试脚本后,没有真实被测件来让我们执行测试脚本,进而调试脚本。这也是我在给大家讲CANoe工具和CAPL编程语言时,很多人会问我的问题:他们没有CANoe硬件,又或者他们没有测试环境,也就是被测件。也就无法确定自己辛辛苦苦敲出的代码,是不是能够顺利运行?
没有CANoe硬件不会成为你学习CANoe工具的障碍,没有真实被测件也不会是你练习CAPL代码的拦路虎。这些我们在《CAPL编程语言系统性课程》里都有过详细的介绍。
今天我们就针对如何让你编写的网络管理的测试脚本顺利运行,聊一聊在CANoe中要如何模拟一个ECU仿真节点,让其具有网络管理功能。
首先,添加一个网络节点:
接着要让ECU在收到外部网络管理报文时唤醒(假设是远程唤醒),唤醒的表现就是自己进入Repeat Message状态时要往外发送自己的网络管理报文和应用报文。
要实现上面的需求并非难事,大家都是使用CAPL的高手,有好几层楼那么高:
on message *
{
if (this.id == @sysvar::ExtNmMsg::id)//接收到外部网络管理报文,唤醒,往外发送自己的网管报文和应用报文
{
setTimerCyclic(t_intNmMsg, @sysvar::IntNmMsg::period);//循环发送自己的网络管理报文
setTimerCyclic(t_intAppMsg, @sysvar::IntAppMsg::period);//循环发送周期性报文
}
}
通过上面的代码,仿真节点在接收到外部网管报文后开始循环发送自己的网管报文和应用报文,可以看作是唤醒并进入Repeat Message了。然后呢?什么时候Repeat Message状态结束?如何进入Normal Operation或Ready Sleep?这些要如何通过代码实现?
按照上面的思路走一步看一步写一步肯定是不行的,逻辑太多了,有很多的异步需要处理。
就算是上面的代码,其实也有逻辑上的漏洞。仿真节点在接收到外部网管报文时是不是应该要先判断自己是不是处于Bus Sleep状态,才能决定是否要唤醒呢?所以看似简单的实现,要考虑的因素太多,有个完整的代码结构很重要!
下面我们来聊一聊我在《CAPL编程语言系统性课程》中是如何实现的。
思路
首先,ecu节点的网络管理状态,是互斥的,也就是说同时只能有一种状态,且进入某种状态时会自动触发这个状态的某些行为。比如说进入RepeatMessage时ecu开始发送nm和app报文,所以在capl中我们可以用一个什么东西表示网络管理状态?同时当进入这个状态时能够自动触发操作呢?
答案是系统变量!所以我们定义一个系统变量表示网络管理状态,它就是网络管理状态标志位。它的不同值表示不同的状态。当ecu进入某个状态时,就把这个系统变量值改变为这个状态值,同时用on sysvar事件函数来实现进入这个状态时的行为。
- Sysvar::NmState::Flag = 0 -> BusSleepMode
- ......................= 1 -> RepeatMessage
- ......................= 2 -> NormalOperation
- ......................= 3 -> ReadySleep
- ......................= 4 -> PrepareBusSleepMode
那ecu如何唤醒和如何维持在ReadySleep,这是如何实现呢?
可以通过on message事件函数来接收外部网络管理报文,当接收到外部网络管理报文时,ecu从BusSleepMode唤醒,进入RepeatMessage,那么只需要把网络管理状态标志位,也就是那个系统变量设置为RepeatMessage的值。
当然,不是任何状态下接收到外部网络管理报文都要切状态的,所以还需要判断当前的状态,也就是获取系统变量当前的值。
每个状态的timeout,也就是定时器是如何倒计时的?
这个简单,capl中的timer就是一个定时器,就可以倒计时。那么进入某个状态就
需要启动自己的定时器,当倒计时结束时,就需要离开这个状态,进入下一个状态,也就是把代表网络管理状态标志位的系统变量值改为下一个状态的值。
为了让大家能够运行自己编写的网络管理的脚本,我用这种思路实现了这两条状态切换链路:
-
BusSleepMode -> RepeatMessage -> ReadySleep -> PrepareBusSleepMode
-
BusSleepMode -> RepeatMessage -> ReadySleep -> ReadySleep -> ReadySleep…
最终的代码量其实很少,这里就不放出来了。 感兴趣的可以参加CAPL课程,里面有很多能让你学习的东西。
最后,有人可能会说:“我有测试环境,我干嘛要写一个模拟的网络管理功能的被测件?”
有的时候,写代码是工作,但写一些工作之外的代码,可以是一种兴趣,那才是你前进的动力!
由此深入,要如何模拟一个能够满足以太网测试的被测件呢?我们在《车载以太网通信测试课程》中继续详聊!