查看原文
其他

STM32 CAN过滤器的几个术语

miler 茶话MCU 2022-09-11


围绕STM32芯片CAN外设的过滤器,常有人对过滤器组、过滤器、过滤器编号、过滤器索引这几个术语有些疑惑。这里就一起聊聊相关话题,先以实际案例开始。


案例1:某工程师使用STM32F407VG开发产品,在做CAN的调试过程中发现,CAN1接收、CAN2发送,工作正常。但反过来就有问题,即CAN2收,CAN1发就无法正常接收。

后来发现CAN 过滤器配置的地方有问题。他使用STM32Cube固件库,两句关键代码如下:


sFilterConfig.FilterNumber = m;   //……【1】

sFilterConfig.BankNumber  = n;   //……【2】


第【1】句代码就是选择某过滤器组进行初始化并配置接收过滤器。对于双CAN产品,m的值为0到27。对于单CAN产品而言,m的值为0~13。

【2】句代码针对双CAN的STM32产品,配置CAN2可使用的过滤器组的起始编号,n取值范围为0~28.从编号为n的过滤器组到编号为27的过滤器组分配给CAN2使用。通过配置寄存器CAN2SB[5:0]@CAN_FRM确定。如果第【2】句配置不在代码中明确写出来,默认值就是14. 即硬件默认将编号为14起往后的过滤器组分配给CAN2使用。




对于双CAN STM32芯片,如果sFilterConfig.BankNumber=0,则所有过滤器组分配给CAN2使用,CAN1没得用。若sFilterConfig.BankNumber=28,则所有过滤器组分配给CAN1使用,CAN2就没得用了。


具体结合到本案例,客户代码里对CAN1、CAN2的过滤器进行配置时,当前过滤器组始终为0,即sFilterConfig.FilterNumber=0,而分配给CAN2的过滤器组又是从BANK 14开始的,即sFilterConfig.BankNumber = 14。


这样配置的话,CAN1接收,CAN2发的确不会有问题。反过来,CAN1发送,CAN2接收就会有问题。因为他一方面只是将Filter BANK 14到27分配给CAN2,同时又选择Filter BANK 0来配置CAN2的接收滤波器。所以要想CAN1发送,CAN2接收正常,其它参数不动的话,为CAN2配置滤波器时选择的过滤器组【Filter BANK】至少为14才可以,即sFilterConfig.FilterNumber=14。


案例2:在STM32双CAN产品中,CAN2不能进行接收,发送没问题。


这个问题经常有人碰到。很多情况是因为用户没有开启CAN1,或者在配置滤波器时,不是使用CAN1作为主体,而选择了CAN2。对于STM32双CAN芯片,CAN专用SRAM的访问以及对外来数据的滤波接收功能统一通过CAN1行使。因此,CAN1被称作为Master,CAN2被称作为Slave.换言之,CAN2对专用SRAM的访问和对信息滤波接收须借助CAN1来实现和管理。



顺便提下,这里说的MASTER CAN1和 SLAVE CAN2是从芯片内部资源管理职能而言的,并非针对CAN节点通信而言,否则就让人犯迷糊了。毕竟CAN通信并没有主从的说法。打个比方,就像你和某人一组共用一批设备各自做自己的课题,对方为组长。原则上这些设备共用,但由组长管理。你需要使用某些设备时需对方的协助与支持,至于你到底做什么,对方不干涉。反过来,组长需要使用那些设备时就不需要你的支持和协助,它自行使用和管理。


在使用STM32Cube库配置CAN2的过滤器时,早期版本在做CAN2的过滤器配置使用如下函数将CanHandle配置为CAN2时会有问题,须改用CAN1。不过后来的版本将这点做了修正。即使此为CAN2,在具体配置过滤器时的函数里还是会用CAN1去配置,详细可以查看该函数代码。【记得尽量使用最新版本库或手册】


HAL_CAN_ConfigFilter(&CanHandle,&sFilterConfig)


