[车联网] CAN总线与DBC详解

0 序

1 CAN总线-概述

1.0 简介

  • CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种 ISO 国际标准化的、能够实现分布式实时控制的串行通信网络。

  • 应用领域:其广泛应用于汽车工业自动化/工业控制机器人等现场控制领域中进行数据传输。

  • 发展历程

  • 1986年,德国Bosch公司为解决现代汽车中众多的控制与测试仪器之间的数据交换而开发的一种串行数据通信协议。
  • 1993年11月,国际标准化组织ISO正式颁布了关于CAN总线的ISO11898标准。

该标准成为国际上应用最广泛的现场总线之一。

  • 企业支持情况:目前CAN得到了Motorola、Intel、 Philips 、Siemens、NEC等公司的支持。

  • 传输介质:它使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。

  • 核心特性:CAN协议的特性包括:完整性的串行数据通讯、提供实时支持、传输速率高达1Mb/s、同时具有11位的寻址以及检错能力。

此外,CAN协议还支持功能安全应用,具有高可靠性、抗干扰能力强、支持多节点等优点。

  • 报文格式:CAN协议支持两种报文格式标准格式为11位标识符,扩展格式为29位标识符,支持多种传输速率和数据长度,满足不同应用场景的需求。

1.1 优点

  • 传输速度高。传输速度最高到1Mbps,通信距离最远到10km,无损位仲裁机制,多主结构。近些年来,CAN控制器价格越来越低。
  • 低成本:ECUs通过单个CAN接口进行通信,布线成本低。
  • 高集成:CAN总线系统允许在所有ECUs上进行集中错误诊断和配置。
  • 可靠性:该系统对子系统的故障和电磁干扰具有很强的鲁棒性,是汽车控制系统的理想选择。
  • 高效率:可以通过id对消息进行优先级排序,以便最高优先级的id不被中断。
  • 灵活性:每个ECU包含一个用于CAN总线收发芯片,随意添加CAN总线节点。

CAN总线分层模型

  • CAN-Bus规范定义了:物理层、数据链路层、应用层(CANopen、DeviceNet等)。

  • 应用层可自行设计,支持多主通信模式

  • CAN总线协议也涵盖了 ISO 规定的 OSI 基本参照模型中的传输层、数据链路层及物理层。

  • CAN 协议中关于 ISO/OSI 基本参照模型中的传输层、数据链路层及物理层,具体定义:

  • 数据链路层分为 MAC 子层和 LLC 子层, MAC 子层是 CAN 协议的核心部分。数据链路层的功能是将物理层收到的信号组织成有意义的消息,并提供传送错误控制等传输控制的流程。具体地说,就是消息的帧化、仲裁、应答、错误的检测或报告。数据链路层的功能通常在 CAN 控制器的硬件中执行。
  • 物理层定义了信号实际的发送方式、位时序、位的编码方式及同步的步骤。具体地说,信号电平、通信速度、采样点、驱动器和总线的电气特性、连接器的形态等均未定义(驱动器及总线的电气特性等在博世公司的 CAN 规格书中没有定义。但在 CAN 的 ISO 标准(ISO11898、ISO11519-2 等)中分别定义了总线及驱动器的电气特性等 ),这些必须由用户根据系统需求自行确定。

CAN协议的标准、版本

  • CAN协议经过ISO标准化后有2个标准: ISO11898标准、IS011519-2标准。两种标准对于数据链路层的定义相同,但物理层不同。

  • CAN 1.0/2.0 : (2套标准的主要区别)

  • ISO11898 是针对通信速率为125Kbps~1Mbps高速(总线)通信标准(闭环);
  • IS011519-2是针对通信速率为125Kbps以下的低速(总线)通信标准(开环);

  • CAN总线使用两根线链接各个节点,分别是CAN_HighCAN_Low两根,数据的0和1是由总线点位差来判断的。

其中总线电平分为显性和隐性两种电平,显性表示逻辑0,隐性表示逻辑1,符合总线上执行线与功能。

由上图可以清楚的看到IS011899高速标准中,隐性时CAN_High和CAN_Low电位相同,电位差0V,表示逻辑1;显性时CAN_High电位高于CAN_Low电位,电位差为2.0V,表示逻辑0。

而低速IS011519-2标准中,显性时CAN_High电位低于CAN_Low电位,电位差为-1.5V,表示逻辑1;隐性时CAN_High电位高于CAN_Low电位,电位差为3.0V,表示逻辑0。

  • CAN FD:数据段速率已经可以提升到8Mbps(实际工程中常用2Mbps),有效负载带宽也提升到64 bytes。

  • CAN XL:数据段速率据说可以稳定达到10Mbps,有效负载带宽进一步拓展到2048 bytes。

  • Kbps:总线的通信速率,指的是位速率(比特率)
  • 比特率波特率不是一回事:单位时间内,通信线路上传输的二进制位的数量,其基本单位是 bps 或者 b/s (bit per second)。

1.2 CAN总线网络

简单的CAN总线网络

  • CAN总线网络主要挂在CAN_H和CAN_L,各个节点通过这两条线实现信号的串行差分传输.
  • 为了避免信号的反射和干扰,还需要在CAN_H和CAN_L之间接上120欧姆的终端电阻。为什么是120Ω?因为电缆的特性阻抗为120Ω,为了模拟无限远的传输线

复杂的CAN总线网络

1.3 CAN收发器

  • CAN收发器的作用是负责逻辑电平信号电平之间的转换。

即:从CAN控制芯片输出逻辑电平CAN收发器;然后,经过CAN收发器【内部转换】将逻辑电平转换为差分信号输出到CAN总线上,CAN总线上的节点都可以决定自己是否需要总线上的数据。
具体的引脚定义如下:

1.4 CAN信号表示

  • CAN总线采用不归零码位填充技术

也就是说,CAN总线上的信号有两种不同的信号状态,分别是: 显性的(Dominant)逻辑0和隐形的(recessive)逻辑1,信号每一次传输完后不需要返回到逻辑0(显性)的电平。

  • 显性电平隐性电平的解释:
  • CAN的数据总线有两条,一条是黄色的CAN_High,一条是绿色的CAN_Low
  • 没有数据发送时,两条线的电平一样都为2.5V,称为静电平,也就是隐性电平
  • 有信号发送时,CAN_High的电平升高1V,即3.5V,CAN_Low的电平降低1V,即1.5V。
  • 按照定义的:
  • CAN_H-CAN_L < 0.5V 时候为隐性的,逻辑信号表现为"逻辑1" - 高电平
  • CAN_H-CAN_L > 0.9V 时候为显性的,逻辑信号表现为"逻辑0" - 低电平

1.5 CAN信号传输

  • 发送过程CAN控制器CPU传来的信号转换为逻辑电平(即: 逻辑0-显性电平 或者 逻辑1-隐性电平)。CAN收发器(发射器)接收逻辑电平之后,再将其转换为差分电平输出到CAN总线上。

  • 接收过程CAN发射器(接收器)CAN_HCAN_L 线上传来的差分电平转换为逻辑电平输出到CAN控制器CAN控制器再把该逻辑电平转化为相应的信号发送到CPU上。

1.6 CAN数据传输

  • CAN总线传输的是CAN帧CAN的通信帧分成5种,分别为:数据帧远程帧错误帧过载帧帧间隔
  • 数据帧根据仲裁段长度的不同,而分为:标准帧(2.0A)和扩展帧(2.0B)。

  • 位填充:在 CAN 总线中,为了确保足够的转换以保持同步,在相同极性5连续位(bit)之后使用位填充

下面以 标准格式来进行说明,先看下面标准格式的帧的图示:

  • 在某些文档中,将 CAN 帧分为以下部分:
  • Header ( H ): 由 Start of Frame (SOF) 、 Arbitration Field、 Control Field 组成。
  • Data field ( D ): 即数据域
  • CRC field ( R ):即 CRC 域的 CRC 部分。其内容由 CAN 控制器在运行时计算,因此不能由应用程序直接修改。
  • Unstuffed trailer ( U ): 由 CRC delimiter、the ACK slot、the ACK delimiter、the End of Frame (EOF) field. 组成。

特别说明:位填充

  • BOSCH CAN2.0 规范规定,DATA FRAMEREMOTE FRAME 中的位字段 START OF FRAMEARBITRATION FIELDCONTROL FIELDDATA FIELDCRC SEQUENCE 都需要通过比特填充的方法编码。

每当发送器要发送的比特流中检测到相同值的五个连续比特时,则:自动在实际发送的比特流中插入一个相反的比特位,这种方法被称为位填充

  • DATA FRAMEREMOTE FRAME 的剩余位字段 CRC DELIMITERACK FIELDEND OF FRAME固定格式不需要填充

  • ERROR FRAMEOVERLOAD FRAME 也是固定格式,不通过位填充方法编码。

  • 消息中的比特流根据不归零法Non-Return-to-ZeroNRZ)进行编码。

这意味着在总比特时间内,生成的比特电平要么是“显性”要么是“隐性”。
下图为一个填充示意图:

  • 在使用比特填充的字段中,相同极性的六个连续比特111111000000)被认为是错误

检测到错误时,节点可以发送主动错误标志
主动错误标志由 6 个连续的比特位的显性电平组成,这违反了位填充规则。

  • 位填充方案的一个副作用是,接收到的消息中的少量位错误可能会破坏解填充过程接收器需要去除填充位),从而导致大量错误在解填充消息中传播。

这降低了 CRC 针对原始错误提供的保护级别。
该协议的不足之处已经在 CAN FD 帧中得到了解决,具体方法是:通过使用固定填充比特和记录插入的填充比特数的计数器的组合。

  • 帧长度

在位填充之后,CAN 帧的大小将增大。填充位本身可以是五个连续相同位中的第一个。
因此,在最坏的情况下,每四个原始位有一个填充位。帧大小可以使用如下公式表示:

  • s:由控制域中 DLC 定义的数据域的长度
  • 8s:数据域的 比特位 数
  • 47:从 SOF 开始到帧间隔(3个比特位的隐性电平),除去数据域部分(8s 单独表示)
  • 8s + 47:表示填充之前帧的大小。
  • 34:根据规范的要求,可能受到位填充的位的数量。去除了不可填充的部分和某些固定位。在最坏情况下,原数据除了第一个 4 位后,在每个 4 位后增加 1 位(所以分子减去 1)

帧起始

  • 由一个显性位(低电平)组成,发送节点发送帧起始,其他节点同步于帧起始;

帧结束

  • 由7个隐形位(高电平)组成。

仲裁段

  • 只要总线空闲,总线上任何节点都可以发送报文,如果有两个或两个以上的节点开始传送报文,那么就会存在总线访问冲突的可能。但是CAN使用了标识符的逐位仲裁方法可以解决这个问题。

  • CAN总线控制器发送数据的同时监控总线电平

  • 如果电平不同,则:停止发送并做其他处理。
  • 如果该位位于仲裁段,则:退出总线竞争;
  • 如果位于其他段,则:产生错误事件。
  • 假设节点A、B和C都发送相同格式、相同类型的帧,如标准格式数据帧,它们竞争总线的过程是:

  • 帧ID越小,优先级越高。

  • 由于数据帧的RTR位为显性电平,远程帧为隐性电平。所以,帧格式和帧ID相同的情况下,数据帧优先于远程帧;由于标准帧的IDE位为显性电平,扩展帧的IDE位为隐形电平,对于前11位ID相同的标准帧和扩展帧,标准帧优先级比扩展帧高。

数据段

  • 一个数据帧传输的数据量为0~8个字节,这种短帧结构使得CAN-bus实时性很高,非常适合汽车和工控应用场合下图所示。

  • 数据量小,发送和接收时间短,实时性高,被干扰的概率小,抗干扰能力强。

归零编码(RZ)和不归零编码(NRZ)

  • 无论是归零编码(return-to-zero,RZ)还是不归零编码(non-return to zero,NRZ),信号都是在正 (+V) 和负 (- V) 电压之间交替。

逻辑1 表示正电压下的信号,逻辑 0 表示负电压下的信号。
然而,在 NRZ 方法中,从逻辑 0 到逻辑 1 的转换(反之亦然),直接跨越零电压电平,而在 RZ 方法中,转换暂时停留在零电压电平上。如下图所示:

  • 在光通信中,术语 RZNRZ 使用与以上含义不同,因为没有负光。

NRZ 意味着逻辑值 1 (光脉冲)的一个位在位周期的边界上改变它的值(从有光到无光、或反之亦然)。
相反,RZ 表示光脉冲比比特周期窄。在光信号中,逻辑 1 导通大约三分之一的位周期并且关闭大约三分之二。 逻辑 0 在比特周期的三分之二时间内保持关闭状态。

单极信号、双极信号、多级信号

  • 双极信号(bipolar signal) 是一个三电压级的信号,通常在正电压和负电压之间摇摆。双极信号可以是 RZNRZ。在数字双极信号中,正电压和负电压交替出现。这导致输电线路上的零直流分量。

  • 单极信号(unipolar signal) 是一种两级信号,通常在零级正级之间波动。

单极信号被认为是一种开关信号,可以应用于电信号或光学信号。在电力传输中,假设统计上有相同数量的1和0,那么直流分量可能达到峰值正电压的一半。对于长距离传输,这种直流分量是不可取的。在光学传输中,单极信号也称为开关键控。

  • 还有一类是多级信号。在这种情况下,可以使用几个电压电平(例如,8),每个电平对应8个代码中的一个。尽管多级信号由于其固有的编码压缩特性而具有很大的吸引力,但它们并不用于通信网络的传输。在光传输中,不存在多电平信号。

4B/5B, 8B/10B CODING

  • 4B/5B 代码将 4 位转换成 16 个预定的 5 位代码之一。

因此,即使原始的 4 位代码是 0000,它也被转换为 5 位非全零代码。
此方法避免在任何代码中都包含所有零。
它也可以设计成连续模式避免某些字符串。
4B/5B 意味着转换后的初始 1 Gb/s 比特率由于增加了比特而增加到 1.25 Gb/s。
也就是说,有 25% 的开销带宽损失。
类似地,8B/10B 代码将 8 位转换成 256 个预定的 10 位代码之一。
带宽损失也是25%。

2 CAN DBC协议文件

2.1 CAN 总线拓扑图

2.2 CAN 闭环总线网络

  • CAN闭环通讯网络,是一种遵循ISO11898标准的高速短距离网络。
  • 它的总线最大长度为40m、通信速度为40m,通信速度最高位1Mbps
  • 总线的两端要求有一个120欧姆的电阻。

2.3 CAN 开环总线网络

  • CAN开环总线网络是遵循IDO11519-2标准的低速远距离网络。
  • 它的最大传输距离为1km、最高通讯速率为125kbps
  • 两根总线是独立的、不形成闭环;
  • 要求每根总线上各串联有一个2200欧姆的电阻。

2.4 CAN 报文的解析规则

通常是将接收到的16进制码流数据翻译成数值、字符串格式的数据,根据 dbc 文件中定义的规则来进行解析。

  • 以CDCU_ICAN_Release.dbc为例来介绍:

版本(version)、新符号(NS)

波特率定义(BS_)

  • 定义格式
BS_:[baudrate:BTR1,BTR2];

其中BS_为关键字,用于定义CAN网络的波特率
[ ]内容表示为可选部分,可以省略,但关键字BS_:必须存在,省略则会出错。

网络节点定义(BU_)

  • 定义格式:
BU_:Nodename1 Nodename2 Nodename3 ……

其中BU_为关键字,表示网络节点,格式中的Nodename1Nodename2表示定义的网络节点名字,由用户自己定义;但需保证节点命名的唯一性

报文帧定义(BO_)

  • 定义格式:
BO_ MessageId(10进制数表示) MessageName: MessageSize Transmitter
  • (1)、BO_为关键字,表示报文;
  • (2)、MessageId为定义的报文ID,是以10进制数表示的;如例子中的996,代表报文ID为0x3E4;
  • (3)、MessageName表示该报文的名字,命名规则和C语言变量相同;
  • (4)、MessageSize表示该报文数据域字节数,为无符号整型数据;
  • (5)、Transmitter表示发送该报文的网络节点(发送节点);如果该报文没有指定发送节点,则该值需设置为”Vector__XXX”。

信号定义(SG_)

  • 定义格式:
SG_ SignalName : StartBit|SignalSize@ByteOrder ValueType (Factor,Offset) [Min|Max] Unit Receiver
  • (1)SG_为关键字,表示信号;
  • (2)SignalName、 StartBit、 SignalSize分别表示该信号名起始位信号长度
  • (3)ByteOrder表示信号的字节顺序大小端):0代表Motorola格式(大端),1代表Inter格式(小端);
  • (4)ValueType 表示该信号的数值类型+表示无符号数-表示有符号数
  • 注:Java 的Long是8字节(64bit)的有符号数、其作为【有符号数】的取值范围:
    [-2^ 63= -9223372036854775808 , +2^ 63 -1 = 9223372036854775807 ] = [1000000000000000000000000000000000000000000000000000000000000000, 0111111111111111111111111111111111111111111111111111111111111111]
  • 注:Java 的Long,针对【长度为 64 bit、无符号数,且上报的信号bit流的第1位为1】的CAN信号情况,根据其取值范围可知、是装不下的。
  • (5)Factor表示系数因子,Offset表示偏移量;这两个值于该信号的原始值与物理值之间的转换。

计算方法:信号的物理值 = 原始值*因子 + 偏移量

  • (6)Min|Max表示该信号的最小值最大值,即指定了该信号值的范围;这两个值为double类型;
  • (7)Unit表示该信号的物理单位,为字符串类型;
  • (8)Receiver表示该信号的接收节点;若该信号没有指定的接收节点,则必须设置为” Vector__XXX”。

注解部分(CM_)

  • 定义格式
CM_ Object MessageId/NodeName "Comment"
  • (1)、 CM_为关键字,表示注解信息
  • (2)、 Object表示进行注解的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”;
  • (3)、 MessageId/NodeName 表示进行注解的对象,若前面的对象类型是信号或者报文,则这里的值应为报文的ID(10进制数表示);若前面的对象类型为节点,则这里的值应为节点的名字;
  • (4)、 Comment表示进行注解的文本信息

属性定义部分(BA_DEF_/BA_DEF_DEF_)

  • 定义格式:
BA_DEF_ Object AttributeName ValueType Min Max;
BA_DEF_DEF_ AttributeName DefaultValue;
  • (1)、 BA_DEF_为关键字,表示属性定义;
  • (2)、 Object表示属性定义的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”、网络节点” ”(用空格表示)等;
  • (3)、 AttributeName表示进行定义的属性名字;
  • (4)、 ValueType表示属性值的类型,可以是整型、字符串、浮点型、枚举类型等;
  • (5)、Min/Max表示属性值的上下最值,即指定了取值范围(字符串类型没有此项)。
  • (6)、 BA_DEF_DEF_为关键字,表示定义属性的初始值;
  • (7)、 DefaultValue表示该属性的初始值。

数值表部分

  • 定义格式
VAL_ MessageId SignalName N "DefineN" …… 0 "Define0";
  • (1)、VAL_为关键字,表示数值表定义;
  • (2)、 MessageId表示该信号所属的报文ID(10进制数表示);
  • (3)、 SignalName表示信号名;
  • (4)、 N “DefineN” …… 0 “Define0”表示定义的数值表内容,即该信号的有效值分别用什么符号表示

2.5 辨析:字节序(ByteOrder) := 大小端、比特序(bitOrder) := 正序/逆序

序:CAN报文中的字节序

  • 数据在CAN报文中存放顺序
  • CAN每个报⽂可包含8Byte的字节数据域,在报⽂内数据的字节序和位序如下:
  • 字节序:Byte0、Byte1、Byte2、Byte3、Byte4、Byte5、Byte6、Byte7
  • 位序:bit7、bit6、bit5、bit4、bit3、bit2、bit1、bit0
  • CAN报文数据域的传输顺序
  • 字节顺序:先传Byte0,最后传Byte7;
  • 字节内位序:先传bit7,最后传bit0;

字节内始终采用 msb(大端位序),即:信号高有效位在字节内的高位, 信号低有效位在字节内的低位。

  • 跨字节、单字节:

关于CAN报文,用Motorola,还是Intel格式,只在信号数据跨字节解析时,才有区别。单个字节数据没有区别。

LSB/MSB、lsb/msb

位序和字节序都有大端和小端,共有四种:

  • LSB:Least significant byte(CAN某个信号的最低字节/byte)

  • MSB:Most significant byte(CAN某个信号的最⾼字节/byte)

  • lsb:Least significant bit(CAN某个信号中某个字节的最低有效位/bit)

  • msb:Most significant bit(CAN某个信号中某个字节的最⾼有效位/bit)

  • 扩展解释:

  • msb与lsb是存在于二进制BIT中的计算机名词,msb代表一组二进制中最高位(一般为符号位),lsb代表二进制中的最低位。

如:一个1字节的二进制数:(msb)100000000(lsb)

  • 也可能是一个4字节的整型数据:(msb)100000000 100000000 100000000 100000000(lsb)
  • 无论这组二进制数据多大,有多少位,最高位都是msb,最低位就是lsb。
  • 一般这两个名词多用在通讯上,msb用来校验这组数据是否为负数,为1则负;lsb用来校验奇偶,为1则偶数
  • 案例:

假设一个一字节的数0x9A转换成2进制为“1001 1010”,那么lsbmsb则应该是这样分布的:

字节序

  • Motorola格式/大端模式(0)

MSB存放在低字节单元,反映到矩阵图中就是以起始位为原点,自下而上填充。Motorola格式,MSB在LSB上面。
一个数值的最高字节(MSB)存储在内存的最低地址处,而最低字节(LSB)存储在内存的最高地址处。这种存储方式类似于人类阅读和书写数字的方式,即从左到右,高位在前

  • Intel格式/小端模式(1)

MSB存放在高字节单元,反映到矩阵图中就是以起始位为原点,自上而下填充。Intel格式,MSB在LSB下面。
高字节存放在高地址,低字节存放在低地址

  • 跨字节

没有跨字节是看不出来这两种有啥区别的。来看个跨字节的例子:

当然这里只是为了解释这两个的区别,才把一个报文中的两个信号设置成不同的格式,实际项目中一般不会出现这种情况

  • 案例

案例

比特序

小结

  • 当信号在一个字节内实现(信号不跨字节)时,Intel模式和Motorola模式的信号字节顺序,完全一样:

信号的高位(msb)放在该字节的高位,信号的低位(lsb)放在该字节的低位。

  • 当信号在多个字节内实现(信号跨字节)时,Intel模式和Motorola模式的信号字节顺序,明显不同:
  • Intel模式:信号的高位(MSB)放在高字节的高位,信号的低位(LSB)放在低字节的低位;
  • Motorola模式:信号的高位(MSB)放在低字节的高位,信号的低位(LSB)放在高字节的低位。
  • 俗称:
  • 小端模式 “低(低位字节)在前(低地址),高(高位字节)在后(高地址)”;
  • 大端模式 “高(高位字节)在前(低地址),低(低位字节)在后(高地址)”。
  • 不管是Intel模式,还是Motorola模式,起始位都该信号的低位(LSB)。

2.X Can 报文实际解析

案例1:(大端模式/Motorola/0)

  • 使用can lin 串口工具抓取rawdata :
30 2E 71 00 00 00 00 00 00 00 00 25 49 15 00 00 00 01 10 00 00 00 00 00 00 00 00 00 00 00 0A 00 34 1D 07 41 D0 40 3C 3C 00 00 28 FF FF FF FF FF FF FF FE 00 00 00 00 00 00 00 00 00 00 00 00 00
  • 通过 dbc 文件找到报文的定义

  • 解析第1个signal:SG_ I_CDCU_KL15State

RawData:30 ------> 0011 0000 从第位开始2个bit

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

  • 值定义:
VAL_ 816 I_CDCU_KL15State 0 "IG_OFF" 1 "LOCAL_IG_ON" 2 "REMOTE_IG_ON" 3 "Reserved" ;

1 ---> LOCAL_IG_ON

  • 再解析信号: I_CDCU_SWITCH_Temp
SG_ I_CDCU_SWITCH_Temp : 319|8@0+ (1,-40) [-40|100] "degC" Vector__XXX

Rawdata:3C ---------> 00111100

I_CDCU_SWITCH_Temp的定义从第 319 开始、8个bit,rawdata 中找到对应的字节是第40个字节3C

第40个字节的二进制排列

319bit 318bit 317bit 316bit 315bit 314bit 313bit 312bit
0 0 1 1 1 1 0 0

根据公式计算出来对应的值:1*60-40=20;加上单位为20degC

案例2:(小端模式/Intel/1)

  • DBC协议文件

1、如下是一个完整的、准确的Intel模式 CAN信号解析过程。
2、Intel模式信号:低位在右、高位在左;读取顺序:从右往左读。与之相对的是 摩托罗拉信号。
3、DBC的某个CAN帧的信号:

BO_ 1443 BMS_moduleTemperature02: 8 BMS
 SG_ bms_moduleXTempSync02 : 0|4@1+ (1,0) [0|15] "" TBOX
 SG_ bms_moduleXTempSensor7 : 8|9@1+ (0.5,-40) [-40|210] "℃" TBOX
 SG_ bms_moduleXTempSensor8 : 17|9@1+ (0.5,-40) [-40|210] "℃" TBOX
 SG_ bms_moduleXTempSensor9 : 26|9@1+ (0.5,-40) [-40|210] "℃" TBOX
 SG_ bms_moduleXTempSensor10 : 35|9@1+ (0.5,-40) [-40|210] "℃" TBOX
 SG_ bms_moduleXTempSensor11 : 44|9@1+ (0.5,-40) [-40|210] "℃" TBOX
 SG_ bms_moduleXTempSensor12 : 53|9@1+ (0.5,-40) [-40|210] "℃" TBOX

0x5A3 = 1443

  • 上报的CAN帧

rawdata : 0050D4408102050A

图片仅供参考,非实际CAN帧的准确瞬时截图

  • 信号解析

0050D4408102050A :=
0000 0000
0101 0000
1101 0100
0100 0000
1000 0001
0000 0010
0000 0101
0000 1010

  • <---- bit编号:从0到X、从右至左、从上到下
  • ↓ :字节地址(从上到下:低地址 => 高地址)
  • 解析方法1:不反转法(适用于人眼直接阅读)
  • 1101 0100 高位 <-- 低位 ↓
  • 0100 0000 高位 <-- 低位 ↓
    => 00 1101010 => 106 => 13
  • 解析方法2:每8bit反转1次(便于通过程序实现)
  • 0010 1011
  • 0000 0010
    => 010 1011 00 => 再反转1次(作用:还原顺序) => 00 1101 010 => 106*0.5-40=13

案例3:(大端模式/Motorola/0)

  • DBC定义
BO_ 908 BCM_38C: 8 INFO_CAN
 SG_ BCM_FLWINOpenDegree : 6|7@0+ (1,0) [0|127] "" VHR
 SG_ BCM_FRWINOpenDegree : 14|7@0+ (1,0) [0|127] "" VHR
 SG_ BCM_RLWINOpenDegree : 22|7@0+ (1,0) [0|127] "" VHR
 SG_ BCM_RRWINOpenDegree : 30|7@0+ (1,0) [0|127] "" VHR
 SG_ bcm_doorTopSwitchSts : 36|2@0+ (1,0) [0|3] "" VHR
 SG_ BCM_VSPReq : 38|2@0+ (1,0) [0|3] "" VHR
 SG_ BCM_FLWINReason : 43|4@0+ (1,0) [0|15] "" VHR
 SG_ BCM_FRWINReason : 47|4@0+ (1,0) [0|15] "" VHR
 SG_ BCM_RLWINReason : 51|4@0+ (1,0) [0|15] "" VHR
 SG_ BCM_RRWINReason : 55|4@0+ (1,0) [0|15] "" VHR
 SG_ BCM_RainAutoCloseWinFedb : 57|2@0+ (1,0) [0|3] "" VHR
 SG_ BCM_RainAutoCloseWinResult : 59|2@0+ (1,0) [0|3] "" VHR
 SG_ BCM_LockFaultReason : 63|4@0+ (1,0) [0|15] "" VHR

VAL_ 908 BCM_FLWINOpenDegree 0 "Inactive" 1 "0%(全关)" 101 "100%(全开)" 102 "reserve" 126 "reserve" 127 "Invalid" ;
VAL_ 908 BCM_FRWINOpenDegree 0 "Inactive" 1 "0%(全关)" 101 "100%(全开)" 102 "reserve" 126 "reserve" 127 "Invalid" ;
VAL_ 908 BCM_RLWINOpenDegree 0 "Inactive" 1 "0%(全关)" 101 "100%(全开)" 102 "reserve" 126 "reserve" 127 "Invalid" ;
VAL_ 908 BCM_RRWINOpenDegree 0 "Inactive" 1 "0%(全关)" 101 "100%(全开)" 102 "reserve" 126 "reserve" 127 "Invalid" ;
VAL_ 908 bcm_doorTopSwitchSts 0 "INACTIVE" 1 "OFF" 2 "ON" 3 " INVALID" ;
...
  • 解析过程分析
  • canFrameId : 38c
  • canFrameContent : 7f7f010110110021

原始二进制 : 0111111101111111000000010000000100010000000100010000000000100001
01111111 : 7F
01111111 : 7F
00000001 : 01
00000001 : 01
00010000 : 10
00010001 : 11
00000000 : 00
00100001 : 21

以第1个信号(BCM_FLWINOpenDegree)为例,从第6位开始,读取7个字节。

使用解析方法2来处理原始CAN帧的二进制流
1000010000000000100010000000100010000000100000001111111011111110

