-
-
[原创]CAN协议分析
-
发表于: 2024-9-13 01:48 7559
-
文章引自https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252
进行补充完善
CAN 协议即控制器局域网络 (Controller Area Network)简称,由研发和生产汽车电子产品著称的德国 BOSCH 公司开发,成为国际标准ISO11519以及ISO11898
==ISO11519和ISO1189==
CAN 总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线
can协议分为物理层和协议层
CAN使用异步通信,利用CAN_High和CAN_Low两条信号线组成的差分信号线进行通讯(和传统的时钟通信不同)
500kbps和125kbps的总线分别针对不同类型的ECU
差分信号通信是一种通过两条导线(或信号线)传输数据的方式,主要用于提高抗干扰能力和信号完整性
在差分信号通信中,同一信号的两个版本会同时在两条导线上传输:
例如:
如果正信号是高电平(+5V),负信号就是低电平(0V)
如果正信号是低电平(0V),负信号就是高电平(+5V)
发送端通过一个差分驱动器(或发送器)生成差分信号:
例如:
当发送逻辑“1”时,D+线上为高电平,D-线上为低电平
当发送逻辑“0”时,D+线上为低电平,D-线上为高电平
差分信号通过两条导线同时传输,导线之间的电压差(即差分电压)决定了信号的逻辑状态:
==差分电压 = D+ 电压 - D- 电压==
接收端使用差分接收器来解读信号
差分接收器不直接读取D+或D-的电压值,而是读取它们之间的电压差
:
当外部噪声(如电磁干扰)影响到传输线时,通常会同时影响到D+和D-两条线,使它们的电压同时上升或下降
但由于接收器只关注两条线之间的电压差,这种共模噪声不会改变信号的逻辑状态,因此可以被有效抑制
CAN 总线协议的物理层==只有 1 对差分线==,在==一个时刻只能表示一个信号==,所以对通讯节点来说,CAN 通讯是==半双工==的,==收发数据需要分时进行==
CAN 的通讯网络中,因为==共用总线==,在整个网络中同一时刻==只能有一个通讯节点发送信号==,==其余的节点在该时刻都只能接收==
can的物理层的形式有两种
总线最大长度为 1km
最高通讯速率为 125kbps
每根总线串联一个2.2kΩ的电阻
一个总线可以挂载多个节点
CAN 通讯协议不对节点进行地址编码,对数据内容进行编码的
节点个数理论上不受限制(总线的负载足够即可,通过中继器增强负载)
==接收和发送流程相反==
CAN 总线网络将数据通过差分线CAN_High 和 CAN_Low 发送
收发器把总线上收到的 CAN_High 及 CAN_Low 信号转化成普通的逻辑电平信号
最后通过 CAN_Rx 线输出到控制器中
==总线上的各个通讯节点只要约定好 1 个 Tq 的时间长度以及每一个数据位占据多少个 Tq,就可以确定 CAN 通讯的波特率==
详细计算方式参考:CAN总线波特率的设定——以STM32F103为例 - 知乎 (zhihu.com)
示例:
假设1Tq=1us,而每个数据位由 19 个 Tq 组成,则传输一位数据需要时间 T1bit=19us,从而每秒可以传输的数据位个数为:1x10次方/19 = 52631.6 (bps)
==每秒可传输的数据位的个数即为通讯中的波特率==
CAN 属于异步通讯,没有时钟信号线
==连接在同一个总线网络中的各个节点会像串口异步通讯那样,节点间使用好的波特率进行通讯==
(同时使用“位同步”的方式来抗干扰、吸收误差,实现对总线电平信号进行正确的采样,确保通讯正常)
CAN 协议把每一个数据位的时序分解成SS 段,PTS 段,PBS1 段,PBS2 段
==四段的长度加起来即为一个 CAN 数据位的长度==
分解后的最小时间单元为Tq(一个完整的位由 8~25 个 Tq组成)
(此处高低电平直接代表信号逻辑 0 或逻辑 1)
示例的的数据:位长度为19Tq
同步段(大小固定为 1Tq)
==检测到总线上信号的跳变沿被包含在 SS 段的范围之内,则表示节点与总线的时序是同步的==
传播时间段(大小为 1~8Tq)
==补偿网络的物理延时时间==,总线上输入比较器延时和输出驱动器延时总和的两倍
相位缓冲段(大小为 1~8Tq)
==补偿边沿阶段的误差==,它的时间长度在重新同步的时候可以加长
另一个相位缓冲段(大小为 2~8Tq)
==也是用来补偿边沿阶段误差的==,时间长度在重新同步时可以缩短
简述同步:使数据接收方能够正确地解释和处理从发送方接收到的数据,确保接收方能够准确地识别出每个数据位的开始和结束
==CAN的同步分为两种:硬同步和软同步==
硬同步是当CAN节点在总线上检测到一个显性边沿(即从隐性位跳变到显性位)时进行的同步操作
帧起始位(SOF):
每一个数据帧都由一个显性位标识(从隐性状态转换而来的)开始,从而让节点识别到开始接受一个新的数据
触发硬同步:
在显性边沿被检测时触发,节点的位时钟会立即被重置,开始新的计时周期(确保了节点能够准确地与总线上的其他节点同步,从而正确解码数据)
假设有两个CAN节点,节点A(发送方)和节点B(接收方)(同一个CAN总线上通信)
节点A准备发送一帧数据,节点B则负责接收该帧数据
在开始通信之前,CAN总线处于空闲状态,此时总线的电压处于隐性位(逻辑1),节点A和节点B都在等待总线的变化。
节点A开始发送一个数据帧。CAN通信的规则规定,帧的开始由一个显性位表示,称为帧起始位(SOF)。因此,节点A从隐性位(逻辑1)切换到显性位(逻辑0),即电压变化使CAN H和CAN L线之间的差异增加。
当节点B在总线上检测到这一从隐性位跳变到显性位的电压变化(显性边沿)时,它会执行“硬同步”操作:
在长帧传输时,(时钟漂移导致节点的时钟和总线的时钟出现偏差)确保节点的时钟与总线保持同步
CAN节点的内部时钟(位时钟)与总线上的信号发生了偏移,
重新同步通过检测==普通数据位的跳变沿(从高电平到低电平,或从低电平到高电平)==来对齐时钟
节点的时钟比总线时钟快,这意味着节点会比总线更早检测到数据位的跳变沿
==通过延长相位缓冲段1(PBS1)的时间来使节点的时钟与总线对齐==
节点的时钟比总线时钟慢,节点在总线跳变沿之后才检测到信号
==通过减少相位缓冲段1(PBS1)的时间来赶上总线时钟==
调整时钟的一种机制,用来修正节点时钟与总线信号之间的偏差
CAN控制器通常会为SJW设置一个最大值(单次同步操作中,时钟的调整范围不能超过设置的最大值)
偏差超过最大值(不能再一次完成),只能通过多次小幅度的调整完成
PBS1(相位缓冲段1):
通常是增加时间的段,如果时钟偏快,会延长PBS1以减慢时钟
PBS2(相位缓冲段2):
通常是减少时间的段,如果时钟偏慢,会缩短PBS2以加快时钟
SPI 通讯,片选、时钟信号、数据输入及数据输出这 4 个信号均有单独的信号线
I2C 协议,包含有时钟信号及数据信号 2 条信号线,异步串口包含接收与发送 2 条信号线
但是CAN只有两条差分信号线(只能表达一个信号),所以CAN协议==对数据、操作命令 (如读/写) 以及同步信号进行打包,打包后的这些内容称为报文==
把上述的内容按照特定格式打包,可以用一个通道表达各种信号,对应设备按照格式去解读就能还原数据——CAN的数据帧
==开始:==(帧起始)
一个显性位 (逻辑 0)
==中间:==
仲裁段,控制段,数据段,CRC 段,ACK 段
==最后:==(帧结束)
7 个连续的隐性位 (逻辑 1)
==多个报文发送时,根据仲裁段决定具体的传输报文==
物理协议基础:总线上同时出现显性电平和隐性电平,总线的状态会被置为显性电平
==若两个节点同时竞争 CAN 总线的占有权,当它们发送报文时,若首先出现隐性电平,则会失去对总线的占有权,进入接收状态==
示例:
开始阶段,两个设备发送的电平一样,所以它们一直继续发送数据
箭头时序处,节点单元 1 发送的为隐性电平,节点单元 2 发送的为显性电平,==总线的物理协议基础使它表达出显示电平单元 2 竞争总线成功,该报文得以被继续发送出去==
IDE 位
(标识符扩展位):区分标准格式与扩展格式,==显性电平时表示标准格式,隐性电平时表示扩展格式==
RTR 位
(标准格式下的远程传输请求位):区分数据帧和遥控帧的,==显性电平时表示数据帧,隐性电平时表示遥控帧==
SRR 位
(扩展格式下的远程传输请求位):扩展帧中的 SRR 位在数据帧为隐性位,RTR 在数据帧为显性位,所以在两个 ID 相同的标准格式报文与扩展格式报文中,标准格式的优先级较高
==指定报文的长度和扩展标识符的使用情况==
IDE
位(标识符扩展位):区分标准帧和扩展帧,==显性电平时表示标准格式,隐性电平时表示扩展格式==
RTR
位(远程请求位):区分数据帧和远程帧,==显性电平时,表示发送的数据帧,隐形电平时表示发送的远程帧==(不包含数据,通常用于请求其他节点发送数据)
保留位
(r0,r1):用于==协议的扩展==,一般被设置为显性电平
DLC 位
(数据代码长度):表示报文中实际传输的数据字节数(4位的字段),范围是0-8,对应数据的字节大小(预留4位的空间是为了保证协议的拓展性)
确保数据完整性,包含CRC序列和CRC界定符
长度固定位1位的隐性位,用来将CRC序列与后续的ACK段
确保数据帧被正确接收,包含ACK槽位和ACK界定符
用于接收节点确认报文是否正确接收,如果正确接收报文且无报错,接收节点通过ACK槽位向发送节点发送确认信号(将隐性位覆盖为显性位)
==工作原理:==
发送节点只负责在ACK槽位发送隐性位(1):
表示它已经完成了数据发送,将该槽位设置为隐性位(1)(等待接受节点确认)
接收节点负责覆盖ACK槽位中的隐性位:
如果接收成功,接收节点会将该位改为显性位(0)(发送确认信号)
长度固定为1位的隐性位,将ACK槽位与结束帧分隔
https://www.ti.com/lit/an/sloa101b/sloa101b.pdf
支持bxCAN控制器(CAN 协议 2.0A 和 2.0B 标准‘最高速率1Mb/s
支持自动地接收和发送 CAN 报文
支持使用标准ID 和扩展 ID 的报文
支持使用软件控制发送报文的优先级
支持记录发送的时间,2 个 3 级深度的接收 FIFO(两个 FIFO 队列,每个队列都可以存储最多 3 个数据项),不支持DMA(直接内存访问,用于高效数据传输的技术,不需要 CPU 的干预)
CAN 控制器1和2
CAN1 是主设备(控制存储访问控制器)
CAN2 无法直接访问存储区域(必须支持CAN1 外设时钟)
包括CAN 控制内核(主要分析主控制寄存器 CAN_MCR,时序寄存器 CAN_BTR)
==主要控制CAN 的工作模式==
用于设置CAN 控制器在进入调试模式时的通信功能,工作状态和禁止收发状态
==设定禁止收发状态后在进入调试状态后将关闭通信功能==(不阻碍FIFI访问,同时可以读取已经接受的消息)
==用于支持预定的时间点发送和接收消息==(需要严格的时间同步和实时性要求的场景下使用
功能实现:==(内部定时器产生计时器)==
==用于处理 CAN 节点由于错误累积过多而进入离线状态的情况==
CAN 节点在离线上检测到发送或接收错误累计超过一定的阈值时,会自动进入Bus-Off(离线)状态,在此状态下,节点将无法接收或发送任何CAN报文
错误监测与离线状态
通过错误计数器监测发送和接收过程中的错误(阈值一般为256,),超过会进入Bus-Off
自动恢复机制:
ABOM功能允许CAN控制器在进入离线状态后,自动恢复为在线状态(无需人工干预)
==节点经过足够长的时间不再出现错误时,ABOM机制会自动复位错误计数器,并重新加入CAN网络,恢复通信==
恢复的条件通常是离线在状态下链路检测到一定的无错误触发信号(11个连续的无错误位)
手动恢复机制
当未启动ABOM功能时,进入离线状态后,需要手动恢复(例如:外部程序发送重置命令,重启CAN 节点)
==在CAN控制器进入低功耗的睡眠模式后,自动侦听睡眠活动,并在有通信时发生自动唤醒设备==
实现功能:
当NART位被设置为0时,CAN 控制器会==在发送失败时自动重传该报文==,直至发送成功状态
当NART位被设置为 1时,自动重传功能被禁用,==无论发送结果如何,每个消息都只会被发送一次==
==用于锁定接收 FIFO==
当FIFO 锁定时,接收到的FIFO溢出时,会直接丢弃下一个报文,将当前的的报文保留在FIFO中
当FIFO没有锁定时,下一个接受的报文会覆盖原报文
==TXFP控制了当CAN发送邮箱中有多个待发送报文时,优先发送哪一条消息==
==配置测试模式、波特率以及各种位内的段参数==
静默和环回模式用于调试和测试CAN通信==(通过CAN_MCR注册中的位30和位31(看上图)进行启动)==
CAN ==可以接收数据,但是不会主动发送数据==,进行干扰(检测到错误,也不会发送错误帧)
主要用于睡眠监听,不影响睡眠上的正常通信
位31
0:正常工作
1:静默模式
CAN ==将自己发送的报文直接传入到自己的寄存器上==,用于自我检测(节点自我检测报文能否正常回传,而不接入CAN 网络)
位30
0:禁止回环模式
1:支持回环模式
如果同时启用静默模式(SILM = 1)和环回模式(LBKM = 1),CAN控制器将进入静默环回模式
CAN控制器==不会与实际行走通信,但可以通过内部自我实现环回实现自动化自收==
(采样点位于BS1 及 BS2 段交界)
SYNC_SEG 段固定长度为 1Tq
BS1,BS2的长度在CAN_BTR中设置(支持在重新同步期间增长或缩短)
BS1段类似CAN 标准协议中PTS段+PBS段
BS2段类似CAN 标准协议中的PBS2 段
配置位时序寄存器 CAN_BTR的TS1[3:0] ,
TS2[2:0],设定 BS1 及 BS2 段的长度
确定每个CAN 数据位的时间:
Fpclk一般为42MHz
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- [原创]CAN协议分析 7560
- [原创]pwn—栈的学习 8665
- [原创]Tenda 路由器栈溢出复现(CVE-2018-18708)详解 3356
- [原创]cython逆向-语言特性分析 8920