前言
随着工业革命的进步,汽车的发展迅猛,随着汽车各种需求的提升,从机械化到电气化,ECU节点不断涌现,总线也五花八门,慢慢的汽车的系统的设计开始不堪重负,可以理解为一个总线的屎山开始堆积。
屎山总有屎崩的一天,坑总会有填的时候。于是为了适应“通过多个LAN,进行大量数据的高速通信”、“减少车载总线线束”的需求。1986年,CAN总线在博世公司诞生了,通过ISO11898以及ISO11519协议标准化CAN,从此CAN总线正式登上舞台。。。
车载网络构想
在了解CAN之前我们看下一个经典的车载网络的构想。CAN 等通信协议的开发,使多种LAN 通过网关进行数据交换得以实现。所以,可以看出我们在抓取实车报文的时候要注意我们需要抓取的是哪一路网络,然后接到正确的网络上。
车载网络的设想图
车载网络接线实物图
CAN总线简单的介绍
CAN网络全称Controller Area Network(局域控制器网络),首先记住它的特点,串行异步通信,电平信号是差分信号,通信速率125kbps~500kbps。这将会为后面为了收发器电路的设计、保证信号一致性引发的位同步的措施,埋下了伏笔。
CAN总线拓扑
CAN硬件的组成一般由控制器+收发器组成,电平为显性和隐性两种,目前普通的CAN网络分为500kbps和125kbps,两者的ECU通过网关CCU实现数据的交换,但是各个ECU看到的只是网关CCU发出来的报文。
CAN总线的特点
多主控制:优先级仲裁,ID越低优先级越高,但是不能都是0,这是给错误检测机制用的
消息发送:一个通信网络的基础工作
系统柔性好:节点的增删不会对网络的性能造成影响
通信速度:相同的网络的速率都是一样的,不同的网络速率才可以不同
远程数据请求:可通过远程帧(遥控帧)其他节点请求数据
错误检测、通知、恢复:
错误检测--所有单元都能检测总线的错误(发送&接收)
错误通知--检测出错误的单元会通知其他单元
错误恢复--正在发送的单元如果检测出错误,会强制结束此次发送,并通过强制发送此消息尝试恢复,此阶段有快周期发送和慢周期发送
故障隔离:CAN总线能判断出错误的类型是暂时的故障还是持续的故障。当总线发生持续错误时,可将引起持续错误的单元从总线上隔离出去。
连接:CAN总线理论上可以连接无限单元,但是连接的数量却受总线的时间延迟、电气负载和CAN收发器的驱动能力限制,提高总线速度,单元就得减少,线束也会拉短。降低总线速度,单元可以增加,线束也可以拉长。
CAN总线发送/接收流程与总线状态转换
继续上经典图,CAN总线的技术比较成熟留下了很多经典~,
下图是总线发送/接收的流程图,这部分在数据链路层实现。
然后是节点通信的三种状态,这个状态机的切换也在链路层实现
ECU总是处于三种状态之一,说明下这三种状态下的收发情况
主动错误:
正常通信,当检测到发送或者接收错误时,输出主动错误标志,也就是主动错误帧6个显示性。这里可以留一个疑问,为啥是6个?
被动错误:
当接收错误或者发送错误持续累积超过127次后,ECU要进入被动错误状态,为了不妨碍其他单元的通信,在接收过程中不能发送错误标志。
处于被动错误状态的节点即使检测出了错误,而其他处于所以即使是发现错误的节点检测处错误,只要总线上其他处于主动错误的节点没检测出错误,总线就是没有错误的。
处于被动错误的节点检测出错误后,会发送错误标志,为6个隐性位。节点发送完后,下一次发前,需要在间隔帧期间内插入“延迟传输”也就是8个隐性位(当检测到至少连续5个隐形位总线认为是空闲)。
总线关闭:
当错误计数器累计达到256后,BUS OFF状态,总线关闭状态,接收和发送均被禁止。
CAN单元的各个状态的转化过程,由错误计数器作触发,由控制器自主实现并提供状态接口给外部其他组件调用。
举个例子,瑞萨的RH850的CAN控制器中有下面的标志位做判断,对应用来说,只需要实现对CAN控制器各寄存器的控制接口并根据企标进行设置(如硬件初始化、开启、关闭)、实现对CAN控制器请求的服务响应接口(如中断响应)、实现给应用层提供读取相应寄存器的状态数据接口,应用层面依据状态做相关逻辑的函数,以此组成协议栈中物理层和数据链路层的相关组件。
CAN协议的ISO/OSI模型
CAN协议也是符合ISO/OSI模型,如CAN数据链路层(LLC\MAC)和物理层所对应ISO11898、ISO11519、应用层所对应的ISO14229,传输层所对应的ISO15765等,这些协议共同组成了CAN总线的各种功能(如UDS诊断、网络管理等)。
举个例子,ISO 15765-2定义了应用层、传输层、数据链路层之间的编程接口,ISO 14229-1生成诊断服务,ISO 15765-2对诊断服务进行分包并把分包后的数据交给ISO 11898,ISO 11898给收到的数据加上CAN总线特有的包头和包尾,然后通过双绞线以电压差的形式发送出去。
对于物理层和数据链路层,这两层的实现大部分工作都由控制器本身去实现,上面提到实现CAN软件组件其实只是在软件层面对控制器的设置和请求的处理,协议栈也是以此构建了相关的驱动组件,换言之,也就是CAN规范只是定义了最低下的两层,这两层由硬件实现,不需要软件开发者写软件和固件,实际应用中只需要知道调用寄存器和接口即可实现对控制器的控制,下图实现了上述例子的过程。
ISO11898、ISO11519
CAN数据链路层的实现都是由硬件控制器实现,博世的CAN规格书中并未定义驱动器和总线电气特性,ISO11898和ISO11519就是CAN规格上的定义的一个标准,两者都对此做了定义,同时其区别也在物理层,数据链路层是一样的。
ISO11898主要应用于125K~1M的通信领域,ISO11519一般用于125K以下的场景。
在物理层下,PMA层和MDI层的区别定义有下表的不同点,特备注意画红框的地方哦~,这两个区别直接体现在波形上。
ISO11898 示波器实测波形
随着通信速度的提高,双绞线的线束的长度会逐步递减。
常见的收发器驱动IC解决方案,其实还有很多,如TJA1051,TJA1043,TJA1145等,主要看该收发器驱动IC支持的协议。
CAN的其他标准
不仅仅是ISO,很多其他的机构和企业像SAE等,基于CAN协议规范也制定了很多应用于各种场景下的协议,在实际应用中,这些协议甚至有可能是互相套用去实现具体的解决方案。
CAN的帧类型
CAN协议有五种帧类型:数据帧、遥控帧(远程帧)、间隔帧、过载帧、错误帧。
·数据的帧化以及发送逻辑均由CAN控制器硬件实现,对于应用,我们只需要在具体的寄存器存入需要外发的配置数据即可,但我们还是要了解一下,感兴趣的可以用逻辑分析仪抓取CAN_TX和CAN_RX引脚查看。
数据帧和遥控帧这些带ID号,就存在标准帧格式和扩展帧格式两种。标准帧格式为11个位的ID号,扩展帧格式为29个位的ID号。
CAN帧解析
数据帧
数据帧的格式如下:
数据帧的标准帧和扩展帧格式,不同点在仲裁段和控制段,上面的各个标号的解释如下。
SOF: 起始位,1位隐形位
ID: 11位ID号,数字越小优先级越高,如0x200优先级大于0x202,注意不能用连续7个隐形位的ID,如0x1111111xxxx
RTR: 远程帧标志位,RTR=1,表示此位为远程帧,RTR=0,表示此帧为数据帧,可以看出,同ID的情况下,数据帧的优先级高于远程帧
IDE: 扩展帧标志位,IDE=1,表示扩展帧,IDE=0,表示标准帧,且有个特点,IDE是位于11位ID号之后的,如果是扩展帧,后面就会跟着18bit的扩展帧ID
r0/r1: 预留位
DLC: 数据长度,无论是CAN还是之后的CAN FD,都是4位,具体定义如下,总之到了DLC=9后的对应关系没有啥技巧,纯映射。。。
DATA: 具体有效数据
CRC: CRC校验位,15bits
ACK段: ACK槽,发送端发送完毕后该位为隐性,接收端接收后,回复显性
EOF: 结束标志位,7位显性位
SRR: 扩展帧和标准帧标识位,SRR的隐形,标准帧的优先级大于扩展帧
遥控帧
可以看出遥控帧比数据帧没有DATA,遥控帧的DLC是所请求得数据帧的数据长度。
错误帧
错误帧由错误标志和错误界定符构成。
发送单元发送完错误帧后,将再次发送数据帧或遥控帧。
错误帧的构成:
主动错误标志:6 个位的显性位。
被动错误标志:6 个位的隐性位。
错误界定符:错误界定符由 8 个位的隐性位构成。
错误帧的输出
错误帧有5种输出方式,对应5种错误场景,我们在平时分析错误帧时,可用示波器、逻辑分析仪,通过抓取错误帧开始发送的位置,确认是什么错误。如果有CANoe可以更方便的知道发送错误的帧ID等信息,方便对总线的调试。
位错误--时序同步问题造成,需要调整对应的波特率寄存器等
填充错误--填充位错误
ACK错误--ACK未回应,接收单元没有拉低ACK槽
格式错误--数据格式错误
以上4种错误在帧发送过程中检测到,则下一位开始输出错误帧,注意没有间隔帧。。。
CRC错误--CRC校验错误,这个在接收单元接收检验后,如果是CRC出错,则在ACK界定符后面开始输出错误帧。
过载帧
格式和主动错误的错误帧相同,用于接收单元通知接收准备未完成
间隔帧
3个隐性位,用于除了错误帧和过载帧以外,多帧发送中间间隔插入。
CAN FD帧与CAN2.0的对比
上面分析了CAN2.0的帧内容,随着技术的发展,传统的CAN数据帧格式已经无法满足日常需要,于是出现了更快的CAN FD,讲CAN FD的文章很多,其实和CAN对比后,我们平时需要明白的也就几个点。。。,先上图
1)CAN的波特率最高是1M,而CAN FD可以到5M。一般CAN设置500K,125K,CAN FD设置2M。
2) CAN的数据长度是8byte,而CAN FD可以到64byte。
3)CAN FD的标准帧ID可用到12bits
4)CAN FD 新增了FDF、BRS、ESI
FDF:表示 CAN 报文还是 CAN FD 报文;隐性位为CAN FD。
BRS:表示位速率转换,该位隐性时,速率可变(即 BSR 到 CRC 使用转换速率传输),该位为显性时,以正常的 CAN-FD 总线速率传输(恒定速率)。比方说,仲裁域是500K,那之后就可能会到2M。
ESI:表示发送节点状态,显性为主动错误,隐性为被动错误。
5)CAN FD对CRC算法进行了改进,CRC对填充位也加入了计算。在校验和部分为避免有连续位超过6个,就确定在第一位以及以后每4位添加一个填充位加以分割,这个填充位的值是上一位的反码,作为格式检查,如果填充位不是上一位的反码,就作出错处理。CAN FD的CRC场扩展到了21位。
6)CAN FD支持2bits的ACK的识别。
位填充
为防止突发错误,在SOF~CRC之间的数据位,每发送连续相同的5位,就要插入一位反相位。对接收单元,当连续接收到5位相同的电平,则会剔除第6位的,但是如果接收到6位电平没有反相,则触发一次接收错误,REC+1,发送错误帧。
位时序
CAN数据的每一位的时间是Tq的倍数,一个位由四个段组成,每个段由若干个Tq组成,这被称为位时序。
同步段--SS。
传播时间段--PTS。
相位缓冲段1--PBS1。
相位缓冲位--PBS2。
重同步补偿宽度--SJW。
位同步
有硬同步和重同步。三张图就可以解释它们的关系。
先看下每个位的组成图,
然后看下在总线从空闲到有数据发现处,接收端的硬同步图,
接收单元在总线空闲状态检测出帧起始时进行的同步调整。 在检测出边沿的地方不考虑 SJW 的值而认为是 SS 段。


对于CAN同步机制的处理,对于MCU的应用来说,主要是配置相关寄存器。比方说,对瑞萨D1M1系列的MCU,有如下描述,其实就是通过设置SEG1、SEG2、BRP的配置实现,对应的测试环境,也是这几个参数。
CANoe有针对性的采集DEMO,在下载完CANOE后,在该路径下找到,配合V5640等合适的CAN CASE便可,做采样点测试。
结语
至此,以上是CAN最最基础的内容,也许这些内容是很多人看了无数次。但不积硅步,何以成千里,作为记录自己学习成长的笔记,对于自己来说写这些基础文也是一种总结。
一开始本想把所学到的内容揉在一篇万字长文,后面发现迟迟无法写完,内容实在太多太多。于是决定做切割,分成几个模块一步步叙述这个故事。。。后面再写写不定时更新遇到过的坑,SAE J1939的内容以及目前接触到具体的CAN方案落地,网络管理,车载诊断,OBD,Bootloader的内容,最后实现一个开源的车载CAN协议栈,共勉吧。。。