Skip to content

Commit 39fd6f3

Browse files
committed
Many changes and fixes in here, still TODO comments
I think it is time for a little reorganization, but on top of that this branch and commit aims to: * Fix enumeration generation * Add in a better framework for handling options and different version which need generating. * Add new utility functions There will be a few other tasks such as: * Bring up code to coding standards * Add in more comments to the generated code (asking for donations, pointing to product website, etc.) * Updated MPC library * Implement/Fix TODOs
1 parent 11790e5 commit 39fd6f3

16 files changed

+4775
-4560
lines changed

2c.c

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -862,21 +862,65 @@ static int switch_function_print(FILE *c, dbc_t *dbc, bool prototype, const char
862862
return fprintf(c, "\treturn -1; \n}\n\n");
863863
}
864864

865-
static void msg2h_define_can_ids(dbc_t *dbc, FILE *h) {
865+
// TODO: Define enums as well/instead of.
866+
/* NB. We should really use these enum names instead of the msg->id */
867+
static void msg2h_define_can_ids(dbc_t *dbc, FILE *h, dbc2c_options_t *copts) {
868+
assert(dbc);
869+
assert(h);
870+
assert(copts);
871+
872+
if (dbc->message_count == 0)
873+
return;
874+
875+
const int ens = copts->generate_enum_can_ids;
876+
877+
if (ens) {
878+
fprintf(h, "enum {\n"); // TODO: Typedef
879+
}
866880
for (size_t i = 0; i < dbc->message_count; i++) {
867-
char* name = duplicate(dbc->messages[i]->name);
881+
can_msg_t *msg = dbc->messages[i];
882+
char *name = duplicate(msg->name);
868883

869884
for (size_t i = 0; name[i] != 0; i++)
870885
name[i] = toupper(name[i]);
871-
872-
fprintf(h, "#define CAN_ID_%s %lu\n", name, dbc->messages[i]->id);
886+
if (ens) {
887+
fprintf(h, "\tCAN_ID_%s = %lu, /* 0x%lx */\n", name, msg->id, msg->id);
888+
} else {
889+
fprintf(h, "#define CAN_ID_%s (%lu) /* 0x%lx */\n", name, msg->id, msg->id);
890+
}
873891

874892
free(name);
875893
}
894+
if (ens) {
895+
fprintf(h, "};\n");
896+
}
876897

877898
fprintf(h, "\n");
878899
}
879900

901+
static char *escape_string(const char *s, int upper) {
902+
const size_t max_char_len = 4;
903+
const size_t l = strlen(s) * max_char_len + 1;
904+
char *n = allocate(l);
905+
int ch = 0;
906+
for (size_t i = 0, j = 0; (ch = s[i]); i++) {
907+
assert(j < l);
908+
ch = ch == ' ' ? '_' : ch;
909+
if (!isalnum(ch) && ch != '_') {
910+
911+
sprintf(&n[j], "_%02x_", ch);
912+
j += max_char_len;
913+
} else {
914+
if (upper > 0)
915+
ch = toupper(ch);
916+
if (upper < 0)
917+
ch = tolower(ch);
918+
n[j++] = ch;
919+
}
920+
}
921+
return n;
922+
}
923+
880924
static int msg2h_types(dbc_t *dbc, FILE *h, dbc2c_options_t *copts)
881925
{
882926
assert(h);
@@ -901,24 +945,32 @@ static int msg2h_types(dbc_t *dbc, FILE *h, dbc2c_options_t *copts)
901945
signal_t* signal = msg->sigs[i];
902946
val_list_t *list = signal->val_list;
903947

904-
if (list == NULL)
948+
if (!list)
905949
continue;
906950

951+
/* We really should use enum values in generated C codes/as types */
907952
fprintf(h, "typedef enum {\n");
908953
for (size_t j = 0; j < list->val_list_item_count; j++) {
909954
val_list_item_t *item = list->val_list_items[j];
910955

911-
char enum_value_name[MAX_NAME_LENGTH] = {0};
912-
913-
if (copts->version >= 2)
914-
snprintf(enum_value_name, MAX_NAME_LENGTH-1, "%s_%s_%s", name, list->name, item->name);
915-
else
916-
fprintf(h, "\t%s_%s_e = %d,\n", list->name, item->name, item->value);
917-
918-
for (int i = 0;enum_value_name[i] != 0;i++)
919-
enum_value_name[i] = toupper(enum_value_name[i]);
956+
int r = 0;
957+
958+
if (copts->version >= 2) {
959+
char *ename = escape_string(item->name, 0);
960+
if (strlen(ename) != strlen(item->name))
961+
warning("Non C-Ident characters in enumeration generation: '%s' -> '%s'", item->name, ename);
962+
char enum_value_name[MAX_NAME_LENGTH] = { 0, };
963+
r = snprintf(enum_value_name, MAX_NAME_LENGTH-1, "%s_%s_%s", name, list->name, ename);
964+
for (int i = 0; enum_value_name[i]; i++)
965+
enum_value_name[i] = toupper(enum_value_name[i]);
966+
fprintf(h, "\t%s = %d,\n", enum_value_name, item->value);
967+
free(ename);
968+
} else {
969+
r = fprintf(h, "\t%s_%s_e = %d,\n", list->name, item->name, item->value);
970+
}
971+
if (r < 0)
972+
error("output failed");
920973

921-
fprintf(h, "\t%s = %d,\n", enum_value_name, item->value);
922974
}
923975

924976
if (copts->version >= 2)
@@ -999,7 +1051,7 @@ int dbc2c(dbc_t *dbc, FILE *c, FILE *h, const char *name, dbc2c_options_t *copts
9991051
"/* If the contents of this file have caused breaking changes for you, you could try using\n"
10001052
" an older version of the generator. You can specify this on the command line with\n"
10011053
" the -n option. */\n"
1002-
"#define DBCC_GENERATOR_VERSION %i\n\n"
1054+
"#define DBCC_GENERATOR_VERSION (%d)\n\n"
10031055
"#include <stdint.h>\n"
10041056
"%s\n\n"
10051057
"#ifdef __cplusplus\n"
@@ -1032,7 +1084,7 @@ int dbc2c(dbc_t *dbc, FILE *c, FILE *h, const char *name, dbc2c_options_t *copts
10321084
fprintf(h, "} dbcc_signal_status_e;\n");
10331085
fprintf(h, "#endif\n\n");
10341086

1035-
msg2h_define_can_ids(dbc, h);
1087+
msg2h_define_can_ids(dbc, h, copts);
10361088

10371089
if (msg2h_types(dbc, h, copts) < 0) {
10381090
rv = -1;

2c.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ typedef struct {
1414
bool use_doubles_for_encoding;
1515
bool generate_print, generate_pack, generate_unpack;
1616
bool generate_asserts;
17+
bool generate_enum_can_ids;
1718
int version;
1819
} dbc2c_options_t;
1920

2csv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static int msg2csv(can_msg_t *msg, FILE *o)
3232
}
3333

3434
/* "MSG, ID, DLC, Signal, Start, Length, Endianess, Scaling, Offset, Minimum, Maximum, Signed, Units, Multiplexed */
35-
fprintf(o, "%s, %lu, %u, ", msg->name, msg->id, msg->dlc);
35+
fprintf(o, "%s, %lu, %u, ", msg->name, msg->id | ((unsigned long)msg->is_extended << 31) , msg->dlc);
3636
fprintf(o, "%s, ", sig->name);
3737
fprintf(o, "%u, ", sig->start_bit);
3838
fprintf(o, "%u, ", sig->bit_length);

2json.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ static int msg2json(can_msg_t *msg, FILE *o, unsigned depth)
104104
assert(o);
105105
indent(o, depth);
106106
fprintf(o, "{\n");
107-
pfield(o, depth+1, false, STRING, "name", "%s", msg->name);
108-
pfield(o, depth+1, false, INT, "id", "%u", msg->id);
109-
pfield(o, depth+1, false, INT, "dlc", "%u", msg->dlc);
107+
pfield(o, depth+1, false, STRING, "name", "%s", msg->name);
108+
pfield(o, depth+1, false, INT, "id", "%u", msg->id);
109+
pfield(o, depth+1, false, BOOL, "extended", "%s", msg->is_extended ? "true" : "false");
110+
pfield(o, depth+1, false, INT, "dlc", "%u", msg->dlc);
110111

111112
signal_t *multiplexor = NULL;
112113
indent(o, depth+1);

2xml.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ static int msg2xml(can_msg_t *msg, FILE *o, unsigned depth)
136136
pnode(o, depth+1, "name", "%s", msg->name);
137137
pnode(o, depth+1, "id", "%u", msg->id);
138138
pnode(o, depth+1, "dlc", "%u", msg->dlc);
139+
pnode(o, depth+1, "extended", "%d", (int)msg->is_extended);
139140

140141
signal_t *multiplexor = NULL;
141142
for (size_t i = 0; i < msg->signal_count; i++) {

can.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,19 @@ static can_msg_t *ast2msg(mpc_ast_t *top, mpc_ast_t *ast, dbc_t *dbc)
239239
r = sscanf(id->contents, "%lu", &c->id);
240240
assert(r == 1);
241241

242+
/* Extended CAN messages use the top most bit (which should
243+
* not normally be set) to indicate that they are extended
244+
* and not normal messages. */
245+
246+
// TODO: Handle version generation
247+
//if (copt->version >= 3 || copt->feature_mask_ids) {
248+
const uint32_t msk = 0x80000000u;
249+
if (c->id & 0x80000000u) {
250+
c->is_extended = true;
251+
c->id &= ~msk;
252+
}
253+
//}
254+
242255
signal_t **signal_s = allocate(sizeof(*signal_s));
243256
size_t len = 1, j = 0;
244257
for (int i = 0; i >= 0;) {

can.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ typedef struct {
6464
size_t signal_count; /**< number of signals */
6565
unsigned dlc; /**< length of CAN message 0-8 bytes */
6666
unsigned long id; /**< identifier, 11 or 29 bit */
67+
bool is_extended; /**< is extended mode message (29bit) */
6768
char *comment;
6869
} can_msg_t;
6970

@@ -73,6 +74,7 @@ typedef struct {
7374
can_msg_t **messages; /**< list of messages */
7475
size_t val_count; /**< count of vals */
7576
val_list_t **vals; /**< value list; used for enumerations in DBC file */
77+
int version; /**< version information used for generating files (not just C) */
7678
} dbc_t;
7779

7880
dbc_t *ast2dbc(mpc_ast_t *ast);

dbcc.xsd

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<xs:element name="id" type="can-id"/>
3131
<!-- 11 or 29 bit CAN ID -->
3232
<xs:element name="dlc" type="dlc"/>
33+
<xs:element maxOccurs="1" minOccurs="0" name="extended" type="intBool"/>
3334
<xs:element minOccurs="0" maxOccurs="unbounded" ref="signal"/>
3435
<xs:element maxOccurs="1" minOccurs="0" ref="multiplexor-group"/>
3536
</xs:sequence>
@@ -131,4 +132,10 @@
131132
<xs:maxInclusive value="64"/>
132133
</xs:restriction>
133134
</xs:simpleType>
135+
<xs:simpleType name="intBool">
136+
<xs:restriction base="xs:integer">
137+
<xs:minInclusive value="0"/>
138+
<xs:maxInclusive value="1"/>
139+
</xs:restriction>
140+
</xs:simpleType>
134141
</xs:schema>

dbcc.xslt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<th>Message</th>
1717
<th>Id. (decimal)</th>
1818
<th>DLC</th>
19+
<th>Extended</th>
1920
<th>Signals</th>
2021
</tr>
2122
<xsl:apply-templates select="message">
@@ -48,6 +49,7 @@
4849
<td> <xsl:value-of select="name"/> </td>
4950
<td> <xsl:value-of select="id"/> </td>
5051
<td> <xsl:value-of select="dlc"/> </td>
52+
<td> <xsl:value-of select="extended"/> </td>
5153
<td>
5254
<xsl:apply-templates select="signal" mode="signal-name">
5355
<xsl:sort select="name"/>

double_signal.dbc

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
1-
VERSION "HIPBNYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY/4/%%%/4/'%**4YYY///"
2-
3-
4-
NS_ :
5-
NS_DESC_
6-
CM_
7-
BA_DEF_
8-
BA_
9-
VAL_
10-
CAT_DEF_
11-
CAT_
12-
FILTER
13-
BA_DEF_DEF_
14-
EV_DATA_
15-
ENVVAR_DATA_
16-
SGTYPE_
17-
SGTYPE_VAL_
18-
BA_DEF_SGTYPE_
19-
BA_SGTYPE_
20-
SIG_TYPE_REF_
21-
VAL_TABLE_
22-
SIG_GROUP_
23-
SIG_VALTYPE_
24-
SIGTYPE_VALTYPE_
25-
26-
BS_:
27-
28-
BU_: NewNode0
29-
30-
31-
BO_ 1024 NewMessage0: 8 NewNode0
32-
SG_ DoubleSignal0 : 0|64@1- (1,0) [0|0] "" Vector__XXX
33-
34-
35-
SIG_VALTYPE_ 1024 DoubleSignal0 : 2;
1+
VERSION "HIPBNYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY/4/%%%/4/'%**4YYY///"
2+
3+
4+
NS_ :
5+
NS_DESC_
6+
CM_
7+
BA_DEF_
8+
BA_
9+
VAL_
10+
CAT_DEF_
11+
CAT_
12+
FILTER
13+
BA_DEF_DEF_
14+
EV_DATA_
15+
ENVVAR_DATA_
16+
SGTYPE_
17+
SGTYPE_VAL_
18+
BA_DEF_SGTYPE_
19+
BA_SGTYPE_
20+
SIG_TYPE_REF_
21+
VAL_TABLE_
22+
SIG_GROUP_
23+
SIG_VALTYPE_
24+
SIGTYPE_VALTYPE_
25+
26+
BS_:
27+
28+
BU_: NewNode0
29+
30+
31+
BO_ 1024 NewMessage0: 8 NewNode0
32+
SG_ DoubleSignal0 : 0|64@1- (1,0) [0|0] "" Vector__XXX
33+
34+
35+
SIG_VALTYPE_ 1024 DoubleSignal0 : 2;

enum.dbc

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
VERSION ""
2+
3+
4+
NS_ :
5+
NS_DESC_
6+
CM_
7+
BA_DEF_
8+
BA_
9+
VAL_
10+
CAT_DEF_
11+
CAT_
12+
FILTER
13+
BA_DEF_DEF_
14+
EV_DATA_
15+
ENVVAR_DATA_
16+
SGTYPE_
17+
SGTYPE_VAL_
18+
BA_DEF_SGTYPE_
19+
BA_SGTYPE_
20+
SIG_TYPE_REF_
21+
VAL_TABLE_
22+
SIG_GROUP_
23+
SIG_VALTYPE_
24+
SIGTYPE_VALTYPE_
25+
BO_TX_BU_
26+
BA_DEF_REL_
27+
BA_REL_
28+
BA_DEF_DEF_REL_
29+
BU_SG_REL_
30+
BU_EV_REL_
31+
BU_BO_REL_
32+
SG_MUL_VAL_
33+
34+
BS_:
35+
36+
BU_: Destination IVT_30_Node
37+
38+
39+
BO_ 2147483938 IVT_SleepAck: 1 IVT_30_Node
40+
SG_ IVT_SleepAck : 0|4@1- (1,0) [0|0] "" Destination
41+
42+
BO_ 3 IVT_Ctrl: 8 Destination
43+
SG_ IVT_Ctrl_Fuse_State : 13|1@1+ (1,0) [0|0] "" IVT_30_Node
44+
45+
BO_ 1 enum1: 8 Destination
46+
SG_ state : 0|4@1+ (1,0) [0|0] "" A_node
47+
48+
BO_ 4 enum2: 8 Destination
49+
SG_ state : 0|4@1+ (1,0) [0|0] "" A_node
50+
51+
52+
CM_ BO_ 2147483938 "Control message 1.";
53+
CM_ SG_ 2147483938 IVT_SleepAck "cm 1";
54+
CM_ BO_ 3 "Control message 2.";
55+
CM_ SG_ 3 IVT_Ctrl_Fuse_State "cm 1";
56+
BA_DEF_ "Version" STRING ;
57+
BA_DEF_ "SyncJumpWidthMin" INT 1 4;
58+
BA_DEF_ "SyncJumpWidthMax" INT 1 4;
59+
BA_DEF_ "SamplePointMin" INT 1 100;
60+
BA_DEF_ "SamplePointMax" INT 1 100;
61+
BA_DEF_ SG_ "GenSigStartValue" INT -2147483648 2147483647;
62+
BA_DEF_ "Baudrate" INT 250000 1000000;
63+
BA_DEF_ "BusType" STRING ;
64+
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65535;
65+
BA_DEF_DEF_ "Version" "1_1_0_Released";
66+
BA_DEF_DEF_ "SyncJumpWidthMin" 1;
67+
BA_DEF_DEF_ "SyncJumpWidthMax" 1;
68+
BA_DEF_DEF_ "SamplePointMin" 1;
69+
BA_DEF_DEF_ "SamplePointMax" 1;
70+
BA_DEF_DEF_ "GenSigStartValue" 0;
71+
BA_DEF_DEF_ "Baudrate" 500000;
72+
BA_DEF_DEF_ "BusType" "CAN";
73+
BA_DEF_DEF_ "GenMsgCycleTime" 0;
74+
BA_ "SyncJumpWidthMin" 2;
75+
BA_ "SyncJumpWidthMax" 4;
76+
BA_ "SamplePointMin" 80;
77+
BA_ "SamplePointMax" 84;
78+
BA_ "Baudrate" 500000;
79+
BA_ "BusType" "CAN";
80+
BA_ "GenMsgCycleTime" BO_ 3 100;
81+
VAL_ 1 state 0 "Inactive" 1 "Active";
82+
VAL_ 2 state 3 "OFF" 4 "ON";
83+
VAL_ 3 IVT_Ctrl_Fuse_State 1 "Fuse+ AND Fuse- closed" 0 "Fuse+ OR Fuse- open";
84+
VAL_ 2147483938 IVT_SleepAck 15 "reserved 15" 14 "reserved 14" 13 "reserved 13" 12 "reserved 12" 11 "reserved 11" 10 "reserved 10" 9 "reserved 9" 8 "reserved 8" 7 "reserved 7" 6 "reserved 6" 5 "reserved 5" 4 "reserved 4" 3 "reserved 3" 2 "reserved 2" 1 "Sleep request acknowledged" 0 "Sleep request not acknowledged";

0 commit comments

Comments
 (0)