CAN通信协议 - ISO 11898
CAN基本信息
CAN控制器根据两根通信线(CAN_H、CAN_L)上的电位差来判断总线电平(差分信号)。总线电平分为显性电平(逻辑0)和隐性电平(逻辑1),二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。
CAN总线是:异步,半双工。其无需时钟线,通信速率由设备各自约定,并且由于其半双工通信可挂载多设备,多设备同时发送数据时通过仲裁判断先后顺序。
其中对于同步和异步的区别:
同步时钟:指的是在执行操作时,各个参与者(如线程、设备或系统)在同一时刻进行协调。所有的操作都需要在一个共同的时序框架下进行。
异步时钟:步指的是操作之间没有强制的时间协调,各个参与者可以独立地进行操作,不必等待其他操作完成。
对于单工,半双工,全双工的区别:
单工:数据传输仅能沿一个方向,不能实现反向传输,只有一条通信路线;
半双工:数据传输可以沿两个方向,但需要分时进行,也只有一条通信线路;
全双工:数据可以同时进行双向传输,具有两条通信线路。
其中高速CAN使用闭环网络,两端分别有一个终端电阻,两个120Ω终端电阻的作用:
①防止回波反射,使波形更平稳;
②在没有设备操作时,使电压“收紧”,使其电压一致。CAN总线是差分信号,所以终端电阻可以在没有设备操作时将两根线“收紧”至电压一致状态,代表就是默认的逻辑电平“1”
低速CAN使用开环网络,CAN_H和CAN_L其中一端添加2.2kΩ的终端电阻
对于高速CAN:
(显性电平和隐性电平的0和1定义有点反逻辑,有个简单的记法:显灵显灵→显0,反正我是这样记得,还是很有效)
压差为0V时表示逻辑1(隐形电平)
压差为2V时表示逻辑0(显性电平)
对于低速CAN:
电压差为-1.5V时表示逻辑1(隐性电平)
电压差为3V时表示逻辑0(显性电平)
CAN总线发送总流程
CAN总线数据帧格式
数据帧
数据帧由 7 个不同的位场组成:帧起始、仲裁场/段、控制场/段、数据场/段、CRC 场/段、应答场/段、帧结尾。数据场的长度可以为 0。
帧起始:标志着数据帧和远程帧的其实,由一个单独的显性位组成,且起始帧必为显性电平(逻辑0)
仲裁段:包括报文标识符和RTR位;仲裁位主要是用来判断发送单元的优先顺序(连续输出显性电平最多的单元可继续发送,这也就是为什么最小的优先级最高的原因)
识别符的长度为 11 位。这些位的发送顺序是从 ID-10 到 ID-0。最低位是 ID-0。最高的 7 位(ID-10 到 ID-4)必须不能全是“隐性”。
RTR 位:该位在数据帧里必须为“显性”,而在远程帧(遥控帧)里必须为“隐性”。主要是为了区分数据帧和遥控帧。
控制段:包括IDE,r0保留位和DLC数据长度
- IDE表示拓展标志位,用于区分拓展格式还是标准格式 ,其中标准格式为显性(0),拓展格式为隐性(1)
- DLC表示后面的数据有几个字节
数据段:需要传输的数据内容,传统CAN(Classic CAN)报文中,数据段(Data Field)的长度确实只有0到8个字节,这也就是常说的CAN只支持传输最长8个字节的数据(CAN FD支持最长64个字节)。这是CAN协议“短帧”设计的核心特点,也是它能够提供高实时性和高可靠性的原因之一。
ps:数据帧又分为标准格式(上述)和拓展格式,且标准格式的发送优先级优于拓展格式。
CRC段:CRC 段是检查帧传输错误的帧。由 15 个位的 CRC 顺序和 1 个位的 CRC 界定符(用于分隔的位,为隐性位)构成。
ACK段:
主要分为ACK slot和ACK界定符;
发送单元的ACK段:发送单元在 ACK 段发送 2 个位的隐性位。
接收单元的ACK段:接收到正确消息的单元在 ACK 槽(ACK Slot)发送显性位,通知发送单元正常接收结束。这称作“发送 ACK”或者“返回 ACK”。
帧结束:由7个隐形位构成,代表该帧的结束
拓展:CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
遥控/远程帧
接收单元向发送单元请求发送数据所用的帧。遥控帧由6个段组成,遥控帧没有数据帧的数据段,RTR为隐性电平1,其他部分与数据帧相同。
ps:遥控帧相较于数据帧,数据帧是发送方,主动连续有间隔地向外广播数据;而遥控帧则是接收方主动请求发送方发送广播数据,接收方进行接收
错误帧
用于在接收和发送消息时检测出错误通知错误的帧。一旦发现“位错误”或“填充错误”或“CRC错误”或“格式错误”或“应答错误” ,这些设备便会发出错误帧来破坏数据,同时终止当前的发送设备。错误帧由错误标志和错误界定符构成:
错误标志:包括主动错误标志和被动错误标志两种。
- 主动错误标志: 处于主动错误状态的单元检测出错误时输出的错误标志。
设备默认处于出于主动错误状态。当设备检测到发生错误,会连续发送6个显性位“0”,显性是拉开总线,总选又一个被拉开,就必然处于显性状态(“线与”特性,“0”和“1”相遇时,肯定显示“0”),这样就会破坏掉总线数据,其他设备检测到数据错误就会抛弃当前数据(所有数据全抛弃),若是主动错误产生太过频繁,说明这个设备不太可靠,设备就会进入被动错误状态。 - 被动错误标志:处于被动错误状态的单元检测出错误时输出的错误标志。
当设备检测到发生错误,会连续发送6个隐性位。隐性就是不去碰总线,那么总线状态就不会发生变化,就不会总线上别人发的数据,只会破坏自己发的数据(仅抛弃自己的数据)
错误界定符:由8个隐性位构成
过载帧
过载帧是用于接收单元通知其尚未完成接收准备的帧。当接收方收到大量数据而无法处理时,其可以发出过载帧,延缓发送方的数据发送,以平衡总线负载,避免数据丢失。过载帧由过载标志和过载界定符构成:
过载标志:6 个位的显性位。过载标志的构成与主动错误标志的构成相同。过载界定符:8 个位的隐性位。过载界定符的构成与错误界定符的构成相同。
帧间隔
帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开。过载帧和错误帧前不能插入帧间隔。
间隔:3 个位的隐性位。总线空闲:隐性电平,无长度限制(0 亦可)。本状态下,可视为总线空闲,要发送的单元可开始访问总线。延迟传送(发送暂时停止):8 个位的隐性位。只在处于被动错误状态的单元刚发送一个消息后的帧间隔中包含的段。
位填充
位填充是为防止突发错误而设定的功能。发送方每发送5个相同电平后,自动追加一个相反电平的填充位,接收方检测到填充位时,会自动移除填充位,恢复原始数据。
参考文章: 八万字解析CAN总线协议·从入门到实战保姆级教学(源码可直接移植使用)_can总线协议详解-CSDN博客
CAN总线通信详解 (超详细配34张高清图)_can通讯-CSDN博客
CRC循环冗余校验码
模 2 除法
模 2 除法与算术除法类似,但每一位除的结果不影响其它位,即不向上一位借位,所以实际上就是异或。
例如被除数 100101(2) 对除数 1110(2) 采用模 2 除法后,商为 11(2),余数为 1。(只要往后借一位,位数与除数一致,商就为1,否则为0,需要继续往后借)
由以上分析可知,既然除数是随机的,或者按标准选定,所以 CRC 校验的关键是如何求出余数,也就是 CRC 校验码。
下面以一个例子来具体说明整个过程。现假设选择的 CRC 生成多项式为 P(X) = X4 + X3 + 1,要求出二进制序列 10110011 的 CRC 校验码。下面是具体的计算过程:
(1)首先把生成多项式转换成二进制数,由P(X) = X4 + X3 + 1可以知道,它一共是 5 位(总位数等于最高位的幂次加1,即 4+1=5),然后根据多项式各项的含义(多项式只列出二进制值为 1 的位,也就是这个二进制的第 4 位、第 3 位、第 0 位的二进制均为 1,其它位均为 0)很快就可得到它的二进制比特串为 11001。
(2)因为生成多项式的位数为 5,根据前面的介绍,得知 CRC 校验码的位数为 4(校验码的位数比生成多项式的位数少 1)。因为原数据帧 10110011,在它后面再加 4 个 0,得到 101100110000,然后把这个数以“模2除法”方式除以生成多项式,得到的余数,即 CRC 校验码为 0100。
CRC算法
发送方和接收方在通信前,约定好一个预设整数作为除数。
发送方在发送前根据原始数据和约定好的除数进行模二除法运算生成余数(即CRC码),然后将其附加到原始数据后面一起发送给接收方。
接收方收到后将其模二除以约定好的除数,当且仅当余数为0时接收方认为没有差错。
常用CRC版本
表示法中的最高位必须为1,故实际看1后面的几位16进制
CAN数据链路层中的CRC Field
该CRC字段长度为15比特;
• 该CRC生成多项式为:P(x)=x15+x14+x10+x8+x7+x4+x3+1
• 该CRC校验数据的范围是SOF(Start of Frame,帧起始)字段至Data Field(数据域)结束;
• 若某接收节点计算的CRC字段与其接收到的CRC字段数值不一致,则会在ACK-DEL(ACK字段界定符)之后发出错误帧。
Checksum和Rolling Counter
Checksum确保CAN报文数据内容未被破坏,而Rolling Counter则确保数据帧的连续性和有序性,两者相辅相成,这样既保证了数据的正确性,也检测了数据的完整性与顺序性,这对于汽车这样对通讯网络实时性和安全性要求极高的系统至关重要。
常见的Rolling Counter和Checksum的在一帧CAN报文中的布局(数据帧的最后俩字节)
checksum
Checksum即校验和,Checksum是一种CAN报文的数据校验码,用于检查通信数据的完整性;
Checksum是一种高效的错误检测机制,其原理是:发送端先通过规定的计算方法得到一个Checksum值,再作为一个信号添加到CAN报文的数据段,发送出去;接收端接收到该报文后,先使用相同的计算方法重新计算出一个Checksum值,然后与接收到的Checksum值进行比较。如果结果一致就说明接收数据正确,否则就认为数据有错误。
发送方:
先初始化Checksum值为 0,并将所有数据项相加,结果为36;
再通过一套特定的算法计算得到最终Checksum值为 9;
最后发送方将数据和Checksum值一起打包发送给接收方。
接收方:
先解包所接收的数据,再采用与发送方相同的方法相加所有数据;
然后通过一套规定的算法计算得到最终Checksum值,最终接收方计算出的Checksum值为 0,这意味着数据未损坏。
比对Checksum值进行判断,一般规定连续三帧以上信号的Checksum不对,则认为该报文数据有问题,并丢弃该报文数据,以此防止发送的报文出错。
checksum和CRC的区别
两者的位置。Checksum在CAN报文的数据段,8Bit,一般在数据场的第一个字节或者最后一个字节,而CRC在CAN报文的CRC段,15Bit;
两者的计算对象。Checksum是针对CAN报文数据段的信号采用相应的CRC校验算法(常使用CRC8, 16, 32)计算出Checksum值,而CRC是针对CAN报文的帧起始、仲裁段、控制段和数据段采用相应的CRC校验算法(常使用CRC1, 15, 17和21)计算出CRC值;
两者的作用。Checksum是用来校验数据被正确的打包和解包、确保数据的加密和数据的可信度,而CRC用来保证数据传输的正确性和完整性。
Rolling Counter
Rolling counter即滚动计数器,也叫Alive counter。它用于跟踪报文的序列,确保报文按预期顺序接收。它是一个简单的递增计数器,位于CAN报文的数据段,占用4bit长度,因此Rolling counter的数值范围为0~15。每发送一帧报文Rolling counter就加1,到15就循环回到初始值,即在0~15之间循环增加,如下所示:
参考文章:一文详解Checksum和Rolling Counter校验 - 极术社区 - 连接开发者与智能计算生态
DBC文件的解读
DBC文件的依据主要是OEM厂商制作的CAN matrix,CAN matrix里面定义了每个报文的ID,字节长度,每个字节每个位代表什么含义,根据这些内容使用CANoe制作对应的DBC文件,并使用dbc文件读取软件(如ZLG),就可以加载所有的报文信息
CAN报文类型
CAN报文主要有四个类型:应用报文、诊断报文、网管报文、标定报文
应用报文:各ECU之间传输的报文
诊断报文:由诊断仪和ECU之前传输的报文
网管报文:用于网络管理的报文
标定报文:校准调整参数系数
