CAN in - CAN input mailbox

The CAN_in block implements an input mailbox that supports receiving messages using the CAN bus protocol. To send messages, the CAN out block should be used instead. The supported CAN protocol variants are as follows:

  • CAN 2.0A: standard format (11-bit identifier), up to 8 bytes payload
  • CAN 2.0B: extended format (29-bit identifier), up to 8 bytes payload
  • CAN FD: standard and extended format, up to 64 bytes payload

CAN 2.0A/B are supported on all imperix controllers, provided that the related hardware exists. However, CAN FD (flexible data) is only supported on the B-Box 4. The detailed compatibility list is shown below.

CANopen is a high-level protocol (OSI layer 7), which should not be confused with CAN (OSI layers 1 and 2). It is currently not supported on imperix equipment.

ControllerHardware resourcesCAN 2.0ACAN 2.0BCAN FD
B-Box 42x channels (one RJ45 socket for each)
Max. 5 Mbps (FD)
YesYesYes
B-Box 3 (RCP)1x channel (one RJ45 socket)
Max. 1 Mbps
YesYesNo
B-Board 3 (PRO)1x channel (Tx/Rx pins or D-sub on EVM)
Max. 1 Mbps
YesYesNo
B-Box microN/ANoNoNo
TPI 80321x channel (two common RJ45 sockets)
Max. 1 Mbps
YesYesNo
Supported variants of the CAN protocol on imperix controllers

Parameters

Addressing

  • Physical port: selects the port on which the mailbox operate. Port B is only available for B-Box 4. For all the other devices, Port A must be selected.
  • Frame format: selects between Standard (11-bit identifier) and Extended (29-bit identifier).
  • Identifier (ID): sets the CAN identifier.

Communication parameters

  • Signal(s) type: defines the data type accepted in the data input (int8, int16, int32, uint8, uint16, uint32, float32, or float64).
  • Number of signals: specifies the vector size of the data to be sent.
  • Byte order: defines the byte order in which the data will be sent. Either little-endian or big-endian.
  • Data transmission mode: selects when the data is sent.
    • On-demand: the user manually triggers the message transmissions.
    • Periodically: the message is sent periodically, whether the data has been changed or not.
  • Initial value: sets the initial data value of the data output before any data are received.

CAN bus configuration

In Simulink, the CAN bus configuration is performed from within the CAN block. In PLECS, the configuration is performed in the Target tab of Coder options windows (Coder -> Coder options, or Ctrl+Alt+B).

  • The bitrate is the rate at which bits are transmitted on the bus (up to 1 Mbps),
  • The data bitrate is the increased bitrate used to transmit the CAN FD frame payload when the Bit Rate Switch (BRS) is enabled (up to 5 Mbps).
CAN bus configuration in Simulink
CAN bus configuration in PLECS

Simulink block

Signal specification

  • The data output signal returns a vector containing the data read from the CAN bus. The vector length can be configured with the  Number of signals parameter. The output data type is configured by the Signal type parameter.
  • The second signal is the data valid output. It is set to 1 each time new data are available.

Mask

PLECS block

Signal specification

  • The data output signal returns a vector containing the data read from the CAN bus. The vector length can be configured with the  Number of signals parameter. The output data type is configured by the Signal type parameter.
  • The second signal is the data valid output. It is set to 1 each time new data are available.

Mask

C++ functions

Standard functions

void Can_ConfigureCanBus(unsigned int bitrate, tCanPort can_port, bool canfd, 
unsigned int dataBitrate);Code language: C++ (cpp)

Configures the CAN bus.

Can only be called in UserInit().

Parameters

  • bitrate: transfer rate of the CAN bus in bits/s (up to 1 Mbit/s)
  • can_port: CAN port to configure (CAN_A or CAN_B)
  • canfd: enable CAN FD mode (false = classic CAN, true = CAN FD)
  • dataBitrate: transfer rate of the data phase for CAN FD (only used if canfd = true, up to 5 Mbit/s)
bool Can_ConfigureInputMailbox(unsigned int maildboxId, unsigned int canIdentifier, 
unsigned int dataLength, tEndianness endianness, bool extended, tCanPort can_port);Code language: C++ (cpp)

