Loading...
Searching...
No Matches
Protocols::CAN Namespace Reference

Detailed Description

Hand-written rather than a Spirit X3 grammar, though X3 is used elsewhere in the tree:

  • The NS_ block is a bare list of the same tokens as the top-level constructs, so the file is not dispatchable by leading keyword without a stateful "inside NS_" switch.
  • Vendor files carry typos, and the contract is to keep going and name what could not be read (Database::warnings). X3 reports failure as a bool.
  • DBC is line-sensitive in two places and free-form elsewhere, so no single skipper fits.
  • The grammar has no recursion to exploit.

Classes

struct  Attribute
 
struct  AttributeSet
 Attributes attached to one object, with the BA_DEF_DEF_ defaults folded in. More...
 
struct  Database
 
struct  Message
 
struct  Signal
 
struct  ValueDescription
 One entry of a VAL_ / VAL_TABLE_ enumeration. More...
 

Enumerations

enum class  ByteOrder { BigEndian , LittleEndian }
 Bit numbering of a signal inside a frame. More...
 
enum class  ValueType { Unsigned , Signed , Float32 , Double64 }
 How the extracted bits are to be read as a number. More...
 

Functions

Database parseDBC (std::string_view content)
 Parse a DBC held in memory. Never throws; see Database::warnings.
 
Database parseDBCFile (const std::string &path)
 
void applyNodeIdOffset (Database &db, int32_t offset)
 
void applyFloat32Override (Database &db)
 
constexpr int flipBitPos (int p) noexcept
 
uint64_t extractRawBits (const uint8_t *data, int dataSize, int startBit, int length, ByteOrder order) noexcept
 
constexpr int64_t signExtend (uint64_t raw, int length) noexcept
 Interpret length right-aligned bits as a two's-complement number.
 
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.
 
uint64_t rawSignalBits (const Signal &sig, const uint8_t *data, int dataSize) noexcept
 

Variables

constexpr const char * independentSignalMessage = "VECTOR__INDEPENDENT_SIG_MSG"
 
constexpr uint32_t dbcExtendedFlag = 0x80000000u
 Bit 31 of a raw DBC identifier marks a 29-bit (extended) identifier.
 
constexpr uint32_t dbcIdentifierMask = 0x1FFFFFFFu
 

Enumeration Type Documentation

◆ ByteOrder

enum class Protocols::CAN::ByteOrder
strong

Bit numbering of a signal inside a frame.

Enumerator
BigEndian 

@0 in the file. The start bit is the position of the signal's most significant bit, and the following bits run towards the end of the frame.

LittleEndian 

@1 in the file. The start bit is the position of the signal's least significant bit, and the following bits run towards the end of the frame.

◆ ValueType

enum class Protocols::CAN::ValueType
strong

How the extracted bits are to be read as a number.

Enumerator
Unsigned 

+ in the file

Signed 

- in the file, two's complement

Float32 

SIG_VALTYPE_ ... 1.

Double64 

SIG_VALTYPE_ ... 2.

Function Documentation

◆ applyFloat32Override()

void Protocols::CAN::applyFloat32Override ( Database db)

Reinterpret every 32-bit integer signal as an IEEE 754 single.

Opt-in and off by default: it exists for databases that declare a float payload as 32@1- with a (1,0) scaling and no SIG_VALTYPE_ record, which decodes to garbage as written. Signals that already carry an explicit SIG_VALTYPE_ float type are untouched.

◆ applyNodeIdOffset()

void Protocols::CAN::applyNodeIdOffset ( Database db,
int32_t  offset 
)

Shift every message identifier of the database by offset.

See CANSpecificSettings::nodeIdOffset: one vendor DBC hardcodes one node id, and the same file has to serve every device of a chain.

Messages that would leave the identifier space are left untouched and a warning is recorded, rather than silently wrapping onto another device.

◆ extractRawBits()

uint64_t Protocols::CAN::extractRawBits ( const uint8_t *  data,
int  dataSize,
int  startBit,
int  length,
ByteOrder  order 
)
inlinenoexcept

Extract length raw bits of a signal, right-aligned and zero-extended.

Bits that fall outside the frame read as zero rather than out of bounds: a device may legitimately send a frame shorter than the DLC the database declares, and dropping the whole frame over it would lose the signals that are present.

◆ flipBitPos()

constexpr int Protocols::CAN::flipBitPos ( int  p)
constexprnoexcept

Convert a DBC bit position to its "MSB-first sequential" index and back.

DBC numbers bits inside a byte from the LSB (0) to the MSB (7), but a big-endian signal runs from its MSB downwards inside a byte and then continues in the next byte. Flipping the low three bits of the position maps that discontinuous walk onto plain increments: in flipped space, index 0 is the MSB of byte 0, index 7 its LSB, index 8 the MSB of byte 1, and so on.

The mapping is an involution: flipBitPos(flipBitPos(p)) == p.

◆ parseDBCFile()

Database Protocols::CAN::parseDBCFile ( const std::string &  path)

Parse a DBC from disk. On failure the database is empty and a warning explains why.

◆ rawSignalBits()

uint64_t Protocols::CAN::rawSignalBits ( const Signal sig,
const uint8_t *  data,
int  dataSize 
)
inlinenoexcept

The raw, unscaled bits of a signal – what a multiplexer switch is compared against, and what the tests use as an oracle.

Variable Documentation

◆ independentSignalMessage

constexpr const char* Protocols::CAN::independentSignalMessage = "VECTOR__INDEPENDENT_SIG_MSG"
inlineconstexpr

The magic message name under which Vector CANdb++ parks the signals that are defined in the database but not assigned to any frame. It is not a message and must never become part of the node tree.