Files
dbc/README.md
2026-03-13 13:14:20 -04:00

479 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DBC Parser Module 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 using simplified J1939 logic
---
## 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 example:
CM_ BO_ 256 "Engine data frame";
Signal comment example:
CM_ SG_ 256 EngineSpeed "Actual engine speed";
Stored in:
- FrameInfo::comment
- SignalInfo::comment
---
# PGN Extraction
PGN is derived using simplified J1939 logic.
Typical identifier layout:
Priority
Reserved
Data Page
PDU Format
PDU Specific
Source Address
The parser extracts PGN from the 29bit CAN identifier.
This is only an approximation and not full J1939 validation.
---
# Example 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
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
- complex syntax variations
These can be added later if required.
---
# Design Principles
## KISS
The parser avoids complex grammar systems or tokenizers in order to keep the code easy to understand and maintain.
## Separation of Concerns
Parsing, storage, and tree building are separate components.
This allows reuse for:
- GUI display
- runtime decoding
- export
- filtering
- testing
## 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
- parent pointer in TreeNode
- 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
- draganddrop plotting
---
# Intended Usage in FrameTap
This module allows 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
Factories can be introduced later if multiple internal representations become necessary.
---
# Build Integration
The module is independent of any specific build system.
It can be integrated using:
- CMake
- qmake
- Makefile
Simply include the source files in your project.
---
# Summary
This module provides a minimal but extensible DBC parser designed for **FrameTap**.
Key properties:
- simple
- modular
- Qtindependent
- extendable
It converts a DBC file into an internal structure:
frame → signals
with metadata such as:
- transmitter
- receivers
- comments
- basic PGN information
This forms the foundation for future CAN signal visualization and decoding.