【问题标题】:python-can J1939 filter maskpython-can J1939过滤掩码
【发布时间】:2021-06-03 15:45:39
【问题描述】:

我一直在使用 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 , "can_mask": ?? , "extended": True}])

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

2021 年 3 月 10 日更新

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

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)

输出:

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

【问题讨论】:

    标签: python can-bus python-can j1939


    【解决方案1】:

    您可以使用"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, "can_mask": 0xFFFFFFF, "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, "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'deprecated 支持interface="socketcan"。我已经成功使用后者一段时间了,没有任何警告消息。

    【讨论】:

    • 你好,@Sean。我试图测试你的代码,但实际上还没有工作它仍然返回所有消息,不仅仅是我设置的消息:/
    • @GabrielLincoln 我的错。我的"can_mask": 0(所有位为 0 或关闭)只是让一切通过。对于完全匹配,请尝试"can_mask": 0xFFFFFFF(所有掩码位 1 或设置为 on)。
    • 谢谢@Sean!它有效,也让我了解面具是如何工作的。另外,感谢有关“socket native”的提示
    猜你喜欢
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 2022-10-13
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    相关资源
    最近更新 更多