dbcppp DBC File Parser

repository·master·Indexed 43 days ago

https://github.com/xr3b0rn/dbcppp

A high-performance C/C++ DBC and KCD file parser built on boost.spirit for fast decoding of CAN messages. It includes a C API for network and signal manipulation, as well as CLI tools for converting DBC files to C source or human-readable formats via the dbc2 subprogram and decoding candump-style traffic via the decode subprogram.

Tokens
2.2K
Snippets
6
Records
11
Agent score
55%

What's inside dbcppp

  1. Overview of Boost.Spirit libraries

    master
    Boost.Spirit is a set of C++ libraries designed for parsing and output generation. It uses Domain Specific Embedded Languages (DSEL) implemented via Expression templates and Template Meta-Programming. This allows developers to write target grammars directly in C++, mixing grammar specifications with standard C++ code that is immediately executable.
  2. Use Spirit.X3 for fast parsing

    master

    Spirit.X3 is the 3rd generation of Spirit. It is optimized for faster compile times and currently functions exclusively as a parser framework.

    Important Compatibility Notes:

    • Support for C++14 compilers is being deprecated.
    • Recent versions (starting from Boost 1.81) require C++17 features.

    Supported Compilers:

    • Clang 4 (minimum)
    • GCC 7 (minimum)
    • VS 2017 v15.8 (minimum)
  3. Use Spirit V2 for comprehensive data manipulation

    master

    Spirit V2 is the 2nd generation and serves as the Long Term Support (LTS) version. It is a versatile toolkit for data manipulation on various input types and consists of three main frameworks:

    • Qi: A parser framework.
    • Karma: A generator framework.
    • Lex: A lexical analyzer framework.

    Spirit V2 is compatible with most C++03 compilers (e.g., GCC 4.1, Clang 3.0, VS 2005).

  4. Build and install dbcppp

    master

    To build and install dbcppp from source, use CMake to generate build files, then compile and install. Ensure you include submodules during the clone process.

    git clone --recurse-submodules https://github.com/xR3b0rn/dbcppp.git
    cd dbcppp
    mkdir build
    cd build
    cmake -DCMAKE_BUILD_TYPE=Release ..
    make -j
    make RunTests
    make install
    ldconfig # on Unix-systems only
    git clone --recurse-submodules https://github.com/xR3b0rn/dbcppp.git
    cd dbcppp
    mkdir build
    cd build
    cmake -DCMAKE_BUILD_TYPE=Release ..
    make -j
    make RunTests
    make install
    ldconfig
  5. Use the dbcppp C API

    master

    The C API provides a procedural interface for interacting with DBC files.

    Key functions:

    • dbcppp_NetworkLoadDBCFromFile(const char*): Loads a network.
    • dbcppp_NetworkMessages_Size(net) and dbcppp_NetworkMessages_Get(net, index): Access messages.
    • dbcppp_MessageId(msg): Retrieves the message ID.
    • dbcppp_MessageForEachSignal(msg, callback, user_data): Iterates through signals using a callback.
    • dbcppp_SignalDecode(sig, data): Decodes the raw signal value.
    • dbcppp_SignalRawToPhys(sig, raw): Converts raw value to physical value.
    • dbcppp_NetworkFree(net): Releases network resources.
    #include <stdio.h>
    #include <dbcppp/CApi.h>
    
    int main()
    {
        const dbcppp_Nework* net = dbcppp_NetworkLoadDBCFromFile("your.dbc");
        if (net)
        {
            can_frame frame;
            while (1)
            {
                receive_can_frame_from_somewhere(&frame);
                auto n_msgs = dbcppp_NetworkMessages_Size(net);
                for (uint64_t i = 0; i < n_msgs; i++)
                {
                    const dbcppp_Message* msg = dbcppp_NetworkMessages_Get(net, i);
                    if (dbcppp_MessageId(msg) == frame.can_id)
                    {
                        printf("Received message: %s\n", dbcppp_MessageGetName(msg));
                        dbcppp_MessageForEachSignal(msg, print_signal_data, &frame);
                        for (uint64_t j = 0; j < dbcppp_MessageSignals_Size(msg); j++)
                        {
                            const dbcppp_Signal* sig = dbcppp_MessageSignals_Get(msg, j);
                            uint64_t raw = dbcppp_SignalDecode(sig, frame.data);
                            double phys = dbcppp_SignalRawToPhys(sig, raw);
                            printf("\t%s=%f\n", dbcppp_SignalName(sig), phys);
                        }
                    }
                }
            }
        }
        dbcppp_NetworkFree(net);
    }
  6. Supported DBC data types

    master

    The following DBC components are currently supported by the parser:

    • version
    • new_symbols
    • bit_timing
    • nodes
    • value_tables
    • messages
    • message_transmitters
    • environment_variables
    • environment_variables_data
    • signal_types
    • comments
    • attribute_definitions
    • attribute_defaults
    • attribute_values
    • value_descriptions
    • signal_extended_value_type_list
    • signal_groups
    • signal_multiplexer_value

    Note: sigtype_attr_list and signal_type_refs are not yet supported.

  7. Decode CAN traffic via CLI

    master

    You can perform cantools-like decoding by piping candump output directly into the dbcppp decode command. You can specify multiple buses and their corresponding DBC/KCD files.

    candump any | dbcppp decode --bus=vcan0,file1.dbc --bus=vcan1,file2.dbc
    candump any | dbcppp decode --bus=vcan0,file1.dbc --bus=vcan1,file2.dbc
  8. Use the dbc2 command for DBC/KCD processing

    master

    The dbc2 subcommand of the dbcparser CLI tool allows you to perform several tasks with DBC and KCD files:

    • Generate C source: Convert DBC/KCD files into C source code.
    • Merge or Beautify: Merge two files (DBC or KCD) or format them.
    • Human Readable Print: Output the contents of DBC/KCD files in a readable format.
    # generate C source from DBC/KCD
    dbcparser dbc2 --dbc=file.dbc --format=C
    
    # beauty or merge DBC/KCD
    dbcparser dbc2 --dbc=file1.dbc --dbc=file2.kcd --format=DBC
    
    # print DBC/KCD in human readable format
    dbcparser dbc2 --dbc=file1.dbc --dbc=file2.kcd --format=human
    dbcparser dbc2 --dbc=file.dbc --format=C
  9. Use the dbc2 subprogram to convert DBC files

    master

    The dbc2 subprogram allows you to convert DBC files into different formats: C source code, DBC format (for beautifying or merging), or a human-readable format. You must specify the output format and provide at least one DBC file.

    Options:

    • --format=<format>: Specifies the output format. Supported values are C, DBC, or human.
    • --dbc=<dbc filename>: One or more DBC files to process.
    • --help: Displays help information for the dbc2 subprogram.
    # Example: Convert a DBC file to C source code
    dbcppp dbc2 --format=C --dbc=my_network.dbc
    
    # Example: Convert multiple DBC files and merge them into human-readable format
    dbcppp dbc2 --format=human --dbc=file1.dbc --dbc=file2.dbc
  10. Use the decode subprogram to parse CAN traffic

    master

    The decode subprogram reads candump-style lines from standard input and decodes them using provided DBC files. It maps bus names in the input stream to specific DBC files.

    Input Format: The subprogram expects lines in the candump format: [bus name] [msg id] [data length] [data bytes...] (e.g., vcan0 123 [3] 11 22 33).

    Options:

    • --bus=<bus name>:<DBC filename>: Maps a specific bus name (from the input stream) to a DBC file. You can provide multiple --bus arguments.
    • --help: Displays help information for the decode subprogram.
    # Example: Decode traffic from 'vcan0' using 'my_bus.dbc'
    # Assuming traffic is being piped from candump
    candump vcan0 | dbcppp decode --bus=vcan0:my_bus.dbc
    
    # Example: Decode traffic from multiple buses
    candump all | dbcppp decode --bus=can0:bus0.dbc --bus=can1:bus1.dbc