максимальная скорость протокола linux CAN

#python #linux #can-bus #socketcan #python-can

#python #linux #can-bus #socketcan #python-can

Вопрос:

Я пишу программу, которая должна обрабатывать 20000 сообщений CAN в секунду. При написании кода с помощью python под Linux с использованием socketcan кажется, что я начинаю терять сообщения, когда значение msg_per_second превышает 200.

Что может быть ограничивающим фактором и как я могу изменить настройки программы или ОС, чтобы избежать потери сообщений CAN?

Приведенный ниже код показывает количество около 990, когда msg_per_second равно 1000. Они должны быть равны.

 #!/usr/bin/env python3

import time
import can 
import datetime

count = 0
count_print_time = datetime.datetime.now()

bus = can.Bus(interface='socketcan', channel='vcan0', bitrate=500000)
msg = can.Message(arbitration_id=0x123, data=[1, 2, 3, 4, 5, 6], is_extended_id=True)
msg_per_second = 1000
period = 1 / msg_per_second
bus.send_periodic(msg, period)

while(True):
    bus.recv(timeout=None)
    count = count   1

    time_elapsed = datetime.datetime.now() - count_print_time

    if time_elapsed.total_seconds() >= 1:
        count_print_time = datetime.datetime.now()
        print(f"count : {count}")
        count = 0
 

Вывод:

количество: 989 количество: 988 количество: 988 количество: 990 количество: 990 количество: 990 количество: 990 количество: 990

Мой вопрос может быть связан с размером буфера приема. Когда я запускаю следующий код, я всегда читаю 278 сообщений:

 import can

count = 0

bus1 = can.Bus(interface='socketcan', channel='vcan0', bitrate=500000)
bus2 = can.Bus(interface='socketcan', channel='vcan0', bitrate=500000)

for i in range(1000):
    msg = can.Message(arbitration_id=i, data=[1, 2, 3, 4, 5, 6], is_extended_id=True)
    bus1.send(msg)

while(True):
    msg = bus2.recv(timeout=None)
    count = count   1
    print(f"count: {count}") 
 

Вывод:
количество: 1
количество: 2

количество: 277
количество: 278

Я посмотрел в документации socketcan и не смог найти информацию о размере буфера.

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

1. Выведите значение period — это 0? Вы выполняете целочисленную арифметику.

2. @barny Это Python 3, по умолчанию он выполняет реальное деление, а не целочисленное деление.

3. Я попытался использовать sock1.getsockopt(сокет. SOL_SOCKET, сокет. SO_SNDBUF), и он показывает размер буфера как 212992. Изменение этого значения с помощью setsockopt никоим образом не меняет поведение программы.

4. О, я провалил этот вопрос интервью:-(

5. Если вы пытаетесь получить 20 000 кадров CAN в секунду при скорости передачи данных 500 000 бит / с, у вас есть не более 25 бит на кадр. Наименьший возможный кадр CAN (11-битный идентификатор, без полезной нагрузки) составляет не менее 47 бит. 20 000 кадров / с теоретически может работать при скорости 1 Мбит / с, но не на практике, даже если накладные расходы SocketCAN python-can были незначительными,

Ответ №1:

Для выполнения функции recv() требуется от 800 до 1200 us. При 1200us это дает максимальную скорость приема 833 сообщений в секунду.

Если время обработки приема превышает время обработки отправки, сообщения, вероятно, накапливаются в буфере и в конечном итоге удаляются при заполнении буфера.

Я не смог найти способ увеличить размер буфера. Второй фрагмент кода всегда выдает мне последние 278 сообщений. Остальные сообщения отбрасываются.