Skip to content

Commit cd51ec4

Browse files
authored
check whether CAN settings were correctly applied (hardbyte#1426)
1 parent 8a7b1d0 commit cd51ec4

File tree

2 files changed

+69
-4
lines changed

2 files changed

+69
-4
lines changed

can/interfaces/vector/canlib.py

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def __init__(
140140
141141
:raise ~can.exceptions.CanInterfaceNotImplementedError:
142142
If the current operating system is not supported or the driver could not be loaded.
143-
:raise can.exceptions.CanInitializationError:
143+
:raise ~can.exceptions.CanInitializationError:
144144
If the bus could not be set up.
145145
This may or may not be a :class:`~can.interfaces.vector.VectorInitializationError`.
146146
"""
@@ -218,15 +218,17 @@ def __init__(
218218
interface_version,
219219
xldefine.XL_BusTypes.XL_BUS_TYPE_CAN,
220220
)
221+
self.permission_mask = permission_mask.value
221222

222223
LOG.debug(
223224
"Open Port: PortHandle: %d, PermissionMask: 0x%X",
224225
self.port_handle.value,
225226
permission_mask.value,
226227
)
227228

229+
# set CAN settings
228230
for channel in self.channels:
229-
if permission_mask.value & self.channel_masks[channel]:
231+
if self._has_init_access(channel):
230232
if fd:
231233
self._set_bitrate_canfd(
232234
channel=channel,
@@ -242,6 +244,51 @@ def __init__(
242244
elif bitrate:
243245
self._set_bitrate_can(channel=channel, bitrate=bitrate)
244246

247+
# Check CAN settings
248+
for channel in self.channels:
249+
if kwargs.get("_testing", False):
250+
# avoid check if xldriver is mocked for testing
251+
break
252+
253+
bus_params = self._read_bus_params(channel)
254+
if fd:
255+
_canfd = bus_params.canfd
256+
if not all(
257+
[
258+
bus_params.bus_type is xldefine.XL_BusTypes.XL_BUS_TYPE_CAN,
259+
_canfd.can_op_mode
260+
& xldefine.XL_CANFD_BusParams_CanOpMode.XL_BUS_PARAMS_CANOPMODE_CANFD,
261+
_canfd.bitrate == bitrate if bitrate else True,
262+
_canfd.sjw_abr == sjw_abr if bitrate else True,
263+
_canfd.tseg1_abr == tseg1_abr if bitrate else True,
264+
_canfd.tseg2_abr == tseg2_abr if bitrate else True,
265+
_canfd.data_bitrate == data_bitrate if data_bitrate else True,
266+
_canfd.sjw_dbr == sjw_dbr if data_bitrate else True,
267+
_canfd.tseg1_dbr == tseg1_dbr if data_bitrate else True,
268+
_canfd.tseg2_dbr == tseg2_dbr if data_bitrate else True,
269+
]
270+
):
271+
raise CanInitializationError(
272+
f"The requested CAN FD settings could not be set for channel {channel}. "
273+
f"Another application might have set incompatible settings. "
274+
f"These are the currently active settings: {_canfd._asdict()}"
275+
)
276+
else:
277+
_can = bus_params.can
278+
if not all(
279+
[
280+
bus_params.bus_type is xldefine.XL_BusTypes.XL_BUS_TYPE_CAN,
281+
_can.can_op_mode
282+
& xldefine.XL_CANFD_BusParams_CanOpMode.XL_BUS_PARAMS_CANOPMODE_CAN20,
283+
_can.bitrate == bitrate if bitrate else True,
284+
]
285+
):
286+
raise CanInitializationError(
287+
f"The requested CAN settings could not be set for channel {channel}. "
288+
f"Another application might have set incompatible settings. "
289+
f"These are the currently active settings: {_can._asdict()}"
290+
)
291+
245292
# Enable/disable TX receipts
246293
tx_receipts = 1 if receive_own_messages else 0
247294
self.xldriver.xlCanSetChannelMode(self.port_handle, self.mask, tx_receipts, 0)
@@ -340,6 +387,21 @@ def _find_global_channel_idx(
340387
error_code=xldefine.XL_Status.XL_ERR_HW_NOT_PRESENT,
341388
)
342389

390+
def _has_init_access(self, channel: int) -> bool:
391+
return bool(self.permission_mask & self.channel_masks[channel])
392+
393+
def _read_bus_params(self, channel: int) -> "VectorBusParams":
394+
channel_mask = self.channel_masks[channel]
395+
396+
vcc_list = get_channel_configs()
397+
for vcc in vcc_list:
398+
if vcc.channel_mask == channel_mask:
399+
return vcc.bus_params
400+
401+
raise CanInitializationError(
402+
f"Channel configuration for channel {channel} not found."
403+
)
404+
343405
def _set_bitrate_can(
344406
self,
345407
channel: int,

test/test_vector.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def mock_xldriver() -> None:
6262
# backup unmodified values
6363
real_xldriver = canlib.xldriver
6464
real_waitforsingleobject = canlib.WaitForSingleObject
65+
real_has_events = canlib.HAS_EVENTS
6566

6667
# set mock
6768
canlib.xldriver = xldriver_mock
@@ -72,6 +73,7 @@ def mock_xldriver() -> None:
7273
# cleanup
7374
canlib.xldriver = real_xldriver
7475
canlib.WaitForSingleObject = real_waitforsingleobject
76+
canlib.HAS_EVENTS = real_has_events
7577

7678

7779
def test_bus_creation_mocked(mock_xldriver) -> None:
@@ -870,13 +872,14 @@ def xlGetChannelIndex(
870872
def xlOpenPort(
871873
port_handle_p: ctypes.POINTER(xlclass.XLportHandle),
872874
app_name_p: ctypes.c_char_p,
873-
access_mask: xlclass.XLaccess,
874-
permission_mask_p: ctypes.POINTER(xlclass.XLaccess),
875+
access_mask: int,
876+
permission_mask: xlclass.XLaccess,
875877
rx_queue_size: ctypes.c_uint,
876878
xl_interface_version: ctypes.c_uint,
877879
bus_type: ctypes.c_uint,
878880
) -> int:
879881
port_handle_p.value = 0
882+
permission_mask.value = access_mask
880883
return 0
881884

882885

0 commit comments

Comments
 (0)