CAN Transport Interfaces

The implementation for Transport Interfaces that can be used with CAN bus is located in uds.transport_interface.can_transport_interface module.

Common

Common implementation for all all CAN Transport Interfaces is included in AbstractCanTransportInterface.

Warning

A user shall not use AbstractCanTransportInterface directly, but one is able (and encouraged) to use AbstractCanTransportInterface implementation on any of its children classes.

Configuration

CAN bus specific configuration is set upon calling uds.transport_interface.can_transport_interface.common.AbstractCanTransportInterface.__init__() method. The following configuration parameters are set then:

Most of these attributes (all except addressing_information) can be changed after object is created.

Python-CAN

Class PyCanTransportInterface contains the implementation of CAN Transport Interface that uses python-can package for receiving and transmitting CAN frames.

Note

Right now only half-duplex communication is implemented.

The matter is further explained in handling unexpected CAN packets arrivals chapter.

Configuration

Configuration is set upon calling uds.transport_interface.can_transport_interface.python_can.PyCanTransportInterface.__init__() method and from the user perspective it does not provide any additional features to common implementation provided by uds.transport_interface.can_transport_interface.common.AbstractCanTransportInterface.__init__().

Example code:

import uds
from can import Bus

# define example python-can bus interface (https://python-can.readthedocs.io/en/stable/bus.html#bus-api)
python_can_interface = Bus(interface="kvaser", channel=0, fd=True, receive_own_messages=True)

# define Addressing Information for a CAN Node
can_node_addressing_information = uds.can.CanAddressingInformation(
    addressing_format=uds.can.CanAddressingFormat.NORMAL_11BIT_ADDRESSING,
    tx_physical={"can_id": 0x611},
    rx_physical={"can_id": 0x612},
    tx_functional={"can_id": 0x6FF},
    rx_functional={"can_id": 0x6FE})

# configure CAN Transport Interface for this CAN Node
can_transport_interface = uds.transport_interface.PyCanTransportInterface(
    can_bus_manager=python_can_interface,
    addressing_information=can_node_addressing_information,
    n_as_timeout=50,
    n_ar_timeout=900,
    n_bs_timeout=50,
    n_br=10,
    n_cs=0,
    n_cr_timeout = 900,
    dlc=0xF,
    use_data_optimization=True,
    filler_byte=0x55,
    flow_control_parameters_generator=uds.can.DefaultFlowControlParametersGenerator(st_min=0,
                                                                                    block_size=5,
                                                                                    wait_count=0,
                                                                                    repeat_wait=False))

# change CAN Transport Interface configuration
can_transport_interface.n_as_timeout = uds.transport_interface.PyCanTransportInterface.N_AS_TIMEOUT
can_transport_interface.n_ar_timeout = uds.transport_interface.PyCanTransportInterface.N_AR_TIMEOUT
can_transport_interface.n_bs_timeout = uds.transport_interface.PyCanTransportInterface.N_BS_TIMEOUT
can_transport_interface.n_br = uds.transport_interface.PyCanTransportInterface.DEFAULT_N_BR
can_transport_interface.n_cs = uds.transport_interface.PyCanTransportInterface.DEFAULT_N_CS
can_transport_interface.n_cr_timeout = uds.transport_interface.PyCanTransportInterface.N_CR_TIMEOUT
can_transport_interface.dlc = 8
can_transport_interface.use_data_optimization = False
can_transport_interface.filler_byte = 0xAA
can_transport_interface.flow_control_parameters_generator = uds.can.DefaultFlowControlParametersGenerator(
    st_min=100,
    block_size=15,
    wait_count=1,
    repeat_wait=True)

Synchronous communication

Warning

Synchronous and asynchronous implementation shall not be mixed, therefore for transmitting and receiving UDS Messages and CAN Packets use either:

or

Send Message

Once an object of PyCanTransportInterface class is created, use send_message() method to receive UDS messages over CAN.

Example code:

# let's assume that we have `can_transport_interface` already configured as presented in configuration example above

# define some UDS message to send
message = uds.message.UdsMessage(addressing_type=uds.transmission_attributes.AddressingType.PHYSICAL,
                                 payload=[0x10, 0x03])

# send UDS Message and receive UDS message record with historic information about the transmission
message_record = can_transport_interface.send_message(message)

Receive Message

Once an object of PyCanTransportInterface class is created, use receive_message() method to receive UDS messages over CAN.

Example code:

# let's assume that we have `can_transport_interface` already configured as presented in configuration example above

# receive an UDS message with timeout set to 1000 ms
message_record = can_transport_interface.receive_message(timeout=1000)

Send Packet

Once an object of PyCanTransportInterface class is created, use send_packet() method to send CAN packets.

Example code:

# let's assume that we have `can_transport_interface` already configured as presented in configuration example above

# define some UDS message to send
message = uds.message.UdsMessage(addressing_type=uds.transmission_attributes.AddressingType.PHYSICAL,
                                 payload=[0x10, 0x03])

# segment the message to create a CAN packet
can_packet = can_transport_interface.segmenter.segmentation(message)[0]

# send CAN packet and receive CAN packet record with historic information about the transmission and the transmitted CAN packet
can_packet_record = can_transport_interface.send_packet(can_packet)

Receive Packet

Once an object of PyCanTransportInterface class is created, use receive_packet() method to receive CAN packets.

Example code:

# let's assume that we have `can_transport_interface` already configured as presented in configuration example above

# receive a CAN packet with timeout set to 1000 ms
can_packet_record = can_transport_interface.receive_packet(timeout=1000)

Asynchronous communication

Warning

Synchronous and asynchronous implementation shall not be mixed, therefore for transmitting and receiving UDS Messages and CAN Packets use either:

or

Note

In all examples, only a coroutine code was presented. If you need a manual how to run an asynchronous code, visit https://docs.python.org/3/library/asyncio-runner.html#running-an-asyncio-program.

Send Message

Once an object of PyCanTransportInterface class is created, use async_send_message() method to receive UDS messages over CAN.

Example code:

# let's assume that we have `can_transport_interface` already configured as presented in configuration example above

# define some UDS message to send
message = uds.message.UdsMessage(addressing_type=uds.transmission_attributes.AddressingType.PHYSICAL,
                                 payload=[0x10, 0x03])

# send UDS Message and receive UDS message record with historic information about the transmission
message_record = await can_transport_interface.async_send_message(message)

Receive Message

Once an object of PyCanTransportInterface class is created, use async_receive_message() method to receive UDS messages over CAN.

Example code:

# let's assume that we have `can_transport_interface` already configured as presented in configuration example above

# receive an UDS message with timeout set to 1000 ms
message_record = await can_transport_interface.async_receive_message(timeout=1000)

Send Packet

Once an object of PyCanTransportInterface class is created, use async_send_packet() method to send CAN packets.

Example code:

# let's assume that we have `can_transport_interface` already configured as presented in configuration example above

# define some UDS message to send
message = uds.message.UdsMessage(addressing_type=uds.transmission_attributes.AddressingType.PHYSICAL,
                                 payload=[0x10, 0x03])

# segment the message to create a CAN packet
can_packet = can_transport_interface.segmenter.segmentation(message)[0]

# send CAN packet and receive CAN packet record with historic information about the transmission and the transmitted CAN packet
can_packet_record = await can_transport_interface.async_send_packet(can_packet)

Receive Packet

Once an object of PyCanTransportInterface class is created, use async_receive_packet() method to receive CAN packets.

Example code:

# let's assume that we have `can_transport_interface` already configured as presented in configuration example above

# receive a CAN packet with timeout set to 1000 ms
can_packet_record = await can_transport_interface.async_receive_packet(timeout=1000)