Update readme
This commit is contained in:
437
README.md
437
README.md
@@ -1,34 +1,431 @@
|
||||
# dbc parser skeleton
|
||||
DBC Parser Documentation
|
||||
Overview
|
||||
|
||||
A minimal DBC parser skeleton for the **FrameTap** project.
|
||||
This module implements a minimal DBC parser intended for use in the FrameTap project.
|
||||
|
||||
The purpose of this module is to read a DBC file and convert it into a simple internal representation that can later be:
|
||||
Its purpose is to read a DBC file and convert it into an internal representation that can later be used for:
|
||||
|
||||
- displayed as a tree
|
||||
- connected to `Qt Model/View`
|
||||
- used for signal selection
|
||||
- extended toward runtime CAN frame decoding
|
||||
displaying CAN frames and signals
|
||||
|
||||
---
|
||||
building a hierarchical structure for UI
|
||||
|
||||
## Overview
|
||||
integrating with Qt Model/View
|
||||
|
||||
The architecture is intentionally simple:
|
||||
selecting signals for plotting
|
||||
|
||||
1. `dbc_parser` reads a DBC file
|
||||
2. parsed data is stored in `DbcDatabase`
|
||||
3. `dbc_tree_builder` converts it into a `TreeNode` hierarchy
|
||||
4. the resulting tree can later be adapted to `QAbstractItemModel`
|
||||
preparing for runtime CAN/J1939 decoding
|
||||
|
||||
This keeps the parser independent from Qt and makes it easier to test and evolve.
|
||||
The implementation intentionally follows the KISS principle:
|
||||
|
||||
---
|
||||
simple
|
||||
|
||||
## Currently supported
|
||||
readable
|
||||
|
||||
### Frame definitions
|
||||
easy to modify
|
||||
|
||||
Supported frame lines:
|
||||
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:
|
||||
|
||||
```text
|
||||
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.
|
||||
Reference in New Issue
Block a user