Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DBC CAN Message Type Generator for C++

Extends the code generation capability of cantools, which outputs C sources from DBC frame definitions, to create idiomatic C++ interfaces for using CAN message types.

Usage

In package.xml, you'll need this as a build_depend.

In your CMakeLists.txt:

find_package(dbc_gen_cpp REQUIRED)
...

generate_dbc_cpp(my_can_library_name
  DBC ${CMAKE_CURRENT_SOURCE_DIR}/database.dbc
)

...

target_link_libraries(my_library PUBLIC my_can_library_name)

CAN Messages

Message structs are defined in the library name's namespace.

They can be implicitly converted to can_frame from <linux/can.h>

#include "my_can_library_name/my_can_library_name.hpp"

...

my_can_library_name::MessageName message{value};
my_can_socket->send(message);
can_frame frame = message;
my_can_socket->send(frame);

CAN Handler - Receive/Subscribe to CAN Messages

A helper class dbc_gen_cpp::CANHandler is provided.

Simply register a handler function for a type via set_handler, then forward all can_frames received to the handle() method to trigger the registered handler functions with the typed structs.

dbc_gen_cpp::CANHandler handler;
handler.set_handler<my_can_library_name::MessageName>(
  [](const my_can_library_name::MessageName & message) {
    printf('Received MessageName (value %f)\n', message.value);
  });

my_can_socket.on_receive(
  [&](can_frame frame) {
    handler.handle(frame);
  });

J1939-Specific Handling

How is J1939 Defined in DBCs

DBC files indicate whether a message uses Standard CAN or J1939 via the two lines below. The first line defines the attribute itself. The second line is applied per message and should appear once for each message that is intended to be treated as J1939, using that message’s specific CAN ID.

BA_DEF_ BO_ "VFrameFormat" ENUM "StandardCAN","ExtendedCAN","reserved","J1939PG";
BA_ "VFrameFormat" BO_ 2364539904 3;

J1939 Specific Constants

The following will only be defined if a message is labeled as J1939 in the DBC:

  • static constexpr uint32_t Pgn
  • static constexpr uint8_t DefaultPriority = 3;
  • static constexpr uint8_t SourceAddress = 37;
  • static constexpr bool IsPduBroadcast = true;

The following will only be defined if the message is J1939 and it's of type PDU1 (destination specific):

  • static constexpr uint8_t DefaultDestinationAddress

Note: If you want to safely test if a message is of the J1939 Standard, use the variable IsJ1939.

J1939 Logic Changes

  1. When passing a can frame into the explicit constructor, it will only check if the PGN of the incoming frame matches, instead of the whole CAN ID.

Tests for dbc_gen_cpp

Since dbc_gen_cpp provides mostly functionality via the install/ space with CMake functions and a Python package with importlib-registered Jinja templates, it's not possible to test the full usage of that package internally.

test_dbc_gen_cpp is fully dedicated to providing tests, it is not meant to be used as a dependency by any package.

About

DBC CAN Message Type Generator for cpp

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages