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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy