Skip to content

Commit fa848aa

Browse files
Improved SCA publish
1 parent 3eac7b8 commit fa848aa

File tree

5 files changed

+104
-33
lines changed

5 files changed

+104
-33
lines changed

src/CommandLineUtilities/AliceLowlevelFrontend/ProgramAliceLowlevelFrontendServer.cxx

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@ struct ServiceDescription
8383
std::vector<uintptr_t> addresses;
8484
};
8585

86-
struct Sca
86+
struct ScaSequence
8787
{
88-
std::vector<std::pair<uint32_t, uint32_t>> commandDataPairs;
88+
std::vector<Sca::CommandData> commandDataPairs;
8989
};
9090

91-
boost::variant<Register, Sca> type;
91+
boost::variant<Register, ScaSequence> type;
9292
};
9393

9494
/// Class that handles adding/removing publishers
@@ -151,8 +151,8 @@ class PublisherRegistry
151151
<< type.addresses.size() << " address(es) at interval "
152152
<< mDescription.interval.count() << "ms" << endm;
153153
},
154-
[&](const ServiceDescription::Sca& type){
155-
registerValues.resize(1); // SCA publisher only publishes 1 value
154+
[&](const ServiceDescription::ScaSequence& type){
155+
registerValues.resize(type.commandDataPairs.size() * 2); // Two result 32-bit integers per pair
156156

157157
getInfoLogger() << "Starting SCA publisher '" << mDescription.dnsName << "' with "
158158
<< type.commandDataPairs.size() << " commands(s) at interval "
@@ -183,17 +183,14 @@ class PublisherRegistry
183183
registerValues.at(i) = channel.readRegister(index);
184184
}
185185
},
186-
[&](const ServiceDescription::Sca& type){
186+
[&](const ServiceDescription::ScaSequence& type){
187187
auto sca = Sca(channel, channel.getCardType());
188-
189188
for (size_t i = 0; i < type.commandDataPairs.size(); ++i) {
190189
const auto& pair = type.commandDataPairs[i];
191-
sca.write(pair.first, pair.second);
192-
if (i+1 == type.commandDataPairs.size()) {
193-
// Last one, we do a read. This result is published.
194-
auto result = sca.read();
195-
registerValues.at(0) = channel.readRegister(result.data);
196-
}
190+
sca.write(pair);
191+
auto result = sca.read();
192+
registerValues[i*2] = result.command;
193+
registerValues[i*2 + 1] = result.data;
197194
}
198195
}
199196
);
@@ -296,6 +293,8 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
296293
[&](auto parameter){return registerWrite(parameter, bar0);});
297294
auto serverPublishStart = makeServer(names.publishStartCommandRpc(),
298295
[&](auto parameter){return publishStartCommand(parameter, mCommandQueue);});
296+
auto serverPublishScaStart = makeServer(names.publishScaStartCommandRpc(),
297+
[&](auto parameter){return publishScaStartCommand(parameter, mCommandQueue);});
299298
auto serverPublishStop = makeServer(names.publishStopCommandRpc(),
300299
[&](auto parameter){return publishStopCommand(parameter, mCommandQueue);});
301300
auto serverScaRead = makeServer(names.scaRead(),
@@ -347,6 +346,16 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
347346
}
348347
}
349348

349+
/// Try to add a command to the queue
350+
static bool tryAddToQueue(const CommandVariant& command, CommandQueue& queue)
351+
{
352+
if (!queue.write(command)) {
353+
getInfoLogger() << " command queue was full!" << endm;
354+
return false;
355+
}
356+
return true;
357+
}
358+
350359
/// RPC handler for register reads
351360
static std::string registerRead(const std::string& parameter, ChannelSharedPtr channel)
352361
{
@@ -387,7 +396,7 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
387396
}
388397

389398
/// RPC handler for publish commands
390-
static std::string publishStartCommand(const std::string& parameter, CommandQueue& commandQueue)
399+
static std::string publishStartCommand(const std::string& parameter, CommandQueue& queue)
391400
{
392401
getInfoLogger() << "Received publish command: '" << parameter << "'" << endm;
393402
auto params = split(parameter, ";");
@@ -397,19 +406,39 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
397406
description.dnsName = params.at(0);
398407
description.interval = std::chrono::milliseconds(int64_t(b::lexical_cast<double>(params.at(2)) * 1000.0));
399408

400-
if (!commandQueue.write(CommandPublishStart{std::move(description)})) {
401-
getInfoLogger() << " command queue was full!" << endm;
409+
tryAddToQueue(CommandPublishStart{description}, queue);
410+
return "";
411+
}
412+
413+
/// RPC handler for SCA publish commands
414+
static std::string publishScaStartCommand(const std::string& parameter, CommandQueue& queue)
415+
{
416+
getInfoLogger() << "Received SCA publish command: '" << parameter << "'" << endm;
417+
418+
auto params = split(parameter, ";");
419+
420+
// Convert command-data pair string sequence to binary format
421+
ServiceDescription::ScaSequence sca;
422+
auto commandDataPairStrings = split(params.at(1), "\n");
423+
sca.commandDataPairs.resize(commandDataPairStrings.size());
424+
for (size_t i = 0; i < commandDataPairStrings.size(); ++i) {
425+
sca.commandDataPairs[i] = stringToScaCommandDataPair(commandDataPairStrings[i]);
402426
}
427+
428+
ServiceDescription description;
429+
description.type = sca;
430+
description.dnsName = params.at(0);
431+
description.interval = std::chrono::milliseconds(int64_t(b::lexical_cast<double>(params.at(2)) * 1000.0));
432+
433+
tryAddToQueue(CommandPublishStart{description}, queue);
403434
return "";
404435
}
405436

406437
/// RPC handler for publish stop commands
407-
static std::string publishStopCommand(const std::string& parameter, CommandQueue& commandQueue)
438+
static std::string publishStopCommand(const std::string& parameter, CommandQueue& queue)
408439
{
409440
getInfoLogger() << "Received stop command: '" << parameter << "'" << endm;
410-
if (!commandQueue.write(CommandPublishStop{parameter})) {
411-
getInfoLogger() << " command queue was full!" << endm;
412-
}
441+
tryAddToQueue(CommandPublishStop{parameter}, queue);
413442
return "";
414443
}
415444

@@ -461,26 +490,18 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
461490
std::stringstream resultBuffer;
462491
auto sca = Sca(*bar2, bar2->getCardType());
463492

464-
for (std::string token : tokenizer(parameter, sep)) {
493+
for (const std::string& token : tokenizer(parameter, sep)) {
465494
// Walk through the tokens, these should be the pairs (or comments).
466495
if (token.find('#') == 0) {
467496
// We have a comment, skip this token
468497
continue;
469498
} else {
470-
// The pairs are comma-separated, so we split them.
471-
std::vector<std::string> pair = split(token, ",");
472-
if (pair.size() != 2) {
473-
BOOST_THROW_EXCEPTION(
474-
AlfException() << ErrorInfo::Message("SCA command-data pair not formatted correctly"));
475-
}
476-
auto command = convertHexString(pair[0]);
477-
auto data = convertHexString(pair[1]);
478-
499+
auto commandData = stringToScaCommandDataPair(token);
479500
try {
480-
sca.write(command, data);
501+
sca.write(commandData);
481502
auto result = sca.read();
482-
getInfoLogger() << (b::format("cmd=0x%x data=0x%x result=0x%x") % command % data % result.data).str()
483-
<< endm;
503+
getInfoLogger() << (b::format("cmd=0x%x data=0x%x result=0x%x") % commandData.command % commandData.data %
504+
result.data).str() << endm;
484505
resultBuffer << std::hex << result.data << '\n';
485506
} catch (const ScaException &e) {
486507
// If an SCA error occurs, we stop executing the sequence of commands and return the results as far as we got
@@ -494,6 +515,20 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
494515
return resultBuffer.str();
495516
}
496517

518+
static Sca::CommandData stringToScaCommandDataPair(const std::string& string)
519+
{
520+
// The pairs are comma-separated, so we split them.
521+
std::vector<std::string> pair = split(string, ",");
522+
if (pair.size() != 2) {
523+
BOOST_THROW_EXCEPTION(
524+
AlfException() << ErrorInfo::Message("SCA command-data pair not formatted correctly"));
525+
}
526+
Sca::CommandData commandData;
527+
commandData.command = convertHexString(pair[0]);
528+
commandData.data = convertHexString(pair[1]);
529+
return commandData;
530+
};
531+
497532
int mSerialNumber = 0;
498533
CommandQueue mCommandQueue;
499534
double mTemperature = 40;

src/CommandLineUtilities/AliceLowlevelFrontend/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,30 @@ The return string could be "success:" or "failure:Address out of range".
2525

2626
## Service description
2727

28+
#### Publish registers
29+
Starts a service under a DNS name, that publishes the contents of the given register addresses at the specified
30+
interval.
31+
Values are published as array of 32 bit unsigned integers.
32+
* Service type: RPC call
33+
* Service name: PUBLISH_START
34+
* Parameters: DNS name to publish at, comma-separated register addresses, interval in seconds
35+
* Return: empty
36+
37+
#### Publish SCA
38+
Starts a service under a DNS name, that executes and publishes the results of the given SCA write sequence at the
39+
specified interval. Values are published as array of 32 bit unsigned integers.
40+
* Service type: RPC call
41+
* Service name: PUBLISH_SCA_START
42+
* Parameters: DNS name to publish at, comma-separated register addresses, interval in seconds
43+
* Return: empty
44+
45+
#### Publish stop
46+
Stops a publishing service (either regular or SCA) registered under the given DNS name.
47+
* Service type: RPC call
48+
* Service name: PUBLISH_STOP
49+
* Parameters: DNS name
50+
* Return: empty
51+
2852
#### Register read
2953
* Service type: RPC call
3054
* Service name: REGISTER_READ

src/CommandLineUtilities/AliceLowlevelFrontend/Sca.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,20 @@ class Sca
2525
uint32_t data;
2626
};
2727

28+
struct CommandData
29+
{
30+
uint32_t command;
31+
uint32_t data;
32+
};
33+
2834
Sca(RegisterReadWriteInterface& bar2, CardType::type cardType);
2935

3036
void initialize();
3137
void write(uint32_t command, uint32_t data);
38+
void write(CommandData commandData)
39+
{
40+
write(commandData.command, commandData.data);
41+
}
3242
ReadResult read();
3343
ReadResult gpioRead();
3444
ReadResult gpioWrite(uint32_t data);

src/CommandLineUtilities/AliceLowlevelFrontend/ServiceNames.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ std::string ServiceNames::_function() const \
2020
DEFSERVICENAME(registerReadRpc, "REGISTER_READ")
2121
DEFSERVICENAME(registerWriteRpc, "REGISTER_WRITE")
2222
DEFSERVICENAME(publishStartCommandRpc, "PUBLISH_SERVICE")
23+
DEFSERVICENAME(publishScaStartCommandRpc, "PUBLISH_SCA_SERVICE")
2324
DEFSERVICENAME(publishStopCommandRpc, "PUBLISH_SERVICE_STOP")
2425
DEFSERVICENAME(scaRead, "SCA_READ")
2526
DEFSERVICENAME(scaWrite, "SCA_WRITE")

src/CommandLineUtilities/AliceLowlevelFrontend/ServiceNames.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ServiceNames
2424
std::string registerReadRpc() const;
2525
std::string registerWriteRpc() const;
2626
std::string publishStartCommandRpc() const;
27+
std::string publishScaStartCommandRpc() const;
2728
std::string publishStopCommandRpc() const;
2829
std::string scaWrite() const;
2930
std::string scaWriteSequence() const;

0 commit comments

Comments
 (0)