CANoe简易教程2

来源:互联网 发布:c语言逻辑优先级 编辑:程序博客网 时间:2024/04/29 04:36

转载自 http://blog.michiru.me/posts/canoe-tutorial-part-2.html

在这份教程的第一部分,我们提到没有CAN数据库,CANoe还不能工作。在第二部分,我们来看看CAN数据库是怎样的。通过CANoe的Tools菜单,或者从开始菜单打开Vector的CAN数据库编辑器——CANdb++ Editor。

CANdb++ Editor interface

简介

CAN总线上有4种报文:数据帧、远程帧、错误帧、超载帧。其中只有数据帧真正承载数据。CAN数据库储存这些的数据帧的所有属性,这样当我们发现了某条报文在总线上出现时,利用数据库中的数据,就能查询出相关的数据。比如这条报文的收发者,以及其表示的意义。

在Vector格式的数据库中,数据被组织成了6种不同的对象(Object):

  • 信号(Signal)
  • 报文(Message)
  • 网络节点(Network node),或者简称节点
  • 环境变量(Environment variable)
  • 设备(ECU)
  • CAN网络(Network)

对象是有级别的,高级的对象由若干低级对象附加额外的属性构成。如下图:

CANdb Object Model

信号和报文信号的关系稍后会解释。报文信号到报文的箭头表示(若干)信号组成报文;报文到节点的箭头表示报文拥有发送节点;报文信号到节点的箭头表示拥有接收节点;节点和环境变量到ECU的箭头表示它们组成了ECU;同样,ECU组成了网络。这和CAN总线的交互结构是一样的。

在CANoe自带的CANdb++版本中,一个数据库最高级的对象是Network,且只能有一个,其名字与文件名相同。在更高级的Vector CANdb++ Admin版本中,最高级为一个叫Vehicles的对象,可以包含若干Network。

对象说明

信号

信号(Singal)代表了信息的最小单位,也就是一个“值”。例如发动机转速,开关的位置等。其主要的属性有:name, length, Byte order, Value type。具体含义可以参考CANdb++的Help中,Signal and Message Signal一节。注意Byte order属性,我们称之为“格式”,它可以设置为Motorola或者Intel,稍后会详细介绍。

报文信号

报文信号(Mapped signal)其实就是信号,区别在于当一个信号成为报文的组成部分时,它就会变成报文信号。因为它算是存在于报文中的,因此多了两个属性:

  • Startbit: 起始位,也就是信号在报文中的位置。
  • Receivers: 这个Signal会被哪个节点接收,这也是上图信号到节点的箭头的意义。

一个信号可以包含在多个报文中,之后会变成多个不同的报文信号,CANdb++ Editor中也叫映射的信号(Mapped Signal)。这是为了Singal可以重用,数据库中其它对象都不能这样重用。

报文

报文(Message)代表一条CAN报文,它就是在CAN总线上实际发送的内容。报文包含若干信号,有name, ID,DLC, Transmitters等属性,具体参考Help文档。需要说明的是,理论上只有一个节点会是报文的发送者,不过CANdb++ Editor中可以设置多个。

另外,Message的属性页中的Layout,可以直观的设置Message包含的Message Signal的位置(也就是其Startbit属性),它编辑的并不是Message的属性。

网络节点

网络节点(Node),它几乎代表了一个设备(ECU)。之所以说几乎,首先是因为ECU还包含了环境变量,其次是因为有一种特殊的ECU模型,它叫做网关(Gateway)。网关包含两个或更多节点,我们等会儿再来说明它。

所以通常,节点 + 环境变量 = ECU,节点的主要属性就只有name而已。

环境变量

环境变量(Environment varisble),用来储存ECU中的数据,比如开关位置、传感器信号等。节点读写这些变量,同时,环境变量还能够被其它东西读写,比如虚拟的传感器。环境变量的存在是为了更好的模拟ECU这个模型。节点利用环境变量和环境交换信息。

ECU

上面已经差不多说明了,ECU其实就是节点和环境变量的组合,代表真实世界的仪器设备。在CANdb++ Editor中,ECU的可设置的属性只有其包含哪些环境变量。ECU对象名字无法编辑的,它等于节点的名字。

网络

Network表示真实世界中的一条CAN总线,它包含若干ECU。

网关

