CAN总线和DCB文件格式

CAN总线和DBC格式

1. CAN总线

控制器局域网总线(CAN,Controller Area Network)一般被我们称为CAN总线,常用于汽车各不同原件之间的通信。

1.1 CAN总线的组织结构

CAN节点一般由MCU控制器、CAN控制器和CAN收发器组成。
CAN的信号传递介质为一股双绞线,双绞线由一条CAN-High和一条CAN-Low组成,这两条线的电势差用来表征CAN的总线值,在CAN通讯中,低电平代表的是显性电平,高电平代表的是隐性电平

发送节点通过使总线的电平产生变化,将其信息传输到CAN总线上。接收节点通过监听总线的电平,将总线的信息读入接收器上。
CAN总线的数据按照协议以报文的形式发送,并广播到网络中的所有结点。对于每个节点,无论报文是否是发送给自己都进行接收。

1.2 CAN的信号结构

CAN通讯的结构是基于帧的,CAN的帧分为两种:标准帧和扩展帧。这也分别对应着两个不同的协议:CAN2.0A和CAN2.0B。帧结构如下图:
在这里插入图片描述

以下是帧结构的组成部分:

  1. 帧起始。帧起始是一个显性位电平,当总线空闲时,发送节点发送一个显性电平,所有的接收节点同步于该帧起始位。这一个显性电平的发出代表着一帧信号的开始。

  2. 仲裁段。任何CAN节点在任何时刻都可以向总线发送数据,但总线同一时刻只能发送一帧消息,因此总线在同一时刻接受多个帧时需要通过帧的仲裁段来决定优先级。在进行裁决的时候,依据就是信号的ID,总线会对ID进行逐位的比较,比较的过程中显性电平胜出,隐形电平退出发送。在这里插入图片描述
    在进行裁决的时候,依据就是信号的ID,总线会对ID进行逐位的比较,比较的过程中显性电平胜出,隐形电平退出发送。在这里插入图片描述
    仲裁段的ID越小,优先级越高。仲裁段中除了ID外,还有RTR,这个位是为了区分数据帧和远程帧的。如果在一帧消息内,ID都是完全一样的,数据帧的优先级高于远程帧。

  3. 控制段。两种类型的帧控制段的长度都是六位,在标准帧中的控制段包含IDE,保留位r0以及数据长度DLC;在扩展帧中的控制段包含保留位r0,r1以及数据长度DLC。在这里插入图片描述

  4. 数据段。数据段根据需要传输的数据长度传输相应的字节,但最大不能超过8byte。在这里插入图片描述

  5. CRC段。CRC中文的意思是循环冗余校验,其目的就是要对这一帧信号中前面的部分进行校验,以保证数据传输的正确性,校验的部分包括:帧起始、仲裁段、控制段以及数据段。

  6. ACK段。这一段和CRC是相关的,上一段进行了CRC校验的比对,如果CRC校验结果没有问题的话,接收节点会在总线发送一个显性电平。在这里插入图片描述

  7. 帧结束。和一开始的帧起始相呼应,帧结束是由七个连续的隐性电平组成。

2. DBC格式

DBC(Database CAN)是一种由Vector公司定义的一种网络通信文件格式,是CAN总线数据库文件。CAN总线中传输的二进制帧信号不利于分析报文的具体内容,DBC最基础的作用就是帮助解释二进制的帧信号,以便分析报文信息。
这里附上DBC的官方文档:DBC file Format Documentation v1.05

2.1 通用描述

2.1.1关键字

下面的表格给出了DBC文件中用于标识对象类型的DBC关键字。关键字的具体含义在后面会说到。

关键字对象类型
BU_网络节点
BO_报文
SG_信号
EV_环境变量
SIG_GROUP_信号组
VAL_TABLE_数值表

2.1.2数据类型

DBC文件对属性值由数据类型的区分,下表为DBC文件中可选的数据类型。

符号类型
unsigned_interger无符号整型
singed_integer有符号整型
double双精度浮点数
char_string字符串
C_identifierC语言变量名

其中C_identifiers必须以字母字符或下划线开始,并可以由字母、数字字符和下划线组成。如:Abc_string, acb_123_string

2.1.3 语法描述

DBC文件中使用扩展的巴斯科范式(Backus-Naur-Format, BNF)表示法来进行语法描述。如下表所示:

符号含义
==左侧的名称使用右侧的语法进行定义,简单说就是赋值
使用分号结束一个定义
∣ \vert 垂直条表示替代选项
[ … ]反括号内的定义是可选的(0次或一次)
{ … }大括号内的定义可以重复(0次或多次)
( … )括号用于定义分组元素
’ … ’连字符中的文本必须按照定义进行显示
(* … *)表示注释

2.2 DBC文件的结构

DBC文件的整体结构如下所示:

version
new_symbols
bit_timing                  (*已废弃但仍需要*)
nodes
value_tables
messages
message_transmitters
environment_variables
environment_variables_data
signal_types
comments
attribute_definitions
sigtype_attr_list
attribute_defaults
attribute_values
value_descriptions
category_definitions        (*已废弃*)
categories                  (*已废弃*)
filter                      (*已废弃*)
signal_type_refs
signal_groups
signal_extended_value_type_list
extended_multiplexing ;

描述DBC文件基本通信的文件主要有以下几个:

  • Bit_timing

这部分是必须的,但通常为空。。

  • nodes

这部分是必须的,定义了网络节点。

  • messages

这部分定义了报文和信号。

以下部分未在普通DBC文件中使用。此处仅为完整起见对其进行定义:

  • signal_types
  • sigtype_attr_list
  • category_definitions
  • categories
  • filter
  • signal_type_refs
  • signal_extended_value_type_list

官方文档中写道:

DBC files that describe the CAN communication and don’t define any additional
data for system or remaining bus simulations don’t include environment variables.

这段话的具体含义我没太搞懂,但总之就是很多DBC文件没有环境变量的意思。

2.2.1 符号定义的格式

这部分是DBC格式的重点。

1. version和new symbol的格式
CBD文件的开头是version和new symbol组成的标头。versiond的格式为:

version = ['VERSION' '"' { CANdb_version_string } '"' ];

双引号中的内容可以为空,也可以用户自定义。

举例:VERSION " "VERSION "1.0"

new symbol的格式为:

new_symbols = [ '_NS' ':' ['CM_'] ['BA_DEF_'] ['BA_'] ['VAL_'] ['CAT_DEF_'] ['CAT_'] ['FILTER'] ['BA_DEF_DEF_'] ['EV_DATA_'] ['ENVVAR_DATA_'] ['SGTYPE_'] ['SGTYPE_VAL_'] ['BA_DEF_SGTYPE_'] ['BA_SGTYPE_'] ['SIG_TYPE_REF_'] ['VAL_TABLE_'] ['SIG_GROUP_'] ['SIG_VALTYPE_'] ['SIGTYPE_VALTYPE_'] ['BO_TX_BU_']['BA_DEF_REL_'] ['BA_REL_'] ['BA_DEF_DEF_REL_'] ['BU_SG_REL_'] ['BU_EV_REL_'] ['BU_BO_REL_'] ];

符号定义关键字为NS_。在DBC文件里第一个new symbol通常为NS_,但不知为何官方文档给出的为_NS

2. bit timing的格式

波特率关键字为BS_。波特率部分定义了网络的波特率以及BTR寄存器值,此部分已废弃,但是关键字 “BS_” 必须在DBC文件中出现。因此在文件中一般只有一个单独的BS_

3. nodes的格式

节点的关键词为BU_。节点定义了此网络中所有参与通讯的节点,每个节点定义必须是唯一的,命名方式同C语言。

nodes = 'BU_:' {node_name} ;
node_name = C_identifier ;

举例:BU_ : ECU1 ECU2 ECU3 Tester

4. messages的格式(重点)

报文的关键词为BO_。报文定义了集群中所有帧的名称以及其属性以及在帧上传输的信号。其中message_id在此网络中必须是唯一的,CAN ID可以是标准帧ID或者扩展帧ID,它们不同的地方在于帧ID的长度,标准帧的帧ID长度是11位,也就是帧ID的范围是000-7FF。扩展帧的帧ID长度是29位,也就是帧ID的范围是00000000-7FFFFFFF。

messages = {message} ; 
message = BO_ message_id message_name ':' message_size transmitter {signal} ; 
message_id = unsigned_integer ;

BO_ message_id为报文的CAN ID,在DCB文件中为十进制,注意有时需要换算为对应的十六进制ID。

message_name = C_identifier ;

message_name命名规则与C语言相同。

message_size = unsigned_integer ;

message_size也就是所谓的DLC,是无符号整型数,单位是Byte,其规定了报文数据域的字节数。标准CAN最大支持8个Byte,CANFD最大支持64个Byte.

transmitter = node_name | ‘Vector__XXX’ ;

