RK3588调试CAN驱动记录

背景

汽车芯片公司,IP领导随机分配,主要任务是各种IP的硅前验证,包括uboot命令行和Linux kernel验证。工作两年半没什么外设经验也没做过CAN总线(前两年在一家芯片公司做各种加解密IP的开发),一个人的摸索过程可以说是充满了坎坷,请教过硬件同事,看过硬件原理图,看过databook、datasheet,看过其他前辈的CSDN,前前后后花了两三个多星期。。。
言归正传,我手中的开发板是ITX-3588J,在Linux内核中既有can驱动也有can-fd的驱动,我的任务是先利用can驱动进行数据的收发,进而再详细深入代码,画出从上层APP到底层操作寄存器的硬件行为的整个流程图。。。

拿到任务后决定先去了解一下CAN协议与CAN-FD协议,了解的差不多了,再看CAN驱动代码和CAN-FD驱动代码。

CAN协议

CAN(Controller Area Network,控制器局域网)是一种能有效支持分布式控制和实时控制的串行通讯网络。
(所谓的局域网就是大家常见的将几台电脑同时连接在一个路由器上,那么这几个电脑之间就可以进行通信,这就叫局域网)

在这里插入图片描述
CAN-bus: Controller Area Network-bus,控制器局域网总线技术。
(这里所说的控制器就是汽车电子中的ECU)

在这里插入图片描述

CAN总线系统结构

在这里插入图片描述

微处理器

CAN控制器

CAN收发器

CAN数据总线

120欧的终端电阻

在这里插入图片描述
传输数据的数据线,两根 CAN-high and CAN-low,差分信号(就是利用两根信号线来传输一位数据)。抗干扰能力强,传输距离远。双绞线即使发生信号突变也是CAN_H和CAN_L同时发生突变,但最终差值不变。

CAN总线系统的数据传输

CAN总线节点上的节点发送数据是以报文的形式广播给网络中所有节点。收发器接收到数据就把数据传送给控制器,再由控制器检查判断是不是所需数据。不是则忽略。

  • 网络上任何一个节点在任何时候都可以发送数据
  • 多个节点发送数据,优先级低主动退出发送
  • 短帧结构,每帧数据信息为0~8字节(具体用户定义),对数据编码而不是地址编码
  • CAN每帧都有CRC校验和其他检验措施,严重错误的情况下具有自动关闭输出的功能

CAN控制器

CAN控制器用于将欲收发的消息(报文),转换为符合CAN规范的CAN帧,通过CAN收发器,在CAN-bus上交换信息。

CAN控制器分类
CAN控制器芯片分为两类:

独立的控制器芯片,如SJA1000
CAN控制器集成在微控制器中,如NXP半导体公司的Cortex-M0内核LPC11Cxx系列微控制器、LPC2000系列32位ARM微控制器。

CAN控制器工作原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

接口管理逻辑

接口管理逻辑用于连接外部主控制器,解释来自主控制器的命令,控制CAN控制器寄存器的寻址,并向主控制器提供中断信息和状态信息。

CAN核心模块

收到一个报文时,CAN核心模块根据CAN规范将串行位流转换成用于接收的并行数据,发送一个报文时则相反。

发送缓冲器

发送缓冲器用于存储一个完整的报文,当CAN控制器发送初始化时,接口管理逻辑会使CAN核心模块从发送缓冲器读CAN报文。

验收滤波器

验收滤波器可以根据用户的编程设置,过滤掉无须接收的报文。

接收FIFO

接收FIFO是验收滤波器和主控制器之间的接口,用于存储从CAN 总线上接收的所有报文。

工作模式

CAN控制器可以有两种工作模式(BasicCAN和PeliCAN)。BasicCAN仅支持标准模式,PeliCAN支持CAN2.0B的标准模式和扩展模式。

CAN收发器

CAN收发器是CAN控制器和物理总线之间的接口,将CAN控制器的逻辑电平转换为CAN总线的差分电平,在两条有差分电压的总线电缆上传输数据。

CAN收发器的类型

汽车车载网络CAN收发器也分为独立型与组合型两大类。由于前者应用灵活,可以与多种CAN控制器进行连接使用,故应用最广泛。后者通常与CAN控制器组合在一起,形成一个具有CAN收发功能的CAN控制器组件。

终端电阻

根据电磁场和微波理论,高频电路中负载阻抗需与传输线的特性阻抗一致,否则电信号在线束端遭遇阻抗突变,产生反射现象,造成波形震荡,信号反射造成的信号不完整性,是属于直接将数据反射,不管数据反射到哪里。

在这里插入图片描述

解决:反射都在首端或者末端进行数据传输,因此在首尾加上120欧姆,加在中间不推荐,有可能反射不到。

在这里插入图片描述

CAN总线系统数据格式

CAN通信是通过以下5种类型的帧进行的:

  • 数据帧
  • 遥控帧
  • 错误帧
  • 过载帧
  • 间隔帧

另外,数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有 11 个位的标识符(Identifier: 以下简称 ID), 扩展格式有 29 个位的 ID。

在这里插入图片描述

1 CAN数据帧

结构上由7个段组成,其中根据仲裁段ID码长度的不同,分为标准帧(CAN2.0A)和扩展帧(CAN2.0B)。

在这里插入图片描述

  • 帧起始:表示数据帧开始的段;
  • 仲裁段:表示该帧优先级的段,根据仲裁段ID码长度的不同,分为标准帧(CAN 2.0A)和扩展帧(CAN 2.0B);
  • 控制段:表示数据的字节数及保留位的段;
  • 数据段:数据的内容,可发送0~8个字节的数据;
  • CRC段:检查帧的传输错误的段;
  • ACK段:表示确认正常接收的段;
  • 帧结束:表示数据帧结束的段。

1.1 帧起始和帧结束

帧起始由1个显性位组成。总线空闲时,发送节点发送帧起始,其他接收节点同步于该帧起始位。

在这里插入图片描述

总线上的电平有显性电平和隐性电平两种。

总线上执行逻辑上的线“与”时,显性电平的逻辑值为“0”,隐性电平为“1”。

“显性”具有“优先”的意味,只要有一个单元输出显性电平,总线上即为显性电平。并且,“隐性”具有“包容”的意味,只有所有的单元都输出隐性电平,总线上才为隐性电平。(显性电平比隐性电平更强。)

1.2 仲裁段

仲裁段用于写明需要发送到目的CAN节点的地址、确定发送的帧类型(当前发送的是数据帧还是遥控帧),并确定发送的帧格式是标准帧还是扩展帧。

仲裁段在标准格式帧和扩展格式帧中有所不同。标准格式帧的仲裁段由11位标识符和远程发送请求位RTR组成,扩展格式帧的仲裁场由29位标识符和远程发送请求位RTR组成。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1.2.1 标准数据帧

标准数据帧基于早期的CAN规格(1.0和2.0A版),使用了11位的识别域。

CAN标准帧帧信息是11字节,包括帧描述符和帧数据两部分。如下表所列:

在这里插入图片描述

前3字节为帧描述部分。字节1为帧信息,第7位(FF)表示帧格式,在标准帧中FF=0,第6位(RTR)表示帧的类型,RTR=0表示为数据帧,RTR=1表示为远程帧。DLC表示在数据帧时实际的数据长度。

标准数据帧的 ID 有 11 个位。从 ID10 到 ID0 依次发送。禁止高 7 位都为隐性(禁止设定:ID=1111111XXXX)。

字节2~3为报文识别码,其高11位有效。

字节4~11为数据帧的实际数据,远程帧时无效。

1.2.2 扩展数据帧

CAN扩展帧帧信息是13字节,包括帧描述符和帧数据两部分,如下表所示:

在这里插入图片描述
前5字节为帧描述部分。字节1为帧信息,第7位(FF)表示帧格式,在扩展帧中FF=1,第6位(RTR)表示帧的类型,RTR=0表示为数据帧,RTR=1表示为远程帧。DLC表示在数据帧时实际的数据长度。

扩展格式的 ID 有 29 个位。基本 ID 从 ID28 到 ID18,扩展 ID 由 ID17 到 ID0 表示。基本 ID 和 标准格式的 ID 相同。禁止高 7 位都为隐性(禁止设定:基本 ID=1111111XXXX)。

字节2~5为报文识别码,其高28位有效。

字节6~13为数据帧的实际数据,远程帧时无效。

1.3 控制段

控制段由6个位组成,包括数据长度代码和两个将来作为扩展用的保留位,标准格式和扩展格式的构成有所不同。

数据长度代码指示了数据段中的字节数量。数据长度代码为4个位,在控制段里被发送,数据帧长度允许的字节数为0、1、2、3、4、5、6、7、8,其他数值为非法的。

在这里插入图片描述
留位(r0、r1)必须全部以显性电平发送。但接收方可以接收显性、隐性及其任意组合的电平。

数据长度码(DLC)与数据的字节数的对应关系如下表所示:

在这里插入图片描述
数据的字节数必须为 0~8 字节,但接收方对 DLC = 9~15 的情况并不视为错误。

1.4 数据段

数据段由数据帧中的发送数据组成,它可以为0~8字节,每字节包含了8位,首先发送最高有效位MSB,依次发送至最低有效位LSB。

在这里插入图片描述

1.5 CRC段

CRC段是检查帧传输错误的帧,包括:15 个位的 CRC序列(CRC SEQUENCE)和1 个位的CRC界定符(CRC DELIMITER)构成。

在这里插入图片描述

CRC序列是根据多项式生成的 CRC 值,CRC 的计算范围包括:帧起始、仲裁段、控制段、数据 段。 接收方以同样的算法计算 CRC 值并进行比较,不一致时会通报错误。

1.6 ACK段

ACK段用来确认是否正常接收。由 ACK 槽(ACK SLOT)和 ACK 界定符(ACK DELIMITER)2 个位构成。

在这里插入图片描述

发送单元在 ACK 段发送 2 个位的隐性位。当接收器正确地接收到有效的报文时,接收器就会在应答间隙(ACK SLOT)期间(发送ACK 信号)向发送器发送一个“显性”的位以示应答,通知发送单元正常接收结束,这称作“发送 ACK”或者“返回 ACK”。

发送 ACK/返回 ACK是在既不处于总线关闭态也不处于休眠态的所有接收单元中,接收到正常消息的单元 (发送单元不发送 ACK)。所谓正常消息是指不含填充错误、格式错误、CRC 错误的消息。

2 远程帧

2.1 遥控帧格式
远程帧是接收单元向发送单元请求发送数据所用的帧,远程帧由 6 个段组成,远程没有数据段。

远程帧的构成如下所示:

  • 帧起始(SOF):表示帧开始的段;
  • 仲裁段:表示该帧优先级的段。可请求具有相同 ID 的数据帧;
  • 控制段:表示数据的字节数及保留位的段;
  • CRC 段:检查帧的传输错误的段;
  • ACK 段:表示确认正常接收的段;
  • 帧结束:表示远程帧结束的段。

远程帧格式如下图所示:

在这里插入图片描述
2.2 数据帧和远程帧的区别

数据帧和远程帧主要有两点区别:

  • 远程帧没有数据帧的数据段;
  • 远程帧RTR位是隐性,RTR位的极性表示了所发送的帧是数据帧(RTR位“显性”)还是远程帧(RTR位“隐性”)。所以,没有数据段的数据帧和远程帧可通过RTR 位区别开来。

在这里插入图片描述

3 CAN错误帧

3.1 错误帧格式

错误帧由错误标志(Error Flag)和错误界定符(Error Delimiter)组成。