网关(Gateway),是一种特殊的ECU,它包含多个节点,以及环境变量。各个节点属于不同的网络,通过共用的环境变量交换数据。这样,各个网络就可以通过网关交换信息。这也是“网关”名字的由来。需要注意的是,CANdb++ Editor非Admin版本中,dbc文件只能含有唯一一个Network,因此网关这种模型是建立不出来的(汗

关于信号的起始位

稍微了解点CAN之后,CAN数据库非常容易理解,它其实就是CAN总线的模型。不过信号的“起始位”属性,还是得仔细说明。借助报文的Layout,理解起来会稍容易一些。

我们已经知道,报文包含若干信号。信号的格式(Byte order)可以是两种之一:Motorola或者Intel。他们是指Motorola和Intel处理器中使用的数据的储存格式,也就是两种字节序,Motorola是大端字节序,Intel是小端字节序。具体来说,十进制数128,写成二进制数1000 0000,就是大端字节序,而写成0000 0001就是小端字节序。

Byte order for Motorola processors (Big Endian):MSB ... ... LSBByte order for Intel processors (Little Endian):LSB ... ... MSB

CANdb++ Editor中,都表示成(注意大小写):

msb ... ... lsb

不过我认为这样理解起来更加混乱,因此我们还是按照MSB和LSB来看。

这两种字节序的信号在报文中的排列规则也不同。为了解释这些规则,我们假如报文的DLC为8,也就是报文中含有8字节的数据,共8 * 8 = 64 bit。把每一位都列在一张表中。

如果位编号从右至左(R2L),那么:

 7   6   5   4   3   2   1   0--------------------------------                                | 0                                | 1                                | 2                                | 3                                | 4                                | 5                                | 6                                | 7

如果位编号从左至右(L2R),那么:

 0   1   2   3   4   5   6   7--------------------------------                                | 0                                | 1                                | 2                                | 3                                | 4                                | 5                                | 6                                | 7

这两种编号方式中,字节的编号是一样的,位的编号不同。CAN报文是串行发送的,CAN节点在发送报文时,不论如何编号,总是从表的左上第一位开始发送。从左至右,从上至下。

 x   x   x   x   x   x   x   x--------------------------------1st 2nd 3rd 4th 5th 6th 7th 8th | 0... ... ... ... ... ... ... ... | 1... ... ... ... ... ... ... ... | 2... ... ... ... ... ... ... ... | 3... ... ... ... ... ... ... ... | 4... ... ... ... ... ... ... ... | 5... ... ... ... ... ... ... ... | 6... ... ... ... ... ... ... last| 7

上面说到不同字节序(格式)的信号在报文中的排列规则也不同:Intel格式的信号的每位,从MSB到LSB,按照从右至左,从上至下的顺序排列(向右上角塞):

 x   x   x   x   x   x   x   x-------------------------------->.. ... ... ... ... ... ... MSB | 0                LSB ... ... ..> | 1                                | 2                                | 3                                | 4                                | 5                                | 6                                | 7

在CANdb++中看时,记得把MSB和LSB分别换成lsb和msb(注意顺序)。

而Motorola格式的信号,从MSB到LSB,按照每位从左至右,从上至下排列(向左上角塞):

 x   x   x   x   x   x   x   x--------------------------------MSB ... ... ... ... ... ... ..< | 0<.. ... ... LSB                 | 1                                | 2                                | 3                                | 4                                | 5                                | 6                                | 7

在CANdb++中看时,记得把MSB和LSB分别换成msb和lsb。

<或者>表示信号的衔接点。通常一个Message中只应该含有同一种格式的信号。否则:

 x   x   x   x   x   x   x   x-------------------------------->l   e   t   n   I  ... ... MSB | 0                LSB ... ... ..> | 1MSB ...  M   o   t   o   r   o< | 2<l   a  ... LSB                 | 3                                | 4                                | 5                                | 6                                | 7

于是Intel向左上挤,占据了12个位。Motorola向右上挤就只能从byte2开始排列了,中间的4位不得不空出来。

至此应该没有太多问题,不过接下来才是混乱的:Intel格式的信号有2种表示方法Intel StandardIntel Sequential:

Intel Standard表示法:

 7   6   5   4   3   2   1   0--------------------------------                                | 0>.. ... ... MSB                 | 1LSB ... ... ... ... ... ... ..> | 2                                | 3

这种表示法使用从右至左的位编号方式。例子中我们假设前12位(bit0~11)已经被其它信号占满了。这个信号起始位为MSB,即:12。说出Intel Standard、起始位12、长度12位,就能在Message中确定Singal的位置了。

Intel Sequential表示法:

 0   1   2   3   4   5   6   7--------------------------------                                | 0>.. ... ... MSB                 | 1LSB ... ... ... ... ... ... ..> | 2                                | 3

这种表示法使用从左至右的位编号方式。前12位(bit7~0, 15~12)已经被占,这个信号起始位为MSB,即:11。

Motorola式的信号有4种表示方法,分别是:Motorola Forward LSBMotorola Forward MSBMotorola SequentialMotorola Backward

Motorola Forward LSB:

 7   6   5   4   3   2   1   0--------------------------------                                | 0                MSB ... ... ..< | 1<.. ... ... ... ... ... ... LSB | 2                                | 3

从右至左编号方式,起始位为LSB,即:16。

Motorola Forward MSB:

 7   6   5   4   3   2   1   0--------------------------------                                | 0                MSB ... ... ..< | 1<.. ... ... ... ... ... ... LSB | 2                                | 3

从右至左编号方式,起始位为MSB,即:11。

Motorola Sequential:

 0   1   2   3   4   5   6   7--------------------------------                                | 0                MSB ... ... ..< | 1<.. ... ... ... ... ... ... LSB | 2                                | 3

从左至右编号方式,起始位为MSB,即:12。

也许你觉得最后一种方法应该是从左至右编号,起始位为LSB,但是世间万物总是那么不如意。

Motorola Backward:

 7   6   5   4   3   2   1   0--------------------------------                                | 3                MSB ... ... ..< | 2<.. ... ... ... ... ... ... LSB | 1                                | 0

非常费解的编号方式,它的字节编号是从下到上,位编号从右到左,起始位置为LSB,即8。

针对两种格式信号使用的表示法可以在CANdb++ Editor菜单栏的Option > Settings > Display中设置。但不论设置如何,数据库进行储存时,Intel格式使用Intel Sequential表示法储存,Motorola格式使用Motorola Sequential表示法储存,避免在设置不同的编辑器中打开时出现误解。

在这份教程里,我们都使用Motorola格式的信号,并且使用Motorola Forward MSB式的表示方法。它应该和很多人(比如我)的第一感觉相同。

第一份CAN数据库

现在让我们着手建立一份简单的CAN数据库。它有1个信号,1条报文,2个节点分别作为收发节点,1个环境变量用来演示其使用。当然,不用说,有1个网络。

CANdb++ Editor中,使用File > Create Database... 来新建一个叫candb.dbc的数据库,程序会询问你使用的模板。不同模板的区别在于每个对象的属性多少。越复杂的模板属性越多,这里我们使用最简单的EmptyTemplate.dbc

在CANdb++ Editor默认打开的Overall View窗口的左侧,我们可以看到各个对象的分类。如果不是的话,找菜单栏View > Overall View

建立节点

在Newwork noedes上右键新建,

Name: ECM

同样再新建一个:

Name: METER

建立报文

在Message上右键,新建:

Name: EngineStateType: CAN StandardID: 0x1DLC: 1

Transmitters中,点击Add...,选择ECM。

建立信号

在Singal上点击右键,New...,之后输入:

Name: SpeedLength[bit]: 8Byte Order: MotorolaValue Type: UnsignedUnit: m/sFactor: 0.1Offset: 0Minimum: 0Maximum: 25.5

Messages页中点击Add...,选择EngineState。

编辑报文信号

展开左侧Messages下的EngineState,右键点击Speed,选择Edit Mapped Singal

Startbit[bit]: 7

Receivers页中点击Add...,选择METER。

建立环境变量

在左侧Environment variables上右键新建

Name: env_speedValue Type: FloatAccess: ReadUnit: m/sInitial Value: 0Minimum: 0Maximum: 25.5

Control units页中添加ECM。

再次确认一下,使用View > Communication Matrix

CANdb Communication Matrix

非常好,我们的数据库如此精炼。数据库的教程至此,保存在<project>\database文件夹中吧。

额外的说明

Vector的CANdb数据库其实是一个编码为ANSI的文本文件,可以使用任何文本编辑器打开。其结构可以参考Vector的DBC File Format Documentation,在官网似乎搜不到这份文件,就只有提供民间版本了。

这在你有了某种结构的数据库文件(比如表格文件格式),想要转换成Vector的dbc文件的,可以写程序转换,而不是手动输入。


0 0
原创粉丝点击