Author Topic: CANdb++ .dbc to C/C++ .h converter  (Read 18603 times)

0 Members and 1 Guest are viewing this topic.

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
CANdb++ .dbc to C/C++ .h converter
« on: February 12, 2017, 09:03:39 am »
Hi everybody,

I would like to share a tool with you that I have recently built at work and think is worth sharing.
It's a universal .dbc to .h converter. The idea is that embedded systems developers/programmers shouldn't have to manually maintain their code to match the requirements, messages and signals of the current CAN bus project.

As these projects are very often being maintained using Vector's CANdb++ tool to define messages, signals, nodes, etc - I set off to create a convenient way to import that information into C source code.
After some experimenting, I found a good way to structure the information in a most useful way for C. My main goal was to enable auto-completion (e.g. in eclipse) so that I could easily get a list of available messages and signals, their meta-information (ID, length, position, IDE bit, etc).

I then also implemented a generic way to extract specific signal values by name - also autocomplete supported. This is done using a macro that links a struct pointer to the uint8_t[8] array. The comments contain usage examples and should help understanding the concept. It's all very simple to use.
And most important of all, it is easy to use -> simply import the .h file into your project and off you go.

(I had to make the structs static, unfortunately - otherwise I'd have to split the whole thing up into a .c/.h pair and it wouldn't be as portable. I checked compiled code sizes, though and it seems as if the code size is unaffected by this. If you experience any issues, please let me know and you're free to un-static the structs and split them up into a .c/.h pair)
This has been tested successfully on the STM32 family using Atollic TrueStudio IDE. It requires the raw CAN data to be received in the form of a little endian uint_t8 array, just like it is the case per default on STM32 HAL.

Usage example:
C++:
Code: [Select]
io::CAN_message_CPP msg;
{
auto const& dbc = DBC_IMED_HELMBUS_MSG_M_assignID;
DBC_setup(dbc, msg);
DBC_makeSignalAccessor(dbc, msg, msg_access);
msg_access->UID = pNode->getUID();
msg_access->AssignedID = aid;
}
this->can->send(msg);
C:
Code: [Select]
{
uint8_t uid;
uint8_t RxMessage[8];
DBC_setup(DBC_IME_AI_MSG_CAN_IMED_MSG_PA_SP, RxMessage);
DBC_makeSignalAccessor(DBC_IME_AI_MSG_CAN_IMED_MSG_PA_SP, RxMessage, msg_access);
uid = msg_access->UID;
msg_access->AssignedID = 42;
}
For anything else, please read the comments as they contain usage examples and should get you up and running. If anything is unclear, please let me know in here.

Download: click the attached dbc2h.zip at the bottom of this post.

I hope that this little tool is of help for all you CAN afficionados out there - it most definitely is a LOT for me ;)
« Last Edit: March 26, 2019, 09:28:02 pm by gnasirator »
Kiwi by heart. But never liked Vegemite.
 
The following users thanked this post: jnz

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: Vector CANdb++ to C/C++ .h converter
« Reply #1 on: February 12, 2017, 09:07:21 am »
<Reserved>
Kiwi by heart. But never liked Vegemite.
 

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: Vector CANdb++ to C/C++ .h converter
« Reply #2 on: February 12, 2017, 09:07:40 am »
<Reserved>
Kiwi by heart. But never liked Vegemite.
 

Offline jnz

  • Frequent Contributor
  • **
  • Posts: 593
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #3 on: February 12, 2017, 05:47:00 pm »
I stopped using dbc when I stopped using Vector products, but pretty interesting and I'll keep it in mind.

What are you using when you are working in dbc?
 

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #4 on: July 05, 2017, 03:03:40 am »
At the moment: nothing. Only my STM32 project.
But I find it much more convenient to define messages, signals and their positions in CANdb++ than doing it manually, e.g. in an excel sheet.

Also that .dbc file then helps e.g. in debugging as some of those can viewers support dbc imports and convert signals to their physical values on the fly...