transmitter表示报文发送的节点,该节点必须是在nodes部分定义中的某个节点,或者是 ‘Vector__XXX’
‘Vector__XXX’这个字符串的意思是,如果某个报文没有指定发送节点,则必须设置为 ’Vector_XXX’.

举例:BO_ 100 test_message1: 8 ECU1定义报文test_message1, CAN ID为100(dec),DLC为8,发送方为ECU1。

5. signals的格式

信号的关键字为SG_。报文的信号部分列出了放置在报文上的所有信号以及信号在报文的数据字段中的位置及其属性。

signal = ‘SG_' signal_name multiplexer_indicator ' : ' start_bit ' | ' signal_size ' @ ' byte_order value_type ' ( ' factor ' , ' offset ' ) ' ' \[ ' minimum ' | ' maximum ' \] ' unit receiver {',' receiver} ;
signal_name = C_identifier ;

上面定义的signal_name对于同一个报文内的信号必须是唯一的。

multiplexer_indicator = ' ' | [m multiplexer_switch_value] [M] ;

其中多路复用器指示器指示该信号是正常信号、复用信号开关还是多路复用信号。“M”(大写)字符将信号定义为多路复用器开关。单个消息中只有一个信号可以是多路复用器开关。
“m”(小写)字符后跟无符号整数将信号定义为由多路复用。
如果多路复用器信号的开关值等于其multiplexer_switch_value,则多路复用信号在消息中传输。(这一项不常见)

start_bit = unsigned_integer ;
signal_size = unsigned_integer ;

start_bit指定了信号在帧的数据段内的起始位,必须在(8*message_size-1)的范围内。signal_size 指信号的长度。

byte_order = '0' | '1' ;

1代表指intel格式,称为小端模式;0代表motorola格式称为大端模式。

value_type = '+' | '-' ;

+表示无符号数, -表示有符号数

factor = double ;
offset = double ; 

facator与offset是用来将原始值与物理值之间进行转化,物理值就是我们希望使用的,原始值是报文中记录的值。minumum与maximum表示信号的最大最小值,这四个参数均为为double类型
其中facator和offset参与计算的关系如下:

physical_value = raw_value * factor + offset
raw_value = (physical_value – offset) / factor

从上式中可以看出factor不得为0。
unit为字符串,用来表示信号单位,没有单位则此项为空。

receiver = node_name | 'Vector__XXX' ;

receiver和前面的transmitter一样。

举例:

BO_ 101 test_message2: 8 ECU2
SG_ test_signal2: 10|5@1+ (1,-1) [0|31] “cm” ECU3

定义test_message2中的一个信号test_signal2, 起始位为10,长度为5,采用Intel格式,无符号整型,因子为1,偏移为-1,最小最大值为0和31,单位为cm,接收方是ECU3。

6. value Encodings的格式
信号值的关键字为VAL_。信号值描述定义了特定信号原始值的编码。

value_descriptions = { value_descriptions_for_signal | value_descriptions_for_env_var } ; 
value_descriptions_for_signal = 'VAL_' message_id signal_name { value_description } ';' ;

举例:VAL_ 100 test_signal1 0 “Off” 1 “On” 2 “Reserved” 3 “Invalid” ;定义message ID 为100的报文中test_signal1的encodings,0的含义是off,1的含义是on,2的含义保留,3表示无效值。

实际上encoding值是为了告诉诊断,测试人员,相对于的值代表什么意思。
这个属性不是必须的,不是每个信号都需要。

7. environment variable的格式

环境变量的关键字为EV_。此部分略过,因为一般只在系统仿真和总线仿真工具中使用的环境变量。

8. signal group的格式

信号组的关键字为SIG_GROUP_。信号组用于定义消息中的一组信号。信号组的概念属于功能安全端对端保护(E2E)中的部分,其中的一个目的就是一个组的信号必须共同更新。

signal_groups = 'SIG_GROUP_' message_id signal_group_name repetitions ':' { signal_name } ';' ; 
signal_group_name = C_identifier ; 
repetitions = unsigned_integer ;

举例:

SIG_GROUP_ 100 test_message1_group 1 : CheckSum_test_message1 test_signal1 RollingCounter_test_message1 ;

定义CAN ID为100的报文中的信号组test_message1_group, repetitions为1,其中的信号包含CheckSum_test_message1,test_signal1,RollingCounter_test_message1。

9. comment的格式

注释的关键字为CM_。注释部分包含对象注释。主要是说明信号的描述。

comments = {comment} ; 
comment = 'CM_' (char_string |  'BU_' node_name char_string |  'BO_' message_id char_string |  'SG_' message_id signal_name char_string |  'EV_' env_var_name char_string)  ';' ;

举例:
CM_ SG_ 100 test_signal1 “The left door status” ;
定义帧100中的信号test_signal1的描述为"The left door status"

10. user defined attribute的格式

在DBC中,除了规定的属性以外,还可以有用户自己定义的属性,但是同样需要遵守一定的规则。
用户定义的属性必须使用具有属性默认值的属性定义来定义这些附加属性。对于每个具有为属性定义值的对象,必须定义属性值条目。如果没有为对象定义属性值条目,则该对象的属性值是该属性的默认值。
属性采用如下方法定义:

attribute_definitions = { attribute_definition } ; 
attribute_definition = 'BA_DEF_' object_type attribute_name attribute_value_type ';' ; 
object_type = '' | 'BU_' | 'BO_' | 'SG_' | 'EV_' ; 
attribute_name = '"' C_identifier '"' ; 
attribute_value_type = 'INT' signed_integer signed_integer | 
'HEX' signed_integer signed_integer | 
'FLOAT' double double | 
'STRING' | 
'ENUM' [char_string {',' char_string}] 
attribute_defaults = { attribute_default } ; 
attribute_default = 'BA_DEF_DEF_' attribute_name attribute_value 
';' ; 
attribute_value = unsigned_integer | signed_integer | double | 
char_string ;

属性值的定义方法:

attribute_values = { attribute_value_for_object } ;
attribute_value_for_object = 'BA_' attribute_name (attribute_value | 
'BU_' node_name attribute_value | 
'BO_' message_id attribute_value | 
'SG_' message_id signal_name attribute_value | 
'EV_' env_var_name attribute_value) 
';' ;

举例:
定义一个所有报文都具有的属性

BA_DEF_ BO_ “GenMsgSendType” ENUM “Cyclic”,“Event” ;

因为发送类型是针对报文而言的,所有使用的是BO_,如果是针对信号的,那就使用SG_, GenMsgSendType是定义的属性名字,ENUM指的是枚举类型,它包含两个类型:"Cyclic"和 “Event”

3. DBC文件官方示例

VERSION ""

NS_ :
 NS_DESC_
 CM_
 BA_DEF_
 BA_
 VAL_
 CAT_DEF_
 CAT_
 FILTER
 BA_DEF_DEF_
 EV_DATA_
 ENVVAR_DATA_
 SGTYPE_
 SGTYPE_VAL_
 BA_DEF_SGTYPE_
 BA_SGTYPE_
 SIG_TYPE_REF_
 VAL_TABLE_
 SIG_GROUP_ 
 SIG_VALTYPE_
 SIGTYPE_VALTYPE_
 BO_TX_BU_
 BA_DEF_REL_
 BA_REL_
 BA_DEF_DEF_REL_
 BU_SG_REL_
 BU_EV_REL_
 BU_BO_REL_

BS_:

BU_: Engine Gateway

BO_ 100 EngineData: 8 Engine
 SG_ PetrolLevel : 24|8@1+ (1,0) [0|255] "l" Gateway
 SG_ EngPower : 48|16@1+ (0.01,0) [0|150] "kW" Gateway
 SG_ EngForce : 32|16@1+ (1,0) [0|0] "N" Gateway
 SG_ IdleRunning : 23|1@1+ (1,0) [0|0] "" Gateway
 SG_ EngTemp : 16|7@1+ (2,-50) [-50|150] "degC" Gateway
 SG_ EngSpeed : 0|16@1+ (1,0) [0|8000] "rpm" Gateway

CM_ "CAN communication matrix for power train electronics
*******************************************************

implemented: turn lights, warning lights, windows";