10000100
00000000
10001000
00001000
10000000
10000000
11111110
11111110
  • 解析结果
  • BCM_FLWINOpenDegree | signal bits : 1111111 , signalValue : 127, startBit : 0, bitLen : 7 | bigEndStartBit : 56
  • BCM_FRWINOpenDegree | signal bits : 1111111 , signalValue : 127, startBit : 8, bitLen : 7 | bigEndStartBit : 48
  • BCM_RLWINOpenDegree | signal bits : 1000000 , signalValue : 1, startBit : 16, bitLen : 7 | bigEndStartBit : 40
  • bcm_doorTopSwitchSts | signal bits : 01 , signalValue : 2, startBit : 35, bitLen : 2 | bigEndStartBit : 27
  • BCM_VSPReq | signal bits : 00 , signalValue : 0, startBit : 37, bitLen : 2 | bigEndStartBit : 29
  • BCM_FRWINReason | signal bits : 1000 , signalValue : 1, startBit : 44, bitLen : 4 | bigEndStartBit : 20
  • ...

案例4:(大端模式/Motorola/0)

  • 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_
 SG_MUL_VAL_

BS_:

BU_:  EOCM_F_FO Dummy_FO


BO_ 1414 RVB_TVR_Debug2_FO: 7 EOCM_F_FO
 SG_ VBBrkCntlAccel : 45|12@0- (0.01,0) [-20.48|20.47] "m/s^2"  Dummy_FO
 SG_ VBTOSObjID : 35|6@0+ (1,0) [0|63] ""  Dummy_FO
 SG_ VBTOSTTC : 31|12@0+ (0.025,0) [0|102.375] "s"  Dummy_FO
 SG_ VBTOSLatPstn : 11|11@0- (0.125,0) [-128|127.875] "m"  Dummy_FO
 SG_ VBTOSLonPstn : 7|12@0- (0.125,0) [-256|255.875] "m"  Dummy_FO
  • 发送CAN报文

根据上面的dbc文件,我们进行如下示例分析。向can0网卡发送数据 cansend can0 586#d465737400000000, ekuiper 输出以下结果:

[
 {
  "VBBrkCntlAccel": 0,
  "VBTOSLatPstn": 87.125,
  "VBTOSLonPstn": -87.25,
  "VBTOSObjID": 0,
  "VBTOSTTC": 46.400000000000009
 }
]

我们尝试通过对dbc数据库文件的理解进行分析,看看是否与ekuiper的计算结果一致。在分析前,我们需要了解几点内容:

  • 1、位序。我们知道: 字节序是一个对象中的多个字节之间的顺序问题比特序就是一个字节中的8个比特位(bit)之间的顺序问题

一般情况下系统的比特序和字节序是保持一致的。
比如:二进制数11010100,若比特序为大端msb,则:最高有效比特位在高位,最低有效比特位在低位,那么:它代表的值为0xd4;
比特序为lsb,则:最高有效比特位在低位,最低有效比特位在高位,那么:它代表的值为0x2b。

  • CAN 总线协议中规定位序都是大端模式,即 msb

  • 2、motorolainter字节序dbc文件解析中,信号定义中有一个参数ByteOrder表示信号的字节顺序。分别为inter和Motorola两种格式。
  • Intel格式跟小端格式一样,低地址代表低字节,高地址代表高字节。
  • Motorola格式跟大端格式一样,低地址代表高字节,高地址代表低字节。

注:Motorola格式有2种表达方式,一种是Motorola_LSB,另一种是Motorola_MSB。Motorola_LSB的起始位是从低字节开始的,而Motorola_MSB的起始位是从高字节开始的。
dbc文件默认表示Motorola_MSB表达方式;而CANdb++则是Motorola_LSB

  • 3、信号传输,都是以补码的形式传输

  • 分析:

  • 586#d465737400000000表示报文ID0x586=1414,与RVB_TVR_Debug2_FO报文匹配。其中d465737400000000则为该报文的数据部分。
  • 因为CAN总线协议规定位序都是大端模式,即可得到下面的layout图。其中蓝色背景为数据内容,因为RVB_TVR_Debug2_FO报文长度仅有7Byte

  • VBBrkCntlAccel信号的起始位bit45,且为Motorola字节序,则:bit45是信号VBBrkCntlAccel最高有效比特位。因此,信号内容如下。即信号原始值000000000000物理值=原始值*(0.01)+0 = 0

同理,可得到其它信号的layout如图。

  • VBTOSObjID原始值为000000,物理值=0*1+0=0;
  • VBTOSTTC原始值为011101000000,物理值=1856*0.025+0=46.4。至于最终的打印结果为什么是46.400000000000009,可以参考我的博客flaot 数据类型的一些坑(大数吃小数)。
  • VBTOSLatPstn原始值为01010111001,物理值=697*0.125+0=87.125。
  • VBTOSLonPstn原始值为110101000110。因为该信号为有符号数,因此最高位1,则表示该值为负。
    原始值的补码110101000110,则:原始值为101010111010=-698。物理值=-698*0.125+0=-87.25。
  • 同样的dbc文件,若由CANdb++进行解析,如下。可知Startbit与dbc文件不一致。因为CANdb++默认是Motorola_LSB表达方式。

案例5:Intel

  • Intel格式:Intel格式跟小端格式一样,低地址代表低字节,高地址代表高字节。比如一个信号Intel,它的起始位为3,长度为10,在dbc中它的排列顺序如下所示:

要注意其箭头的增长方向,这样我们在提取该信号的值为: Intel = (byte0 >> 3) + (byte1 << 5)

其中: (byte0 >> 3)为低字节的值,(byte1 << 5)为高字节的值。

案例6:Motorola_LSB

  • Motorola格式
  • Motorola格式跟大端格式一样,低地址代表高字节,高地址代表低字节。
  • 与Intel不一样的是,Motorola格式有2种表达方式,一种是Motorola_LSB,另一种是Motorola_MSB,但实际上它们代表的数据结构是一样的,只是表达方式不一样而已
  • 其中Motorola_LSB的起始位是从低字节开始的,而Motorola_MSB的起始位是从高字节开始的。
  • 在dbc中,比如一个Motorola_LSB的信号MotorolaSignal,其起始位为10,长度为10,在dbc中,其排列顺序如下所示:

