Skip to content

Commit

Permalink
Allow restarting of transmission tasks for socketcan (#1440)
Browse files Browse the repository at this point in the history
* Allow restarting of transmission tasks for socketcan

* Update can/interfaces/socketcan/socketcan.py

Co-authored-by: zariiii9003 <52598363+zariiii9003@users.noreply.github.com>
  • Loading branch information
hardbyte and zariiii9003 authored Nov 18, 2022
1 parent 44853c5 commit 485b1b4
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions can/interfaces/socketcan/socketcan.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,9 @@ def __init__(
self.task_id = task_id
self._tx_setup(self.messages)

def _tx_setup(self, messages: Sequence[Message]) -> None:
def _tx_setup(
self, messages: Sequence[Message], raise_if_task_exists: bool = True
) -> None:
# Create a low level packed frame to pass to the kernel
body = bytearray()
self.flags = CAN_FD_FRAME if messages[0].is_fd else 0
Expand All @@ -363,7 +365,8 @@ def _tx_setup(self, messages: Sequence[Message]) -> None:
ival1 = 0.0
ival2 = self.period

self._check_bcm_task()
if raise_if_task_exists:
self._check_bcm_task()

header = build_bcm_transmit_header(
self.task_id, count, ival1, ival2, self.flags, nframes=len(messages)
Expand All @@ -375,7 +378,7 @@ def _tx_setup(self, messages: Sequence[Message]) -> None:

def _check_bcm_task(self) -> None:
# Do a TX_READ on a task ID, and check if we get EINVAL. If so,
# then we are referring to a CAN message with the existing ID
# then we are referring to a CAN message with an existing ID
check_header = build_bcm_header(
opcode=CAN_BCM_TX_READ,
flags=0,
Expand All @@ -387,12 +390,19 @@ def _check_bcm_task(self) -> None:
can_id=self.task_id,
nframes=0,
)
log.debug(
f"Reading properties of (cyclic) transmission task id={self.task_id}",
)
try:
self.bcm_socket.send(check_header)
except OSError as error:
if error.errno != errno.EINVAL:
raise can.CanOperationError("failed to check", error.errno) from error
else:
log.debug("Invalid argument - transmission task not known to kernel")
else:
# No exception raised - transmission task with this ID exists in kernel.
# Existence of an existing transmission task might not be a problem!
raise can.CanOperationError(
f"A periodic task for task ID {self.task_id} is already in progress "
"by the SocketCAN Linux layer"
Expand Down Expand Up @@ -438,15 +448,15 @@ def modify_data(self, messages: Union[Sequence[Message], Message]) -> None:
send_bcm(self.bcm_socket, header + body)

def start(self) -> None:
"""Start a periodic task by sending TX_SETUP message to Linux kernel.
"""Restart a periodic task by sending TX_SETUP message to Linux kernel.
It verifies presence of the particular BCM task through sending TX_READ
message to Linux kernel prior to scheduling.
:raises ValueError:
If the task referenced by ``task_id`` is already running.
"""
self._tx_setup(self.messages)
self._tx_setup(self.messages, raise_if_task_exists=False)


class MultiRateCyclicSendTask(CyclicSendTask):
Expand Down

0 comments on commit 485b1b4

Please sign in to comment.