Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4915ed1

Browse files
committed
Added core signals/message expression printer code.
1 parent 45a85ac commit 4915ed1

File tree

2 files changed

+179
-0
lines changed

2 files changed

+179
-0
lines changed

src/codegen/c-sigprinter.cpp

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
#include "c-sigprinter.h"
22

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+
}
314

415
CSigPrinter::CSigPrinter()
516
{
17+
sigs_expr.clear();
618
}
719

820
CSigPrinter::~CSigPrinter()
921
{
22+
sigs_expr.clear();
1023
}
1124

1225
void CSigPrinter::AddMessage(const std::vector<MessageDescriptor_t*> message)
@@ -29,12 +42,172 @@ void CSigPrinter::AddMessage(const MessageDescriptor_t& message)
2942
// add them to dedicated members, set signal stdint type
3043
// and push it to vector
3144

45+
BuildCConvertExprs(nexpr);
46+
3247
sigs_expr.push_back(nexpr);
3348
}
3449

50+
// This function determines what type will have struct
51+
// field for the @signal. It saves the <stdint> name
3552
std::string CSigPrinter::GetSignalType(const SignalDescriptor_t& signal)
3653
{
3754
std::string ret = "";
3855

3956
return ret;
4057
}
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+
}

src/codegen/c-sigprinter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@ class CSigPrinter
1717
private:
1818
std::string GetSignalType(const SignalDescriptor_t& signal);
1919

20+
int32_t BuildCConvertExprs(CiExpr_t* msg);
21+
22+
std::string PrintSignalExpr(SignalDescriptor_t* sig, std::vector<std::string>& to_bytes);
23+
24+
void AppendToByteLine(std::string& expr, std::string str);
25+
2026
};

0 commit comments

Comments
 (0)