маска фильтра python-can J1939

#python #can-bus #python-can #j1939

#python #can-bus #python-can #j1939

Вопрос:

Я работал в малине с устройством шины CAN MCP2515 для чтения целых значений сообщений J1939 при трансляции с помощью python.

Я хотел бы отфильтровать сообщения J1939, но я не понимаю значения can-маски и того, как я ее искажаю. В документах python-can говорится :

Возвращаются все сообщения, соответствующие хотя бы одному фильтру. Если filters — None или последовательность нулевой длины, все сообщения сопоставляются.

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

Несмотря на то, что я понял эту часть «Нет», я не понял, как идентифицировать маску для моего идентификационного сообщения

Пример:

Я хотел бы просто получить с помощью скрипта только сообщения с идентификаторами «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}])
 

Как я должен заполнять каждую переменную и как я определяю маску идентификатора?

ОБНОВЛЕНИЕ 03/10/2021

Я попробовал приведенный ниже код, но все равно возвращаю все сообщения

 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
 

Ответ №1:

Вы можете использовать "can_id":0xCF00400, "can_mask": 0xFFFFFFF для эффективной фильтрации (на уровне ядра) для нужного вам идентификатора cob без необходимости маски / фильтра. Маска 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> amp; can_mask == can_id amp; can_mask . Если extended также задано, оно соответствует только сообщениям where <received_is_extended> == extended . В противном случае он соответствует всем сообщениям, основанным только на идентификаторе и маске арбитража.

Итак, в качестве примера:

 # The following just equals zero
0xCF00400 amp; 0 == 0 # True

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

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

# The following obviously would get through the filter   mask:
0xCF00400 amp; 0xFFFFFFF == 0xCF00400 amp; 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" . Я успешно использую последнее в течение довольно долгого времени, и никаких предупреждающих сообщений.

Комментарии:

1. Привет, @Sean. Я пытался протестировать ваш код, но на самом деле он еще не работает, он по-прежнему возвращает все сообщения, а не только сообщения, которые я установил :/

2. @GabrielLincoln виноват. Мой "can_mask": 0 (все биты 0 или выключены) просто пропускает все. Для точного совпадения попробуйте "can_mask": 0xFFFFFFF (все биты маски 1 или установлены на).

3. Спасибо @Sean! Это сработало, а также помогло мне понять, как работает маска. Кроме того, спасибо за подсказку о «встроенном сокете»