首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python-can J1939过滤掩码

python-can J1939过滤掩码
EN

Stack Overflow用户
提问于 2021-03-04 23:16:30
回答 1查看 1.5K关注 0票数 4

我一直在使用带有MCP2515 CAN总线设备的Raspberry在用python广播时读取J1939消息的全部值。

我想过滤J1939消息,但我并没有忘记can掩码的含义和我是如何不一致的。在python的文档中,说:

返回与至少一个筛选器匹配的所有邮件。如果筛选器为无长度序列或零长度序列,则所有消息都匹配。

代码语言:javascript
复制
[{"can_id": 0x11, "can_mask": 0x21, "extended": False}]

尽管我理解这个“无”部分,但我不知道如何识别我的ID消息的掩码

示例:

我只想通过脚本获取ID为"0xCF00400“和”0x18Fe927“的消息。

代码语言:javascript
复制
import can

# CAN Setting
can_interface = 'can0'
bus = can.interface.Bus(can_interface, bustype='socketcan_native')

while True:
     message = bus.recv()

     bus.set_filters([{"can_id":0xF004 , "can_mask": ?? , "extended": True},
                      {"can_id":0xfee9 , "can_mask": ?? , "extended": True}])

如何填充每个变量以及如何确定ID的掩码?

更新03/10/2021

我已经尝试了下面的代码,但仍然返回所有消息。

代码语言:javascript
复制
import can

# CAN Setting
can_interface = 'can0'

can_filters = [{"can_id":0xCF00400, "can_mask": 0, "extended": True},
               {"can_id":0x18fee927, "can_mask": 0, "extended": True}]

bus = can.interface.Bus(can_interface, bustype='socketcan_native',can_filters=can_filters)

while True:
     message = bus.recv()
     print(message)

输出:

代码语言:javascript
复制
Timestamp: 1615382511.238233    ID: 18fee500    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.238893    ID: 18fef100    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.247038    ID: 18fef100    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.247611    ID: 18fee500    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.248222    ID: 18fee900    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.248868    ID: 0cf00400    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.257056    ID: 0cf00400    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.257623    ID: 18fee900    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.258223    ID: 18fef100    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.258827    ID: 18fee500    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.267039    ID: 18fee500    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.267624    ID: 18fef100    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.268229    ID: 0cf00400    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.268835    ID: 18fee900    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.277035    ID: 18fee900    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.277620    ID: 0cf00400    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.278220    ID: 18fee500    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
Timestamp: 1615382511.278823    ID: 18fef100    X                DLC:  8    ff ff ff ff ff ff ff ff     Channel: can0
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-07 21:01:02

您可以使用"can_id":0xCF00400, "can_mask": 0xFFFFFFF对所需的cob ID进行有效的筛选(在内核级别),而不需要掩码/过滤器。0xFFFFFFF的掩码(所有掩码位设置为1)需要在can_id上完全匹配。

代码语言:javascript
复制
bus.set_filters([{"can_id":0xCF00400, "can_mask": 0xFFFFFFF, "extended": True},
                 {"can_id":0x18fee927, "can_mask": 0xFFFFFFF, "extended": True}])

例如,文件上说:

过滤器匹配,当<received_can_id> & can_mask == can_id & can_mask。如果也设置了extended,那么它只匹配<received_is_extended> == extended中的消息。否则,它只基于仲裁ID和掩码匹配所有消息。

举个例子:

代码语言:javascript
复制
# The following just equals zero
0xCF00400 & 0 == 0 # True

# The following equals 0xCF00400 (217056256 in decimal) exactly
0xCF00400 & 0xFFFFFFF == 0xCF00400 # True
0xCF00400 & 0xFFFFFFF == 217056256 # True

# The following can_id would not get through the filter + mask:
0x18fee500 & 0xFFFFFFF == 0xCF00400 & 0xFFFFFFF # False

# The following obviously would get through the filter + mask:
0xCF00400 & 0xFFFFFFF == 0xCF00400 & 0xFFFFFFF # True

我会将bus.set_filters()放在while True循环之前,在bus.recv之前。这是一个设置,所以您只需要在开始时设置一次。

您最好在初始化总线时添加它,如下所示:

代码语言:javascript
复制
can_filters = [{"can_id":0xCF00400, "can_mask": 0xFFFFFFF, "extended": True},
               {"can_id":0x18fee927, "can_mask": 0xFFFFFFF, "extended": True}]

bus = can.Bus(
    interface="socketcan",
    channel="can0",
    can_filters=can_filters
)

而且,我相信bustype='socketcan_native'已弃用赞成interface="socketcan"的。我已经成功地使用了后者一段时间,没有任何警告信息。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66484457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档