接收节点发现总线上的报文有错误时,将自动发出活动错误标志,它是6个连续的显性位。其他节点检测到活动错误标志后发送错误认可标志,它由6个连续的隐性位组成。由于各个接收节点发现错误的时间可能不同,所以总线上实际的错误标志可能由6~12个显性位组成。

错误界定符由 8 个位的隐性位构成。当错误标志发生后,每一个CAN 节点监视总线,直至检测到一个显性电平的跳变。此时表示所有的节点已经完成了错误标志的发送,并开始发送8个隐性电平的界定符。

3.2 错误帧类型

错误帧共有 5 种,多种错误可能同时发生,种类如下所示:

  • 位错误
  • 填充错误
  • CRC 错误
  • 格式错误
  • ACK 错误

错误的种类、错误的内容、错误检测帧和检测单元如下表所示:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4 CAN过载帧

过载帧是用于接收单元通知其尚未完成接收准备的帧,过载帧由过载标志和过载界定符构成。

在这里插入图片描述

  • 过载标志由6个位的显性位组成,过载标志的构成与主动错误标志的构成相同。过载标志其形式破坏了间歇场的固定格式,结果使其他所有节点也检测到了一个出错状态,就都各自送出一个超载标志。
  • 过载界定符由8个位的隐性位组成,过载界定符的构成与错误界定符的构成相同。过载标志发送完毕后,每个节点都对总线进行监察,直到检测到一个隐性位为止。此时,每个节点均已发送完各自的过载标志,接着所有节点还要同时开始发送7个隐性位,配齐长达8位的过载界定符。

过载帧的构成如下所示:
在这里插入图片描述

5 CAN帧间隔

帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开,过载帧和错误帧前不能插入帧间隔。

帧间隔的构成如下图所示:

在这里插入图片描述

帧间隔由间隔段、总线空闲段和延迟传送段组成,具体说明如下所示:

  • 间隔段:间歇由3个隐性位构成。在间歇期间,不允许任何节点发送数据帧或远程帧。唯一可以执行的操作是通报超载状态;
  • 总线空闲段:总线空闲时间长短不限。总线一经确认处于空闲状态,则任何节点都可以访问总线来传送信息。因另一帧正在传送而延期发送的帧是从间歇之后的第一位开始送出的。通过对总线进行检测,出现在总线空闲期间的显性位将被认为是帧起始;
  • 延迟传送段:处于错误认可状态的节点完成其发送动作后,在被允许发送下一帧以前,它要在间歇之后送出8个隐性位。如果间歇期间执行了(由另一个节点引起的)发送动作,此节点将会变成正被发送的帧的接收器。

CAN-FD

CAN FD 协议是 CAN-BUS 协议的最新升级,将 CAN 的每帧 8 字节数据提高到 64 字节,波特率从最高的 1Mbps 提高到 8-15Mbps,使得通讯效率提高 8 倍以上,大大提升了车辆的通讯效率。

CAN FD具有以下4个主要优点:

  • 1、增加了数据的长度

    CAN FD每个数据帧最多支持64个数据字节,而传统CAN最多支持8个数据字节。这减少了协议开销,并提高了协议效率。

  • 2、增加传输的速度

    CAN FD支持双比特率:与传统CAN一样,标称(仲裁)比特率限制为1
    Mbit/s,而数据比特率则取决于网络拓扑/收发器。实际上,可以实现高达5 Mbit/s的数据比特率。

  • 3、更好的可靠性

    CANFD使用改进的循环冗余校验(CRC)和“受保护的填充位计数器”,从而降低了未被检测到的错误的风险。这在汽车和工业自动化等安全攸关的应用中至关重要。

  • 4、平滑过渡

    在一些特定的情况下CAN FD能用在仅使用传统CAN的ECU上,这样就可以逐步引入CAN FD节点,从而为OEM简化程序和降低成本。
    实际上,与传统CAN相比,CAN FD可以将网络带宽提高3到8倍,从而为数据的增长提供了一种简单的解决方案。

1 CAN FD的改进