edit:
We have released a free public beta of the tool. Please try it out and report back to me  :-+
http://www.imed.co.nz/software.html
Kiwi by heart. But never liked Vegemite.
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2299
  • Country: gb
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #5 on: July 06, 2017, 07:54:03 am »
Hey,
I had a browse around your website, nice product, must be satisfying to design and install these custom helms.
When I get my superyacht I'll give you a call  8)
 

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #6 on: July 07, 2017, 11:02:21 am »
Oh yes, it's great fun and all very lovely people in that industry. But believe me, you don't want your own superyacht :)
Charter one for a while!
« Last Edit: July 07, 2017, 11:04:22 am by gnasirator »
Kiwi by heart. But never liked Vegemite.
 
The following users thanked this post: voltsandjolts

Offline franzle

  • Newbie
  • Posts: 1
  • Country: it
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #7 on: October 30, 2017, 05:30:50 pm »
Hi,
I've found your tool very usefull and well thought out!
Unfortunately I noticed the following limitation, which make this tool unpractical for me:
My can packet has a dlc of say 8, but the sig are sparse and cover only a non contiguous portion of the 64 bits, the bit fields in the .h file turns out to be scrambled:
Here underneath a portion of  the dbc file:


Any workaround (beside filling missing gaps manually? over 3000 signals, sig):

BO_ 2250326016 STATUS_BCM: 8 BCM
 SG_ BonnetSts : 15|1@0+ (1,0) [0|1] "-" IPC
 SG_ BrakeFluidLevelSts : 6|1@0+ (1,0) [0|1] "-" IPC
 SG_ BrakePadWearSts : 7|1@0+ (1,0) [0|1] "-" IPC,TUM
 SG_ DriverDoorLockSts : 29|1@0+ (1,0) [0|1] "-" TUM
 SG_ DriverDoorSts : 10|1@0+ (1,0) [0|1] "-" ASM,IPC,TUM
 SG_ FpsNotAvailable : 55|1@0+ (1,0) [0|1] "" IPC,TUM
 SG_ FPSSts : 31|1@0+ (1,0) [0|1] "-" IPC,TUM
 SG_ FuelLevel : 47|8@0+ (1,0) [0|100] "%" IPC
 SG_ FuelLevelFailSts : 32|1@0+ (1,0) [0|1] "-" IPC
 SG_ HandBrakeSts : 5|1@0+ (1,0) [0|1] "-" ASM,IPC,TUM
 SG_ IMMOCodeWarningLightSts : 54|7@0+ (1,0) [0|18] "-" IPC
 SG_ InternalLightSts : 3|1@0+ (1,0) [0|1] "-" IPC,LTM,RRM,SDM
 SG_ KeySts : 23|4@0+ (1,0) [0|12] "-" ACM,AHM,ASM,IPC,LTM,RRM,SDM,TPM,TTM
 SG_ LHRDoorSts : 12|1@0+ (1,0) [0|1] "-" ASM,IPC,TUM
 SG_ LowFuelWarningSts : 33|1@0+ (1,0) [0|1] "-" IPC,TUM
 SG_ PsngrDoorSts : 11|1@0+ (1,0) [0|1] "-" ASM,IPC,TUM
 SG_ RainSensorFailSts : 63|1@0+ (1,0) [0|1] "-" IPC,TUM
 SG_ RechargeSts : 19|1@0+ (1,0) [0|1] "-" ACM,ASM,SDM,TUM
 SG_ RHatchSts : 14|1@0+ (1,0) [0|1] "-" IPC,LTM,TUM
 SG_ RHRDoorSts : 13|1@0+ (1,0) [0|1] "-" ASM,IPC,TUM
 SG_ SysEOLSts : 2|1@0+ (1,0) [0|1] "-" IPC

to make it work correctly I would have to add by hand the following dummy signals:

 SG_ XF1 : 1|2@0+ (1,0) [0|1] "-" IPC
 SG_ XF2 : 4|1@0+ (1,0) [0|1] "-" IPC
 SG_ XF3 : 9|2@0+ (1,0) [0|1] "-" IPC
 SG_ XF4 : 18|3@0+ (1,0) [0|1] "-" IPC
 SG_ XF5 : 28|5@0+ (1,0) [0|1] "-" IPC
 SG_ XF6 : 30|1@0+ (1,0) [0|1] "-" IPC
 SG_ XF7 : 39|6@0+ (1,0) [0|1] "-" IPC
 SG_ XF8 : 62|7@0+ (1,0) [0|1] "-" IPC