Configures a CAN input mailbox.

Can only be called in UserInit().

Parameters

  • mailboxId: a CAN input mailbox unique identifier. This ID must be unique throughout all UDP and CAN input/output mailboxes
  • canIdentifier: the identifier of the CAN input mailbox. The CAN identifier range is 0 to 2047
  • dataLength: number of bytes of data to read from the CAN bus (1 to 8 bytes)
  • endianness: defines the bytes order (BIG_ENDIAN or LITTLE_ENDIAN)
  • extended: enable the extended frame format (true = 29-bit identifier, false = 11-bit identifier)
  • can_port: the target CAN port (CAN_A or CAN_B)

Return value

  • Returns false if the maximum input mailbox limit is reached or if the canIdentifier is invalid.
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, void *data, int size);Code language: C++ (cpp)

Configures the initial value returned by the Can_Read() function before any CAN frame is received in the mailbox.

Can only be called in UserInit().

Parameters

  • mailboxId: the CAN input mailbox unique identifier
  • data: pointer to the default data returned by Can_Read() before the arrival of data on the CAN input mailbox
  • size: number of bytes of the default data (1 to 8 bytes)
int Can_Read(unsigned int maildboxId, void* data, int size);Code language: C++ (cpp)

Reads data from the input mailbox. The stored value persists until overwritten by a subsequent data read.

Can only be called in the interrupt routine.

