APP下载

CAN 总线报文接收准确率的优化设计

2023-05-10吴同晔刘石冯进良黄伟

关键词:低电平高电平寄存器

吴同晔,刘石,冯进良,黄伟

(长春理工大学 光电工程学院,长春 130022)

现场总线是由电气行业发展而来的一种数据总线,目前常用的汽车总线技术主要有FlexRay、MOST、CAN 和LIN,而 其 中CAN(Controller Area Network)总线更是应用十分广泛。CAN 总线作为唯一一个被ISO(国际标准化)组织认证的总线,有多主方式同时操作、取消了对节点地址和通信模块的编码等优秀性能。但CAN 总线同样包含着许多缺点,如传统CAN 总线以单片机STM32 为主,但STM32 已经满足不了现在高速率通信、高稳定性的需求[1],并且由于取消了对节点地址和通信模块的编码,导致CAN 总线在发出报文后可能会被多个节点甚至全部节点接收,造成多次播报或错误播报,增加了接收报文的错误率。因此迫切需要一种高速率通信、高稳定性、提高报文接收准确率的新型的CAN 总线。

近年来,越来越多的学者投入到研究新型CAN 总线的设计中。例如,时旭等人[2]提出了一种基于FPGA 的CAN 总线通信系统的设计,将FPGA 芯片替换掉传统的单片机STM32 芯片,提升了通信速度和稳定性,但未提出提高报文接收准确率的方法,并且占用FPGA 内部资源过多;纪振平等人[3]提出一种新型的基于FPGA 的CAN 总线控制器设计,将传统CAN 总线中的组合逻辑设计改为时序逻辑设计,减少了FPGA 内部资源的占用,但仍未提出如何解决CAN 总线报文接收错误率过高的问题。

针对报文接收错误率高这一问题,本文设计了一个报文接收模块,可以更准确、更有效率地传输数据。当一个节点发送报文时,首先被CAN总线接收,然后写入缓存区中。当状态寄存器检查完毕、缓存区释放时[4],按照指令向缓存区读取报文。如果发送报文的节点需要指定节点进行接收,则报文接收模块不工作;如果发送报文的节点向任意节点发送报文时,报文接收模块会任选三个节点,当这三个节点其中的任意一个接收到发出的报文,那么报文接收模块中的D触发器就会向状态寄存器发送已接收信号,使状态寄存器ALE 的状态锁存,缓存区关闭,之后不会再向其他节点发送已被接收的报文;反之如果三个节点没有接收,就向状态寄存器发送未接收信号,缓存区继续处于释放状态,重新选择三个节点接收报文,直到此报文被接收。与传统的CAN 总线接收报文相比,本设计具有准确率更高、减少重复接收报文的次数、减少资源浪费、专用性与集成度更高等特点。

1 报文发送和接收模块的原理

1.1 报文种类以及仲裁机制

CAN 总线之所以应用如此广泛,最大特点之一就是取消了对通信模块和节点地址进行编码,因此CAN 总线的节点可以有无数个,这也让CAN 总线拥有非常高的灵活性以及可操作性[5]。CAN 总线以报文的形式进行数据传输,这些报文通常定义为具有特定格式的数据流,他们的格式可以不相同[6],但是有一定的限制。CAN 总线的报文传输种类有:过载帧、错误帧、远程帧、帧间隔以及数据帧。其中数据帧是最常见的报文种类。

(1)数据帧:用于发送节点向接收节点传送数据的帧。

(2)远程帧:用于发送节点向具有相同ID 的接收节点发送数据的帧。

(3)错误帧:用于当检测出错误时向其他节点通知错误的帧。

(4)过载帧:用于通知尚未做好接收数据准备的帧。

(5)帧间隔:用于将数据帧及远程帧与之前传输的数据分隔开的帧。

图1 为最常见的数据帧内部结构。

图1 最常见的数据帧内部结构

如果总线处于闲置状态[7],那么系统内多个节点的发送和接收工作就可以正常进行。但如果总线上的多个节点同时发送报文,则优先级标识符较高的报文单元可以首先发送报文。在CAN 总线的报文当中,二进制数值的高低决定了标识符传送的优先级,数值越小,则优先级越高。在解决总线上数据发送冲突问题时,采取的是非破坏性仲裁技术。当报文的发送过程出现冲突时,在不影响其他模块工作的前提下[8],逐一进行标识符优先级的确定。具有最低值标识符的报文指定为优先级最高。即有多个节点同时发出报文时,优先级高的节点获得仲裁资格,并继续发送数据,优先级低的节点仲裁失败放弃发送,先进行报文的接收工作。这种仲裁机制会显著提高系统可靠性和稳定性,节约仲裁时间。

1.2 发送和接收报文流程

在发送报文的时候,第一步首先要判断缓存区(ALE)是否处于锁定状态[9]。当ALE 处于低电平时,即为锁存状态,此时的数据处于待命状态,无法被接收。当缓存区释放时,数据会以特定的格式发送到缓存区。发送报文流程图如图2 所示。

图2 发送报文流程图

