【转载】CANoe 入门 Step by step系列(三)简单例子的剖析
来源:http://www.cnblogs.com/dongdonghuihui/archive/2012/09/26/2704623.html
最好的学习方式是什么?模仿。有人会问,那不是山寨么?但是我认为,那是模仿的初级阶段,当把别人最好的设计已经融化到自己的血液里,变成自己的东西,而灵活运用的时候,才是真正高级阶段。正所谓画虎画皮难画骨。但初级阶段仍然是必须经历的过程,他会使你在达到高级阶段的过程中少走很多弯路,下面我们来迈出这一步。先研究一下别人的简单例子。
最好的例子莫过于Vector本身的Demo了,这个在安装完CANoe之后就会被自动安装。先看最简单的一个,名字叫Easy,但并不简单哦,比我们之前介绍的所有的东西都整合再一起了,很简单,但很全面。但是假如你说,这个我自己也可以完全自己写出来(并不是仅仅是看懂哦),那么我可以肯定的说,在工作中,你完全可以胜任一般的任务要求哦~,剩下的只是工作量的问题了。但我相信到现在为止,你们很多人,都无法写出这样的程序,所以我建议你们把这个程序好好的研究明白,这点很重要。废话不多说,上图,下面是打开运行后的界面。
通过面板可以控制,及显示很多动画效果,做的非常的漂亮。在其余的窗体也将主要的数据以图表等表现方式呈现出来。
我们先看一下DBC的内容吧
Signals:
EngineSpeed 车速信息
FlashLight 双跳灯
HeadLight 大灯
OnOff 引擎状态
Messages:
EngineState 引擎状态:包含的信号有OnOff,EngineSpeed
LightState 灯光状态:包含的信号有FlashLight,HeadLight
Network nodes:
Display 显示节点,接收所有消息
Engine 引擎节点,发送EngineState 消息
Light 灯光节点,发送LightState 消息
Environment variables: 环境变量,一般与界面的组件相关联,这样就实现了图形化界面的控制与显示,下面就是关联的界面组件
EnvEngineSpeedDspMeter
EnvEngineSpeedDspText
EnvEngineSpeedEntry
EnvEngineStateDsp
EnvEngineStateSwitch
EnvHazardLightsSwitch
EnvHeadLightSwitch
EnvLightDsp
注意一下信号的信息:
Definition页面的,Init.Val的输入框使能了,之前是灰色的状态,为什么呢?点击一下蓝色的带下划线的连接,弹出窗台如下:
意思是说这个值的设置,必须要定义的属性才能有效,之前一直没有提到信号的属性,这次还是第一次遇到哦。个人理解信号属性是表明信号的特点的一系列参数,当然消息和节点也都有对应的属性。为了更加详细的了解这个属性,我们求助于帮助。
哦,明白了,原来是用来初始化数据的哦。其实在Definition表示的是物理值,都要转换成Raw值保存到GenSigStartValue属性中。在属性的创建我们之前也没有提到过,这里讲一下,请在CANdb++ Editor菜单中,View->Attribute Definitions
右键,New,填写好信息即可。属性背后跟行为是密切相关的,甚至跟底层dll,其他的一些属性请参考Help文档,当然重要的属性我们也会跟大家在后面提到。
dbc还有一些细节,就是接受的消息的定义,之间也没介绍过,例如Display节点只接收消息,那么你就应该在节点的属性上进行配置,方法是右击节点然后点Edit Node,在Mapped Rx Sig.中就可以定义接收的信号了,Add…
其实不定义接收消息也是可以的,但会在File->Consistency check 的检查中中显示出无接收节点等的报警。例如前面第一讲例子的dbc的检查如下:
再看一下CAPL程序。
engine.can 程序如下:
variables
{
}
on envvar EnvEngineStateSwitch //当拨动开关的时候,会更改发动机发出的信号
{
$EngineState::OnOff = @this; //注意信号和环境变量直接赋值时的符号,信号用$,环境变量用@
if(@this)
$EngineState::EngineSpeed = @EnvEngineSpeedEntry;
else
$EngineState::EngineSpeed = 0;
}
on envvar EnvEngineSpeedEntry //当移动车速滑条时,会更改发动机发出的信号
{
if(@EnvEngineStateSwitch)
{
$EngineState::EngineSpeed = @this;
}
}
on start //程序开始运行的时候,将调用所有的环境变量的事件
{
CallAllOnEnvVar(); // call all envvar procedures of this model and
// thus consider the START VALUES of all environment
// variables for:
// - initialization of all message variables
// - starting of any timers
// - sending messages (output) with start values
}
light.can 的程序如下:
variables
{
msTimer tFlashLightFrequency; //定义闪灯定时器
const int gFlashLightFrequency = 500; //定义闪灯频率,初始化为500ms
int gHazardLightsStatus = 0; //定义危险灯信号
int gDebugCounterTX = 0; //用于调试,记录TX报文个数
int gDebugCounterTXRQ = 0; //用于调试,记录TXRQ报文个数
int gDebugCounterRX = 0; //用于调试,记录RX报文个数
}
on envvar EnvHeadLightSwitch //大灯开关状态更改时,更新灯光消息的信号
{
// assign EV value to the message signal
$LightState::HeadLight = @this;
}
on start
{
CallAllOnEnvVar(); // call all envvar procedures of this model and
// thus consider the START VALUES of all environment
// variables for:
// - initialization of all message variables
// - starting of any timers
// - sending messages (output) with start values
setWriteDbgLevel(0); // set DbgLevel = 1 to get more information in Write-Window
}
on message LightState //调试用,打印相关信息
{
if (this.dir == TX)
{
gDebugCounterTX++;
if(gDebugCounterTX == 10)
{
writeDbgLevel(1,"LightState TX received by node %NODE_NAME%");
gDebugCounterTX = 0;
}
}
if(this.dir == TXREQUEST)
{
gDebugCounterTXRQ++;
if(gDebugCounterTXRQ == 10)
{
writeDbgLevel(1,"LightState TXREQUEST received by node %NODE_NAME%");
gDebugCounterTXRQ = 0;
}
}
if (this.dir == RX)
{
gDebugCounterRX++;
if(gDebugCounterRX == 10)
{
writeDbgLevel(1,"Error: LightState RX received by node %NODE_NAME%");
gDebugCounterRX = 0;
}
}
}
on envVar EnvHazardLightsSwitch //危险警示灯开关变化时,更新灯光消息的闪灯信号
{
if (@this)
{
gHazardLightsStatus = 1;
setTimer(tFlashLightFrequency, gFlashLightFrequency);
}
else
{
cancelTimer(tFlashLightFrequency);
gHazardLightsStatus = 0;
}
$LightState::FlashLight = gHazardLightsStatus;
}
on timer tFlashLightFrequency //危险报警灯间隔闪烁的控制
{
gHazardLightsStatus = (gHazardLightsStatus == 1 ? 0 : 1);
$LightState::FlashLight = gHazardLightsStatus;
setTimer(this, gFlashLightFrequency);
}
on key '0' //按键事件,定义打印调试信息的等级
{
setwriteDbgLevel(0);
}
on key '1' //按键事件,定义打印调试信息的等级
{
setwriteDbgLevel(1);
}
以上程序,有C语言基础的同学应该都可以看得懂,这里不用详细介绍了。
看完程序大家可能有个疑问,没有调用任何发送CAN消息的函数(只是更改其中的信号),但报文却真的发出去了,这是为什么呢?
这是因为周期发送消息的工作,已经在消息的属性中定义了,这样消息会自动周期的发送。如下:
这个在消息的属性查看中的界面,当然也可以在上面我们介绍的View->Attribute Definitions,进行修改和查看,但区别是,这个只是针对个别消息的,View->Attribute Definitions,是针对所有的情况。还有消息属性中,对此进行归类,以上归类到Interaction Layer这个是CAN通讯的交互层。上面的各个属性的具体含义,请参考帮助文档,都有详细的说明。
下面说一下界面。
选中一个界面组件,在状态栏中可显示他的类型,关联的对象等信息。右边为属性窗口,定义选中组件的属性
这个组件类型为:Switch/Indicator
属性栏中:
Image 表示该组件使用的图片,因为要表示几种状态,所以做成这样,尺寸105x34 pix
State Count 表示状态的个数
其他的属性不一一介绍了,自己试一下基本可以知道,实在不行求助帮助文档,这里不一 一介绍了。
到现在整个工程的剖析基本上结束了,但说过的这些不足以覆盖所有的细节,但基本脉络已经很清晰了,剩下的可以自己研究,都不难理解。个人建议,在实际工作中创建自己的工程,当遇到问题是,参考例子中的实现方式,这样更加帮助理解。进步也最快。
【转载】CANoe 入门 Step by step系列(三)简单例子的剖析的更多相关文章
- CANoe 入门 Step by step系列(三)简单例子的剖析【转】
最好的学习方式是什么?模仿.有人会问,那不是山寨么?但是我认为,那是模仿的初级阶段,当把别人最好的设计已经融化到自己的血液里,变成自己的东西,而灵活运用的时候,才是真正高级阶段.正所谓画虎画皮难画骨. ...
- ASP.Net Core 2.2 MVC入门到基本使用系列 (三)
本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...
- ASP.Net Core 2.2 MVC入门到基本使用系列 (三)(转)
本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...
- 【转载】网站配置Https证书系列(三):IIS网站设置Http链接直接跳转Https安全连接
Http链接请求是以明文的方式传输,在传输的过程中很容易被篡改数据,一个典型的例子就是运营商的网络劫持注入广告信息等,而Https请求则是安全加密的请求,报文数据以密文的形式进行传输.当IIS网站配置 ...
- sql server 备份与恢复系列三 简单恢复模式下的备份与还原
一.概述 前面讲了备份的一些理论知识,这篇开始讲在简单恢复模式下的备份与还原.在简单模式下是不能做日志备份的,发生灾难后,数据库最后一次备份之后做的数据修改将是全部丢失的,所以在生产环境下,数据又很重 ...
- ASP.Net Core 2.2 MVC入门到基本使用系列 (二)
本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...
- ASP.Net Core 2.2 MVC入门到基本使用系列 (四)
本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...
- Linux Kernel系列三:Kernel编译和链接中的linker script语法详解
先要讲讲这个问题是怎么来的.(咱们在分析一个技术的时候,先要考虑它是想解决什么问题,或者学习新知识的时候,要清楚这个知识的目的是什么). 我在编译内核的时候,发现arch/arm/kernel目录下有 ...
- 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥) 介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...
随机推荐
- 【JAVAWEB学习笔记】网上商城实战5:后台的功能模块
今日任务 完成后台的功能模块 1.1 网上商城的后台功能的实现: 1.1.1 后台的功能的需求: 1.1.1.1 分类管理: [查询所有分类] * 在左侧菜单页面中点击分类管理: * ...
- html <input type="text" />加上readonly后在各种浏览器的差异。
<html> <body> <p>Name:<input type="text" name="email" /> ...
- 前端程序员的蜕变——JS的 event 对象属性、使用实例、兼容性处理(极大提高代码效率、减少代码量)
下面讨论一下 js 中的 Event 对象,主要从以下三个方面详细的描述(点击标题可跳转到对应部分): 1.什么是event 2.怎么用event,用他该注意什么,几个简单实际应用 3.event在不 ...
- 【JavaScript学习】-JS内置对象1-对象概述
对象(object): JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和 方法.JavaScript 提供多个内建对象,比如 String.Date.Ar ...
- ASP.NET Core配置Kestrel 网址Urls
ASP.NET Core中如何配置Kestrel Urls呢,大家可能都知道使用UseUrls() 方法来配置. 今天给介绍全面的ASP.NET Core 配置 Urls,使用多种方式配置Urls.让 ...
- Chrome debug tooltip having scrollbars
谷歌浏览器debugger,查看变量值,出现滚动条无法查看到具体的值 I had the same problem and found your post. I went as far as rein ...
- 警惕System.Environment.CurrentDirectory 获取当前目录
最近工作中,要做个客户端提醒的小工具:winform程序自然少不了要读取和应用程序同一个目录的配置文件(不是exe.config文件): 要读取当前应用程序所在目录我立马想到了System.Envir ...
- 如何卸载CentOS自带的apache
查看安装的组件: rpm -qa | grep httpd 如果预装有apache,那么会显示像httpd-2.2.3-22.el5.centos这种的组件名. 卸载组件: rpm -e httpd- ...
- 【Android Developers Training】 17. 停止和重启一个Activity
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- JAVA基础——Arrays工具类十大常用方法
Arrays工具类十大常用方法 原文链接:http://blog.csdn.net/renfufei/article/details/16829457 0. 声明数组 String[] aArray ...