要注意其箭头的增长方向,这样我们在提取该信号的值为: MotorolaSignal= (byte1 >> 2) + (byte0 << 6)

其中(byte1 >> 2)为低字节的值,(byte0 << 6)为高字节的值。

  • 如果该MotorolaSignal信号用Motorola_MSB表示,则:起始位为3,长度为10,但其值的计算方式跟Motorola_LSB是一样的。

案例7:大端模式 + 小端模式

  • 以8 byte的CAN帧为例,其位序为下保持不变。

| 7  -   0 |
| 15 -   8 |
| 23 -  16 |
| 31 -  24 |
| 39 -  32 |
| 47 -  40 |
| 55 -  48 |
| 63 -  56 |

.dbc描述中,一般只会给出某个信号的startbit及len,我们先以大端模式为例阐述这样的一个例子: startbit = 20, len = 15
那么大端的数据范围是

上图中38bit为lsb,20bit为msb,DBC描述是从msb->lsb方向描述一个信号,接下来看看小端是如何描述的

其中20bit是lsb,34bit为ms,所以小端格式下,DBC描述是从lsb->msb的方向描述一个信号

案例8:小端模式(Intel)

  • DBC中的CAN帧定义
BO_ 1300 BMS_metric: 8 BMS_EV
 SG_ bms_SOC : 0|10@1+ (0.1,0) [0|100] "%" GW_R
 SG_ bms_SOH : 10|10@1+ (0.1,0) [0|100] "%" GW_R
 SG_ bms_SOE : 20|10@1+ (0.1,0) [0|100] "%" GW_R
 SG_ bms_SOCActual : 30|10@1+ (0.1,0) [0|100] "%" GW_R
 SG_ bms_maxChargeSOC : 40|7@1+ (1,0) [0|100] "" GW_R
 SG_ BMS_BatterFaultLightContro : 47|1@1+ (1,0) [0|1] "" GW_R
 SG_ BMS_BatteryTempLowLight : 50|1@1+ (1,0) [0|1] "" GW_R
 SG_ BMS_NavigChrgPostFB : 51|3@1+ (1,0) [0|7] "" GW_R
 SG_ bms_stEgyFlowSysDischRgn : 54|2@1+ (1,0) [0|3] "" GW_R
 SG_ bms_stEgyFlowOBCAndBatt : 56|2@1+ (1,0) [0|3] "" GW_R
 SG_ bms_BatteryWarmst : 61|3@1+ (1,0) [0|7] "" GW_R
 SG_ bms_chargeFormstatus : 58|3@1+ (1,0) [0|7] "" GW_R
  • CAN帧
030000031e080348
  • 信号计算结果(以bms_SOC信号为例)

小结:CAN总线/报文、DBC文件、CANdb++的字节序、位序(比特序)

  • Motorola格式:跟大端格式一样,低地址代表高字节,高地址代表低字节。

注:Motorola格式有2种表达方式,一种是Motorola_LSB,另一种是Motorola_MSB。Motorola_LSB的起始位是从低字节开始的,而Motorola_MSB的起始位是从高字节开始的。

  • CAN总线协议中规定,位序都是大端模式,即 msb first => 因此不需要区分; 但对字节序没有规定,就出现了两种情况:MotorolaIntel 格式。

字节内始终采用 msb(大端位序),即:信号高有效位在字节内的高位, 信号低有效位在字节内的低位。

  • dbc文件默认表示Motorola_MSB字节序;而CANdb++则是Motorola_LSB

CANdb++默认是Motorola_LSB字节序

3 CAN-FD 总线协议

3.1 CAN 总线通信协议 ==> CAN FD 总线通信协议

  • CAN 总线通信也渐渐显现出来一些不足,主要有以下几方面:
  • (1)最高数据传输速率限制为1 Mbit/s,车载领域实际使用速率最高为500 Kbit/s,无法满足越来越高的数据吞吐量需求;
  • (2)每帧报文有效数据场为8 字节,仅占整帧报文信息不足50%;
  • (3)性能上难以应对Flexray、Ethernet 等新型车载总线的威胁。
  • 市场对提升 CAN 总线性能的强烈需求使CAN-FD (Flexible Data rate)应运而生,CAN-FD发扬了CAN 的优点,并弥补了 CAN 的不足,其主要特性如下:
    (1)采用与 CAN 通信相同的事件触发模式,软件容易开发和移植;
    (2)最高数据传输速率5Mbit/s,更好地满足要求高实时性高数据传输速率的应用;
    (3)每帧报文有效数据长64 字节,占整帧报文信息超过70%;
    (4)相比Flexray、Ethernet 等新兴总线的成本更低。

  • CAN与CAN-FD性能对比

| Frame Type | NO.Data Bytes | Arb.Bit-Rate | Opt.Bit-Rate | Avg.Bit-Rate | Frame Duration |

