微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python-can J1939过滤面罩

如何解决python-can J1939过滤面罩

我一直在使用带有 MCP2515 CAN 总线设备的 RaspBerry 工作,用于在使用 python 广播时读取 J1939 消息的整个值。

我想过滤 J1939 消息,但我不明白 can-mask 的含义以及我如何发现它。在 python-can 的文档中说:

返回匹配至少一个过滤器的所有消息。如果过滤器 为 None 或零长度序列,所有消息都匹配。

[{"can_id": 0x11,"can_mask": 0x21,"extended": False}]

即使我理解了这个“无”部分,我还是不明白如何识别我的 ID 消息的掩码

示例:

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

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,"extended": True}])

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

更新 03/10/2021

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

import can

# CAN Setting
can_interface = 'can0'

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

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

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

输出

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

解决方法

您可以使用 "can_id":0xCF00400,"can_mask": 0xFFFFFFF 高效过滤(在内核级别)您想要的 cob ID,无需掩码/过滤器。 0xFFFFFFF 的掩码(所有掩码位设置为 1)要求与 can_id 完全匹配。

bus.set_filters([{"can_id":0xCF00400,"can_mask": 0xFFFFFFF,"extended": True},{"can_id":0x18fee927,"extended": True}])

例如,文档说:

过滤器匹配,当 <received_can_id> & can_mask == can_id & can_mask。 如果 extended 也被设置,它只匹配消息 <received_is_extended> == extended。否则它匹配每个 仅基于仲裁 ID 和掩码的消息。

举个例子:

# 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 之前。这是一个设置,所以你只需要在开始时设置一次。

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

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

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

此外,我相信 bustype='socketcan_native'deprecated 支持 interface="socketcan"。我已经成功使用后者很长一段时间了,并且没有任何警告消息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。