1 # Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
3 @page canbus_usecase3 CAN Interpreter
5 ## CAN Interpreter Module workflow
9 The interpreter module for DBC format is initialized as follows:
12 dwCANInterpreterHandle_t interpreter;
13 dwCANInterpreter_buildFromDBC(&interpreter, "path/to/definition.dbc", ...);
16 The DBC message and signals definition file will be parsed to initialize
17 the interpreter. Please refer to a DBC file format documentation for additional
18 details on the expected syntax.
20 An interpreter for user-defined format is initialized as follows:
23 dwCANInterpreterInterface interpreter;
25 // following callbacks to be implemented by user
26 interpreter.addMessage = cb_addMessage;
27 interpreter.getDataf32 = cb_getDataf32;
28 interpreter.getDataf64 = cb_getDataf64;
29 interpreter.getDatai32 = cb_getDatai32;
30 interpreter.getNumAvailableSignals = cb_getNumAvailableSignals;
31 interpreter.getSignalInfo = cb_getSignalInfo;
33 dwCANInterpreter_buildFromCallbacks(&canParser, interpreter, NULL, ...);
36 The `dwCANInterpreterInterface` structure is populated with pointers
37 to the callbacks implemented by the user. The expected callback signatures are
38 detailed in Interpreter.h. The callbacks are used as follows:
40 - `dwCANInterpreterInterface.addMessage` gets called with a `dwCANMessage` to be interpreted
41 - `dwCANInterpreterInterface.getNumAvailableSignals` and `dwCANInterpreterInterface.getSignalInfo` are used to extract signals from CAN messages
42 - `dwCANInterpreterInterface.getDataf32`, `dwCANInterpreterInterface.getDataf64` and `dwCANInterpreterInterface.getDatai32` are used to read the corresponding signal type data from each message
44 The following callbacks are required to be implemented:
47 - `getNumAvailableSignals`
50 The following callbacks are optional and have to be implemented only
51 if a signal data type requires them:
57 An example implementation of those callbacks is provided in @ref dwx_canbus_message_sample
59 ### Consuming messages
61 CAN messages can be provided to the interpreter for parsing as follows:
64 dwCANInterpreter_consume(&msg, interpreter);
71 dwStatus status = dwCANInterpreter_getNumberSignals(&num, interpreter);
73 if (status == DW_SUCCESS && num > 0)
75 int32_t int_value = 0;
76 float32_t float_value = 0;
77 dwTime_t timestamp = 0;
81 for (uint32_t i = 0; i < num; ++i)
84 if (dwCANInterpreter_getSignalName(&name, i, interpreter) == DW_SUCCESS)
86 // do something based on signal name
87 if (strcmp(name, "some_signal_int") == 0)
89 if (dwCANInterpreter_geti32(&int_value, ×tamp, i, interpreter) == DW_SUCCESS)
90 std::cout << "some_signal_int value: " << int_value << std::endl;
92 std::cerr << "error getting value for some_signal_int" << std::endl;
94 elseif (strcmp(name, "some_signal_float") == 0)
96 if (dwCANInterpreter_getf32(&float_value, ×tamp, i, interpreter) == DW_SUCCESS)
97 std::cout << "some_signal_float value: " << float_value << std::endl;
99 std::cerr << "error getting value for some_signal_float" << std::endl;
101 else std::cerr << "unhandled signal name" << std::endl;
107 The above snippet iterates over all signals handled by the intepreter, and
108 attempts to read a value for each signal, in the latest consumed `dwCANMessage`.
110 Note that in general the number of signals as returned by
111 `dwCANInterpreter_getNumberSignals()` is the number of valid signals found
112 in last consumed CAN message. However this does not have to be true in
113 user-provided callback based interpreters, as it is implementation dependent.
115 ### Releasing the interpreter
117 The interpreter can be released as follows:
120 dwCANInterpreter_release(&interpreter);
123 For more details see @ref dwx_canbus_message_sample