接收报文的过程同样需要判断缓存区的状态,这是与发送过程一致的步骤。但接收的流程除了对报文进行接收之外还要进行其他情况的处理。接收流程比发送流程要复杂一些,因为在处理接收报文的过程中,同时要对诸如总线关闭、错误报警、接收溢出等情况进行处理。只有在总线正常,没有错误报警,并且接收缓冲区中有新报文,才开始进行数据接收工作。对接收缓冲区的数据读取完毕后关闭CAN 接收缓冲区。如图3 为接收报文流程图。

图3 接收报文流程图

2 整体结构与报文接收模块设计

本文采用“自上而下”的设计方法[10],将CAN总线划分为三个主要模块:寄存器模块、数据处理模块以及位时序逻辑模块。寄存器模块的主要功能是存储数据,比如CAN 总线控制器的命令、状态、中断等信息,同时与数据处理模块和位时序逻辑模块之间保持着数据传输以及交流,保证信息的实时性;位时序逻辑模块主要是实现CAN 总线对位同步的控制,负责监视串行CAN 总线输入,并处理与总线有关的时序问题;数据处理模块是一个控制数据流的序列发生器,与另两个模块相比更关键也更复杂,是三个模块中最主要的部分。三个子模块互相之间协调搭配,共同构成CAN 总线。本文主要从数据处理模块展开,数据处理模块又划分为六个子模块,如图4 所示为CAN 总线的控制器结构。

图4 CAN 总线的控制器结构

数据处理模块在进行数据传输的同时还执行仲裁、位填充、验收滤波、出错检测和错误处理等功能。根据其功能,数据处理模块又可以划分为以下六个模块:验收滤波、接收模块、发送模块、错误管理、FIFO(First Input First Output)和CRC 校验。各个模块之间相互配合共同组成数据处理模块。如图5 所示为数据模块处理的功能结构。

图5 数据模块处理的功能结构

数据处理模块的主要特点之一就是采用多主方式工作。由于CAN 总线取消了对节点地址和通信模块的编码,从而任意一个节点都可以随时向总线上的其他节点发送信息,所以很容易提高竞争冒险的风险,这也导致一个报文可以被多个节点接收或者全部节点接收,本文基于这个缺陷设计了一个报文的接收模块,当缓存区中的报文被其他节点读取时,按照条件选择三个节点:如果发送报文的节点所发出的报文需要被指定节点接收,则报文接收模块不工作,处于复位状态;如果发送报文的节点对接收报文的节点没有指令,则报文接收模块会任选三个节点,分别定义为寄存器node_1、寄存器node_2、寄存器node_3,如图6 所示为报文接收模块设计原理图。

图6 报文接收模块设计原理图

首先需要判断状态寄存器是否处于锁存状态,SJA1000 的状态寄存器为ALE,当ALE 为低电平时[11],状态寄存器锁存,缓存区处于关闭状态;当ALE 为高电平时,缓存区释放。节点在读取状态寄存器的报文时,ALE 需要处于高电平状态,也就是使能端处于高电平。此时其他节点可以在缓存区中读取到报文。

定义三个寄存器作为节点并设置高电平有效,将复位信号sys_rst_n 设置为高电平有效,同时设计一个D触发器作为控制信号,当D触发器flag 信号为低电平时,输出信号有效。如果此时发送报文的节点指定某个或多个节点接收,则整个模块的状态表现为复位信号sys_rst_n 低电平,即处于复位状态,报文接收模块不工作;而当寄存器状态显示为高电平时,表明已经接收了这个报文。三个寄存器通过或门连接,之间有任意一个为高电平,则D触发器输出为低电平,即flag 信号显示为低电平;如果三个寄存器没有任何一个接收,则D触发器为高电平,即flag信号显示为高电平。当报文被三个节点中的任意一个接收时,flag 就会向状态寄存器发送关闭释放信号,使状态寄存器ALE 锁存处于低电平;当三个节点都没接收时,flag 会向状态寄存器发送继续释放信号,重新选择三个节点进行接收报文的工作。

3 测试结果与比较

3.1 CAN 总线通信的功能验证

信号传输原理:

(1)发送过程:CAN 控制器将CPU 发送来的报文转换为逻辑电平(包括逻辑0 显性电平和逻辑1 隐形电平),通过TX 脚传递给CAN 收发器。CAN 收发器接收逻辑电平之后,再将其转换为差分电平传送到CAN 总线上。

(2)接 收 过 程:CAN 收 发 器 将CAN_H 和CAN_L 线[12]上传来的差分电平转换为逻辑电平传送回CAN 控制器的RX 脚,CAN 控制器再把该逻辑电平转化为相应报文发送到CPU 上。

加入报文接收模块后,CAN 总线能否正常发送和接收数据,对整体CAN 总线的数据传输是否造成影响,需要进行测试[13]。本文采用软件canutils 对后续CAN 总线进行测试。canutils 包内含5 个独立的程序:cansend、candump、canconfig、canecho、cansequence。

cansend:往指定的CAN 总线接口发送指定的数据。

