431 lines
6.9 KiB
Markdown
431 lines
6.9 KiB
Markdown
DBC Parser Documentation
|
|
Overview
|
|
|
|
This module implements a minimal DBC parser intended for use in the FrameTap project.
|
|
|
|
Its purpose is to read a DBC file and convert it into an internal representation that can later be used for:
|
|
|
|
displaying CAN frames and signals
|
|
|
|
building a hierarchical structure for UI
|
|
|
|
integrating with Qt Model/View
|
|
|
|
selecting signals for plotting
|
|
|
|
preparing for runtime CAN/J1939 decoding
|
|
|
|
The implementation intentionally follows the KISS principle:
|
|
|
|
simple
|
|
|
|
readable
|
|
|
|
easy to modify
|
|
|
|
independent from Qt
|
|
|
|
This is not a full DBC parser, but a practical foundation that can be extended gradually.
|
|
Architecture
|
|
|
|
The module uses a simple processing pipeline.
|
|
|
|
DBC file
|
|
↓
|
|
DbcParser
|
|
↓
|
|
DbcDatabase
|
|
↓
|
|
DbcTreeBuilder
|
|
↓
|
|
TreeNode hierarchy
|
|
↓
|
|
Future Qt Model/View integration
|
|
|
|
Each component has a clear responsibility.
|
|
Component Responsibility
|
|
DbcParser Reads and parses the DBC file
|
|
DbcDatabase Stores parsed frames and signals
|
|
DbcTreeBuilder Converts the database into a tree
|
|
TreeNode Represents hierarchical nodes
|
|
|
|
This separation allows the parser to remain independent from UI or visualization logic.
|
|
File Structure
|
|
|
|
The module consists of several logical parts.
|
|
Data structures
|
|
|
|
Files:
|
|
|
|
signal_info.h
|
|
frame_info.h
|
|
dbc_database.h
|
|
|
|
These files define the internal representation of parsed data.
|
|
Tree representation
|
|
|
|
Files:
|
|
|
|
tree_node.h
|
|
tree_node.cpp
|
|
|
|
Defines a simple hierarchical structure that can later be used by UI components.
|
|
Parser
|
|
|
|
Files:
|
|
|
|
dbc_parser.h
|
|
dbc_parser.cpp
|
|
|
|
Responsible for reading the DBC file and extracting frame and signal information.
|
|
Tree builder
|
|
|
|
Files:
|
|
|
|
dbc_tree_builder.h
|
|
dbc_tree_builder.cpp
|
|
|
|
Converts the parsed database into a tree representation.
|
|
Data Structures
|
|
SignalInfo
|
|
|
|
Represents a single signal defined in a DBC file.
|
|
|
|
Fields:
|
|
|
|
name
|
|
startBit
|
|
length
|
|
isLittleEndian
|
|
isSigned
|
|
factor
|
|
offset
|
|
minimum
|
|
maximum
|
|
unit
|
|
receivers
|
|
comment
|
|
|
|
Notes:
|
|
|
|
receivers may contain multiple ECUs
|
|
|
|
comment is optional
|
|
|
|
factor and offset define physical conversion
|
|
|
|
Physical value is calculated as:
|
|
|
|
physical = raw * factor + offset
|
|
|
|
FrameInfo
|
|
|
|
Represents a CAN frame.
|
|
|
|
Fields:
|
|
|
|
name
|
|
canId
|
|
dlc
|
|
transmitter
|
|
comment
|
|
signals
|
|
pgn
|
|
hasPgn
|
|
|
|
Notes:
|
|
|
|
signals is a vector of SignalInfo
|
|
|
|
transmitter is the ECU that sends the frame
|
|
|
|
pgn is derived if the frame appears to follow J1939 rules
|
|
|
|
DbcDatabase
|
|
|
|
Top level container for parsed data.
|
|
|
|
DbcDatabase
|
|
└── vector<FrameInfo>
|
|
|
|
This structure represents the entire DBC file content.
|
|
Tree Representation
|
|
|
|
The module converts the parsed data into a tree.
|
|
|
|
Node types:
|
|
|
|
Root
|
|
Frame
|
|
Signal
|
|
|
|
Example structure:
|
|
|
|
dbc
|
|
├── EngineData
|
|
│ ├── EngineSpeed
|
|
│ ├── OilTemp
|
|
│ └── CoolantTemp
|
|
└── VehicleData
|
|
├── VehicleSpeed
|
|
└── Odometer
|
|
|
|
Each node stores either:
|
|
|
|
FrameInfo
|
|
|
|
SignalInfo
|
|
|
|
This tree structure is designed to integrate easily with Qt Model/View.
|
|
Parser
|
|
|
|
The parser is implemented in:
|
|
|
|
dbc_parser.h
|
|
dbc_parser.cpp
|
|
|
|
It performs line-based parsing of the DBC file.
|
|
|
|
Supported elements:
|
|
|
|
BO_
|
|
SG_
|
|
CM_
|
|
|
|
Supported DBC Syntax
|
|
Frame Definition
|
|
|
|
Example:
|
|
|
|
BO_ 256 EngineData: 8 EEC1
|
|
|
|
Parsed values:
|
|
Field Meaning
|
|
256 CAN identifier
|
|
EngineData frame name
|
|
8 DLC
|
|
EEC1 transmitter ECU
|
|
Signal Definition
|
|
|
|
Example:
|
|
|
|
SG_ EngineSpeed : 0|16@1+ (0.125,0) [0|8000] "rpm" ECU1,ECU2
|
|
|
|
Parsed values:
|
|
Field Meaning
|
|
EngineSpeed signal name
|
|
0 start bit
|
|
16 signal length
|
|
@1 little endian
|
|
+ unsigned
|
|
factor 0.125
|
|
offset 0
|
|
minimum 0
|
|
maximum 8000
|
|
unit rpm
|
|
receivers ECU1, ECU2
|
|
Comments
|
|
|
|
Frame comment:
|
|
|
|
CM_ BO_ 256 "Engine data frame";
|
|
|
|
Signal comment:
|
|
|
|
CM_ SG_ 256 EngineSpeed "Actual engine speed";
|
|
|
|
These values are stored in:
|
|
|
|
FrameInfo::comment
|
|
SignalInfo::comment
|
|
|
|
PGN Extraction
|
|
|
|
PGN is derived using simplified J1939 logic.
|
|
|
|
Typical J1939 identifier layout:
|
|
|
|
Priority
|
|
Reserved
|
|
Data Page
|
|
PDU Format
|
|
PDU Specific
|
|
Source Address
|
|
|
|
The parser extracts PGN from the 29-bit CAN ID.
|
|
|
|
This is a simplified approximation and should not be considered full J1939 validation.
|
|
Example Usage
|
|
|
|
Typical usage:
|
|
|
|
DbcParser parser;
|
|
|
|
DbcDatabase database = parser.ParseFile("example.dbc");
|
|
|
|
DbcTreeBuilder builder;
|
|
|
|
std::unique_ptr<TreeNode> root = builder.Build(database);
|
|
|
|
After this step, the tree can be used by a UI or visualization system.
|
|
Example Tree
|
|
|
|
Example output structure:
|
|
|
|
dbc
|
|
├── EngineData
|
|
│ ├── EngineSpeed
|
|
│ ├── OilTemp
|
|
│ └── CoolantTemp
|
|
└── VehicleData
|
|
├── VehicleSpeed
|
|
└── Odometer
|
|
|
|
Limitations
|
|
|
|
The current implementation intentionally does not support many advanced DBC features.
|
|
|
|
Not supported yet:
|
|
|
|
multiplexed signals
|
|
BA_ attributes
|
|
BA_DEF_ definitions
|
|
VAL_ value tables
|
|
signal groups
|
|
advanced comments
|
|
complex syntax variations
|
|
|
|
These can be added later if required.
|
|
Design Principles
|
|
KISS
|
|
|
|
The parser is intentionally simple.
|
|
|
|
It avoids complex grammar systems and tokenizers in order to keep the code easy to understand and maintain.
|
|
Separation of Concerns
|
|
|
|
Parsing, storage, and tree building are separate components.
|
|
|
|
This makes it easier to:
|
|
|
|
test the parser
|
|
|
|
change UI representation
|
|
|
|
export data
|
|
|
|
reuse the module elsewhere
|
|
|
|
Qt Independence
|
|
|
|
The parser itself does not depend on Qt.
|
|
|
|
Qt integration should be implemented through a separate adapter layer.
|
|
Future Development
|
|
|
|
Recommended evolution path.
|
|
Stage 1 (current)
|
|
|
|
BO_
|
|
SG_
|
|
CM_
|
|
transmitter
|
|
receivers
|
|
basic PGN extraction
|
|
tree representation
|
|
|
|
Stage 2
|
|
|
|
Add:
|
|
|
|
extended CAN ID detection
|
|
better PGN extraction
|
|
TreeNode parent pointer
|
|
Qt Model adapter
|
|
|
|
Stage 3
|
|
|
|
Add support for:
|
|
|
|
VAL_ value tables
|
|
BA_ attributes
|
|
BA_DEF_ definitions
|
|
extended comments
|
|
|
|
Stage 4
|
|
|
|
Advanced functionality:
|
|
|
|
multiplexing
|
|
runtime signal decoding
|
|
integration with CAN stream
|
|
drag-and-drop plotting
|
|
|
|
Intended Usage in FrameTap
|
|
|
|
This module will allow FrameTap to:
|
|
|
|
load DBC files
|
|
display frames and signals
|
|
select signals
|
|
search signals
|
|
display metadata
|
|
prepare runtime decoding
|
|
|
|
Example workflow:
|
|
|
|
Load DBC
|
|
↓
|
|
Browse signals
|
|
↓
|
|
Select signal
|
|
↓
|
|
Decode CAN frames
|
|
↓
|
|
Plot physical values
|
|
|
|
Why Abstract Factory Is Not Used
|
|
|
|
An abstract factory is intentionally not used at this stage.
|
|
|
|
The current structure already separates responsibilities clearly:
|
|
|
|
parser → database → tree builder → tree
|
|
|
|
Introducing factories now would increase complexity without significant benefit.
|
|
|
|
Factories can be added later if multiple internal representations are required.
|
|
Build Integration
|
|
|
|
The module is independent of any specific build system.
|
|
|
|
It can be integrated using:
|
|
|
|
CMake
|
|
qmake
|
|
Makefile
|
|
|
|
Simply add the source files to the project.
|
|
Summary
|
|
|
|
This module provides a minimal but extensible DBC parser designed for FrameTap.
|
|
|
|
Key properties:
|
|
|
|
simple
|
|
modular
|
|
Qt-independent
|
|
extendable
|
|
|
|
It converts a DBC file into an internal structure:
|
|
|
|
frame → signals
|
|
|
|
with additional metadata such as:
|
|
|
|
transmitter
|
|
receivers
|
|
comments
|
|
basic PGN information
|
|
|
|
This forms the foundation for future CAN signal visualization and decoding. |