VAL_ 100 IdleRunning 0 "Running" 1 "Idle" ; # CAN总线和DBC格式
## 1. CAN总线
控制器局域网总线(CAN,Controller Area Network)一般被我们称为CAN总线,常用于汽车各不同原件之间的通信。
### 1.1 CAN总线的组织结构
CAN节点一般由MCU控制器、CAN控制器和CAN收发器组成。
CAN的信号传递介质为一股双绞线,双绞线由一条CAN-High和一条CAN-Low组成,这两条线的电势差用来表征CAN的总线值,在CAN通讯中,低电平代表的是显性电平,高电平代表的是隐性电平
![CAN总线的拓扑结构](CAN%E6%80%BB%E7%BA%BF%E6%8B%93%E6%89%91%E7%BB%93%E6%9E%84.jpeg)
发送节点通过使总线的电平产生变化,将其信息传输到CAN总线上。接收节点通过监听总线的电平,将总线的信息读入接收器上。
CAN总线的数据按照协议以报文的形式发送,并广播到网络中的所有结点。对于每个节点,无论报文是否是发送给自己都进行接收。
### 1.2 CAN的信号结构
CAN通讯的结构是基于帧的,CAN的帧分为两种:标准帧和扩展帧。这也分别对应着两个不同的协议:CAN2.0A和CAN2.0B。帧结构如下图:
![CAN帧结构](%E5%B8%A7%E7%BB%93%E6%9E%84.webp)
以下是帧结构的组成部分:
1. **帧起始**。帧起始是一个显性位电平,当总线空闲时,发送节点发送一个显性电平,所有的接收节点同步于该帧起始位。这一个显性电平的发出代表着一帧信号的开始。
2. **仲裁段**。任何CAN节点在任何时刻都可以向总线发送数据,但总线同一时刻只能发送一帧消息,因此总线在同一时刻接受多个帧时需要通过帧的仲裁段来决定优先级。在进行裁决的时候,依据就是信号的ID,总线会对ID进行逐位的比较,比较的过程中显性电平胜出,隐形电平退出发送。![Alt text](%E4%BB%B2%E8%A3%81%E6%AE%B5%E6%A0%BC%E5%BC%8F.webp)在进行裁决的时候,依据就是信号的ID,总线会对ID进行逐位的比较,比较的过程中显性电平胜出,隐形电平退出发送。![Alt text](%E4%BB%B2%E8%A3%81%E6%AE%B5%E4%BC%98%E5%85%88%E7%BA%A7%E6%AF%94%E8%BE%83.webp)仲裁段的ID越小,优先级越高。仲裁段中除了ID外,还有RTR,这个位是为了区分数据帧和远程帧的。如果在一帧消息内,ID都是完全一样的,数据帧的优先级高于远程帧。
3. **控制段**。两种类型的帧控制段的长度都是六位,在标准帧中的控制段包含IDE,保留位r0以及数据长度DLC;在扩展帧中的控制段包含保留位r0,r1以及数据长度DLC。![Alt text](%E6%8E%A7%E5%88%B6%E6%AE%B5%E7%BB%93%E6%9E%84.webp)
4. **数据段**。数据段根据需要传输的数据长度传输相应的字节,但最大不能超过8byte。![Alt text](%E6%95%B0%E6%8D%AE%E6%AE%B5.webp)
5. **CRC段**。CRC中文的意思是循环冗余校验,其目的就是要对这一帧信号中前面的部分进行校验,以保证数据传输的正确性,校验的部分包括:帧起始、仲裁段、控制段以及数据段。
6. **ACK段**。这一段和CRC是相关的,上一段进行了CRC校验的比对,如果CRC校验结果没有问题的话,接收节点会在总线发送一个显性电平。![Alt text](ACK%E6%AE%B5.webp)
7. **帧结束**。和一开始的帧起始相呼应,帧结束是由七个连续的隐性电平组成。