好,回到标题提到的关于STM32 CAN应用中的几个术语,过滤器组、过滤器、过滤器编号、过滤器索引。


过滤器组【filter bank】,是配置过滤器的原始资源,由2个32位寄存器组成。单CAN芯片有14个过滤器组,双CAN芯片有28个过滤器组,过滤器组编号由硬件拟定。一个过滤器组根据不同的过滤器模式【过滤方式和过滤器宽度】可配置1-4个过滤器。显然,过滤器组并不等同于过滤器。就好像说渔网的编制线材不等同于渔网一样的道理。过滤器组经过适当的配置后才能形成对信息具有过滤作用的过滤器。




做过滤器配置时,首先要选择过滤器组,然后配置过滤器的模式及宽度、并将配置的过滤器组与接收FIFO关联、激活当前的过滤器组。

在对过滤器组进行配置生成过滤器时,各个过滤器都被硬件自动编号,使得每个过滤器都有个编号【Filter Number】。CAN有两个FIFO,即FIFO0/FIFO1.这里有两套过滤器编号,即关联到FIFO0的过滤器与关联到FIFO1的过滤器分别各自从0开始依次编号。



   表一、关联到FIFO0/FIFO1的过滤器编号示例


关联到FIFO里的过滤器组的过滤器的编号原则:

先依据过滤器组的编号大小做基本排序,再按照组内过滤模式及过滤器数量排序编号,可以参照表一、表二协助理解。



    表二、过滤器组的配置及内部过滤器编号顺序


简单点讲,过滤器编号就是关联到各FIFO里的过滤器的序号,而且过滤器的编号跟过滤器组是否激活无关,只要配置且关联到FIFO就行。那过滤器匹配索引又是什么呢?


我们知道,一旦外来信息通过过滤器就会存放到相应的FIFO里,然后通过应用程序从FIFO中读取信息数据到SRAM。为了读取FIFO里的数据及进行存储,往往先要识别信息标识符,然后根据不同标识符将信息数据放到相应位置。不过,以信息标识符为标准来进行判别以及相应的存储访问,这个过程效率就不高。为此,CAN控制器就提供了过滤器匹配索引值【Filter Match Index】这个东西。


当外来信息通过过滤器后存储信息到FIFO的邮箱时,硬件自动将相应的过滤器编号写入FIFO邮箱内相关寄存器的过滤器匹配索引值【FMI】。所以,本质上讲过滤器匹配索引值跟过滤器编号是同一个数据,但代表的意义不一样。FMI表示本信息是经过哪个编号的过滤器匹配过滤而来。通过FMI可以快速找到相应的报文信息。


有了FMI,我们可以利用它作为数组序列直接访问相应的目的信息数据,或者拿收到的报文邮箱里的FMI跟所期望的数值比较来对信息筛选分类等。比如,考生除了名字外,一般都有准考证号。当考完试后,准考证可作为查分索引。如果没有这个准考证号,可能就得敲入考点、学生名字等多个身份信息,但效率就差了很多。




根据过滤器的配置与过滤规则,可能会出现一个外来信息可以通过多个过滤器的情况。这时FMI的值到底取哪一个过滤器的编号呢?这里就根据过滤器优先级原则来定。有如下三条规则:


1、32位过滤器优先于16位过滤器。

2、当过滤器同等宽度时,标识符列表模式优先于标识符屏蔽模式。

3、当过滤器模式及宽度一样时,低过滤器编号优先于高过滤器编号。


OK,到此就将过滤器组、过滤器、过滤器编号、过滤器索引几个术语大致整理了一下。更多细节可以参考STM32相关参考手册和相关代码进一步理解。

===================================

1、STM32定时器周期性地触发ADC的介绍

2、一个因为管脚冲突导致以太网异常的话题

3、使用STM32F4的CCM时遇到的问题分析

4、读取STM32 RTC 日历值不更新的话题

5、一与STM32 GPIO输出速率相关的话题


扫描或长按二维码可关注公众号



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存