CAN Transport Interfaces
The implementation for Transport Interfaces that can be used with CAN bus is located in
uds.transport_interface.can_transport_interface.py
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.AbstractCanTransportInterface.__init__()
method.
The following configuration parameters are set then:
Addressing Information of this CAN node - attribute
addressing_information
driver for a CAN bus interface - attribute
bus_manager
communication timeout parameters (N_As, N_Ar, N_Bs, N_Cr) - attributes
n_as_timeout
,n_ar_timeout
,n_bs_timeout
andn_cr_timeout
UDS 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
,
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.
Configuration
Configuration is set upon calling
uds.transport_interface.can_transport_interface.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.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)
# 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
Send Packet
Once an object of PyCanTransportInterface
class is created,
there are two methods which can be used to transmit CAN packets:
send_packet()
- for synchronous implementationasync_send_packet()
- for asynchronous implementation
Example synchronous 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)
Example asynchronous 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)
Note
In the example above, only a coroutine code was presented. If you need a manual how to run an asynchronous program, visit https://docs.python.org/3/library/asyncio-runner.html#running-an-asyncio-program.
Warning
Synchronous and asynchronous implementation shall not be mixed, so use either
send_packet()
and
receive_packet()
(synchronous)
or async_send_packet()
and
async_receive_packet()
(asynchronous)
methods for transmitting and receiving CAN Packets.
Receive Packet
Once an object of PyCanTransportInterface
class is created,
there are two methods which can be used to receive CAN packets:
receive_packet()
- for synchronous implementationasync_receive_packet()
- for asynchronous implementation
Example synchronous 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)
Example asynchronous 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)
Note
In the example above, only a coroutine code was presented. If you need a manual how to run an asynchronous program, visit https://docs.python.org/3/library/asyncio-runner.html#running-an-asyncio-program.
Warning
Synchronous and asynchronous implementation shall not be mixed, so use either
send_packet()
and
receive_packet()
(synchronous)
or async_send_packet()
and
async_receive_packet()
(asynchronous)
methods for transmitting and receiving CAN Packets.