1
1
#include " c-sigprinter.h"
2
2
3
+ // work buffer for all snprintf operations
4
+ static const size_t WBUFF_LEN = 2048 ;
5
+ static char workbuff[WBUFF_LEN] = { 0 };
6
+
7
+ // additional templates for expression generation
8
+ static std::string msk[] = { " 0" , " 0x01U" , " 0x03U" , " 0x07U" , " 0x0FU" , " 0x1FU" , " 0x3FU" , " 0x7FU" , " 0xFFU" };
9
+
10
+ static inline int32_t ShiftByte (const SignalDescriptor_t* sig, int32_t bn)
11
+ {
12
+ return (sig->Order == BitLayout::kIntel ) ? (bn - 1 ) : (bn + 1 );
13
+ }
3
14
4
15
CSigPrinter::CSigPrinter ()
5
16
{
17
+ sigs_expr.clear ();
6
18
}
7
19
8
20
CSigPrinter::~CSigPrinter ()
9
21
{
22
+ sigs_expr.clear ();
10
23
}
11
24
12
25
void CSigPrinter::AddMessage (const std::vector<MessageDescriptor_t*> message)
@@ -29,12 +42,172 @@ void CSigPrinter::AddMessage(const MessageDescriptor_t& message)
29
42
// add them to dedicated members, set signal stdint type
30
43
// and push it to vector
31
44
45
+ BuildCConvertExprs (nexpr);
46
+
32
47
sigs_expr.push_back (nexpr);
33
48
}
34
49
50
+ // This function determines what type will have struct
51
+ // field for the @signal. It saves the <stdint> name
35
52
std::string CSigPrinter::GetSignalType (const SignalDescriptor_t& signal)
36
53
{
37
54
std::string ret = " " ;
38
55
39
56
return ret;
40
57
}
58
+
59
+ int32_t CSigPrinter::BuildCConvertExprs (CiExpr_t* msg)
60
+ {
61
+ int32_t ret = 0 ;
62
+ std::string tmpstr;
63
+
64
+ msg->to_bytes .clear ();
65
+ msg->to_signals .clear ();
66
+ msg->to_bytes .resize (msg->msg .DLC );
67
+
68
+ // for each signal specific to_signal expression must be defined,
69
+ // and during all signals processing, for each byte to_byte expression
70
+ // must be collected
71
+
72
+ for (size_t i = 0 ; i < msg->msg .Signals .size (); i++)
73
+ {
74
+ // there are two main goal of this code:
75
+ // 1 - to generate bytes to signal C-expression, (_d - name of array).
76
+ // For each signal there is only one byte reference. It's generated
77
+ // once each function call for each signal
78
+ //
79
+ // 2 - to generate signals to each byte expression, (_m - name of struct with
80
+ // signals). For each byte a 8 signals can be referenced. It's generated
81
+ // consequently signal after signal (by adding chunks of expressions to @to_bytes
82
+ // collection)
83
+ //
84
+ // signal expression is saved to vector @to_signals, which id must be
85
+ // fully correlated to id of target signal. the final size of
86
+ // @to_signals vector must be equal to size of Signals vector
87
+ //
88
+ // bytes expression is saved to vector @to_bytes, where id is the
89
+ // byte number in frame payload (i.e. to_bytes.size() == frame.DLC)
90
+ msg->to_signals .push_back (PrintSignalExpr (&msg->msg .Signals [i], msg->to_bytes ));
91
+ }
92
+
93
+ return ret;
94
+ }
95
+
96
+ std::string CSigPrinter::PrintSignalExpr (SignalDescriptor_t* sig,
97
+ std::vector<std::string>& to_bytes)
98
+ {
99
+ // value for collecting expression (to_signal)
100
+ std::string tosigexpr;
101
+
102
+ uint16_t startb = (uint16_t )((sig->Order == BitLayout::kIntel ) ?
103
+ (sig->StartBit + (sig->LengthBit - 1 )) : (sig->StartBit ));
104
+
105
+ if (startb > 63 )
106
+ startb = 63 ;
107
+
108
+ int32_t bn = startb / 8 ;
109
+
110
+ // set valid to_byte prefix
111
+ int32_t bbc = (startb % 8 ) + 1 ;
112
+ int32_t slen = sig->LengthBit ;
113
+
114
+ if (bbc > slen)
115
+ {
116
+ snprintf (workbuff, WBUFF_LEN, " ((_d[%d] >> %d) & (%s))" , bn, bbc - slen, msk[slen].c_str ());
117
+ tosigexpr += workbuff;
118
+
119
+ snprintf (workbuff, WBUFF_LEN, " ((_m->{%s} & (%s)) << %d)" , sig->Name .c_str (), msk[slen].c_str (),
120
+ bbc - slen);
121
+ AppendToByteLine (to_bytes[bn], workbuff);
122
+ }
123
+ else if (bbc == slen)
124
+ {
125
+ // no rolling bits
126
+ snprintf (workbuff, WBUFF_LEN, " (_d[%d] & (%s))" , bn, msk[slen].c_str ());
127
+ tosigexpr += workbuff;
128
+
129
+ snprintf (workbuff, WBUFF_LEN, " (_m->%s & (%s))" , sig->Name .c_str (), msk[slen].c_str ());
130
+ AppendToByteLine (to_bytes[bn], workbuff);
131
+ }
132
+ else
133
+ {
134
+ std::string t64 = " " ;
135
+ slen -= bbc;
136
+
137
+ if (slen > 31 )
138
+ {
139
+ t64 = " (uint64_t)" ;
140
+ }
141
+
142
+ snprintf (workbuff, WBUFF_LEN, " (%s_d[%d] & (%s)) << %d)" , t64.c_str (), bn, msk[bbc].c_str (), slen);
143
+ tosigexpr += workbuff;
144
+
145
+ snprintf (workbuff, WBUFF_LEN, " ((_m->%s >> %d) & (%s))" , sig->Name .c_str (), slen,
146
+ msk[bbc].c_str ());
147
+ AppendToByteLine (to_bytes[bn], workbuff);
148
+
149
+ while ((slen - 8 ) >= 0 )
150
+ {
151
+ t64.clear ();
152
+
153
+ slen -= 8 ;
154
+
155
+ bn = ShiftByte (sig, bn);
156
+
157
+ tosigexpr += " | " ;
158
+
159
+ if (slen == 0 )
160
+ {
161
+ // last byte is aligned
162
+ snprintf (workbuff, WBUFF_LEN, " (_d[%d] & (%s))" , bn, msk[8 ].c_str ());
163
+ tosigexpr += workbuff;
164
+
165
+ snprintf (workbuff, WBUFF_LEN, " (_m->%s & (%s))" , sig->Name .c_str (), msk[8 ].c_str ());
166
+ AppendToByteLine (to_bytes[bn], workbuff);
167
+
168
+ }
169
+ else
170
+ {
171
+ if (slen > 31 )
172
+ {
173
+ t64 = " (uint64_t)" ;
174
+ }
175
+
176
+ snprintf (workbuff, WBUFF_LEN, " (%s(_d[%d] & (%s)) << %d)" , t64.c_str (), bn, msk[8 ].c_str (), slen);
177
+ tosigexpr += workbuff;
178
+
179
+
180
+ snprintf (workbuff, WBUFF_LEN, " ((_m->%s >> %d) & (%s))" , sig->Name .c_str (), slen, msk[8 ].c_str ());
181
+ AppendToByteLine (to_bytes[bn], workbuff);
182
+ }
183
+ }
184
+
185
+ if (slen > 0 )
186
+ {
187
+ bn = ShiftByte (sig, bn);
188
+
189
+ snprintf (workbuff, WBUFF_LEN, " | ((_d[%d] >> %d) & (%s))" , bn, 8 - slen, msk[slen].c_str ());
190
+ tosigexpr += workbuff;
191
+
192
+ snprintf (workbuff, WBUFF_LEN, " ((_m->%s & (%s)) << %d)" , sig->Name .c_str (), msk[slen].c_str (),
193
+ 8 - slen);
194
+ AppendToByteLine (to_bytes[bn], workbuff);
195
+ }
196
+ }
197
+
198
+ return tosigexpr;
199
+ }
200
+
201
+ void CSigPrinter::AppendToByteLine (std::string& expr, std::string str)
202
+ {
203
+ if (expr.size () > 0 )
204
+ {
205
+ // Not first appendingF
206
+ expr += " | " + str;
207
+ }
208
+ else
209
+ {
210
+ // First appending
211
+ expr = str;
212
+ }
213
+ }
0 commit comments