Skip to content

Commit 667540b

Browse files
Kvaser filtering improvements.
Updated documentation regarding filtering behavior. Apply same filters for both read and write handle to allow HW filtering. Removed documentation on threading.
1 parent 3b6f14d commit 667540b

File tree

3 files changed

+29
-27
lines changed

3 files changed

+29
-27
lines changed

can/interfaces/kvaser/canlib.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,6 @@ def __init__(self, channel, can_filters=None, **config):
349349
4)
350350
canSetBusParams(self._read_handle, bitrate, tseg1, tseg2, sjw, no_samp, 0)
351351

352-
self.sw_filters = []
353-
self.set_filters(can_filters)
354-
355352
if self.single_handle:
356353
log.debug("We don't require separate handles to the bus")
357354
self._write_handle = self._read_handle
@@ -360,6 +357,9 @@ def __init__(self, channel, can_filters=None, **config):
360357
self._write_handle = canOpenChannel(channel, canstat.canOPEN_ACCEPT_VIRTUAL)
361358
canBusOn(self._read_handle)
362359

360+
self.sw_filters = []
361+
self.set_filters(can_filters)
362+
363363
can_driver_mode = canstat.canDRIVER_SILENT if driver_mode == DRIVER_MODE_SILENT else canstat.canDRIVER_NORMAL
364364
canSetBusOutputControl(self._write_handle, can_driver_mode)
365365
log.debug('Going bus on TX handle')
@@ -407,9 +407,10 @@ def set_filters(self, can_filters=None):
407407
log.info('Filtering is handled in Python')
408408
self.sw_filters = can_filters
409409

410-
# Set filters for both std and ext IDs
411-
for ext in (0, 1):
412-
canSetAcceptanceFilter(self._read_handle, can_id, can_mask, ext)
410+
# Set same filter for both handles as well as standard and extended IDs
411+
for handle in (self._read_handle, self._write_handle):
412+
for ext in (0, 1):
413+
canSetAcceptanceFilter(handle, can_id, can_mask, ext)
413414

414415
def flush_tx_buffer(self):
415416
"""

doc/kvaser.rst

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,20 @@ Internals
1616
The Kvaser :class:`~can.Bus` object with a physical CAN Bus can be operated in two
1717
modes; ``single_handle`` mode with one shared bus handle used for both reading and
1818
writing to the CAN bus, or with two separate bus handles.
19+
Two separate handles are needed if receiving and sending messages are done in
20+
different threads (see `Kvaser documentation
21+
<http://www.kvaser.com/canlib-webhelp/page_user_guide_threads_applications.html>`_).
1922

2023

2124
.. warning:: Any objects inheriting from `Bus`_ should *not* directly
2225
use the interface handle(/s).
2326

2427

25-
Threading
26-
~~~~~~~~~
28+
Message filtering
29+
~~~~~~~~~~~~~~~~~
2730

28-
To avoid contention for the bus handle in ``single_handle`` mode, access is protected for
29-
the **read** and **write** daemon threads with a ``writing_event`` *Event* and a
30-
``done_writing`` *Condition*.
31-
32-
The read thread acquires ``done_writing`` and while ``writing_event`` is set
33-
blocks waiting on the ``done_writing`` Condition. A 1ms blocking read is carried
34-
out before ``done_writing`` is released.
35-
36-
The write thread blocks for 5ms on a queue (to allow the thread to stop). If
37-
a message was received it *sets* the writing_event to tell the read thread
38-
that a message in waiting to be sent. The ``done_writing`` is acquired for
39-
the actual write, the writing_event is cleared and the ``done_writing`` event
40-
is notified to start the read thread again.
31+
The Kvaser driver and hardware only supports setting one filter per handle.
32+
If one filter is requested, this is will be handled by the Kvaser driver.
33+
If more than one filter is needed, these will be handled in Python code
34+
in the ``recv`` method. If a message does not match any of the filters,
35+
``recv()`` will return None.

test/test_kvaser.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ def test_bus_shutdown(self):
5353
def test_filter_setup(self):
5454
# No filter in constructor
5555
expected_args = [
56-
((0, 0, 0, 0),), # Disable filtering STD
57-
((0, 0, 0, 1),), # Disable filtering EXT
56+
((0, 0, 0, 0),), # Disable filtering STD on read handle
57+
((0, 0, 0, 1),), # Disable filtering EXT on read handle
58+
((0, 0, 0, 0),), # Disable filtering STD on write handle
59+
((0, 0, 0, 1),), # Disable filtering EXT on write handle
5860
]
5961
self.assertEqual(canlib.canSetAcceptanceFilter.call_args_list,
6062
expected_args)
@@ -65,8 +67,10 @@ def test_filter_setup(self):
6567
{'can_id': 0x8, 'can_mask': 0xff}
6668
])
6769
expected_args = [
68-
((0, 0x8, 0xff, 0),), # Enable filtering STD
69-
((0, 0x8, 0xff, 1),), # Enable filtering EXT
70+
((0, 0x8, 0xff, 0),), # Enable filtering STD on read handle
71+
((0, 0x8, 0xff, 1),), # Enable filtering EXT on read handle
72+
((0, 0x8, 0xff, 0),), # Enable filtering STD on write handle
73+
((0, 0x8, 0xff, 1),), # Enable filtering EXT on write handle
7074
]
7175
self.assertEqual(canlib.canSetAcceptanceFilter.call_args_list,
7276
expected_args)
@@ -79,8 +83,10 @@ def test_filter_setup(self):
7983
]
8084
self.bus.set_filters(multiple_filters)
8185
expected_args = [
82-
((0, 0, 0, 0),), # Disable filtering STD
83-
((0, 0, 0, 1),), # Disable filtering EXT
86+
((0, 0, 0, 0),), # Disable filtering STD on read handle
87+
((0, 0, 0, 1),), # Disable filtering EXT on read handle
88+
((0, 0, 0, 0),), # Disable filtering STD on write handle
89+
((0, 0, 0, 1),), # Disable filtering EXT on write handle
8490
]
8591
self.assertEqual(canlib.canSetAcceptanceFilter.call_args_list,
8692
expected_args)

0 commit comments

Comments
 (0)