Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

C++ library for parsing CAN databases (currently only with the DBC format)

License

NotificationsYou must be signed in to change notification settings

xatavian/cpp-can-parser

Repository files navigation

This project provides a C++ library that reads and parsesCAN databases which can then be analyzed for other purposes.

Currently the library only understand a subset of the DBC file format.

How robust and efficient is this library ?

C++ CAN Parser is an open-source project based on my work. The library is currently used in a robustindustrial-grade pipeline. The few test files that I gathered in the tests/dbc-files/ directory areinspired by in-use CAN databases of several automotive industrial companies. So you can safely includethis library into your own pipeline or CAN-based software.

C++ CAN Parser can be useful for building:

can-parse is a tool that analyzes a CAN database and proposes different operations. You can use it to inspect all or part of the database.can-parse printframe CAN_ID notably give detailed and structured information about the layout of a frame. Check outthe dedicated section for more info.

Table of Contents

Compile and include the library

Compilation

cpp-can-parser is not a header-only library. I recommand CMake to include the library into your project:

# After including cpp-can-parser into your project's CMakeLists.txt...target_link_libraries(MyAwesomeProject cpp-can-parser)

By default,cpp-can-parser is linked as a shared object. If you want to use a static library, you can addset(CPP_CAN_PARSER_USE_STATIC TRUE) or set it at "command-line time":cmake -DCPP_CAN_PARSER_USE_STATIC=TRUE ...

If you are not using CMake to manage your whole project:

cpp-can-parser is not provided with an already existing Makefile. You will still need CMake to manage the compilation of the library and then include it with traditional means:

>cd cpp-can-parser> mkdir build&&cd build> cmake ..&& cmake --build. --target cpp-can-parser
LD_FLAGS=-Lpath/to/the/library -lcpp-can-parser

Parsing a CAN database

The main feature of the library is the possibility of parsing a file representing the CAN database. There are several popular file formats and the list of the currently ones is available at the end of this README.

CANDatabase::fromFile("path/to/the/data.dbc") is the function to call in order to parse the database from a file. See the following example for a more "advanced" use:

#include<iostream>#include<cpp-can-parser/CANDatabase.h>intmain(int argc,char** argv) {try {    CppCAN::CANDatabase db =CppCAN::CANDatabase::fromFile(argv[1]);// ...  }catch(const CppCAN::CANDatabaseException& e) {    std::cerr <<"Error:" << e.what();return1;  }return0;}

One can see thatCppCAN::CANDatabase::fromFile() can throw a CANDatabaseException. This happens when the parsing goes wrong (basically when the given file does not exist or when there is a syntax error).CppCAN::CANDatabaseException::what() will give you details on the error.

If the data that you are using does not come from a file, it is also possible to useCppCAN::CANDatabase::fromString("...") which behaves just like its counterpart.

Note that one can construct its own database without parsing a file by diretly manipulating the reevant objects. See the next section for mmore info.

How to use the database

The library exposes three main kind of objects:

  • CANDatabase : represents the whole database. It gatherse all the informations of the database such as the frames and their signals, but you can also find the filename from which the database was created (if applicable).
  • CANFrame: represents a single frame: we know its CAN ID, the DLC (Data length code), its period (in ms) and also its name (if any). Of course, aCANFrame also gathers the list of signals that can be read in a frame
  • CANSignal: represents a single signal: a signal is a parameter of a frame characterized by different properties. It is mostly identificable through its start bit, length andendianness (those three parameters are enough to extract the "raw data" that the signals represent) but one usually also specify a scale and offset factor, a signedness, and a name. More parameters are available and you are welcome to look into theCANSignal.h file to look at all the available properties.

All those classes try to behave the closest possible to STL containers. They notably implement all the required iterators methods sothey can be used in range-based for loops

CANSignal

Here are the most important properties of aCANSignal instance:

  • name(): gives the name of the signal
  • length() : gives the length of the signal
  • start_bit() : gives the start bit of the signal
  • scale() : gives the scale factor of the signal
  • offset() : gives the offset factor of the signal
  • signedness() : gives the signedness of the signal
  • endianness() : gives the endianness of the signal
  • range() : gives the range of the signal (which has amin andmax property)
  • comment() : gives the registered comment (if any)

Sometimes the database also includes "enumerations", ie for given signals we associate string literals to values (example: 0 = Nothing, 1 = State 1, 2 = State 2).choices() allows to iterate through the signal's enumeration (if any).

CANFrame

Here are the most important properties of aCANFrame instance:

  • name(): gives the name of the signal
  • can_id(): gives the CAN ID of the signal
  • dlc(): gives the DLC of the signal
  • period(): gives the period of the signal
  • comment() : gives the registered comment (if any)
  • more properties to behave like a "standard container"

Usebegin()/end() and/or a ranged-based for loop to iterate through the signals of the frame.

const CppCAN::CANFrame& frame = ...;// Print the name of all the frames by increasing orderfor(constauto& sig : frame) {  std::cout <<"Signal:" << sig.second.name() << std::endl;}

You can useCppCAN::CANFrame::operator[](std::string) andCppCAN::CANFrame::at(std::string) toaccess the signals individually. Be aware that they both throw anstd::out_of_range exception ifthe signal does not exist.

CANDatabase

Here are the most important properties of aCANDatabase instance:

  • filename() : gives the source file name (if any)
  • operator[std::string] andat(std::string) : returns a reference to theCANFrame associated with the given frame name. The deviation from the STL behavior is that they both throw anstd::out_of_range exception if the key does not exist (noCANFrame is created like it would withstd::map for instance)
  • operator[unsigned long long] andat(unsigned long long): same but the key is the CAN ID of theCANFrame
  • more properties to behave like a "standard container"
CppCAN::CANDatabase db = ...;// Print the name of all the frames by increasing ordersize_t i =0;for(constauto& frame : db) {  std::cout <<"Frame" << i++ <<":" << frame.second.name() << std::endl;}

Database analysis

C++ CAN Parser provides functions to analyze the coherence of a CAN Database. All the functtions are regrouped into the namespaceCppCAN::analysis. They are notably used bycan-parse and itsCHECKFRAME operations.

  • bool CppCAN::analysis::is_frame_layout_ok(const CppCAN::CANFrame&): returns true if the layout of the CANFrame is correct. An overload exists which gives a list of all the problematic signals. CheckCANDatabaseAnalysis.h for more details.
  • void CppCAN::analysis::assert_frame_layout(const CppCAN::CANFrame&): same asis_frame_layout_ok() but throws aCANDatabaseException is the layout is invalid.

You must includecpp-can-parser/CANDatabaseAnalysis.h to access these functions.

Example:

#include<cpp-can-parser/CANDatabaseAnalysis.h>#include<iostream>CppCAN::CANDatabase db = ...;// Boolean-based version ...for(constauto& frame : db) {if(!CppCAN::analysis::is_frame_layout_ok(frame))    std::cerr <<"Frame" << frame.name() <<" contains a layout error" << std::endl;}// Assert-based version ...for(constauto& frame : db) {try {CppCAN::analysis::assert_frame_layout(frame);  }catch(const CppCAN::CANDatabaseException& e) {    std::cerr <<"Frame" << frame.name() <<" contains a layout error."               <<"Error details:" << e.what() << std::endl;  }}

can-parse

can-parse is a utility program that allows you to parse the content of a CAN database which is then output to the standard output.

Different uses ofcan-parse are possible, mainly 4 operations are included incan-parse:

  • Print a summary of the whole database
  • Print a detailed view of a single entry of the database
    • CAN ID, DLC, Period, Comment
    • Signals' description
      • Name
      • Start bit
      • Length
      • Endianness
      • Signedness
  • Check the integrity of the whole database (a summary is given) (very basic implementation for now)
  • Check the integrity of a single frame (a detailed report is given) (very basic implementation for now)

The Command_Line Interface is very easy to use !

Usage: ./can-parse [ACTION [ARGUMENTS]]<path/to/file>When no action is specified, defaults to printframePossible actions:         printframe [CAN ID]   Print the content of the CAN databaseif CAN ID is specified, prints the details of the given frame        checkframe [CAN ID]   Check different properties of the CAN databaseif CAN ID is specified, print the check details of the given frame        -h / --help           Print the presenthelp message

Compilation:To compile, just use the following instructions:

>cd cpp-can-parser> mkdir build&&cd build> cmake ..&& cmake --build. --target can-parse

There you got yourself a very nice installation ofcan-parse :) !

Supported standards

  • DBC (the relevant subset of the file format)

About

C++ library for parsing CAN databases (currently only with the DBC format)

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp