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:
Addressing Information of this CAN node - attribute
addressing_informationdriver for a CAN bus interface - attribute
bus_managercommunication timeout parameters (N_As, N_Ar, N_Bs, N_Cr) - attributes
n_as_timeout,n_ar_timeout,n_bs_timeoutandn_cr_timeoutUDS message segmentation parameters (base DLC of a CAN frame, flag whether to use data optimization for CAN frame, and the value to use for CAN frame data padding) - attributes
dlc,use_data_optimization,filler_byte,Flow Control generator - attribute
flow_control_parameters_generator
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_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:
send_message()receive_message()send_packet()receive_packet()
or
async_send_message()async_receive_message()async_send_packet()async_receive_packet()
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:
send_message()receive_message()send_packet()receive_packet()
or
async_send_message()async_receive_message()async_send_packet()async_receive_packet()
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)