8.1.1. How to Use the CAN Module
8.1.1.1. How to add a new CAN Message
Add the new CAN message to the symbol file (
tools/dbc/foxbms.sym
).If the message is foxBMS 2 specific prefix it with
foxBMS
.Set the DLC
Add a comment that follows the pattern
Message direction
Comment
transmit
optional comment text (in<file>:<function>, fv:tx) optional comment text
receive
optional comment text (in<file>:<function>, fv:rx) optional comment text
The message direction is specified as seen from the BMS view.
Export the symbol file as dbc file to
tools/dbc/foxbms.dbc
.Declare the callback function for the message in the appropriate file:
Message type
File
cyclic transmit callbacks
src/app/driver/can/cbs/tx-cyclic/can_cbs_tx_cyclic.h
asynchronous transmit callbacks
src/app/driver/can/cbs/tx-async/can_cbs_tx_<my-file-name>.h
receive callbacks
src/app/driver/can/cbs/rx/can_cbs_rx.h
Note 1: every asynchronous transmit callback is implemented in an separate file, that only consists of this one, specific callback.
Note 2: the name callback is kept for the asynchronous transmit callbacks for consistency reasons although they are not callbacks in the classical meaning of the word.
Note 3: Only the transmitted messages are separated in cyclic and asynchronous callbacks, therefore there is only one file for receive callbacks. This file includes the callbacks for the cyclic and asynchronously received messages. The same reason applies for splitting things between asynchronous transmit, cyclic transmit and receive is consistently through the document and code.
Implement a callback in a new file and the accompanying test file/files in the appropriate directories at:
Message type
New file
cyclic transmit callbacks
src/app/driver/can/cbs/tx-cyclic/*
andtests/unit/app/driver/can/cbs/tx-cyclic/*
asynchronous transmit callbacks
src/app/driver/can/cbs/tx-async/*
andtests/unit/app/driver/can/cbs/tx-async/*
receive callbacks
src/app/driver/can/cbs/rx/*
andtests/unit/app/driver/can/cbs/rx/*
Add the message ID and message details
Message type
Declaration file
cyclic transmit callbacks
src/app/driver/config/can_cfg_tx-cyclic-message-definitions.h
asynchronous transmit callbacks
src/app/driver/config/can_cfg_tx-async-message-definitions.h
receive callbacks
src/app/driver/config/can_cfg_rx-message-definitions.h
Add the message to the respective callback array:
Message type |
|
---|---|
cyclic transmit callbacks |
array |
asynchronous transmit callbacks |
The callbacks for asynchronous transmit messages are not stored in some array. These callbacks are only called asynchronously in some specific code paths and so there is no central “processing” function for these callbacks. |
receive callbacks |
array |
Verify that the CAN message is defined and implemented as expected:
PS C:\Users\vulpes\Documents\foxbms-2> .\fox.ps1 run-script tests/can/check_ids.py PS C:\Users\vulpes\Documents\foxbms-2> .\fox.ps1 run-script 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 Cyclic Transmit Message
8.1.1.1.1.1. Creating the Cyclic Transmit Message
In this example a message to transmit the 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) and the message ID 0x220
.
As the message is transmitted (tx
) 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_bms-state.c:CANTX_BmsState, fv:tx)
.
The changed symbol file must be saved and - as changes are applied - the dbc
file must be exported again.
8.1.1.1.1.2. Required Macros
The name of the macros to be implemented in
src/app/driver/config/can_cfg_tx-cyclic-message-definitions.h
need to be
prefixed with CANTX
(as CANTX
is the module prefix) and the message
name in uppercase (BMS_STATE
), i.e., all macro names start with
CANTX_BMS_STATE
.
The message’s
ID with suffix
_ID
,ID type with suffix
_ID_TYPE
,period with suffix
_PERIOD_ms
,phase with suffix
_PHASE_ms
,endianness with suffix
_ENDIANNESS
andDLC with suffix
_DLC
need to be defined through macros:
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 * - data length of the message @{*/
7#define CANTX_BMS_STATE_ID (0x220u)
8#define CANTX_BMS_STATE_ID_TYPE (CAN_STANDARD_IDENTIFIER_11_BIT)
9#define CANTX_BMS_STATE_PERIOD_ms (100u)
10#define CANTX_BMS_STATE_PHASE_ms (0u)
11#define CANTX_BMS_STATE_ENDIANNESS (CAN_BIG_ENDIAN)
12#define CANTX_BMS_STATE_DLC (CAN_DEFAULT_DLC)
13/**@}*/
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
.
1#define CANTX_BMS_STATE_MESSAGE \
2 { \
3 .id = CANTX_BMS_STATE_ID, \
4 .idType = CANTX_BMS_STATE_ID_TYPE, \
5 .dlc = CANTX_BMS_STATE_DLC, \
6 .endianness = CANTX_BMS_STATE_ENDIANNESS, \
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 added to the file
src/app/driver/can/cbs/tx/can_cbs_tx_cyclic.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_bms-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:
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.
PS C:\Users\vulpes\Documents\foxbms-2> .\fox.ps1 run-script tests/can/check_ids.py
PS C:\Users\vulpes\Documents\foxbms-2> .\fox.ps1 run-script tests/can/check_implemented.py
8.1.1.1.2. Example for an Asynchronous Transmit Message
8.1.1.1.2.1. Creating the Asynchronous Transmit Message
In this example a message to asynchronously transmit some debug information on
request is implemented.
The name of the message is therefore DebugResponse
(following PascalCase
naming convention).
In the symbol file the message is implemented as foxBMS_DebugResponse
(prefix foxBMS
followed by the message name) and the message ID 0x227
.
As the message is transmitted (tx
) from the point of view of the BMS, the
comment in the symbol file must be
Message containing some debug information (in:can_cbs_tx_debug-response.c:CANTX_DebugResponse, fv:tx)
.
The changed symbol file must be saved and - as changes are applied - the dbc
file must be exported again.
8.1.1.1.2.2. Required Macros
The name of the macros to be implemented in
src/app/driver/config/can_cfg_tx-async-message-definitions.h
need to be
prefixed with CANTX
(as CANTX
is the module prefix) and the message
name in uppercase (DEBUG_RESPONSE
), i.e., all macro names start with
CANTX_DEBUG_RESPONSE
.
The message’s
ID with suffix
_ID
,ID type with suffix
_ID_TYPE
,endianness with suffix
_ENDIANNESS
andDLC with suffix
_DLC
need to be defined through macros:
1/** CAN message properties for BMS state message. Required properties are:
2 * - Message ID
3 * - Identifier type (standard or extended)
4 * - Endianness of message data
5 * - data length of the message @{*/
6#define CANTX_DEBUG_RESPONSE_ID (0x301u)
7#define CANTX_DEBUG_RESPONSE_ID_TYPE (CAN_STANDARD_IDENTIFIER_11_BIT)
8#define CANTX_DEBUG_RESPONSE_ENDIANNESS (CAN_BIG_ENDIAN)
9#define CANTX_DEBUG_RESPONSE_DLC (CAN_DEFAULT_DLC)
10/**@}*/
8.1.1.1.2.3. Callback Function
The callback declaration must be done in file
src/app/driver/can/cbs/tx-async/can_cbs_tx_debug-response.h
.
1extern STD_RETURN_TYPE_e CANTX_DebugResponse(CANTX_DEBUG_RESPONSE_ACTIONS_e action);
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-async/can_cbs_tx_debug-response.c
.
1extern STD_RETURN_TYPE_e CANTX_DebugResponse(CANTX_DEBUG_RESPONSE_ACTIONS_e action) {
2 STD_RETURN_TYPE_e success = STD_NOT_OK;
3 /* Do message handling stuff */
4 return success;
5}
As last step, the function CANTX_DebugResponse
needs to be called in the
appropriate code path of the user code.
This cannot be covered by the how to as this is too user specific.
See already implemented asynchronous transmitted messages as starting point.
8.1.1.1.2.4. Verification
Run the check scripts to verify that the messages are implemented as described in this how-to.
PS C:\Users\vulpes\Documents\foxbms-2> .\fox.ps1 run-script tests/can/check_ids.py
PS C:\Users\vulpes\Documents\foxbms-2> .\fox.ps1 run-script tests/can/check_implemented.py
8.1.1.1.3. Example for a Receive Message
The implementation of a receive message is done analogous for cyclic transmit
functions, by replacing tx
with rx
in paths, prefixes, function names
etc.
8.1.1.2. Multi-string Support when using Isabellenhuette IVT Current Sensors
In Multi-string systems multiple current sensors must be used in order to measure the current in each string. In case CAN-based Isabellenhuette IVT current sensors are used, the CAN message IDs indicate which current sensor is in which string.
Note
This of course means, that the current sensors must be correctly configured, i.e., that all current sensors in the system use unique CAN messages IDs. Furthermore, the current sensors must be placed in the correct string (accordingly to their CAN message IDs), as otherwise the current measurements would be assigned to the wrong strings.
The string-selection code in the function CANRX_CurrentSensor
right at
the beginning of the function must be adapted as shown in
Listing 8.12.
1 if (message.id <= CANRX_STRING0_ENERGY_COUNTER_ID) {
2 stringNumber = 0u;
3 } else if (message.id <= CANRX_STRING1_ENERGY_COUNTER_ID) {
4 stringNumber = 1u;
5 } else {
6 FAS_ASSERT(FAS_TRAP);
7 }
8.1.1.3. Further Reading
Implementation details of the CAN module are found in CAN.