[英]python-can J1939 filter mask
我一直在使用 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)
Output:
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
有效地過濾(在 kernel 級別)您想要的 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'
已被棄用,取而代之的是interface="socketcan"
。 我已經成功使用后者很長一段時間了,並且沒有警告消息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.