## 2. DBC格式
DBC(Database CAN)是一种由Vector公司定义的一种网络通信文件格式,是CAN总线数据库文件。CAN总线中传输的二进制帧信号不利于分析报文的具体内容,DBC最基础的作用就是帮助解释二进制的帧信号,以便分析报文信息。
这里附上DBC的官方文档:[DBC file Format Documentation v1.05](http://mcu.so/Microcontroller/Automotive/dbc-file-format-documentation_compress.pdf)
### 2.1 通用描述
**2.1.1关键字**

下面的表格给出了DBC文件中用于标识对象类型的DBC关键字。关键字的具体含义在后面会说到。

|  关键字   | 对象类型  |
|  ----  | ----  |
| BU_  | 网络节点 |
| BO_  | 报文 |
| SG_  | 信号 |
| EV_  | 环境变量 |
| SIG_GROUP_  |信号组|
| VAL_TABLE_   | 数值表 |

**2.1.2数据类型**

DBC文件对属性值由数据类型的区分,下表为DBC文件中可选的数据类型。
|符号	|类型|
|  ----  | ----  |
unsigned_interger	|无符号整型
singed_integer	|有符号整型
double	|双精度浮点数
char_string|	字符串
C_identifier	|C语言变量名

其中`C_identifiers`必须以字母字符或下划线开始,并可以由字母、数字字符和下划线组成。如:`Abc_string`, `acb_123_string`。

**2.1.3 语法描述**

DBC文件中使用扩展的巴斯科范式(Backus-Naur-Format, BNF)表示法来进行语法描述。如下表所示:
符号	|含义
|  ----  | ----  |
=	|=左侧的名称使用右侧的语法进行定义,简单说就是赋值
;|	使用分号结束一个定义
$\vert$	|垂直条表示替代选项
[ … ]|	反括号内的定义是可选的(0次或一次)
{ … }	|大括号内的定义可以重复(0次或多次)
( … )|	括号用于定义分组元素
’ … ’	|连字符中的文本必须按照定义进行显示
(* … *)|	表示注释
 ### 2.2 DBC文件的结构
DBC文件的整体结构如下所示:
```DBC_file =
version
new_symbols
bit_timing                  (*已废弃但仍需要*)
nodes
value_tables
messages
message_transmitters
environment_variables
environment_variables_data
signal_types
comments
attribute_definitions
sigtype_attr_list
attribute_defaults
attribute_values
value_descriptions
category_definitions        (*已废弃*)
categories                  (*已废弃*)
filter                      (*已废弃*)
signal_type_refs
signal_groups
signal_extended_value_type_list
extended_multiplexing ;

描述DBC文件基本通信的文件主要有以下几个:

  • Bit_timing

这部分是必须的,但通常为空。。

  • nodes

这部分是必须的,定义了网络节点。

  • messages

这部分定义了报文和信号。

以下部分未在普通DBC文件中使用。此处仅为完整起见对其进行定义:

  • signal_types
  • sigtype_attr_list
  • category_definitions
  • categories
  • filter
  • signal_type_refs
  • signal_extended_value_type_list

官方文档中写道:

DBC files that describe the CAN communication and don’t define any additional
data for system or remaining bus simulations don’t include environment variables.

这段话的具体含义我没太搞懂,但总之就是很多DBC文件没有环境变量的意思。

2.2.1 符号定义的格式

这部分是DBC格式的重点。

1. version和new symbol的格式
CBD文件的开头是version和new symbol组成的标头。versiond的格式为:

version = ['VERSION' '"' { CANdb_version_string } '"' ];

双引号中的内容可以为空,也可以用户自定义。

举例:VERSION " "VERSION "1.0"

new symbol的格式为:

new_symbols = [ '_NS' ':' ['CM_'] ['BA_DEF_'] ['BA_'] ['VAL_'] ['CAT_DEF_'] ['CAT_'] ['FILTER'] ['BA_DEF_DEF_'] ['EV_DATA_'] ['ENVVAR_DATA_'] ['SGTYPE_'] ['SGTYPE_VAL_'] ['BA_DEF_SGTYPE_'] ['BA_SGTYPE_'] ['SIG_TYPE_REF_'] ['VAL_TABLE_'] ['SIG_GROUP_'] ['SIG_VALTYPE_'] ['SIGTYPE_VALTYPE_'] ['BO_TX_BU_']['BA_DEF_REL_'] ['BA_REL_'] ['BA_DEF_DEF_REL_'] ['BU_SG_REL_'] ['BU_EV_REL_'] ['BU_BO_REL_'] ];

符号定义关键字为NS_。在DBC文件里第一个new symbol通常为NS_,但不知为何官方文档给出的为_NS

2. bit timing的格式

波特率关键字为BS_。波特率部分定义了网络的波特率以及BTR寄存器值,此部分已废弃,但是关键字 “BS_” 必须在DBC文件中出现。因此在文件中一般只有一个单独的BS_

3. nodes的格式

节点的关键词为BU_。节点定义了此网络中所有参与通讯的节点,每个节点定义必须是唯一的,命名方式同C语言。

nodes = 'BU_:' {node_name} ;
node_name = C_identifier ;

举例:BU_ : ECU1 ECU2 ECU3 Tester

4. messages的格式(重点)

报文的关键词为BO_。报文定义了集群中所有帧的名称以及其属性以及在帧上传输的信号。其中message_id在此网络中必须是唯一的,CAN ID可以是标准帧ID或者扩展帧ID,它们不同的地方在于帧ID的长度,标准帧的帧ID长度是11位,也就是帧ID的范围是000-7FF。扩展帧的帧ID长度是29位,也就是帧ID的范围是00000000-7FFFFFFF。

messages = {message} ; 
message = BO_ message_id message_name ':' message_size transmitter {signal} ; 
message_id = unsigned_integer ;

BO_ message_id为报文的CAN ID,在DCB文件中为十进制,注意有时需要换算为对应的十六进制ID。

message_name = C_identifier ;

message_name命名规则与C语言相同。

message_size = unsigned_integer ;

message_size也就是所谓的DLC,是无符号整型数,单位是Byte,其规定了报文数据域的字节数。标准CAN最大支持8个Byte,CANFD最大支持64个Byte.

transmitter = node_name | ‘Vector__XXX’ ;

transmitter表示报文发送的节点,该节点必须是在nodes部分定义中的某个节点,或者是 ‘Vector__XXX’
‘Vector__XXX’这个字符串的意思是,如果某个报文没有指定发送节点,则必须设置为 ’Vector_XXX’.

举例:BO_ 100 test_message1: 8 ECU1定义报文test_message1, CAN ID为100(dec),DLC为8,发送方为ECU1。

5. signals的格式

信号的关键字为SG_。报文的信号部分列出了放置在报文上的所有信号以及信号在报文的数据字段中的位置及其属性。

signal = ‘SG_' signal_name multiplexer_indicator ' : ' start_bit ' | ' signal_size ' @ ' byte_order value_type ' ( ' factor ' , ' offset ' ) ' ' \[ ' minimum ' | ' maximum ' \] ' unit receiver {',' receiver} ;
signal_name = C_identifier ;

上面定义的signal_name对于同一个报文内的信号必须是唯一的。

multiplexer_indicator = ' ' | [m multiplexer_switch_value] [M] ;

其中多路复用器指示器指示该信号是正常信号、复用信号开关还是多路复用信号。“M”(大写)字符将信号定义为多路复用器开关。单个消息中只有一个信号可以是多路复用器开关。
“m”(小写)字符后跟无符号整数将信号定义为由多路复用。
如果多路复用器信号的开关值等于其multiplexer_switch_value,则多路复用信号在消息中传输。(这一项不常见)

start_bit = unsigned_integer ;
signal_size = unsigned_integer ;

start_bit指定了信号在帧的数据段内的起始位,必须在(8*message_size-1)的范围内。signal_size 指信号的长度。

byte_order = '0' | '1' ;

1代表指intel格式,称为小端模式;0代表motorola格式称为大端模式。

value_type = '+' | '-' ;

+表示无符号数, -表示有符号数

factor = double ;
offset = double ; 

facator与offset是用来将原始值与物理值之间进行转化,物理值就是我们希望使用的,原始值是报文中记录的值。minumum与maximum表示信号的最大最小值,这四个参数均为为double类型
其中facator和offset参与计算的关系如下:

physical_value = raw_value * factor + offset
raw_value = (physical_value – offset) / factor

从上式中可以看出factor不得为0。
unit为字符串,用来表示信号单位,没有单位则此项为空。

receiver = node_name | 'Vector__XXX' ;

receiver和前面的transmitter一样。

举例:

BO_ 101 test_message2: 8 ECU2
SG_ test_signal2: 10|5@1+ (1,-1) [0|31] “cm” ECU3

定义test_message2中的一个信号test_signal2, 起始位为10,长度为5,采用Intel格式,无符号整型,因子为1,偏移为-1,最小最大值为0和31,单位为cm,接收方是ECU3。

6. value Encodings的格式
信号值的关键字为VAL_。信号值描述定义了特定信号原始值的编码。

value_descriptions = { value_descriptions_for_signal | value_descriptions_for_env_var } ; 
value_descriptions_for_signal = 'VAL_' message_id signal_name { value_description } ';' ;

举例:VAL_ 100 test_signal1 0 “Off” 1 “On” 2 “Reserved” 3 “Invalid” ;定义message ID 为100的报文中test_signal1的encodings,0的含义是off,1的含义是on,2的含义保留,3表示无效值。

实际上encoding值是为了告诉诊断,测试人员,相对于的值代表什么意思。
这个属性不是必须的,不是每个信号都需要。

7. environment variable的格式

环境变量的关键字为EV_。此部分略过,因为一般只在系统仿真和总线仿真工具中使用的环境变量。

8. signal group的格式

信号组的关键字为SIG_GROUP_。信号组用于定义消息中的一组信号。信号组的概念属于功能安全端对端保护(E2E)中的部分,其中的一个目的就是一个组的信号必须共同更新。

signal_groups = 'SIG_GROUP_' message_id signal_group_name repetitions ':' { signal_name } ';' ; 
signal_group_name = C_identifier ; 
repetitions = unsigned_integer ;

举例:

SIG_GROUP_ 100 test_message1_group 1 : CheckSum_test_message1 test_signal1 RollingCounter_test_message1 ;

定义CAN ID为100的报文中的信号组test_message1_group, repetitions为1,其中的信号包含CheckSum_test_message1,test_signal1,RollingCounter_test_message1。

9. comment的格式

注释的关键字为CM_。注释部分包含对象注释。主要是说明信号的描述。

comments = {comment} ; 
comment = 'CM_' (char_string |  'BU_' node_name char_string |  'BO_' message_id char_string |  'SG_' message_id signal_name char_string |  'EV_' env_var_name char_string)  ';' ;

举例:
CM_ SG_ 100 test_signal1 “The left door status” ;
定义帧100中的信号test_signal1的描述为"The left door status"

10. user defined attribute的格式

在DBC中,除了规定的属性以外,还可以有用户自己定义的属性,但是同样需要遵守一定的规则。
用户定义的属性必须使用具有属性默认值的属性定义来定义这些附加属性。对于每个具有为属性定义值的对象,必须定义属性值条目。如果没有为对象定义属性值条目,则该对象的属性值是该属性的默认值。
属性采用如下方法定义:

attribute_definitions = { attribute_definition } ; 
attribute_definition = 'BA_DEF_' object_type attribute_name attribute_value_type ';' ; 
object_type = '' | 'BU_' | 'BO_' | 'SG_' | 'EV_' ; 
attribute_name = '"' C_identifier '"' ; 
attribute_value_type = 'INT' signed_integer signed_integer | 
'HEX' signed_integer signed_integer | 
'FLOAT' double double | 
'STRING' | 
'ENUM' [char_string {',' char_string}] 
attribute_defaults = { attribute_default } ; 
attribute_default = 'BA_DEF_DEF_' attribute_name attribute_value 
';' ; 
attribute_value = unsigned_integer | signed_integer | double | 
char_string ;

属性值的定义方法:

attribute_values = { attribute_value_for_object } ;
attribute_value_for_object = 'BA_' attribute_name (attribute_value | 
'BU_' node_name attribute_value | 
'BO_' message_id attribute_value | 
'SG_' message_id signal_name attribute_value | 
'EV_' env_var_name attribute_value) 
';' ;

举例:
定义一个所有报文都具有的属性

BA_DEF_ BO_ “GenMsgSendType” ENUM “Cyclic”,“Event” ;

因为发送类型是针对报文而言的,所有使用的是BO_,如果是针对信号的,那就使用SG_, GenMsgSendType是定义的属性名字,ENUM指的是枚举类型,它包含两个类型:"Cyclic"和 “Event”

3. DBC文件官方示例

VERSION ""

NS_ :
 NS_DESC_
 CM_
 BA_DEF_
 BA_
 VAL_
 CAT_DEF_
 CAT_
 FILTER
 BA_DEF_DEF_
 EV_DATA_
 ENVVAR_DATA_
 SGTYPE_
 SGTYPE_VAL_
 BA_DEF_SGTYPE_
 BA_SGTYPE_
 SIG_TYPE_REF_
 VAL_TABLE_
 SIG_GROUP_ 
 SIG_VALTYPE_
 SIGTYPE_VALTYPE_
 BO_TX_BU_
 BA_DEF_REL_
 BA_REL_
 BA_DEF_DEF_REL_
 BU_SG_REL_
 BU_EV_REL_
 BU_BO_REL_

BS_:

BU_: Engine Gateway

BO_ 100 EngineData: 8 Engine
 SG_ PetrolLevel : 24|8@1+ (1,0) [0|255] "l" Gateway
 SG_ EngPower : 48|16@1+ (0.01,0) [0|150] "kW" Gateway
 SG_ EngForce : 32|16@1+ (1,0) [0|0] "N" Gateway
 SG_ IdleRunning : 23|1@1+ (1,0) [0|0] "" Gateway
 SG_ EngTemp : 16|7@1+ (2,-50) [-50|150] "degC" Gateway
 SG_ EngSpeed : 0|16@1+ (1,0) [0|8000] "rpm" Gateway

CM_ "CAN communication matrix for power train electronics
*******************************************************

implemented: turn lights, warning lights, windows";

VAL_ 100 IdleRunning 0 "Running" 1 "Idle" ; 
  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值