Thank a lot for your work, any help is welcome!
« Last Edit: October 30, 2017, 05:43:34 pm by franzle »
 
The following users thanked this post: gnasirator

Offline nailgg

  • Newbie
  • Posts: 1
  • Country: tr
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #8 on: November 23, 2017, 10:55:06 pm »
Thanks for sharing this tool. It's awesome.
 
The following users thanked this post: gnasirator

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #9 on: October 29, 2018, 07:03:41 pm »
Any workaround (beside filling missing gaps manually? over 3000 signals, sig):

Hey there,
sorry it took me so long to reply. Was quite busy recently ... new job, moved back to Germany, ...

What would you think about the following result:
Code: [Select]
/**
 * ""
 *
 * ###Parameters###
 * | Name | Value |
 * | ------ | -------- |
 * | ID: | 0x6214000 |
 * | IDE: | EXT |
 * | DLC: | 8 |
 *
 * ###Signals###
 * | Position (Bit) | Signal (Bitlength) |
 * | ------------- | ------------------ |
 * | [2] | @ref DBC_IME_AI_SIG_SysEOLSts "SysEOLSts (1)" |
 * | [3] | @ref DBC_IME_AI_SIG_InternalLightSts "InternalLightSts (1)" |
 * | [5] | @ref DBC_IME_AI_SIG_HandBrakeSts "HandBrakeSts (1)" |
 * | [6] | @ref DBC_IME_AI_SIG_BrakeFluidLevelSts "BrakeFluidLevelSts (1)" |
 * | [7] | @ref DBC_IME_AI_SIG_BrakePadWearSts "BrakePadWearSts (1)" |
 * | [10] | @ref DBC_IME_AI_SIG_DriverDoorSts "DriverDoorSts (1)" |
 * | [11] | @ref DBC_IME_AI_SIG_PsngrDoorSts "PsngrDoorSts (1)" |
 * | [12] | @ref DBC_IME_AI_SIG_LHRDoorSts "LHRDoorSts (1)" |
 * | [13] | @ref DBC_IME_AI_SIG_RHRDoorSts "RHRDoorSts (1)" |
 * | [14] | @ref DBC_IME_AI_SIG_RHatchSts "RHatchSts (1)" |
 * | [15] | @ref DBC_IME_AI_SIG_BonnetSts "BonnetSts (1)" |
 * | [19] | @ref DBC_IME_AI_SIG_RechargeSts "RechargeSts (1)" |
 * | [23] | @ref DBC_IME_AI_SIG_KeySts "KeySts (4)" |
 * | [29] | @ref DBC_IME_AI_SIG_DriverDoorLockSts "DriverDoorLockSts (1)" |
 * | [31] | @ref DBC_IME_AI_SIG_FPSSts "FPSSts (1)" |
 * | [32] | @ref DBC_IME_AI_SIG_FuelLevelFailSts "FuelLevelFailSts (1)" |
 * | [33] | @ref DBC_IME_AI_SIG_LowFuelWarningSts "LowFuelWarningSts (1)" |
 * | [47] | @ref DBC_IME_AI_SIG_FuelLevel "FuelLevel (8)" |
 * | [54] | @ref DBC_IME_AI_SIG_IMMOCodeWarningLightSts "IMMOCodeWarningLightSts (7)" |
 * | [55] | @ref DBC_IME_AI_SIG_FpsNotAvailable "FpsNotAvailable (1)" |
 * | [63] | @ref DBC_IME_AI_SIG_RainSensorFailSts "RainSensorFailSts (1)" |
 *
 */
