集成在微控制器芯片中的CAN总线通信引擎的外设电路系统,有一些典型的实现,例如飞思卡尔半导体(已并入恩智浦半导体)的ColdFire系列微控制器中用到的MSCAN和Kinetis系列微控制器的FlexCAN(由Silvaco International公司设计),这些CAN总线通信引擎在汽车电子应用中已经被广泛使用,用以实现内存中的数据与CAN总线上串行信号的的相互转换。灵动微电子设计生产的MM32F0140和MM32F5系列微控制器芯片也集成了FlexCAN外设模块。本文以MM32F0140 / MM32F5270 微控制器芯片上集成的FlexCAN作为CAN硬件外设模块的实例,讲述硬件的CAN通信引擎的工作方式,以此展现硬件电路系统对CAN总线控制逻辑的建模,建立起软件系统同硬件电路的关联关系。同本系列的其它文章一样,本文希望以尽量简洁的语言,关注基本的原理和常用的功能,建立起对常规CAN外设模块的概念,为后续适配CAN通信协议栈的软件包做好准备。
FlexCAN外设模块是CAN总线通信的协议引擎,通过一个非常灵活的邮箱管理系统(消息缓冲区MB)管理发送和接收CAN通信帧。邮箱管理系统由一组消息缓冲区Message Buffer组成,MB中存放了通信帧的配置信息、数据负载、时间戳、消息ID等。完整的FlexCAN外设,在MB队列中的前38个MB可以配置成FIFO模式,配合一个功能强大的ID过滤机制,可以将总线上捕获到的输入帧同一个ID过滤器表的项目进行匹配(多达128个扩展ID,或者256个标准ID,或者512个8位的ID片段),并且可以在独立掩码寄存器中选择多达32个ID过滤器表项。
同时使用FIFO和独立消息邮箱(单通道)接收帧亦是可行的。使用消息邮箱接收帧,就是将选定的MB同ID固定的消息ID绑定后,该MB仅能接收固定消息ID的通信帧,使用ID掩码机制的情况下,可以将匹配一个范围的ID。
在执行发送帧或者接收帧之前,这里需要强调一个很重要的概念,当说明一个MB处于激活(Active)状态时,在意味着它正在参与发送过程的仲裁或是接收过程中的匹配。此处的激活状态,其实就意味着这个MB当前正被FlexCAN外设或CPU占用,它是不可操作的。
FlexCAN外设模块内部包含总线接口单元、发送机构(包含仲裁)、接收机构(包含匹配)、消息缓冲区,以及协议引擎,有功能框图如图x所示。
figure-flexcan-block-diagram
图x FlexCAN的系统框图CPU通过外设总线访问FlexCAN的寄存器,与FlexCAN外设进行交互,除了通过寄存器配置FlexCAN模块的多种工作模式及反馈信息外,CPU主要是向MB(消息缓冲区)中写入CAN通信帧的数据内容。消息缓冲区的存储块中包含多个MB,每个MB对应一个CAN通信帧内容的数据结构,并且可分别配置为将要发送帧的MB或是准备接收帧的MB。当要发送帧时,先将CAN发送帧的内容(包括帧ID、数据负载等)按照MB的存储结构填充到特定的字段,然后配置MB中的CODE字段为发送命令,则协议引擎PE会自动启动发送操作过程,包括自动同总线上的其他设备进行仲裁,以及在超过连续5个同电平位之后自动翻转等。当要接收帧时,需要从多个帧接收过滤器中拿出一个,设定需要匹配接收帧的ID(或者一个范围),并为之绑定一个存放将要匹配到的CAN通信帧数据内容的MB,之后协议引擎PE会监控CAN总线上的信号流,当遇到匹配ID范围内的通信帧,就存下来到预先准备好的MB。发送和接收完成后,协议引擎都会通过寄存器接口向CPU传达状态的变化,产生中断触发进一步的数据搬运过程。
PS:CAN总线对CAN通信帧进行仲裁时,不是以发送通信帧或接收通信帧的CAN总线设备本身作为获得仲裁优先级的评判依据(CAN节点不参与仲裁),而是以CAN通信帧的ID标识符作为获得仲裁的依据(值越小,优先级越高)。类似的概念还存在于以太网应用中IP主机和端口号的关系,应用程序最终是在端口的层面上进行通信,而不仅仅是拥有IP地址的主机。所以,当某一个CAN节点设备可以收纳多个ID的CAN通信帧时,意味着这个节点设备在CAN总线通信系统中可以被抽象成多个节点。但实际上,在后续介绍的CAN总线通信协议中可以看到,不同的ID将对应总线系统中不同的服务,总线系统中总有一个响应服务的线程,可能位于某个节点设备的某一个ID过滤器之后被实现。
FlexCAN外设模块的总线接口单元以存储空间中的寄存器作为操作界面,可由CPU通过外设总线访问到FlexCAN外设模块内部。虽然不建议开发者通过直接读写外设模块寄存器的方式对FlexCAN外设模块进行开发,因为直接操作寄存器实在是一件繁琐并且容易出错的过程,但本文在这里仍然将FlexCAN外设模块的寄存器清单列写出来,让读者一览FlexCAN外设模块为软件系统开放的应用接口。FlexCAN外设模块的寄存器如表x所示。
表x FlexCAN外设模块寄存器清单
FlexCAN外设地址空间的0x0080 - 0x017F之间的地址,被映射到RAM中,用于存放MB的数据结构,每个MB占用连续的16个字节,总共16个MB。这些MB将用于存放即将向CAN总线发送的帧数据内容,软件需要先把数据填充到MB中再启动发送工程;或者从CAN总线上捕获的CAN数据内容,之后软件就可以从MB中读到接收帧的信息。MB在存储空间中的数据结构,如图x所示。
figure-flexcan-mb-struct
图x MB消息缓冲区结构其中各字段功能为:
CAN总线标准帧同MB消息缓冲区的有一一对映关系,如图x所示。
figure-flexcan-mb-frame
图x CAN总线标准帧同MB消息缓冲区的一一对映CAN总线扩展帧相对于标准帧,多了SRR的字段,但仍同MB消息缓冲区有一一对映的关系,如图x所示。
figure-flexcan-mb-frame-ext
图x CAN总线扩展帧同MB消息缓冲区的一一对映### 初始化过程
FlexCAN外设的工作周期从复位状态开始,可以由如下两种情况触发复位过程:
之后,对FlexCAN模块进行配置。但要注意,任何对FlexCAN外设的配置操作,都需要在FlexCAN外设的冻结模式下才能完成。
一般的初始化FlexCAN外设模块的过程如下:
退出冻结模式之后,FlexCAN外设模块开始同CAN总线同步,接入总线网络。
相对于默认的将每个MB作为一个单独的通道,一帧一帧地接收并处理数据,FIFO模式可以将几个MB的存储空间组织成一个FIFO,FIFO可以缓存更多的帧,在CPU提供同等算力的情况下,提升节点设备的处理CAN总线通信帧的动态吞吐率。
当配置CAN_MCR[RFEN]=1时,启用Rx FIFO模式,此时,原MB列表的部分MB存储区域(MB0 - MB5,模块内偏移地址为0x80 - 0xDC的内存区域)将合并成Rx FIFO,由FIFO引擎管理。其中,原MB0的作为CPU访问Rx FIFO的接口,CPU始终可以从原MB0的位置读到最早进入FIFO的帧信息。此时,Rx FIFO的区域为只读模式,复位缺省值为0x00。
另外,还可以通过配置CAN_CTRL2[RFEN]=1,启用Rx FIFO的另一段区域,这个FIFO对应于原MB6 - MB15的区域(模块内偏移地址为0xE0 - 0x17C的内存区域,将用于存放Rx FIFO的ID过滤器表,只有通过ID过滤器表中的表项匹配的CAN通信帧才能被捕获进入Rx FIFO。ID过滤器表可能有多种模式(匹配不同的位数),可被配置为8至40个表项。复位FlexCAN外设模块后,ID过滤器表的内存区域的默认为从0xE0至0xFC,对应使用原MB6和MB7的空间,同未开启Rx FIFO模式的配置兼容。图x展示了Rx FIFO的数据结构。
figure-flexcan-rx-fifo-struct
图x FlexCAN Rx FIFO数据结构其中,每个ID过滤器表项(ID Filter Table element)占用32位字的空间,可以被分成1个32位、2个16位或4个8位的匹配接收掩码(IDAF,Identifier Acceptance Filters),这需要在CAN_MCR[IDAM]寄存器中设置。图x中展示了这种可能使用多种格式分割ID过滤器表项的格式,但要特别注意,一旦选定一种格式,所有的ID过滤器表项都会使用同一种格式。
figure-flexcan-id-filter-table
图x FlexCAN ID过滤器表项的格式其中,各配置字段的含义如下:
FIFO中MB结构中多出来的IDHIT (Identifier Acceptance Filter Hit Indicator):表示当前的MB匹配到了哪个ID过滤器。
Rx FIFO将6个MB的内存空间整合成一个FIFO,使用FIFO引擎管理先后收到的数据帧。相对于老式的单独管理各个MB,FIFO模式对DMA应用比较友好,并且可以提升从CAN总线上捕获帧的动态吞吐率。
CAN_IFLAG1[BUF5I]标志位,表示Rx FIFO中已经捕获到有效的数据帧,可供CPU读取。这个标志位也可以触发中断,CPU在中断服务程序中读取Rx FIFO的内容后,FlexCAN外设会更新FIFO状态寄存器CAN_RXFIR的值,然后自动清中断标志。如果Rx FIFO中有多个有效的数据帧,则CAN_IFLAG1[BUF5I]会持续置位,触发CPU处理接收帧的过程,直到Rx FIFO中捕获的通信帧全部被读走。
CAN_IFLAG1[BUF6I]标志位,表示Rx FIFO达到警告门限,此时Rx FIFO中已经积压了4个MB(从5个MB读走1个后剩下4个MB的时机),此时意味着Rx FIFO几乎要满到溢出了。这个标志位需要CPU清除。
CAN_IFLAG1[BUF7I]标志位,表示Rx FIFO已经满溢,此时Rx FIFO中已经积压了6个未读的MB,并且有一个新的CAN通信帧被捕获下来。这个标志位需要CPU清除。
CAN_IFLAG1[BUF0I]标志位,可用于清空Rx FIFO。当CPU向该标志位写1时,直接清空Rx FIFO。但这个功能仅在冻结模式下使用,这就意味着,用户不要试图在FlexCAN正常工作的情况下清空Rx FIFO(可以软件读掉Rx FIFO中的数据),这个功能大多用于改变全局配置时,重新初始化FlexCAN模块时使用。
FlexCAN模块中设计了功能强大(略显复杂)的帧过滤器模式,可以由硬件自动过滤掉很多本设备处理不了的帧,这就节约了很多原本需要在接收中断服务程序中判断捕获帧是否能在本机处理的过程。FlexCAN可以同时匹配众多的ID帧标识符,128个Format A格式的IDAF,或者256个Format B格式的IDAF,或者512个Format C格式的IDAF。每个捕获到Rx FIFO中的接收帧都有一个对应的IDHIT,指示它匹配到的过滤器的索引编号,CAN_RXFIR[IDHIT]寄存器字段中也能查看最近捕获的接收帧的IDHIT值。此时,需要在清接收标志之前读CAN_RXFIR寄存器,以确保存放在CAN_RXFIR寄存器中的值不会被后面捕获到帧覆盖掉。
当配置CAN_CTRL2[RFEN]=1时,启用过滤器表,过滤器表中最多可以有16个表项,可以由独立掩码寄存器CAN_RXIMRx分别配置。当CAN_MCR[IRMQ]=0时,过滤器表由CAN_RXFGMASK寄存器配置。
为了能让FlexCAN从CAN总线上捕获到通信帧,CPU(软件)需要准备一些工作:
当MB被激活后,它将会接收到通过ID过滤器匹配的通信帧。
当接收过程成功完成后,FlexCAN外设通过搬运过程将捕获到的通信帧从CAN通信引擎的缓冲中转运至MB中:
因此,建议CPU(软件)在读取CAN接收帧时,遵循如下步骤:
建议当收到CAN接收帧时,尽快把收到的帧读走,解锁MB,为后面接收的帧释放空间。
特别注意的是,在CPU通过轮询过程查看FlexCAN‘释放捕获到接收帧的过程中,应当以CAN_IFLAG1寄存器中的标志位来判定,而不是MB中CODE字段的状态码。读CODE状态码是没有意义的,因为一旦FlexCAN收到通信帧后被CPU读走,CODE不会变为EMPTY,而是仍保持为FULL,需要CPU人为清空。
若是使用FIFO模式,CPU需要在FlexCAN的冻结模式下配置启用Rx FIFO模式,再次启用FlexCAN通信引擎后,FlexCAN将以Rx FIFO模式捕获CAN通信帧:
Rx FIFO对使用DMA的场景更友好。但目前的ECU系统中,因为附加了协议栈和大量的软件干预,所以实际使用DMA的并不多。如果需要,也可以参见芯片用户手册的相关说明。
当要发送一个CAN通信帧,CPU需要选出一个MB,然后执行如下的步骤:
当MB被激活之后,它被加入到FlexCAN外设的发送仲裁过程,根据本地优先级(若有),最终被发送到CAN总线上。
在发送过程成功完成后:
注意,当通过CAN_MCR[AEN]启用了终止通信的功能后,当发送完整中断标志位置位时,此时MB是被锁住的,需要CPU清中断标志位后,才能再次访问MB,准备写入下一个新的通信帧。
此处的仲裁过程并不是指CAN总线网络的仲裁机制,而是FlexCAN外设本身的多个通信通道(MB)争用同一个通信引擎发送至CAN总线上的过程。FlexCAN会扫描当前所有待发送的MB,然后根据特定的策略选出其中一个作为本次发送过程的MB。这个策略是可以通过寄存器配置的,如表x所示。
表x 配置发送仲裁优先级策略
关于仲裁的过程,还有更多的细节,例如,当某个MB被激活发送过程后,如果长时间得不到仲裁优先级,也将会产生一些报警,此时,判断超时和报警的机制,在FlexCAN外设模块上有一些具体的实现策略。这些内容可以根据具体问题具体分析,在遇到具体场景时,再查阅手册一一对症。此处就不做赘述了。
本文描述了一个典型的CAN总线通信引擎FlexCAN外设模块的工作机制。FlexCAN总线以消息缓冲区MB作为数据缓冲单元,收发通信过程同典型的基本通信类引擎(例如UART)相似,但由于CAN总线以通信帧作为基本通信单元(包含ID和最多8个字节的数据负载),而不是基本通信引擎的单元数据,所以需要一个协议引擎,同步地在总线和MB之间搬运包含数据和状态的帧属性信息。CAN总线是一个多对多的网络,因此也引入了网络型通信引擎的问题,例如接收过程的目标地址(ID)匹配,和发送过程中的仲裁(冲突检测)。FlexCAN外设模块在硬件上也提供了对这些问题的解决方案,在接收过程中,设计了非常灵活的接收标识符过滤器组的机制;在发送过程中,设计了(在本地多个待发送MB之间的)本地优先级的机制,至于CAN总线网络上的仲裁,就依赖于网络本身的物理特性完成了。FlexCAN外设还增加实现了Rx FIFO的工作模式,可以将多个MB合在一起以FIFO的方式进行管理,使用FIFO可以提升FlexCAN外设在总线上的动态吞吐率,并且对DMA操作更加友好。本文对于FlexCAN内部机制的一些实现细节仅点到为止,未做详细的拆解,如果读者在具体应用中遇到具体问题,仍可参见芯片用户手册进行针对性阅读。
全部0条评论
快来发表一下你的评论吧 !