#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 сообщений. Остальные сообщения отбрасываются.