candump:从CAN 总线接口接收数据并以十六进制形式打印到标准输出,也可以输出到指定文件。

canconfig:用于配置CAN 总线接口的参数,主要是波特率和模式。

canecho:把从CAN 总线接口接收到的所有数据重新发送到CAN 总线接口。

cansequence:往指定的CAN 总线接口自动重复递增数字,也可以指定接收模式并校验检查接收的递增数字。

首先设置模式为停止,然后设置再启动。一般系统起来后都需要先配置canutils,后续几个程序才能正常使用,如图7 所示为配置canutils。

图7 配置canutils

打开两个终端,一个进行CAN0 设备的发送,一个进行CAN1 设备的接收。在CAN1 终端命令行输入candump can1,意义是CAN1 设备开始进行接收,进程为阻塞型,CAN1 设备将会一直接收发来的CAN0 消息直到用户终止,图8 所示为CAN1 设备开始接收。

图8 CAN1 设备开始接收

在CAN0 发送终端中进行数据发送,使用cansend 命令,其格式为cansend <设备号> <要发送的消息>。而发送的数据只能发送16 进制,并且每次发送的数据为8 个字节。任选ID 为123的CAN 标准帧进行发送测试,波特率为1 M,内容为11 22 33 44 55 66 77 88。如果数据传输无误,则会在CAN1 接收终端接收到发送端发出的标准数据帧。

结果表明,加入报文接收模块后的设计可以正常地进行发送接收信号,并且发送和接收之间并未发生错误,验证了此模块设计通信的可行性。图9 为CAN0 设备发送数据进行测试,图10 为CAN1 设备接收数据成功。

图9 CAN0 设备发送数据进行测试

图10 CAN1 设备接收数据成功

3.2 报文接收模块的验证与资源占用

本文采用FPGA 所用经典软件vivado 来进行仿真验证。将报文接收模块视为顶层文件,写入top 模块中,并写好与之相对应的仿真文件。Run simulation 通过之后,观察波形数据,如图11所示为vivado 验证数据的波形图。

验证一下模块的可行性。先给三个寄存器低电平处于复位状态,即延迟20 ns,寄存器node_1、寄存器node_2、寄存器node_3 均处于低电平状态,D触发器flag 信号处于高电平状态,此时三个寄存器都处于未接收的状态,等待信号的传输。

若延迟40 ns,给了一个输入信号,在时钟信号的作用下传入进寄存器中被node_1 接收,寄存器node_1 处于高电平状态,寄存器node_2、寄存器node_3 均处于低电平状态,则flag 信号此时处于低电平状态,状态寄存器ALE 拉低,处于锁存状态,等待下一信号的到来。

再延迟40 ns,此时结束上一个状态,将节点node_1 重新拉低,可以看到D触发器flag 随之拉高,重新回到复位的状态。

仿真验证通过之后,检查一下报文接收模块的资源占用情况。具体占用资源包括:查找表、寄存器、F7 选择器。从总体看报文接收模块在FPGA 消耗的资源都不是很高,说明该模块资源占用率低。FPGA 资源占用结果如表1 所示。

由表1 可见,报文接收模块查找表占用两个,仅占CAN 总线的0.527 7%,报文接收模块的寄存器占用4 个,仅占CAN 总线的0.570 6%,所以加入报文接收模块并不会影响整体CAN 总线的资源利用。

3.3 报文接收成功率对比结果

均发送10 000 组报文,将加入报文接收模块前后的成功率进行对比,成功率对比结果如表2所示。

表2 成功率对比结果

由表2 可见,发送10 000 组报文时,加入报文接收模块之后的成功组数比加入之前多900组,成功率比加入模块前要高9%,成功率从90%提升到99%,多次播报从479 组降到34 组,降低了92.89%,错误播报从522 组降到66 组,降低了87.36%,验证了报文接收模块的可行性。

4 结论

本文对基于FPGA 的CAN 总线控制器,通过在数据处理中加入一段报文接收模块的代码进行设计。本设计的优点在于,相对于所有节点都可以接收,选择三个节点能大大减少资源的利用与消耗,节省成本。综合数据结果,CAN 总线报文多播或错播的问题得到了解决。加入这部分针对报文接收的模块后,虽然会增加查找表0.527 7%的占用和寄存器0.570 6%的占用,但加入此模块后会提高9%的报文接收准确率,同时降低了92.89%的多次播报率和87.36%的错误播报率,验证设计可行。

猜你喜欢

低电平高电平寄存器
一种基于FPGA的PWM防错输出控制电路
铁道车辆高/低电平信号智能发生器设计
Lite寄存器模型的设计与实现
TS-03C全固态PDM中波发射机开关机控制电路原理及故障分析
2017款凯迪拉克2.8L/3.0L/3.2L/3.6L车型低电平参考电压总线电路图
分簇结构向量寄存器分配策略研究*
DM 50KW中波广播发射机欠推动故障分析
PDM 1kW中波广播发射机保护电路分析
15-MeV电子直线加速器的低电平系统
集成电路静态参数测试