8.1.1. How to Use the CAN Module

8.1.1.1. How to add a new CAN Message

  1. Add the new CAN message to the symbol file (tools/dbc/foxbms.sym).

    1. If the message is foxBMS 2 specific prefix it with foxBMS.

    2. Set the DLC

    3. Add a comment that follows the pattern

      • optional comment text (in<file>:<function>, fv:tx) optional comment text for files that are transmitted and

      • optional comment text (in<file>:<function>, fv:rx) optional comment text for files that are received as seen by the foxBMS 2 hardware.

  2. Export the symbol file as dbc file.

  3. Declare the callback function in

    • in file src\app\driver\can\cbs\tx\can_cbs_tx.h for the transmit callbacks

    • in file src\app\driver\can\cbs\rx\can_cbs_rx.h for the receive callbacks

  4. Implement a callback. If the message handling suites in any of the existing callback implementation files (src/app/driver/can/cbs/tx/* or respectively src/app/driver/can/cbs/rx/*), implement the callback there, otherwise create a new file (and accompanying test file) and implement the callback there.

  5. Add the message ID and message details:

    • in file src/app/driver/config/can_cfg_tx-message-definitions.h for transmit messages

    • in file src/app/driver/config/can_cfg_rx-message-definitions.h for receive messages

  6. Add the message to the callback array in

    • in file src/app/driver/config/can_cfg_tx.c for transmit messages in the array can_txMessages

    • in file src/app/driver/config/can_cfg_rx.c for receive messages in the array can_rxMessages

  7. Verify that the CAN message is defined and implemented as expected by foxBMS 2 guidelines:

    Listing 8.1 Verify CAN message definition and callback implementation
    C:\Users\vulpes\Documents\foxbms-2>python tests/can/check_ids.py
    C:\Users\vulpes\Documents\foxbms-2>python tests/can/check_implemented.py
    

Warning

These script do no syntactical or similar checks of the implementation. These scripts do text based comparisons in order to help to get a consistent style for the CAN message implementations. The correct implementation etc. must be checked by compiling and debugging.

8.1.1.1.1. Example for a Transmit Message

8.1.1.1.1.1. Creating the Transmit Message

In this example a message to transmit the foxBMS 2 system status is implemented. The name of the message is therefore BmsState (following PascalCase naming convention). In the symbol file the message is implemented as foxBMS_BmsState (prefix foxBMS followed by the message name) with the ID 0x220. As the message is transmitted from the point of view of the BMS, the comment in the symbol file must be Message containing the foxBMS system state (in:can_cbs_tx_state.c:CANTX_BmsState, fv:tx). The new dbc file must be exported.

8.1.1.1.1.2. Required Macros

The name of the macro to be implemented in src/app/driver/config/can_cfg_tx-message-definitions.h needs to be prefixed with CANTX_ID (CANTX is the module prefix) followed by the message name in uppercase (BMS_STATE), i.e., the full macro name is CANTX_BMS_STATE_ID. The macro for the period of the transmitted message must be defined: Module prefix CANTX followed by the message name (BMS_STATE) and the period in milliseconds (PERIOD_ms), i.e., the full macro name is CANTX_BMS_STATE_PERIOD_ms. Last, the macro for the phase of the transmitted message must be defined: Module prefix CANTX followed by the message name (BMS_STATE) and the phase in milliseconds (PHASE_ms) i.e., the full macro name is CANTX_BMS_STATE_PHASE_ms.

Listing 8.2 Adding the new message ID to the transmit message definition file src/app/driver/config/can_cfg_tx-message-definitions.h
 1/** CAN message properties for BMS state message. Required properties are:
 2 * - Message ID
 3 * - Identifier type (standard or extended)
 4 * - Message period and phase in ms
 5 * - Endianness of message data @{*/
 6#define CANTX_BMS_STATE_ID         (0x220u)
 7#define CANTX_BMS_STATE_ID_TYPE    (CAN_STANDARD_IDENTIFIER_11_BIT)
 8#define CANTX_BMS_STATE_PERIOD_ms  (100u)
 9#define CANTX_BMS_STATE_PHASE_ms   (0u)
10#define CANTX_BMS_STATE_ENDIANNESS (CAN_BIG_ENDIAN)
11/**@}*/

Now the details of the ID need to be added in an additional macro, that is then used for the initialization of the transmitted messages macro. The macro must be named Module prefix (CANTX) followed by the message name (BMS_STATE) and suffixed with MESSAGE.

Listing 8.3 Adding the details of the new message ID to the transmit message definition file src/app/driver/config/can_cfg_tx-message-definitions.h
 1#define CANTX_BMS_STATE_MESSAGE                                                \
 2    {                                                                          \
 3        .dlc        = CAN_DEFAULT_DLC,                                         \
 4        .id         = CANTX_BMS_STATE_ID,                                      \
 5        .endianness = CANTX_BMS_STATE_ENDIANNESS,                              \
 6        .idType     = CANTX_BMS_STATE_ID_TYPE,                                 \
 7    },                                                                         \
 8    {                                                                          \
 9        .period = CANTX_BMS_STATE_PERIOD_ms, .phase = CANTX_BMS_STATE_PHASE_ms \
10    }

8.1.1.1.1.3. Callback Function

The callback declaration must be done in file src\app\driver\can\cbs\tx\can_cbs_tx.h.

Listing 8.4 Declaration of the callback function in src\app\driver\can\cbs\tx\can_cbs_tx.h
1extern uint32_t CANTX_BmsState(
2    CAN_MESSAGE_PROPERTIES_s message,
3    uint8_t *pCanData,
4    uint8_t *pMuxId,
5    const CAN_SHIM_s *const kpkCanShim);

The callback definition must be done in the appropriate implementation file, i.e., for the BMS state message in src\app\driver\can\cbs\tx\can_cbs_tx_state.c.

Listing 8.5 Definition of the callback function in src\app\driver\can\cbs\tx\can_cbs_tx_state.c
1extern uint32_t CANTX_BmsState(
2    CAN_MESSAGE_PROPERTIES_s message,
3    uint8_t *pCanData,
4    uint8_t *pMuxId,
5    const CAN_SHIM_s *const kpkCanShim) {
6    /* Do message handling stuff */
7    return 0;
8}

8.1.1.1.1.4. Required Variables Adaptations

The message needs to be added the transmitted messages array as follows:

Listing 8.6 Adding the new message to the registry of transmitted messages src/app/driver/config/can_cfg_tx.c
1const CAN_TX_MESSAGE_TYPE_s can_txMessages[] = {
2    /* other messages */
3    {CAN_NODE_1, CANTX_BMS_STATE_MESSAGE, &CANTX_BmsState, NULL_PTR}, /*!< BMS state */
4};

8.1.1.1.1.5. Verification

Run the check scripts to verify that the messages are implemented as described in this how-to’s guidelines.

Listing 8.7 Verify CAN transmit message definition and callback implementation
C:\Users\vulpes\Documents\foxbms-2>python tests/can/check_ids.py
C:\Users\vulpes\Documents\foxbms-2>python tests/can/check_implemented.py

8.1.1.1.2. Example for a Receive Message

The implementation of a receive message is done analogous, by replacing tx with rx in paths, prefixes, function names etc.

8.1.1.2. Using the CAN4 interface

If the CAN Module should be extended to the CAN4 interface, a workaround for a bug in HALCoGen has to be applied. For details, please refer to HALCoGen tool documentation.

8.1.1.3. Further Reading

Implementation details of the CAN module are found in CAN.