CAN Interfaces

The AutobusGW (ABGW) C24-S6 provides 24 CAN ports on the front panel. It is possible with the ABGW to forward messages between CAN ports and / or TCP ports. This is realized using the concept of virtual busses, or vbus’s. A vbus can have any combination of physical CAN ports as members in addition to a TCP socket. This TCP socket will be a member of the virtual bus and will resemble a virtual CAN port. Clients connecting to this TCP sockets will receive all CAN packets seen on the virtual bus and will be able to send CAN packets which will be forwarded to all members of the vbus.

Fields consisting of multiple bytes, such as can_id, is to be transmitted in little-endian format.

In order to configure the vbus’s, the members CAN ports must also be configured with valid configuration (ex: non-zero bitrate).

Configuration of the CAN subsystem is done using the /can/config API endpoint.

Configuring Physical CAN Ports

The configuration of physical CAN ports is achieved using the array of canconfig struct can_channel_config located under /can/config.

Every array element of can_channel_config contains the configuration of a single CAN/CANFD channel and has the following parameters:

protocol (uint8)
0 -> CAN, 1 -> CANFD capable
bitrate (uint32)
The bitrate in bps to run the CAN interface on.
dbitrate (uint32)
Data bitrate in bps to use in CANFD mode.
restart_ms (uint32)
Automatic restart delay timer in ms in case of BUS OFF condition.
sample_point (float)
Sets the sample point for CAN traffic. A value of zero indicates setting recommended defaults. Valid Range = [0.00 - 0.99].
dsample_point (float)
Sets the sample point for CAN FD traffic. A value of zero indicates setting recommended defaults. Valid Range = [0.00 - 0.99].
sjw (uint32)
Synchronization jump width. A value of zero means system defaults (currenty 1). Valid Range = [1-16]. Note that the actual maximum allowed value will depend on bitrate.
dsjw (uint32)
Data Synchronization jump width. A value of zero means system defaults (currenty 1). Valid Range = [1-16]. Note that the actual maximum allowed value will depend on dbitrate.
non_iso (bool)
Enable non-iso mode for CANFD.
canterm_enabled (bool)
Activates the on-board 120-Ohm CAN termination resistor.
enable_tx_completions (bool)
Activating this option will generate a TX completion (i.e. TX Echo) frame whenever a frame is successfully sent on the CAN bus. The TX completion frame is a copy of the original frame with the field is_txc set to 1. The timestamp inside the txc frame corresponds to the transmission time.
port_index (int)
A zero-based index representing the canport this configruation item relates to. If port_index is omitted, it is assumed that the provided configuration list starts with index 0 and counts upwards.

Starting version 1.1.0, setting protocol to CANFD implies CANFD support, which includes classical CAN Frames.

Starting version 2.3.0, a port will be reconfigured only if it’s configuration is changed. Reloading the same port configuration multiple times will not reset the port if the configuration is unchanged.

Starting version 2.3.1, it is possible to upload a partial array of can_channel_config under /can/config by specifying port_index for every configuration element that needs to be changed. If port_index is specified for one item, it must be specified for all others as well. NOTE: Avoid enabling can ports which are not members of any vbus since this will be ignored. If a can port is enabled without being a member of an enabled vbus, it must be disabled (bitrate=0) and reconfigured for it to get activated.

Virtual Bus (vbus) Configuration

The configuration of vbus’s is achieved using the array of structs can_vbus_config located under /can/config.

Every array element of can_vbus_config contains the configuration of a single vbus and has the following parameters:

vbus_enabled (bool)
set to true in order to enable the vbus.
vbus_id (uint8)
The virtual bus ID number in the range [0-255]. This is used to stretch vbus’s across multiple ABGW devices in a multibox configuration.
bitmask (uint64):
This single integer encodes the CAN port membership information for this vbus. Setting the bit with index i adds can port with index i to this vbus. For example, the value ‘15’ (binary b1111) selects CAN ports 0,1,2,3. Selecting CAN ports 0,1,7 can be achieved with value 131 (binary b1000 0011). Bits which map to non-existent ports on the gateway are ignored.
vbus_index (uint32)
A zero-based index representing the vbus this configruation item relates to. If vbus_index is omitted, it is assumed that the provided configuration list starts with index 0 and counts upwards.
port_indices (array of uint32)
Alternative to bitmask, it is possible to set port membership using a list of zero based port indices. If both bitmask and port_indices are provided, contradicting values are not allowed.
tcp_port (uint32)
The TCP port this vbus will wait for connections on ethernet e0. The IP address is defined using system configuratoin /system/config. This port must be unique.
en_multibox (bool)
Enable this vbus for multibox operation on ethernet port e1.
protocol (uint32)
0 -> CAN, 1 -> CANFD capable. Note: avoid assigning CANFD ports as members of a CAN-only vbus.

Starting version 1.1.0, setting protocol to CANFD implies CANFD support, which includes classical CAN Frames.

Starting version 2.3.1, it is possible to upload a partial array of can_vbus_config under /can/config by specifying vbus_index for every configuration element that needs to be changed. If vbus_index is specified for one item, it must be specified for all others as well. It is also possible to provide a port_indices array instead of a bitmask field.

CAN over TCP

The format of the CAN frames over TCP is the based on the one used in the linux kernel. In case of CAN, the struct can_frame_tcpformat is used which wraps the struct can_frame. In case of CANFD, the struct canfd_frame_tcpformat is used, which wraps struct canfd_frame.

The struct can_frame_tcpformat is defined as follows:

struct can_frame_tcpformat
typedef struct can_frame_tcpformat {
    uint8_t protocol; /*0 for classic CAN*/
    uint8_t is_txc; /*indicates if packet is a tx completion*/
    uint8_t reserved_bytes[2];
    struct {
        uint32_t tv_sec;
        uint32_t tv_usec;
    } hw_timestamp;
    uint32_t reserved[1];
    struct can_frame frame; /*see struct can_frame*/
} can_frame_tcpformat_t;

The struct can_frame is defined as follows:

struct can_frame
struct can_frame {
    canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
    __u8    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
    __u8    __pad;   /* padding */
    __u8    __res0;  /* reserved / padding */
    __u8    __res1;  /* reserved / padding */
    __u8    data[CAN_MAX_DLEN] __attribute__((aligned(8))); /** CAN_MAX_DLEN = 8 */
};

The struct canfd_frame_tcpformat is defined as follows:

struct canfd_frame_tcpformat
typedef struct canfd_frame_tcpformat {
    uint8_t protocol; /*1 for CAN FD*/
    uint8_t is_txc; /*indicates if packet is a tx completion*/
    uint8_t reserved_bytes[2];
    struct {
        uint32_t tv_sec;
        uint32_t tv_usec;
    } hw_timestamp;
    uint32_t reserved[1];
    struct canfd_frame frame; /*see struct canfd_frame*/
} canfd_frame_tcpformat_t;

Please note that the contents of hw_timestamp are ignored in the transmit direction.

The struct canfd_frame is defined as follows:

struct canfd_frame
struct canfd_frame {
    canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
    __u8    len;     /* frame payload length in byte */
    __u8    flags;   /* additional flags for CAN FD */
    __u8    __res0;  /* reserved / padding */
    __u8    __res1;  /* reserved / padding */
    __u8    data[CANFD_MAX_DLEN] __attribute__((aligned(8))); /* CANFD_MAX_DLEN = 64 */
};

The structs are valid for both received and transmitted frames over TCP sockets.