Skip to content
This repository has been archived by the owner on May 7, 2021. It is now read-only.

When used on a busy can bus on Linux/socketcan we had overruns as soo… #44

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions pyvit/dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ def __init__(self, device, single_process = False):
self._running = False
self._single_process = single_process

#
# Will only operate on filters if the underlying can hardware supports
# filtering.
#
if hasattr(device, 'apply_filters'):
self._filter_list = []
else:
self._filter_list = None

def add_filter(self, id, mask):
if self._filter_list != None:
self._filter_list.append((id,mask))

if self._device.running:
self._device.apply_filters(self._filter_list)

def add_receiver(self, rx_queue):
if self.is_running:
raise Exception('dispatcher must be stopped to add receiver')
Expand Down Expand Up @@ -53,6 +69,9 @@ def start(self):
if self.is_running:
raise Exception('dispatcher already running')

if self._filter_list:
self._device.apply_filters(self._filter_list)

self._device.start()
self._tx_queue = Queue()

Expand All @@ -78,6 +97,16 @@ def stop(self):
self._device.stop()
self._running = False

#
# Clear any data from current queues
#
for q in self._rx_queues:
while not q.empty():
q.get()
while not self._tx_queue.empty():
q.get()


@property
def is_running(self):
return self._running
Expand Down
18 changes: 18 additions & 0 deletions pyvit/hw/socketcan.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


class SocketCanDev:

def __init__(self, ndev):
self.running = False

Expand All @@ -25,6 +26,23 @@ def start(self):
def stop(self):
pass

def apply_filters(self, filter_list):
#
# The can_filter struct looks like
# struct can_filter{
# uint32_t id;
# uint32_t mask;
# };
# the *optval is an array of the above structures. The size of the array
# cannot exceed 512 entries.
#
encodedArray = b""
for (fid, mask) in filter_list:
entry = struct.pack('<LL', fid, mask)
encodedArray += entry

self.socket.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FILTER, encodedArray)

def recv(self):
assert self.running, 'device not running'
frame_format = "=IB3xBBBBBBBB"
Expand Down
2 changes: 2 additions & 0 deletions pyvit/proto/uds.py
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,8 @@ def __init__(self, dispatcher=False, tx_arb_id=0x7E0, rx_arb_id=0x7E8, extended_
self.transport_layer = IsotpNormalAddressing(dispatcher, tx_arb_id)
self.transport_layer.rx_arb_id = rx_arb_id

dispatcher.add_filter(id=rx_arb_id, mask=0x7ff)

def request(self, service, timeout=0.5):
self.transport_layer.send(service.encode())
if self.transport_layer.N_TAtype == N_TAtype.physical:
Expand Down