努力学习一下RT1xxx的CAN外设,CAN的使用场景还是非常多的,特别在汽车电子更是主流的通信网络,下面就基于RT1xxx的FlexCAN模块学习一下CAN的相关知识。
CAN的基本协议在这里就不多说啥了,网上资料巨多,随便搜一搜就有了。
NXP的FlexCAN外设IP如果按我来评价的话,那是巨复杂,下面就让我们一点点的拨开它。下面框图为FlexCAN的功能框图。
功能框图乍一看上去那是非常的简单,其中:
名称 | 描述 |
---|---|
BIU | 可以理解成是一个总线接口控制器,用来做信号连接的,啥时钟信号,数据信号,中断信号等等信号 |
CHI | 可以理解成是FlexCAN的控制中心 |
PE | 可以理解成是控制中心的执行机构 |
RAM | 一段专门给FlexCAN使用的RAM空间,用来存储收发的报文,也就是MB(message buffer) |
就是这个简单的框图里面包含的东西巨复杂,巨恐怖,继续往下看。
上面已经提到了一点,就是说FlexCAN有一段固定的RAM空间专门用来存放收发的报文,我个人姑且将这段RAM称作为MB系统,为啥叫系统呢,因为它的结构是可变的,是根据相关配置而变化的,下面详细说说。
正常模式下,MB系统分成了64个 MB(邮箱)(只有FlexCAN0有64个,其他的有64个,有32个的,换句话说就是每个FlexCAN模块的RAM空间大小不一样),像这样的邮箱我们姑且称其为标准x邮箱,每个标准x邮箱的结构如下:
邮箱各部分作用介绍如下:
① CODE :邮箱状态编码。用于记录邮箱当前状态以及消息匹配,仲裁过程也会使用到该字段。邮箱用作接收或发送时该字段的含义不同。
当用作接收邮箱时CODE 的值与邮箱状态对应关系如下:
CODE 值(二进制) | 邮箱状态描述 |
---|---|
0b0000: INACTIVE | 邮箱没有被启用。不会接收任何内容。 |
0b0100: EMPTY | 当前邮箱为空。 |
0b0010: FULL | 当前邮箱为满。 |
0b0110: OVERRUN | 当前邮箱溢出。 |
0b1010: RANSWER | 接收到远程请求帧。 |
CODE[0]=1b1 | FlexCAN 正在更新邮箱, CPU 不能访问。 |
当邮箱收到消息或者收到的消息被处理, FlexCAN 会自动更新 CODE 字段的值。 我们可以通过读取该字段的值得知当前邮箱状态。
当邮箱用作发送邮箱时 CODE 的值与邮箱状态对应关系如下所示:
CODE 值(二进制) | 邮箱状态描述。 |
---|---|
0b1000:INACTIVE | 邮箱闲置,未启用。 |
0b1001:ABORT | 停止状态,此时邮箱不参与发送仲裁。邮箱里的内容不会被发送。 |
0b1100:DATA | 无条件执行数据帧传输,传输完成之后 返回到非活动状态。 |
0b1100:REMOTE | 当前邮箱为远程请求帧, FlesCAN 将会无条件的执行发送,并且发送完成后该邮箱自动设置为具有相同 ID 的空接收邮箱。 |
0b1110:TANSWER | 当远程请求匹配时,该邮箱将无条件发送一个响应帧,发送完成后将自动返回到 RANSWER 状态。 |
② SRR 字段、 IDE 字段、 RTR 字段、ID字段、Byte字段以及 DLC 字段为CAN协议里的东西,这里不再赘述。
③TIME STAMP 字段,在 FlexCAN 模块内部拥有一个 16 位自由运行计数器。当FlexCAN 从 CAN 总线上检测到与该邮箱匹配的标识符后采样定时器的计数值保存到该字段。使用到该字段时将会详细介绍。
④PRIO 字段, PRIO 是 priority 前四个字母, 用于设置发送邮箱本地优先级(该功能需要激活),如果邮箱作为接收邮箱则该位不起作用。
激活了CAN FD后,MB系统也分成了若干个 MB(邮箱), MB(邮箱)的结构如下:
可以看出跟上面的标准x邮箱大部分都是相同的,不同的地方都是经典CAN和CAN FD协议不同造成的,这里也就不多做赘述了。
可以看到上面我说了若干个,为啥这里要用若干个呢,因为数量是变化的,都知道CAN FD的数据负载数是可以变化,但是这段RAM的大小是固定的,所以就有了一个此消彼长的结果。MB系统中,把正常模式下每32个MB分成一个block,每个block的数据长度和MB数量的对应关系如下:
正常情况下 | CAN FD 8byte | CAN FD 16byte | CAN FD 32byte | CAN FD 64byte |
---|---|---|---|---|
32 | 32 | 21 | 12 | 7 |
激活了RX FIFO之后,MB的结构就会大变,变成了一个RX_FIFO+FILTER+标准x邮箱的组合情况,其中RX_FIFO+FILTER结构如下:
激活之后,首先在正常模式下前6个标准x邮箱的所处的RAM就变成了深度为6个RX FIFO,再往后就变成了Filter表元素,而这个Filter表元素数量是可以设置的,最大可支持128个,最小4个,而每4个Filter表元素就会占用一个标准x邮箱的空间。举个例子,如果我使能RX FIFO,又激活了128个Filter表元素,那么就会占用前(6+128/4=38)标准x邮箱的RAM空间,那么可用的标准x邮箱个数就为(64-38)个。
那么就有人问了,那如果是CAN FD咋办呢?嘿嘿,实话实说,这种模式下就不支持CAN FD,换句话说,CAN FD和RX FIFO不能共存。
还有人关心CAN在各种模式下对DMA的支持情况,如下表显示:
FlexCAN提供了强大的过滤机制来对总线上的报文进行过滤,只有通过过滤的报文才能成功的被接收。
过滤机制的原理就是通过设置过滤器的ID(29bit),RTR(1bit),IDE(1bit),通过这三个特征来进行过滤,这3个特征加在一起31bit ,总共31个眼睛,再配合MASK来进行过滤,何谓MASK,你可以理解成是一块遮羞布,是用来遮那31个眼睛的遮羞布,31块布随便你怎么遮,遮住的部分don’t care, 没有遮住的部分需要检测,一旦不同,就忽略报文,只有当没有遮住的眼睛全部检查后的报文才能被接收(也或者理解成一个与门,将31bit & MASK)。
而这个过滤机制也是得分成几种情况:
这种情况下,过滤器就是每个接收邮箱MB的中的ID,RTR,IDE,之后又根据Individual MASK有无激活分成两种情况。
①未激活状态下,那么除了14号,15号邮箱之外有自己的个人MASK,其余的接收邮箱则共用一个Global MASK。
②激活状态下,所有的接收邮箱都会有自己的Individual MASK。
RX FIFO的过滤器其实在介绍RX FIFO结构就已经介绍过了,它的过滤器就是上面所说的Filter表元素,每一个Filter表元素占32bits,它根据配置会有A,B,C三种形式,这三种形式不能共存,三种结构如下:
A形式就是一个完整的RTR+IDE+Standard ID,B形式就是两个完整的RTR+IDE+Standard ID或者一个完整的RTR+IDE+extended ID,而C形式就是4个ID片。那么它的MASK在哪里呢,这里比较特殊,如下图所示:
可以看到在这种情况下,每个Filter表元素的MASK是变化的,举个例子,如果我们设置了128个Filter表元素,那么前32个Filter表元素有自己的Individual MASK,其余的Filter表元素则共用一个Global MASK。
前面介绍了FlexCAN强大的过滤机制,那么我们再来看看在这个强大过滤机制下的匹配机制。
匹配的基本过程就是根据MB的序号,从小到大一个一个匹配,直到匹配成功,并将数据移入MB。这里举几个现象,就非常清楚了。
至于其他的什么仲裁机制,什么数据同步机制,什么发送机制等等机制对于我们的使用影响不大,在这里就不多介绍了,感兴趣的小伙伴可以去RT1050的RM手册上找到相关介绍。
至于FlexCAN的使用,大家可参考NXP官方的SDK包示例,里面有几个经典的示例,大家自行参考,如下图:
另外我还搞到了一手内部资料,香香的,由NXP资深大拿Const Yu写的一些SDK里没有的例子,主要是CAN FD,结合MASK,结合DMA使用的一些例子(基于RT1170,但是RT1xxx的FlexCAN是一样的,是同用的,所以其他RT1xxx芯片是可以参考的),如下:
下载地址:
RT1170_CAN_Demo.7z