CAN FD采用了两种方式来提高通信的效率:一种方式为缩短位时间提高位速率;另一种方式为加长数据场长度减少报文数量降低总线负载率。

CAN FD在 CRC 校验段采用了三种多项式来保证高速通讯下的数据可靠性。

1.1 缩短位时间提高位速率

CAN FD支持双比特率,与传统CAN一样,标称(仲裁)比特率限制为1 Mbit/s,而数据比特率则取决于网络拓扑/收发器。实际上,可以实现高达5 Mbit/s的数据比特率。

从控制段中的 BRS 位到 ACK 段之前(含 CRC 分界符)为可变速率,其余部分为原 CAN 总线用的速率。两种速率各有一套位时间定义寄存器,它们除了采用不同的位时间单位 TQ 外,位时间各段的分配比例也可不同。

1.2 加长数据段长度减少报文数量降低总线负载率

CAN FD每个数据帧最多支持64个数据字节,而传统CAN最多支持8个数据字节,这减少了协议开销,并提高了协议效率。
DLC 最大支持 64 个字节,在 DLC 小于等于 8 时与原 CAN 总线是一样的,大于 8 时则有一个非线性的增长,最大的数据场长度可达 64 字节。如下所示为 DLC 数值与字节数的非线性对应关系。

1.3 CRC校验段

CAN FD使用改进的循环冗余校验(CRC)和“受保护的填充位计数器”,由于 DLCs 的长度不同,在 DLC 大于 8 个字节时,CAN FD选择了两种新的 BCH 型 CRC 多项式,从而降低了未被检测到的错误的风险。

2 CAN FD和CAN总线协议帧异同

CAN FD和CAN总线协议帧格式如下所示:

在这里插入图片描述

CAN FD和CAN总线协议帧不同点如下所示:

1、传输速率不同

CAN FD的速率可变,从控制场中的BRS位到ACK场之前(含CRC分界符)为可变速率,最高速率可达到8Mbps,其他部分与CAN相同。

2、数据长度不同

CAN FD支持的最大数据长度为64byte,CAN支持的最大数据长度为8byte。

3、帧格式不同

CAN FD新增了FDF、BRS、ESI位:

  • FDF 位(Flexible Data Rate Format):原 CAN 数据帧中的保留位 r。表示 CAN 报文还是 CAN-FD报文,FDF 位常为隐性(1),表示 CAN FD 报文;
  • BRS 位( Bit Rate Switch):表示位速率转换,当 BRS
    为显性位(0)时数据段的位速率与仲裁段的位速率一致(恒定速率),当 BRS 为隐性位(1)时速率可变(即 BSR 到 CRC
    使用转换速率传输);
  • ESI 位(Error State Indicator):发送节点错误状态指示,主动错误时发送显性位(0),被动错误时发送隐性位(1)。

4、ID长度不同

CAN FD标准帧ID长度可扩展至12bit,CAN的标准帧ID为11bit。

3 解析CAN FD帧结构

CAN FD节点可以正常收、发CAN报文,但CAN节点不能正确收、发CAN FD报文,因为其帧格式不一致。

在这里插入图片描述
与CAN一样,CAN FD一共具有:帧起始,仲裁段,控制段,数据段,CRC段,ACK段和帧结束,7部分组成。

3.1 帧起始

CAN与CANFD使用相同的SOF标志位来标志报文的起始。帧起始由1个显性位构成,标志着报文的开始,并在总线上起着同步作用。

在这里插入图片描述

3.2 仲裁段

与CAN不同,CAN FD取消了对远程帧的支持,用RRS位替换了RTR位,为常显性。IDE用于区分标准帧和扩展帧。

在这里插入图片描述

3.3 控制段

CAN FD与CAN有着相同的IDE、res和DLC位,同时增加了FDF、BRS、ESI三个bit位。

  • FDF 位(Flexible Data Rate Format):原 CAN 数据帧中的保留位 r。表示 CAN 报文还是 CAN-FD报文,FDF 位常为隐性(1),表示 CAN FD 报文;
  • BRS 位( Bit Rate Switch):表示位速率转换,当 BRS为显性位(0)时数据段的位速率与仲裁段的位速率一致(恒定速率),当 BRS 为隐性位(1)时速率可变(即 BSR 到 CRC使用转换速率传输);
  • ESI 位(Error State Indicator):发送节点错误状态指示,主动错误时发送显性位(0),被动错误时发送隐性位(1)。

在这里插入图片描述

3.4 数据段

CAN FD兼容CAN的数据格式,同时最大还能支持:12、16、 20、 24、 32、 48和64byte。

像在传统CAN中一样,CAN FD DLC是4位,表示帧中数据字节的数量。为了维持4位DLC,CAN FD使用从9到15的其余7个值来表示所使用的数据字节数(12、16、20、24、32、48、64)。

在这里插入图片描述

3.5 CRC段

传统CAN中的循环冗余校验(CRC)为15位,而在CAN FD中为17位(最多16个数据字节)或21位(20-64个数据字节)。 在传统CAN中,CRC中可以包含0到3个填充位,而在CAN FD中,总是有四个固定填充位以提高通信可靠性。

在这里插入图片描述

3.6 ACK段

ACK紧跟着CRC结束标识位。不同的是,CAN FD支持2bits的ACK的识别。

3.7 帧结束

与CAN一样,CAN FD的帧结尾也为连续7位的隐性位。

CAN-bus处理数据流程
在这里插入图片描述

RK3588调试CAN

1 驱动文件所在位置

CAN控制器驱动程序所在位置

drivers/net/can/rockchip/rockchip_canfd.c

2 DTS节点配置

主要参数:

  • interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
    转换完成,产生中断信号。
  • clock
    时钟属性,用于驱动开关clk,reset属性,用于每次复位总线。
  • pinctrl

公共配置 kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588s.dtsi

  can0: can@fea50000 {
    
    
            compatible = "rockchip,can-2.0";
            reg = <0x0 0xfea50000 0x0 0x1000>;
            interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
            clocks = <&cru CLK_CAN0>, <&cru PCLK_CAN0>;
            clock-names = "baudclk", "apb_pclk";
            resets = <&cru SRST_CAN0>, <&cru SRST_P_CAN0>;
            reset-names = "can", "can-apb";
            pinctrl-names = "default";
            pinctrl-0 = <&can0m0_pins>;
            tx-fifo-depth = <1>;
            rx-fifo-depth = <6>;
            status = "disabled";
    };

    can1: can@fea60000 {
    
    
            compatible = "rockchip,can-2.0";
            reg = <0x0 0xfea60000 0x0 0x1000>;
            interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>;
            clocks = <&cru CLK_CAN1>, <&cru PCLK_CAN1>;
            clock-names = "baudclk", "apb_pclk";
            resets = <&cru SRST_CAN1>, <&cru SRST_P_CAN1>;
            reset-names = "can", "can-apb";
            pinctrl-names = "default";
            pinctrl-0 = <&can1m0_pins>;
            tx-fifo-depth = <1>;
            rx-fifo-depth = <6>;
            status = "disabled";
    };

    can2: can@fea70000 {
    
    
            compatible = "rockchip,can-2.0";
            reg = <0x0 0xfea70000 0x0 0x1000>;
            interrupts = <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>;
            clocks = <&cru CLK_CAN2>, <&cru PCLK_CAN2>;
            clock-names = "baudclk", "apb_pclk";
            resets = <&cru SRST_CAN2>, <&cru SRST_P_CAN2>;
            reset-names = "can", "can-apb";
            pinctrl-names = "default";
            pinctrl-0 = <&can2m0_pins>;
            tx-fifo-depth = <1>;
            rx-fifo-depth = <6>;
            status = "disabled";
    };

compatible = “rockchip,can-1.0” ,rockchip,can-1.0用来匹配can控制器驱动。
compatible = “rockchip,can-2.0” ,rockchip,can-2.0用来匹配canfd控制器驱动。