3.2 CAN-FD 的技术特点及应用领域

  • `CAN-FD· 通过改变帧结构提高位速率等方法成功的把数据传输速率提高到了5Mbit/s,其基本原理如图所示。

CAN-FD 传输的基本原理

3.3 CAN-FD 的主要应用领域

  • (1)EOL(End-Of-Line)程序烧写:CAN 数据传输速率为500 Kbit/s;CAN-FD 数据传输速率为5 Mbit/s,约10 倍于CAN 传输速率。
  • (2)动力、底盘和安全系统,以及身份认证:数据场支持长达64 字节,避免数据非  必要的拆分。
  • (3)网关:提高网络数据传输速率达5 Mbit/s,提高了有效数据负载率。

3.4 CAN-FD 的设备、工具厂商

  • 车载应用领域,目前已有多家设备、工具厂商支持CAN-FD 总线协议,如维克多(Vector)、罗德与施瓦茨(R&S)和周立功(ZLG)等。
  • 国外厂商以维克多为代表,其在工具体系的完整性方面更为领先。Vector 的工具体系完整的支持CAN-FD 的开发、测试、网络分析等全部功能。另外,其GL 系列总线记录仪也将在不远的将来支持CAN-FD 协议。
  • 国内厂商以周立功为代表,其最新推出的四通道ZDS2024 示波器可以很好的支持  CAN-FD 协议,其关键特性包括:支持4 通道、模拟带宽高达200MHz、采样率每通道均为1GSa/s、21 种协议触发及解码、51 种参数测量及24 种参数同时测量统计。

3.5 位填充法

  • 与CAN一样,填充位插入到SOF和数据场的末尾之间。插入的填充位数值是经过格雷码计算转换后的值,并且用奇偶校验位保护(Stuff Count)。

  • 在CRC校验场中,填充位被放置在固定的位位置,这称为固定填充位(Fixed Stuff Bit FSB)。固定填充位的值是上一位的反码。

  • CRC校验场的第一位

  • 每间隔4位添加一个固定填充位

3.6 CAN-FD帧类型

  • CAN-FD仅定义了数据帧,与传统CAN相比,取消了远程帧的支持。原因是在没有数据的情况下,远程帧没有必要改变数据段的比特率。
  • 与CAN一样,数据帧分为“标准帧(11位ID)”和“扩展帧(29位ID)”格式。从BRS(Bit Rate Switch)到CRC分界符之间为可变速率。橙色表示与CAN的传输速度相同,蓝色表示可加速传输速度。

3.7 CRC-stuff count

  • CAN FD还在安全性上有了提高。为了避免位填充对CRC的影响,CAN FD在CRC场中增加了stuff count记录填充位的个数对应8的模,并用Grey Code表示,还增加了奇偶校验位。FSB(fixed stuff-bit)固定为前一位的补码。

  • Stuff Count由以下两个元素组成:

  • 格雷码计算:CRC区域之前的填充位数除以8,得到的余数(Stuff bit count modulo 8)进行格雷码计算得到的值(Bit0-2)
  • 奇偶校验:通过格雷码计算后的值的奇偶校验(偶校验)

3.8 CRC

  • 随着数据场的扩大,为了保证信息发送的质量,CAN FD的CRC计算不仅要包括数据段的位,还包括来自SOF的Stuff Count和填充位。通过比较CRC的计算结果,可以判断接收节点是否能够正常接收。
  • 在CAN中,CRC的位数是15位,而在CAN FD中,CRC场扩展到了21位,详见以下:
  • 当传输数据为16字节或更少时:CRC 17位
  • 当传输数据超过16个字节时:CRC 21位

3.9 CRC界定符

  • CRC界定符是表示CRC校验场的结束,是一个1位的常态隐性位。但是,在CAN FD中,考虑到节点之间的位的距离,在接收端允许最大2位时间。CAN FD帧的数据场(可变速段)是CRC界定符的第一位采样点。

3.10 ACK应答场

  • CAN FD的ACK应答场包括应答间隙和应答界定符,其构成和CAN是相同的。不同的是,在CAN中,应答场的长度是1位,但在CAN FD,接收节点利用2位时间将其识别为有效应答。
  • 由从高速的数据场到慢速的仲裁场时,时钟切换会引起收发器相移和总线传播延迟。为了补偿其相移和延迟,相比传统的CAN,在CAN FD中多加了这额外的1位时间。在ACK之后,发送ACK界定符。这是一个表示ACK结束的分隔符,为是1位隐性位。

3.11 帧结尾

每一个数据帧均由一标志序列界定,这个标志序列由7个“隐性”位组成。CAN FD的帧结尾与CAN相同。

3.12 有关CRC的ISO CAN FD、non-ISO CAN FD兼容性问题

  • 当前CAN FD协议有两个版本,为提高故障(错误)检测能力,新版本特别引入了一个3位填充位计数器和一个额外的奇偶校验位。此外,CRC计算方法也发生了变化。这些改进使最新的CAN FD协议与博世(BOSCH)开发的原始CAN FD协议不兼容。负责ISO的工作组已完成其文件,并已将其提交给DIS(国际标准草案)在进行投票程序。
  • 为了避免误解,CiA建议使用术语“ISO CAN FD”和“non-ISO CAN FD”。所有符合ISO 11898-2:2015的产品都应称为“ISO CAN FD”。执行博世(BOSCH)原始CAN FD协议的产品应命名为“non-ISO CAN FD”,在这个过度阶段的产品主要目的是用于前期评估和开发,将来所有产品都将符合ISO标准。
  • 请注意,早前一些供应商提供的组件或者工具是针对non-ISO CAN FD协议的,包括目前在售的部分CAN FD产品,CiA建议仅使用ISO CAN FD产品进行设计和开发,不过你可继续使用non-ISO CAN FD做评估和前期开发,因为协议的改变对于用户界面是不可见,但注意的是不能同一个网络混用non-ISO CAN FD和ISO CAN FD接口设备,这样会造成CAN总线错误无法完成发送和接收,如果仅仅是发送或接收传统的CAN帧将不会受到任何影响,幸运的是部分设备供应商提供的组件或者工具允许用户选择支持ISO或者non-ISO模式,这样能很好地在过渡时期帮助你完成工作。

3.13 波形实例

  • 本实例使用 Kingst LA5016 usb 逻辑分析仪检测CAN FD数据通讯。LA5016的CAN FD解析模块,不仅可以解析CAN FD协议,同时也兼容CAN协议解析,以下几图是一个完整的数据包分析截图。从图中可以看到,CAN FD协议可以区分CAN FD及CAN协议,CAN FD协议将协议数据分析为 ID(协议id号), ExternId(扩展id), DLC(数据长度),Data(传输数据), StuffCount,CRC, ACK/NAK 。

协议解析参数设置:

数据包的ID号为0x010, RTR:false(数据帧), DLC:0x8(8个数据),Data:0x00~0x07,CRC为0x0C5E7(17位), ACK:应答。
圆形白点:逻辑数据。
方形白点:填充位。

3.X 参考文献

X 参考文献

"现在最新的已经是CAN-FD协议了,数据域直接扩展到64字节,也就是理论最高位速率直接从1M提升到了8M"

posted @ 2024-04-05 14:09  千千寰宇  阅读(2993)  评论(0编辑  收藏  举报