static struct DBC_IME_AI_MSG_STATUS_BCM {
const uint32_t ID;
const uint8_t IDE;
const uint8_t DLC;
const struct {
signal_positioned SysEOLSts;
signal_positioned InternalLightSts;
signal_positioned HandBrakeSts;
signal_positioned BrakeFluidLevelSts;
signal_positioned BrakePadWearSts;
signal_positioned DriverDoorSts;
signal_positioned PsngrDoorSts;
signal_positioned LHRDoorSts;
signal_positioned RHRDoorSts;
signal_positioned RHatchSts;
signal_positioned BonnetSts;
signal_positioned RechargeSts;
signal_positioned KeySts;
signal_positioned DriverDoorLockSts;
signal_positioned FPSSts;
signal_positioned FuelLevelFailSts;
signal_positioned LowFuelWarningSts;
signal_positioned FuelLevel;
signal_positioned IMMOCodeWarningLightSts;
signal_positioned FpsNotAvailable;
signal_positioned RainSensorFailSts;
} sigParms;
struct __attribute__((packed)) DBC_IME_AI_MSG_STATUS_BCM_sigVals {
void : 1;
void : 1;
uint8_t SysEOLSts : 1;
uint8_t InternalLightSts : 1;
void : 1;
uint8_t HandBrakeSts : 1;
uint8_t BrakeFluidLevelSts : 1;
uint8_t BrakePadWearSts : 1;
void : 1;
void : 1;
uint8_t DriverDoorSts : 1;
uint8_t PsngrDoorSts : 1;
uint8_t LHRDoorSts : 1;
uint8_t RHRDoorSts : 1;
uint8_t RHatchSts : 1;
uint8_t BonnetSts : 1;
void : 1;
void : 1;
void : 1;
uint8_t RechargeSts : 1;
void : 1;
void : 1;
void : 1;
uint8_t KeySts : 4;
void : 1;
void : 1;
uint8_t DriverDoorLockSts : 1;
void : 1;
uint8_t FPSSts : 1;
uint8_t FuelLevelFailSts : 1;
uint8_t LowFuelWarningSts : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
uint8_t FuelLevel : 8;
uint8_t IMMOCodeWarningLightSts : 7;
uint8_t FpsNotAvailable : 1;
void : 1;
void : 1;
uint8_t RainSensorFailSts : 1;
} *sigVals;
} DBC_IME_AI_MSG_STATUS_BCM __attribute__((unused)) = {
.ID = 0x6214000,
.IDE = CAN_ID_EXT,
.DLC = 8,
.sigParms  = {
{2, &DBC_IME_AI_SIG_SysEOLSts},
{3, &DBC_IME_AI_SIG_InternalLightSts},
{5, &DBC_IME_AI_SIG_HandBrakeSts},
{6, &DBC_IME_AI_SIG_BrakeFluidLevelSts},
{7, &DBC_IME_AI_SIG_BrakePadWearSts},
{10, &DBC_IME_AI_SIG_DriverDoorSts},
{11, &DBC_IME_AI_SIG_PsngrDoorSts},
{12, &DBC_IME_AI_SIG_LHRDoorSts},
{13, &DBC_IME_AI_SIG_RHRDoorSts},
{14, &DBC_IME_AI_SIG_RHatchSts},
{15, &DBC_IME_AI_SIG_BonnetSts},
{19, &DBC_IME_AI_SIG_RechargeSts},
{23, &DBC_IME_AI_SIG_KeySts},
{29, &DBC_IME_AI_SIG_DriverDoorLockSts},
{31, &DBC_IME_AI_SIG_FPSSts},
{32, &DBC_IME_AI_SIG_FuelLevelFailSts},
{33, &DBC_IME_AI_SIG_LowFuelWarningSts},
{47, &DBC_IME_AI_SIG_FuelLevel},
{54, &DBC_IME_AI_SIG_IMMOCodeWarningLightSts},
{55, &DBC_IME_AI_SIG_FpsNotAvailable},
{63, &DBC_IME_AI_SIG_RainSensorFailSts}
},
.sigVals = 0
};


as you can see, I filled up unused bits with a dummy signal
Code: [Select]
void : 1;
would that solve your problem? If so, would you mind trying this new version, please?
« Last Edit: March 24, 2019, 01:05:15 pm by gnasirator »
Kiwi by heart. But never liked Vegemite.
 

Offline mikelev

  • Newbie
  • Posts: 5
  • Country: us
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #10 on: March 14, 2019, 12:13:45 am »
Hi,

Very useful tool!

Does it support CAN-FD messages? I think the main difference is that data can be 64 bytes long, not just 8.
I think currently this tool just ignores signals that are not in the first 8 bytes of the data field.
Any plans to support CAN-FD by any chance?

Thanks,
Mike
 

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #11 on: March 16, 2019, 05:57:08 am »
Hey Mike,

at the moment it does not. But it wouldn't be too hard to extend it to support 64 bytes. I might be able to look into it in 1-2 weeks from now. At the moment I don't have the time.
Kiwi by heart. But never liked Vegemite.
 

Offline mikelev

  • Newbie
  • Posts: 5
  • Country: us
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #12 on: March 21, 2019, 03:39:08 am »
I am looking forward to it!
I realize it is not a commercial project for you and do not expect you to jump on it right away :)
 

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #13 on: March 23, 2019, 08:22:18 pm »
mike: can you maybe provide a CanFD .dbc file for me?

edit: never mind, I installed candb++ and got to it.

Result: as it seems, the converter already did support fd in a basic way. I only had to tweak the resulting DLC values. I also fixed a nullptr exception when using it without any defined nodes in the network.
--> the only way to recognize FD frames in the resulting header file is by checking if DLC > 8. I didn't introduce any extra bit or flag. Let me know whether this works for you.

I updated the download link on page 1. Enjoy :)
« Last Edit: March 24, 2019, 01:15:51 pm by gnasirator »
Kiwi by heart. But never liked Vegemite.
 

Offline jnz

  • Frequent Contributor
  • **
  • Posts: 593
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #14 on: March 24, 2019, 07:11:03 pm »
I just wanted to heads up here. I don’t have a use for this converter still (yet) but appreciate the work you’ve put in.
 

Offline mikelev

  • Newbie
  • Posts: 5
  • Country: us
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #15 on: March 25, 2019, 07:56:41 pm »
Thanks a lot for your work!!

Maybe I am not using this converter correctly...
I can see it correctly generates the structures corresponding to CAN signals, but not sure about CAN message structures.
I thought CAN Message structures are supposed to contain all the signals within them (signals as bitfields and also a set of signal_positioned structures). Am I wrong?

Here is a part of .h file generated from your test_fd.dbc:
/**
 * ""
 *
 * ###Parameters###
 * | Name    |   Value      |
 * | ------   |   --------   |
 * | ID:   |   0x64   |
 * | IDE:    |   STD       |
 * | DLC:    |   15         |
 *
 * ###Signals###
 * | Position (Bit)   |   Signal (Bitlength)   |
 * | -------------   |   ------------------   |
 * |
  •          |    @ref DBC_TEST_FD_SIG_test1    "test1 (64)"    |

 *
 */
static struct DBC_TEST_FD_MSG_Mes_CAN_FD_Std {
   const uint32_t ID;
   const uint8_t IDE;
   const uint8_t DLC;
    const struct {
      signal_positioned test1;
   } sigParms;
    struct __attribute__((packed)) DBC_TEST_FD_MSG_Mes_CAN_FD_Std_sigVals {
      int64_t test1   : 64;
   } *sigVals;
} DBC_TEST_FD_MSG_Mes_CAN_FD_Std __attribute__((unused)) = {
   .ID = 0x64,
   .IDE = CAN_ID_STD,
   .DLC = 15,
   .sigParms  = {
      {0,    &DBC_TEST_FD_SIG_test1}
   },
   .sigVals = 0
};


The only signal I see here is "DBC_TEST_FD_SIG_test1", but I expected 8 signals.


I am also attaching my dbc and generated .h files.

Thanks again!
Mikhail
« Last Edit: March 25, 2019, 08:00:50 pm by mikelev »
 

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #16 on: March 25, 2019, 08:07:46 pm »
Hmm jeah seems like there's still something wrong. hang on ...

edit: fixed. had another hard-coded 64 somewhere else in the code :)

Code: [Select]
/**
 * ""
 *
 * ###Parameters###
 * | Name | Value |
 * | ------ | -------- |
 * | ID: | 0x64 |
 * | IDE: | STD |
 * | DLC: | 15 |
 *
 * ###Signals###
 * | Position (Bit) | Signal (Bitlength) |
 * | ------------- | ------------------ |
 * | [0] | @ref DBC_TEST_FD_SIG_test1 "test1 (64)" |
 * | [64] | @ref DBC_TEST_FD_SIG_test1_Copy_1 "test1_Copy_1 (64)" |
 * | [128] | @ref DBC_TEST_FD_SIG_test1_Copy_2 "test1_Copy_2 (64)" |
 * | [192] | @ref DBC_TEST_FD_SIG_test1_Copy_3 "test1_Copy_3 (64)" |
 * | [256] | @ref DBC_TEST_FD_SIG_test1_Copy_4 "test1_Copy_4 (64)" |
 * | [320] | @ref DBC_TEST_FD_SIG_test1_Copy_6 "test1_Copy_6 (64)" |
 * | [448] | @ref DBC_TEST_FD_SIG_test1_Copy_7 "test1_Copy_7 (64)" |
 *
 */
static struct DBC_TEST_FD_MSG_Mes_CAN_FD_Std {
const uint32_t ID;
const uint8_t IDE;
const uint8_t DLC;
const struct {
signal_positioned test1;
signal_positioned test1_Copy_1;
signal_positioned test1_Copy_2;
signal_positioned test1_Copy_3;
signal_positioned test1_Copy_4;
signal_positioned test1_Copy_6;
signal_positioned test1_Copy_7;
} sigParms;
struct __attribute__((packed)) DBC_TEST_FD_MSG_Mes_CAN_FD_Std_sigVals {
int64_t test1 : 64;
int64_t test1_Copy_1 : 64;
int64_t test1_Copy_2 : 64;
int64_t test1_Copy_3 : 64;
int64_t test1_Copy_4 : 64;
int64_t test1_Copy_6 : 64;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
void : 1;
int64_t test1_Copy_7 : 64;
} *sigVals;
} DBC_TEST_FD_MSG_Mes_CAN_FD_Std __attribute__((unused)) = {
.ID = 0x64,
.IDE = CAN_ID_STD,
.DLC = 15,
.sigParms  = {
{0, &DBC_TEST_FD_SIG_test1},
{64, &DBC_TEST_FD_SIG_test1_Copy_1},
{128, &DBC_TEST_FD_SIG_test1_Copy_2},
{192, &DBC_TEST_FD_SIG_test1_Copy_3},
{256, &DBC_TEST_FD_SIG_test1_Copy_4},
{320, &DBC_TEST_FD_SIG_test1_Copy_6},
{448, &DBC_TEST_FD_SIG_test1_Copy_7}
},
.sigVals = 0
};
« Last Edit: March 25, 2019, 09:04:09 pm by gnasirator »
Kiwi by heart. But never liked Vegemite.
 

Offline mikelev

  • Newbie
  • Posts: 5
  • Country: us
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #17 on: March 26, 2019, 12:41:00 am »
Wow! The output looks great. I will try to use it within a few days.

I am not sure if I can use the bitfields in "sigValues" to access signals correctly. Also my compiler does not like "void" bitfields and I might have to remove the "sigValues" from the code.
However, "sigParams" is good enough for me. I can use a function to extract signal values as long as I have a full list of them (with start and length) in one place. And "sigParams" is exactly the list I need.

Thanks!
Mikhail
 

Offline mikelev

  • Newbie
  • Posts: 5
  • Country: us
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #18 on: March 26, 2019, 02:44:05 am »
Also, field "position" in in "signal_positioned" should be bigger than uint8_t. But that is easy to change in generated .h file.

 

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #19 on: March 26, 2019, 05:24:46 pm »
The thing about functions is that they require known types which is why I had to come up with the accessor macro, as you can see in post #1:

Code: [Select]
{
uint8_t uid;
uint8_t RxMessage[8];
DBC_setup(DBC_IME_AI_MSG_CAN_IMED_MSG_PA_SP, RxMessage);
DBC_makeSignalAccessor(DBC_IME_AI_MSG_CAN_IMED_MSG_PA_SP, RxMessage, msg_access);
uid = msg_access->UID;
msg_access->AssignedID = 42;
}

This has worked great for me, using gcc. it took care of all masks and shifts to spit out just the signal I wanted.

you can also replace the void bitfileds with u_08 unused:1; for example. But I think they will then pop up in your autocompletion list, cluttering the results which is why I was happy to see that void worked with gcc.

about signal_positioned: good spot. yes that now has to be u_16. will change that. changed.
« Last Edit: March 26, 2019, 09:28:42 pm by gnasirator »
Kiwi by heart. But never liked Vegemite.
 

Offline vinicaog

  • Newbie
  • Posts: 1
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #20 on: May 07, 2020, 11:53:45 am »
Hi gnasirator,

First of all, thank you for making the DBC to C/C++ converter. I find it very useful and well structurated.

My software receives the CAN message with this structure:

Code: [Select]
typedef struct
   {
    unsigned int ID  :29;
    unsigned int DLC :4;
    uint8_t  DATA[8];
   } Can_Message;
And I would like to apply the values from DATA buffer into the DBC signal.

for example:

Code: [Select]
static const signal DBC_SIG_CCU_SteeringWheelAngle = {
.name = "CCU_SteeringWheelAngle",
.unit = "°",
.valueType = dbc_valueType_unsigned,
.lengthBits = 14,
.factor = 0.5f, .offset = -2048.0f, .min = -2048.0f, .max = 2047.0f
};

Code: [Select]
static struct DBC_MSG_CCU_VehStat {
const uint32_t ID;
const uint8_t IDE;
const uint8_t DLC;
const struct {
signal_positioned CCU_SteeringWheelAngle;
} getSig;
struct __attribute__((packed)) DBC_MSG_CCU_VehStat_getSigVal {
uint16_t CCU_SteeringWheelAngle : 14;
} *getSigVal;
} DBC_MSG_CCU_VehStat __attribute__((unused)) = {
.ID = 0x12,
.IDE = CAN_ID_STD,
.DLC = 8,
.getSig  = {
.CCU_SteeringWheelAngle = {
.position = 7,
.attributes = &DBC_SIG_CCU_SteeringWheelAngle
}
},
.getSigVal = 0
};


How to write values to CCU_SteeringWheelAngle ? So I can send it later.
And also the oposit, I receive the CAN RxMessage.DATA, how to populate the new data, to the header structure?

Thank you.
 
The following users thanked this post: gnasirator

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #21 on: May 07, 2020, 06:37:38 pm »
Hi vinicaog,

please have a look at my usage example in the first post:

Code: [Select]

{
uint8_t uid;
uint8_t RxMessage[8];
DBC_setup(DBC_IME_AI_MSG_CAN_IMED_MSG_PA_SP, RxMessage);
DBC_makeSignalAccessor(DBC_IME_AI_MSG_CAN_IMED_MSG_PA_SP, RxMessage, msg_access);
uid = msg_access->UID;
msg_access->AssignedID = 42;
}

The DBC_setup and DBC_makeSignalAccessor macros basically set up a struct pointer of your defined message type to the data[8] array, here called msg_access. You can then use msg_access to read/write your signals.
Have a look at the macro definition, that should clear it all up.

I think modified to your use case it might look similar to this:
Code: [Select]
typedef struct
   {
    unsigned int ID  :29;
    unsigned int DLC :4;
    uint8_t  DATA[8];
   } Can_Message;

uint16_t angle;

DBC_setup(DBC_MSG_CCU_VehStat, Can_Message.DATA);
DBC_makeSignalAccessor(DBC_MSG_CCU_VehStat, Can_Message.DATA, msg_access);
angle = msg_access->CCU_SteeringWheelAngle;
msg_access->CCU_SteeringWheelAngle = 42;


All the best with your project!
« Last Edit: May 07, 2020, 06:43:06 pm by gnasirator »
Kiwi by heart. But never liked Vegemite.
 

Offline superiorsoftware

  • Newbie
  • Posts: 2
  • Country: us
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #22 on: November 29, 2023, 06:58:59 pm »
It has been several years since there have been post, but I have recently been working with this tool.  I am struggling with a big endian format dbc.  This tool does a nice job, but I must go in and remove the padding added before the first byte (that the tool adds, but I don't think should be there).  The dbc file is mandated to be big endian so I must work with that.

Here is the Can db file description:

BO_ 2565999614 BRM_V_Cell_1_to_4: 8 Vector__XXX
 SG_ Cell_Voltage_4 : 55|16@0+ (0.0001,0) [0|6.5535] "V" Vector__XXX
 SG_ Cell_Voltage_3 : 39|16@0+ (0.0001,0) [0|6.5535] "V" Vector__XXX
 SG_ Cell_Voltage_2 : 23|16@0+ (0.0001,0) [0|6.5535] "V" Vector__XXX
 SG_ Cell_Voltage_1 : 7|16@0+ (0.0001,0) [0|6.5535] "V" Vector__XXX



And here is the output from the conversion program (just a snippet from *.h file).  My question is, Is there a method to eliminate the padded bits prior to the Voltage1 in the structure.  All works fine if I do it by hand, but would really like an automated option.

/**
 * ""
 *
 * ###Parameters###
 * | Name    |   Value      |
 * | ------   |   --------   |
 * | ID:   |   0x18F20BFE   |
 * | IDE:    |   EXT       |
 * | DLC:    |   8         |
 *
 * ###Signals###
 * | Position (Bit)   |   Signal (Bitlength)   |
 * | -------------   |   ------------------   |
 * | [7]         |    @ref DBC_INTERNAL_CAN_V11_SIG_Cell_Voltage_1    "Cell_Voltage_1 (16)"    |
 * | [23]         |    @ref DBC_INTERNAL_CAN_V11_SIG_Cell_Voltage_2    "Cell_Voltage_2 (16)"    |
 * | [39]         |    @ref DBC_INTERNAL_CAN_V11_SIG_Cell_Voltage_3    "Cell_Voltage_3 (16)"    |
 * | [55]         |    @ref DBC_INTERNAL_CAN_V11_SIG_Cell_Voltage_4    "Cell_Voltage_4 (16)"    |
 *
 */
static struct DBC_INTERNAL_CAN_V11_MSG_V_Cell_1_to_4 {
   const uint32_t ID;
   const uint8_t IDE;
   const uint8_t DLC;
   const struct {
      signal_positioned Cell_Voltage_1;
      signal_positioned Cell_Voltage_2;
      signal_positioned Cell_Voltage_3;
      signal_positioned Cell_Voltage_4;
   } sigParms;
   struct __attribute__((packed)) DBC_INTERNAL_CAN_V11_MSG_V_Cell_1_to_4_sigVals {
      void    : 1;
      void    : 1;
      void    : 1;
      void    : 1;
      void    : 1;
      void    : 1;
      void    : 1;

      uint16_t Cell_Voltage_1   : 16;
      uint16_t Cell_Voltage_2   : 16;
      uint16_t Cell_Voltage_3   : 16;
      uint16_t Cell_Voltage_4   : 16;
   } *sigVals;
} DBC_INTERNAL_CAN_V11_MSG_V_Cell_1_to_4 __attribute__((unused)) = {
   .ID = 0x18F20BFE,
   .IDE = CAN_ID_EXT,
   .DLC = 8,
   .sigParms  = {
      {7,    &DBC_INTERNAL_CAN_V11_SIG_Cell_Voltage_1},
      {23,    &DBC_INTERNAL_CAN_V11_SIG_Cell_Voltage_2},
      {39,    &DBC_INTERNAL_CAN_V11_SIG_Cell_Voltage_3},
      {55,    &DBC_INTERNAL_CAN_V11_SIG_Cell_Voltage_4}
   },
   .sigVals = 0
};
 

Offline gnasiratorTopic starter

  • Contributor
  • Posts: 35
  • Country: de
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #23 on: November 29, 2023, 08:02:38 pm »
Hey,
happy to hear this SW getting some use!

It's been a super long time for me to actually use this as I have moved on into automotive where Vector tools are standard now. They take care of all of this.

Anyways, about your question:
When I developed this, I was using it on a little endian machine. Not sure if it properly supports big endianness. If I look at your DBC input it looks to me like there are in fact 7 unused bits in the message before the first signal, right?

Quote
SG_ Cell_Voltage_1 : 7|16@0+ (0.0001,0) [0|6.5535] "V" Vector__XXX

This is what the tool is adding the padding for. I see if this DBC is now using BE, that's not really supported as you can see. I have not seen this format before in a DBC. It's a bit counter intuitive to have the first signal start at byte#1 while the other byte is on location #0.
I would've still expected the DBC to reference the signal as beginning on location byte#0 and only swapping the content due to BE... weird.
« Last Edit: November 29, 2023, 08:08:39 pm by gnasirator »
Kiwi by heart. But never liked Vegemite.
 

Offline superiorsoftware

  • Newbie
  • Posts: 2
  • Country: us
Re: CANdb++ .dbc to C/C++ .h converter
« Reply #24 on: December 04, 2023, 08:30:15 pm »
The tool is very useful, even with the hand modifications.  I will provide more info next week, when I can get back to looking at the dbc file.

Thanks.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf