Loading...
Searching...
No Matches
DBCParser.hpp
1#pragma once
2
14#include <cstdint>
15#include <cstring>
16#include <string>
17#include <string_view>
18#include <vector>
19
20namespace Protocols::CAN
21{
22
24enum class ByteOrder
25{
29
33};
34
36enum class ValueType
37{
38 Unsigned,
39 Signed,
40 Float32,
42};
43
46{
47 int64_t value{};
48 std::string name;
49};
50
60{
61 std::string name;
62 std::string value;
63};
64
67{
68 std::vector<Attribute> attributes;
69
71 const std::string* find(std::string_view name) const noexcept;
72};
73
74struct Signal
75{
76 std::string name;
77 std::string unit;
78 std::string comment;
79 std::vector<std::string> receivers;
80
83 int startBit{};
84
86 int length{1};
87
90
91 double factor{1.};
92 double offset{0.};
93 double min{};
94 double max{};
95
98 bool hasRange{};
99
103
107 int64_t multiplexValue{};
108
109 std::vector<ValueDescription> valueTable;
110
111 AttributeSet attributes;
112};
113
115{
119 uint32_t id{};
120
122 bool extended{};
123
124 std::string name;
125 std::string comment;
126 std::string transmitter;
127
129 int size{};
130
131 std::vector<Signal> signals;
132
133 AttributeSet attributes;
134
135 const Signal* findSignal(std::string_view name) const noexcept;
136};
137
139{
140 std::vector<Message> messages;
141
143 std::string comment;
144
146 std::string version;
147
148 AttributeSet attributes;
149
154 std::vector<std::string> warnings;
155
156 const Message* findMessage(uint32_t id, bool extended) const noexcept;
157};
158
162inline constexpr const char* independentSignalMessage = "VECTOR__INDEPENDENT_SIG_MSG";
163
165inline constexpr uint32_t dbcExtendedFlag = 0x80000000u;
166inline constexpr uint32_t dbcIdentifierMask = 0x1FFFFFFFu;
167
169Database parseDBC(std::string_view content);
170
173Database parseDBCFile(const std::string& path);
174
186constexpr int flipBitPos(int p) noexcept
187{
188 return (p & ~7) | (7 - (p & 7));
189}
190
199inline uint64_t extractRawBits(
200 const uint8_t* data, int dataSize, int startBit, int length,
201 ByteOrder order) noexcept
202{
203 if(length <= 0 || length > 64)
204 return 0;
205
206 const int frameBits = dataSize * 8;
207 uint64_t out = 0;
208
209 // Walk the value from its MSB down to its LSB, so that each step is a plain
210 // shift-in. `k` is the significance of the bit being read.
211 for(int k = length - 1; k >= 0; --k)
212 {
213 int pos;
214 if(order == ByteOrder::LittleEndian)
215 {
216 // The start bit is the LSB and significance grows with the position.
217 pos = startBit + k;
218 }
219 else
220 {
221 // The start bit is the MSB; significance grows *backwards* along the
222 // flipped axis, on which the signal's bits are contiguous.
223 pos = flipBitPos(flipBitPos(startBit) + (length - 1 - k));
224 }
225
226 out <<= 1;
227 if(pos >= 0 && pos < frameBits)
228 out |= uint64_t((data[pos >> 3] >> (pos & 7)) & 1u);
229 }
230
231 return out;
232}
233
235constexpr int64_t signExtend(uint64_t raw, int length) noexcept
236{
237 if(length <= 0 || length >= 64)
238 return int64_t(raw);
239
240 const uint64_t signBit = uint64_t(1) << (length - 1);
241 if(raw & signBit)
242 return int64_t(raw | ~((uint64_t(1) << length) - 1));
243 return int64_t(raw);
244}
245
247inline double decodeSignal(const Signal& sig, const uint8_t* data, int dataSize) noexcept
248{
249 const uint64_t raw
250 = extractRawBits(data, dataSize, sig.startBit, sig.length, sig.byteOrder);
251
252 double physical{};
253 switch(sig.valueType)
254 {
255 case ValueType::Float32: {
256 const auto bits = uint32_t(raw);
257 float f{};
258 std::memcpy(&f, &bits, sizeof(f));
259 physical = double(f);
260 break;
261 }
262 case ValueType::Double64: {
263 double d{};
264 std::memcpy(&d, &raw, sizeof(d));
265 physical = d;
266 break;
267 }
269 physical = double(signExtend(raw, sig.length));
270 break;
272 physical = double(raw);
273 break;
274 }
275
276 return physical * sig.factor + sig.offset;
277}
278
281inline uint64_t
282rawSignalBits(const Signal& sig, const uint8_t* data, int dataSize) noexcept
283{
284 return extractRawBits(data, dataSize, sig.startBit, sig.length, sig.byteOrder);
285}
286
296void applyNodeIdOffset(Database& db, int32_t offset);
297
306void applyFloat32Override(Database& db);
307
308}
Definition DBCParser.cpp:26
constexpr uint32_t dbcExtendedFlag
Bit 31 of a raw DBC identifier marks a 29-bit (extended) identifier.
Definition DBCParser.hpp:165
constexpr int flipBitPos(int p) noexcept
Definition DBCParser.hpp:186
Database parseDBC(std::string_view content)
Parse a DBC held in memory. Never throws; see Database::warnings.
Definition DBCParser.cpp:1379
Database parseDBCFile(const std::string &path)
Definition DBCParser.cpp:1400
void applyNodeIdOffset(Database &db, int32_t offset)
Definition DBCParser.cpp:1420
double decodeSignal(const Signal &sig, const uint8_t *data, int dataSize) noexcept
Extract one signal from a frame and apply its value type, factor and offset.
Definition DBCParser.hpp:247
uint64_t extractRawBits(const uint8_t *data, int dataSize, int startBit, int length, ByteOrder order) noexcept
Definition DBCParser.hpp:199
constexpr const char * independentSignalMessage
Definition DBCParser.hpp:162
ByteOrder
Bit numbering of a signal inside a frame.
Definition DBCParser.hpp:25
ValueType
How the extracted bits are to be read as a number.
Definition DBCParser.hpp:37
@ Float32
SIG_VALTYPE_ ... 1.
@ Signed
- in the file, two's complement
@ Double64
SIG_VALTYPE_ ... 2.
constexpr int64_t signExtend(uint64_t raw, int length) noexcept
Interpret length right-aligned bits as a two's-complement number.
Definition DBCParser.hpp:235
void applyFloat32Override(Database &db)
Definition DBCParser.cpp:1443
uint64_t rawSignalBits(const Signal &sig, const uint8_t *data, int dataSize) noexcept
Definition DBCParser.hpp:282
Definition DBCParser.hpp:60
Attributes attached to one object, with the BA_DEF_DEF_ defaults folded in.
Definition DBCParser.hpp:67
const std::string * find(std::string_view name) const noexcept
nullptr when the attribute is neither set nor defaulted.
Definition DBCParser.cpp:28
Definition DBCParser.hpp:139
std::string comment
CM_ "..." at file scope.
Definition DBCParser.hpp:143
std::string version
DBC "VERSION" record.
Definition DBCParser.hpp:146
std::vector< std::string > warnings
Definition DBCParser.hpp:154
Definition DBCParser.hpp:115
bool extended
Bit 31 of the raw DBC identifier.
Definition DBCParser.hpp:122
int size
Declared payload length in bytes (the DBC "DLC").
Definition DBCParser.hpp:129
Definition DBCParser.hpp:75
bool isMultiplexed
Definition DBCParser.hpp:106
bool isMultiplexer
Definition DBCParser.hpp:102
bool hasRange
Definition DBCParser.hpp:98
int length
1 to 64.
Definition DBCParser.hpp:86
int startBit
Definition DBCParser.hpp:83
One entry of a VAL_ / VAL_TABLE_ enumeration.
Definition DBCParser.hpp:46