Skip to content

Commit d36dba3

Browse files
committed
[alf-client] Extend with operaion flags and swt-stress test
1 parent 6dc60c2 commit d36dba3

File tree

5 files changed

+216
-167
lines changed

5 files changed

+216
-167
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ target_compile_features(ALF PUBLIC cxx_std_17)
9292
####################################
9393

9494
set(EXE_SRCS
95-
ProgramAlf.cxx
96-
ProgramAlfClient.cxx
95+
Alf.cxx
96+
AlfClient.cxx
9797
)
9898

9999
set(EXE_NAMES
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// granted to it by virtue of its status as an Intergovernmental Organization
99
// or submit itself to any jurisdiction.
1010

11-
/// \file ProgramAlf.cxx
11+
/// \file Alf.cxx
1212
/// \brief Definition of the command line tool to run the ALF server
1313
///
1414
/// \author Pascal Boeschoten ([email protected])
@@ -36,10 +36,10 @@ namespace Alf
3636

3737
AliceO2::InfoLogger::InfoLogger logger;
3838

39-
class ProgramAlf : public AliceO2::Common::Program
39+
class Alf : public AliceO2::Common::Program
4040
{
4141
public:
42-
ProgramAlf()
42+
Alf()
4343
{
4444
}
4545

@@ -132,5 +132,5 @@ class ProgramAlf : public AliceO2::Common::Program
132132

133133
int main(int argc, char** argv)
134134
{
135-
return AliceO2::Alf::ProgramAlf().execute(argc, argv);
135+
return AliceO2::Alf::Alf().execute(argc, argv);
136136
}

apps/AlfClient.cxx

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
/// \file AlfClient.cxx
12+
/// \brief Definition of the command line tool to run an ALF client
13+
///
14+
/// \author Pascal Boeschoten ([email protected])
15+
/// \author Kostas Alexopoulos ([email protected])
16+
17+
#include <boost/algorithm/string/case_conv.hpp>
18+
#include <boost/asio.hpp>
19+
#include <chrono>
20+
#include <cstdlib>
21+
#include <thread>
22+
23+
#include "AlfClient.h"
24+
#include "Common/Program.h"
25+
#include "Common/GuardFunction.h"
26+
#include "DimServices/ServiceNames.h"
27+
#include "Logger.h"
28+
29+
namespace ip = boost::asio::ip;
30+
namespace po = boost::program_options;
31+
32+
namespace AliceO2
33+
{
34+
namespace Alf
35+
{
36+
37+
AliceO2::InfoLogger::InfoLogger logger;
38+
39+
class AlfClient : public AliceO2::Common::Program
40+
{
41+
public:
42+
AlfClient()
43+
{
44+
}
45+
46+
virtual Description getDescription() override
47+
{
48+
return { "ALF DIM Client", "ALICE Low-level Front-end DIM client", "o2-alf-client" };
49+
}
50+
51+
virtual void addOptions(po::options_description& options) override
52+
{
53+
options.add_options()("dim-dns-node",
54+
po::value<std::string>(&mOptions.dimDnsNode)->default_value(""),
55+
"The DIM DNS node to connect to if the env var is not set");
56+
options.add_options()("serial",
57+
po::value<int>(&mOptions.serial),
58+
"CRU serial number");
59+
options.add_options()("link",
60+
po::value<int>(&mOptions.link),
61+
"Link number");
62+
options.add_options()("alf-id",
63+
po::value<std::string>(&mOptions.alfId)->default_value(""),
64+
"Hostname of node running the ALF server(required)");
65+
options.add_options()("ic",
66+
po::bool_switch(&mOptions.ic)->default_value(false),
67+
"Flag enabling the ic tests");
68+
options.add_options()("sca",
69+
po::bool_switch(&mOptions.sca)->default_value(false),
70+
"Flag enabling the sca tests");
71+
options.add_options()("swt",
72+
po::bool_switch(&mOptions.swt)->default_value(false),
73+
"Flag enabling the swt tests");
74+
options.add_options()("swt-stress",
75+
po::bool_switch(&mOptions.swtStress)->default_value(false),
76+
"Flag enabling the swt-stress tests");
77+
options.add_options()("swt-stress-cycles",
78+
po::value<int>(&mOptions.swtStressCycles)->default_value(2),
79+
"Number of cycles for which to run the SWT stress test");
80+
options.add_options()("swt-stress-words",
81+
po::value<int>(&mOptions.swtStressWords)->default_value(1000),
82+
"Number of SWT words to write and read in one go");
83+
}
84+
85+
virtual void run(const po::variables_map&) override
86+
{
87+
if (mOptions.alfId == "") {
88+
getErrorLogger() << "Parameter alf-id is required." << endm;
89+
return;
90+
}
91+
92+
getLogger() << "ALF client initializations..." << endm;
93+
94+
if (mOptions.dimDnsNode != "") {
95+
getLogger() << "Setting DIM_DNS_NODE from argument." << endm;
96+
getLogger() << "DIM_DNS_NODE=" << mOptions.dimDnsNode << endm;
97+
setenv("DIM_DNS_NODE", mOptions.dimDnsNode.c_str(), true);
98+
} else if (const char* dimDnsNode = std::getenv("DIM_DNS_NODE")) {
99+
getLogger() << "Picked up DIM_DMS_NODE from the environment." << endm;
100+
getLogger() << "DIM_DNS_NODE=" << dimDnsNode << endm;
101+
mOptions.dimDnsNode = dimDnsNode;
102+
} else {
103+
BOOST_THROW_EXCEPTION(AlfException() << ErrorInfo::Message("DIM_DNS_NODE env variable not set, and no relevant argument provided.")); // InfoLogger and errors?
104+
}
105+
106+
std::string alfId = mOptions.alfId;
107+
boost::to_upper(alfId);
108+
109+
getLogger() << "Starting the DIM Client using ALF ID=" << alfId << ", serial=" << mOptions.serial << " and link=" << mOptions.link << endm;
110+
111+
AlfLink link = AlfLink{ alfId, mOptions.serial, mOptions.link, nullptr };
112+
113+
ServiceNames names(link);
114+
Alf::RegisterReadRpc registerReadRpc(names.registerRead());
115+
Alf::RegisterWriteRpc registerWriteRpc(names.registerWrite());
116+
Alf::SwtSequenceRpc swtSequence(names.swtSequence());
117+
Alf::ScaSequenceRpc scaSequence(names.scaSequence());
118+
Alf::IcSequenceRpc icSequence(names.icSequence());
119+
Alf::IcGbtI2cWriteRpc icGbtI2cWriteRpc(names.icGbtI2cWrite());
120+
121+
// Test register write and read
122+
uint32_t wAddress = 0x00f00078;
123+
uint32_t wValue = 0x4;
124+
uint32_t rAddress = 0x00f0005c;
125+
registerWriteRpc.writeRegister(wAddress, wValue);
126+
uint32_t rValue = registerReadRpc.readRegister(rAddress);
127+
getLogger() << "[REGISTER] Wrote: " << Util::formatValue(wValue) << " Read: " << Util::formatValue(rValue) << endm;
128+
129+
if (mOptions.swt) {
130+
auto swtOut = swtSequence.write({ std::make_pair("0x0000000000000000000", "write"),
131+
std::make_pair("", "reset"),
132+
std::make_pair("0x000000001234", "write"),
133+
std::make_pair("", "read"),
134+
std::make_pair("0xdeadbeef", "write"),
135+
std::make_pair("1", "read"),
136+
std::make_pair("0xbadc0ffee", "write"),
137+
std::make_pair("4", "read") });
138+
getLogger() << "[SWT_SEQUENCE] output: " << swtOut << endm;
139+
}
140+
141+
if (mOptions.swtStress) {
142+
for (int cycle = 0; cycle < mOptions.swtStressCycles; cycle++) {
143+
// Make the input pairs
144+
std::vector<std::pair<std::string, std::string>> swtStressPairs;
145+
swtStressPairs.push_back(std::make_pair("", "reset"));
146+
for (int i = 0; i < mOptions.swtStressWords; i++) {
147+
std::stringstream ss;
148+
ss << "0x" << std::hex << i;
149+
swtStressPairs.push_back(std::make_pair(ss.str(), "write"));
150+
}
151+
swtStressPairs.push_back(std::make_pair("1000", "read"));
152+
153+
auto swtStressOut = swtSequence.write(swtStressPairs);
154+
getLogger() << "[SWT stress] cycle " << cycle << endm;
155+
//getLogger() << "[SWT stress] output: " << swtStressOut << endm;
156+
std::cout << "[SWT stress] output: " << swtStressOut << std::endl; // Infologger gets filled up here...
157+
}
158+
}
159+
160+
if (mOptions.sca) {
161+
auto scaOut = scaSequence.write({ std::make_pair("0x00010002", "0xff000000"),
162+
std::make_pair("0x00020004", "0xff000000"),
163+
std::make_pair("0x00030006", "0xff000000"),
164+
std::make_pair("0x0B950282", "0x50010000"),
165+
std::make_pair("0x0B9601DE", "0x50000000"),
166+
std::make_pair("0x0B970471", "0x50000000"),
167+
std::make_pair("0x0B980461", "0x50000000") });
168+
getLogger() << "[SCA_SEQUENCE] output: " << scaOut << endm;
169+
}
170+
171+
if (mOptions.ic) {
172+
auto icOut = icSequence.write({
173+
std::make_pair("0x54,0xff", "write"),
174+
std::make_pair("0x54", "read"),
175+
std::make_pair("0x55,0xff", "write"),
176+
std::make_pair("0x55", "read"),
177+
std::make_pair("0x56,0xff", "write"),
178+
std::make_pair("0x56", "read"),
179+
});
180+
getLogger() << "[IC_SEQUENCE] output: " << icOut << endm;
181+
182+
icGbtI2cWriteRpc.write(0x3);
183+
}
184+
185+
getLogger() << "See ya!" << endm;
186+
}
187+
188+
private:
189+
struct OptionsStruct {
190+
std::string dimDnsNode = "";
191+
int serial = -1;
192+
int link = -1;
193+
std::string alfId = "";
194+
bool ic = false;
195+
bool sca = false;
196+
bool swt = false;
197+
bool swtStress = false;
198+
int swtStressCycles = 2;
199+
int swtStressWords = 1000;
200+
} mOptions;
201+
};
202+
203+
} // namespace Alf
204+
} // namespace AliceO2
205+
206+
int main(int argc, char** argv)
207+
{
208+
return AliceO2::Alf::AlfClient().execute(argc, argv);
209+
}

0 commit comments

Comments
 (0)