22#include < iostream>
33#include < fstream>
44#include < filesystem>
5+ #include < algorithm>
56#include " parser/dbcscanner.h"
67#include " codegen/c-main-generator.h"
78#include " codegen/c-util-generator.h"
1011
1112#define GEN_UTIL_CODE
1213
14+ #define MIN_ARGC_NUM 4
15+ #define MAX_ARGC_NUM 5
16+
1317char verstr[128 ] = {0 };
1418
1519const char * helptext =
@@ -18,8 +22,10 @@ const char* helptext =
1822" To use utility you need to provide 3 arguments:\n\n "
1923" 1. dbc file path\n "
2024" 2. directory for generated source files (existable)\n "
21- " 3. prefix (driver name) which will be used for naming dirver parts\n\n "
22- " Usage example:\n\n ./dbccoder /home/user/docs/driveshaft.dbc /home/user/docs/gen/ drivedb\n\n " ;
25+ " 3. prefix (driver name) which will be used for naming dirver parts\n "
26+ " 4. (optional) --node-utils will generate specific pairs of binutils drivers for each node"
27+ " which is either transmitter or receiver of at least one frame from dbc.\n\n "
28+ " Usage example:\n\n ./dbccoder /home/user/docs/driveshaft.dbc /home/user/docs/gen/ drivedb --node-utils\n\n " ;
2329
2430DbcScanner* scanner;
2531CiMainGenerator* cigen;
@@ -40,7 +46,7 @@ int main(int argc, char* argv[])
4046std::snprintf (verstr,128 ," \n Dbccoder v%u.%u\n\n " , CODEGEN_LIB_VERSION_MAJ, CODEGEN_LIB_VERSION_MIN);
4147 std::cout << verstr;
4248
43- if (argc== 4 )
49+ if (argc>= MIN_ARGC_NUM )
4450 {
4551 std::ifstream reader;
4652// copy dbc file name to string variable
@@ -79,18 +85,89 @@ int main(int argc, char* argv[])
7985
8086#if defined (GEN_UTIL_CODE)
8187
82- ret = fscreator->PrepareDirectory (dbc_driver_name.c_str (), (source_files_out_path).c_str (),true , info);
83-
84- MsgsClassification groups;
88+ std::string node_util =" --node-utils" ;
8589
86- for (size_t i =0 ; i < scanner->dblist .msgs .size (); i++)
90+ // check if option --node-utils is requested, when requested binutil generation
91+ // wiil be performed on each node from DBC file in accordance to its RX / TX subscription
92+ if (argc == MAX_ARGC_NUM && node_util.compare (argv[4 ]) ==0 )
8793 {
88- groups.Rx .push_back (scanner->dblist .msgs [i]->MsgID );
94+ std::vector<std::string> nodes;
95+
96+ for (size_t num =0 ; num < scanner->dblist .msgs .size (); num++)
97+ {
98+ // iterate all messages and collect All nodes assign to at least one message
99+ auto m = scanner->dblist .msgs [num];
100+
101+ // test transmitter
102+ std::string nodename = m->Transmitter ;
103+ bool found = (std::find (nodes.begin (), nodes.end (), nodename) != nodes.end ());
104+
105+ if (!found)
106+ {
107+ nodes.push_back (nodename);
108+ }
109+
110+ for (size_t recs =0 ; recs < m->RecS .size (); recs++)
111+ {
112+ // test all recs
113+ found = (std::find (nodes.begin (), nodes.end (), nodename) != nodes.end ());
114+
115+ if (!found)
116+ {
117+ nodes.push_back (nodename);
118+ }
119+ }
120+ }
121+
122+ // for each node in collection perform specific bin-util generation
123+ for (size_t node =0 ; node < nodes.size (); node++)
124+ {
125+ std::string util_name = nodes[node] +" _" + dbc_driver_name;
126+
127+ ret = fscreator->PrepareDirectory (util_name.c_str (), source_files_out_path.c_str (),true , info);
128+
129+ MsgsClassification groups;
130+
131+ for (size_t i =0 ; i < scanner->dblist .msgs .size (); i++)
132+ {
133+ auto m = scanner->dblist .msgs [i];
134+
135+ if (m->Transmitter .compare (nodes[node]) ==0 )
136+ {
137+ groups.Tx .push_back (m->MsgID );
138+ }
139+ else
140+ {
141+ bool found = (std::find (m->RecS .begin (), m->RecS .end (), nodes[node]) != m->RecS .end ());
142+
143+ if (found)
144+ {
145+ groups.Rx .push_back (m->MsgID );
146+ }
147+ }
148+ }
149+
150+ if (ret)
151+ {
152+ ciugen->Generate (scanner->dblist , fscreator->FS , groups, dbc_driver_name);
153+ }
154+ }
89155 }
90-
91- if (ret)
156+ else
92157 {
93- ciugen->Generate (scanner->dblist , fscreator->FS , groups, dbc_driver_name);
158+ ret = fscreator->PrepareDirectory (dbc_driver_name.c_str (), (source_files_out_path).c_str (),true , info);
159+
160+ MsgsClassification groups;
161+
162+ for (size_t i =0 ; i < scanner->dblist .msgs .size (); i++)
163+ {
164+ groups.Rx .push_back (scanner->dblist .msgs [i]->MsgID );
165+ }
166+
167+ if (ret)
168+ {
169+ ciugen->Generate (scanner->dblist , fscreator->FS , groups, dbc_driver_name);
170+ }
94171 }
95172
96173#endif