Custom CAN bus objects#

By default, pyXCP automatically creates and manages CAN bus objects for you. In most situations this means you don’t need to worry about setting up the bus manually.

There are three levels of CAN interface integration, ordered from simplest to most flexible:

  1. python-can plugin interface — use any driver that registers itself via python-can’s entry-point plugin system (no wrapper code).

  2. Existing bus object — pass a pre-created can.Bus instance directly (e.g. shared with another application such as UDSonCAN).

  3. Fully custom interface — implement CanInterfaceBase for hardware that is not supported by python-can at all.

Using an existing CAN bus object#

If you already hold a can.Bus instance (e.g. shared with UDSonCAN or another tool running in the same process), pass it directly via the transport_layer_interface parameter:

import can
from pyxcp.cmdline import ArgumentParser

can_if = can.Bus(interface="kvaser", channel="0", fd=False, bitrate=500000)

ap = ArgumentParser(description="external interface test")
with ap.run(transport_layer_interface=can_if) as x:
    x.connect()
    x.disconnect()

Note

  • It is the user’s responsibility to properly initialize and shut down the CAN bus interface.

  • pyxcp merges its filter configuration with any existing one, so make sure no unwanted traffic is forwarded to other applications. The original filter configuration is restored when pyxCP exits.

Fully custom interface (hardware not supported by python-can)#

If your hardware is not supported by python-can at all, implement the thin CanInterfaceBase ABC (a subset of python-can’s BusABC):

from pyxcp.transport.can import CanInterfaceBase

Import the base class and implement the required abstract methods:

#!/usr/bin/env python
import can
from pyxcp.cmdline import ArgumentParser
from pyxcp.transport.can import CanInterfaceBase


class WrappedKvaserInterface(CanInterfaceBase):

    def __init__(self):
        self.canif = can.Bus(interface="kvaser", channel="0", bitrate=500000)

    def set_filters(self, filters):
        self.canif.set_filters(filters)

    def recv(self, timeout=None):
        return self.canif.recv(timeout)

    def send(self, msg):
        self.canif.send(msg)

    @property
    def filters(self):
        return self.canif.filters

    @property
    def state(self):
        return self.canif.state

    def close(self):
        self.canif.shutdown()


custom_interface = WrappedKvaserInterface()

ap = ArgumentParser(description="Wrapped Kvaser CAN driver.")
with ap.run(transport_layer_interface=custom_interface) as x:
    x.connect()
    x.disconnect()

custom_interface.close()

A skeleton example is also available at pyxcp/examples/xcp_user_supplied_driver.py.