Parameters

  • mailboxId: the CAN input mailbox unique identifier
  • data: pointer to the buffer where data read from the CAN bus will be stored
  • size: number of bytes of data to read (must correspond to the configured dataLength the selected mailbox

Return value

  • Returns 1 if a new data is available since the previous read operation, returns 0 otherwise.

Example of use

This example shows how to configure and use CAN Port A in Classic CAN mode with a baud rate of 1 Mb/s. Two mailboxes are initialized using an unique ID of 0 and 1, a CAN identifier of 128 and 129, and a fixed data length of 8 bytes and 8 bytes (total size of the structure).

Upon receipt of data, it can be read and stored into an array (or any other data type or structure) as long as it matches the data length defined in the configuration.

#define MAILBOX_ID_A   0
#define MAILBOX_ID_B   1
#define CAN_ID_A       128
#define CAN_ID_B       129

uint8_t data_a[8];

struct {
  float   field_0;
  uint8_t field_1;
} data_b;

tUserSafe UserInit(void)
{
  Can_ConfigureCanBus(1000000, CAN_A, false, 0);
  Can_ConfigureInputMailbox(MAILBOX_ID_A, CAN_ID_A, sizeof(data_a), LITTLE_ENDIAN, false, CAN_A);
  Can_ConfigureInputMailbox(MAILBOX_ID_B, CAN_ID_B, sizeof(data_b), LITTLE_ENDIAN, false, CAN_A);
  return SAFE;
}
 
tUserSafe UserInterrupt(void)
{
  Can_Read(MAILBOX_ID_A, (void *)data_a, sizeof(data_a));
  Can_Read(MAILBOX_ID_B, (void *)&data_b, sizeof(data_b));

  return SAFE;
}Code language: C++ (cpp)

Legacy functions

// 64-bit (8 bytes) types: uint64, int64 and double
int Can_Read(unsigned int maildboxId, uint64_t& data); //8 bytes
int Can_Read(unsigned int maildboxId, int64_t& data); //8 bytes
int Can_Read(unsigned int maildboxId, double& data); //8 bytesCode language: C++ (cpp)
// 32-bit (4 bytes) types: int32, uint32 and float
// dataLow represents the bytes 0, 1, 2 and 3
// dataHigh represents the bytes 4, 5, 6 and 7
int Can_Read(unsigned int maildboxId, unsigned int& dataLow, unsigned int& dataHigh); //8 bytes
int Can_Read(unsigned int maildboxId, unsigned int& dataLow); //4 bytes
int Can_Read(unsigned int maildboxId, int& dataLow, int& dataHigh); //8 bytes
int Can_Read(unsigned int maildboxId, int& dataLow); //4 bytes
int Can_Read(unsigned int maildboxId, float& dataLow, float& dataHigh); //8 bytes
int Can_Read(unsigned int maildboxId, float& dataLow); //4 bytesCode language: C++ (cpp)
// 16-bit (2 bytes) types: int16 and uint16
// dataLow represents the bytes 0 and 1
// dataMedLow represents the bytes 2 and 3
// dataMedHigh represents the bytes 4 and 5
// dataHigh represents the bytes 6 and 7
int Can_Read(unsigned int maildboxId, uint16_t& dataLow, uint16_t& dataMedLow, uint16_t& dataMedHigh, uint16_t& dataHigh); //8 bytes
int Can_Read(unsigned int maildboxId, uint16_t& dataLow, uint16_t& dataMedLow, uint16_t& dataMedHigh); //6 bytes
int Can_Read(unsigned int maildboxId, uint16_t& dataLow, uint16_t& dataMedLow); //4 bytes
int Can_Read(unsigned int maildboxId, uint16_t& dataLow); //2 bytes
int Can_Read(unsigned int maildboxId, int16_t& dataLow, int16_t& dataMedLow, int16_t& dataMedHigh, int16_t& dataHigh); //8 bytes
int Can_Read(unsigned int maildboxId, int16_t& dataLow, int16_t& dataMedLow, int16_t& dataMedHigh); //6 bytes
int Can_Read(unsigned int maildboxId, int16_t& dataLow, int16_t& dataMedLow); //4 bytes
int Can_Read(unsigned int maildboxId, int16_t& dataLow); //2 bytesCode language: C++ (cpp)
// array of uint8
typedef struct {
  uint8_t data[8];
} tCanMsg;
 
int Can_Read(unsigned int maildboxId, tCanMsg& canMsg); //1 to 8 bytesCode language: C++ (cpp)

Reads data from the input mailbox. The stored value persist until overwritten by a subsequent data read.

Can only be called in the interrupt routine.

Parameters

  • mailboxId: the CAN input mailbox unique identifier
  • data: data read from the input mailbox

Return value

  • Returns 1 if a new data is available since the previous read operation, returns 0 otherwise.
// 64-bit (8 bytes) types: uint64, int64 and double
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, uint64_t data);
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, int64_t data);
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, double data);Code language: C++ (cpp)
// 32-bit (4 bytes) types: int32, uint32 and float
// dataLow represents the bytes 0, 1, 2 and 3
// dataHigh represents the bytes 4, 5, 6 and 7
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, unsigned int dataLow); //4 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, unsigned int dataLow, unsigned int dataHigh); //8 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, int dataLow); //4 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, int dataLow, int dataHigh); //8 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, float dataLow); //4 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, float dataLow, float dataHigh); //8 bytesCode language: C++ (cpp)
// 16-bit (2 bytes) types: int16 and uint16
// dataLow represents the bytes 0 and 1
// dataMedLow represents the bytes 2 and 3
// dataMedHigh represents the bytes 4 and 5
// dataHigh represents the bytes 6 and 7
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, uint16_t dataLow, uint16_t dataMedLow, uint16_t dataMedHigh, uint16_t dataHigh); //8 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, uint16_t dataLow, uint16_t dataMedLow, uint16_t dataMedHigh); //6 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, uint16_t dataLow, uint16_t dataMedLow); //4 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, uint16_t dataLow); //2 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, int16_t dataLow, int16_t dataMedLow, int16_t dataMedHigh, int16_t dataHigh); //8 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, int16_t dataLow, int16_t dataMedLow, int16_t dataMedHigh); //6 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, int16_t dataLow, int16_t dataMedLow); //4 bytes
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, int16_t dataLow); //2 bytes
Code language: C++ (cpp)
// array of uint8
typedef struct {
  uint8_t data[8];
} tCanMsg;
 
void Can_ConfigureInputMailboxInitialValue(unsigned int mailbox_id, tCanMsg &can_msg); //1 to 8 bytesCode language: C++ (cpp)

Configures the initial value returned by the Can_Read() function before any CAN frame is received in the mailbox.

Can only be called in UserInit().

Parameters

  • mailboxId: the CAN input mailbox unique identifier
  • data: default data which will be returned by any call of Can_Read() before the arrival of data on the CAN input mailbox