STbxCAN的filter和mask

  有人问我一段以前写的代码的细节,函数名是xxx_CAN_Config_Rx_ID_Group,用的是ST的芯片

 1 tmpOrRes = 0;
 2 tmpAndRes = xxx_CAN_ID_MAX;
 3 
 4 for(uint32_t i = 0; i < len; i++)
 5 {
 6     if(Rx_ID_Arr[i] > xxx_CAN_ID_MAX)
 7     {
 8         return -1;
 9     }
10     else
11     {
12         tmpAndRes &= Rx_ID_Arr[i];
13         tmpOrRes |= Rx_ID_Arr[i];
14     }
15 }
16 
17 tmpFilter = tmpAndRes;
18 tmpMask = (tmpOrRes ^ xxx_CAN_ID_MAX) | tmpAndRes;

  上面是核心部分的展示,困惑的点是17,18行,filter和mask干什么用的,为什么这么算。

  这代码我都写了两年,不看回技术文档,only god knows。

  怼了他一遍要看技术文档后,我看见这是数学相关的操作,就尝试直接从代码入手看下能不能看懂,毕竟这也是我一直在锻炼的能力。

 

  1.还是要先搞清楚目的,输入和输出。看了下函数名,这个明显是CAN的组过滤的配置,而Rx_ID_Arr就是要过滤出来的id的数组,len就是这个数组的长度,tmpFilter和tmpMask后面赋给了ST库api所需要的实例的成员变量。那显而易见,这个代码片段的作用就是根据要过滤出来的id组生成st寄存器需要用到的filter和mask。

  2.看了下循环,显然,目的有两个,id的合法性检查以及得到这些id的与值和或值

  3.对与和或值的理解改变一下,tmpAndRes:指示所有id里都为1的位;tmpOrRes:指示所有id里置过1的位

  4.对18行的算式分成两部分 (tmpOrRes ^ xxx_CAN_ID_MAX)  和 tmpAndRes 进行理解,第一部分代表了将所有id里都为0的位置1,第二部分代表了将所有id里都为1的位置1,即tmpMask的作用是将所有id里同一位都相同的位置1

  5.结合17行,可以推断(对 这块只能推断,不看文档只看代码哪有那么多100%)寄存器里filter和mask的作用效果是符合 0 == ((id ^ filter) & mask) 的id将满足过滤条件

  6.由此看出这个函数的group配置只能符合满足的最小集合,不能做到只匹配组内成员,比如我要过滤0x21和0x22,那很遗憾,0x20和0x23必然也会被过滤出来

 

  好了,推完了,拿回技术文档出来对比了下,确实如此,nice。

 

posted @ 2025-08-27 12:07  蓝bleu  阅读(12)  评论(0)    收藏  举报