assigned-clock-rates用来配置can的始终频率,如果CAN的比特率低于等于3M建议修改CAN时钟到100M,信号更稳定。高于3M比特率的,时钟设置200M就可以。
pinctrl配置:根据实际板卡连接情况配置can_h和can_l的iomux作为can功能使用。

板级配置 arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dtsi

/* can1 */
&can1 {
    
    
        status = "okay";
        assigned-clocks = <&cru CLK_CAN1>;
        assigned-clock-rates = <200000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&can1m1_pins>;
};

由于系统根据上述dts节点创建的CAN设备只有一个,而第一个创建的设备为CAN0

3 内核配置

linux内核配置项点,在 Networking support > CAN bus subsystem support > CAN Device Drivers 下打开can drivers配置项点,如下图所示:

在这里插入图片描述
save保存退出即可。

Symbol: CANFD_ROCKCHIP [=y]
|
| Type : tristate
|
| Prompt: Rockchip CANFD controller
|
| Location:
|
| -> Networking support (NET [=y])
|
| -> CAN bus subsystem support (CAN [=y])
|
| -> CAN Device Drivers
|
| -> Platform CAN drivers with Netlink support (CAN_DEV [=y])
|
| Defined at drivers/net/can/rockchip/Kconfig:10
|
| Depends on: NET [=y] && CAN [=y] && CAN_DEV [=y] && ARCH_ROCKCHIP [=y]

4 CAN FD 通信测试工具

canutils是常用的CAN通信测试工具包,内含 5 个独立的程序:canconfig、candump、canecho、cansend、
cansequence。这几个程序的功能简述如下:
canconfig
用于配置 CAN 总线接口的参数,主要是波特率和模式。
candump
从 CAN 总线接口接收数据并以十六进制形式打印到标准输出,也可以输出到指定文件。
canecho
把从 CAN 总线接口接收到的所有数据重新发送到 CAN 总线接口。
cansend
往指定的 CAN 总线接口发送指定的数据。
cansequence
往指定的 CAN 总线接口自动重复递增数字,也可以指定接收模式并校验检查接收的递增数字。
ip
CAN波特率、功能等配置。

BR2_PACKAGE_CAN_UTILS=y
BR2_PACKAGE_IPROUTE2=y

注意:busybox里也有集成了ip工具,但busybox里的是阉割版本。不支持CAN的操作。故使用前请先确
定ip命令的版本(iproute2),在buildroot编译目录下/buildroot/output/firefly_rk3588执行make menuconfig,具体配置如下图所示:

buildroot下canutils配置:

在这里插入图片描述

buildroot下iprouter2工具配置:

在这里插入图片描述

5 CAN 常用命令接口

查询当前网络设备:

ifconfig -a

CAN 启动:

ifconfig can0 up

关闭CAN:

ip link set can0 down

设置仲裁段1M波特率,数据段3M波特率:

ip link set can0 type can bitrate 500000

打印can0信息:

ip -details link show can0

CAN FD发送:
发送(标准帧,数据帧,ID:123,date:DEADBEEF):

cansend can0 123##1DEADBEEF

发送(扩展帧,数据帧,ID:00000123,date:DEADBEEF):

cansend can0 00000123##1DEADBEEF

CAN FD接收:
开启打印,等待接收:

candump can0

6 CAN FD 常用命令接口

查询当前网络设备:

ifconfig -a

CAN FD启动:
关闭CAN:

ip link set can0 down

设置仲裁段500k波特率,数据段500k波特率:

ip link set can0 type can bitrate 500000 dbitrate 500000 fd on

打印can0信息:

ip -details link show can0

启动CAN:

ip link set can0 up

CAN FD发送:
发送(标准帧,数据帧,ID:123,date:DEADBEEF):

cansend can0 123#1122334455667788

发送(扩展帧,数据帧,ID:00000123,date:DEADBEEF):

cansend can0 00000123##1DEADBEEF

CAN FD接收:

开启打印,等待接收:

candump can

在网上买一个CAN卡接在rk3588板子的CAN接口上,CAN模块之间接线:CAN_H接CAN_H,CAN_L接CAN_L。

在这里插入图片描述

有两种方式来进行CAN卡与RK3588板子之间进行通信

  1. 利用卖家提供的上位机软件(windows环境下)进行通信
  2. 在Linux环境下进行,将rk3588插在ubuntu主机上,在Linux命令行和串口之间进行通信,串口用的minicom(配置过程中一定要注意波特率要一致,不然串口没有打印或者乱码,出入USB后可以通过 la -la /dev/ttyUSB*或者ls -la /dev/ttyS *来查看CAN卡的端口)

无论哪种方式都是先进行candump can0,再进行cansend can0 123#1122334455667788。

在这里插入图片描述
在这里插入图片描述

RK3588驱动代码解析(按老板要求简单画了一个流程图。。。)

在这里插入图片描述

在测试CAN的时候按照上述5的步骤比较顺利,但是在测试CAN-FD的时候遇到了几个问题,第一就是按照了CAN的设置比特率的命令去设置CAN-FD,在ifconfig can0 up的时候显示:
ifconfig: SIOCSIFFLAGS: Invalid argument
[ 2835.008047] [dhd] CFG80211-ERROR) wl_cfg80211_netdev_notifier_call : wdev null. Do nothing
[ root@RK3588:/# 2835.008151] rockchip_canfd fea60000.can can0: incorrect/missing data bit-timing
根据提示定位到代码的open_canedv()函数中:

int open_candev(struct net_device *dev)
{
    
    
	struct can_priv *priv = netdev_priv(dev);
	printk("priv->bittiming.bitrate = %ld\n", priv->bittiming.bitrate);
	if (!priv->bittiming.bitrate) {
    
    
		netdev_err(dev, "bit-timing not yet defined\n");
		return -EINVAL;
	}

	/* For CAN FD the data bitrate has to be >= the arbitration bitrate */
	if ((priv->ctrlmode & CAN_CTRLMODE_FD) &&
	    (!priv->data_bittiming.bitrate ||
	     priv->data_bittiming.bitrate < priv->bittiming.bitrate)) {
    
    
		netdev_err(dev, "incorrect/missing data bit-timing\n");
		return -EINVAL;
	}

	/* Switch carrier on if device was stopped while in bus-off state */
	if (!netif_carrier_ok(dev))
		netif_carrier_on(dev);

	return 0;
}

其中有句注释大意是说对于CAN-FD而言,数据比特率要大于等于仲裁比特率,虽然当时不是太明白这句话,但我意识到我用ip link set can0 type can bitrate 500000这个命令操作CAN-FD是有问题的,随后换成ip link set can0 type can bitrate 500000 dbitrate 500000 fd on,而后就可以利用CAN-FD进行数据的收发了。。。

按照配置CAN的方式去配置CAN-FD,导致少配置了CAN-FD的数据比特率,导致出错。之前配置CAN的指令为ip link set can0 type can bitrate 500000,实际通过分析CAN-FD的驱动代码以及CAN-FD通信协议的报文格式发现,对于CAN-FD,数据比特率是要大于仲裁比特率的。换用ip link set can0 type can bitrate 500000 dbitrate 500000 fd on配置数据比特率之后,CAN-FD就可以正常收发数据了。

分析:CAN-FD采用了两种方式来提高通信的效率,其中一种叫可变及更高的数据传输速率:从控制场中的BRS位到ACK场之前(含CRC分界符)为可变速率,CAN-FD数据段的传输速率最大可达5Mbit/s。但为了保证总线的健壮可靠,仲裁段(ID和ACK)保持不变,采用原CAN总线用的速率(最高1Mbit/s)。
注意:两种速率各有一套位时间定义寄存器,对于CAN-FD来说均需要配置。

猜你喜欢

转载自blog.csdn.net/qq_41483419/article/details/130065140