mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
move formatting of printing to stdout to separate class and make in configurable
Signed-off-by: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
This commit is contained in:
parent
498af9fd1c
commit
ce1e8e28ce
2 changed files with 92 additions and 18 deletions
|
@ -62,6 +62,87 @@ protected:
|
|||
bool dmaLoopback;
|
||||
};
|
||||
|
||||
class BufferedSampleFormatter {
|
||||
public:
|
||||
virtual void format(float value) = 0;
|
||||
virtual void output(std::ostream& out)
|
||||
{
|
||||
out << buf.data() << std::flush;
|
||||
clearBuf();
|
||||
}
|
||||
virtual void clearBuf()
|
||||
{
|
||||
for (size_t i = 0; i < bufSamples && buf[i*bufSampleSize] != '\0'; i++) {
|
||||
buf[i*bufSampleSize] = '\0';
|
||||
}
|
||||
currentBufLoc = 0;
|
||||
}
|
||||
protected:
|
||||
std::vector<char> buf;
|
||||
const size_t bufSamples;
|
||||
const size_t bufSampleSize;
|
||||
size_t currentBufLoc;
|
||||
|
||||
BufferedSampleFormatter(const size_t bufSamples, const size_t bufSampleSize) :
|
||||
buf(bufSamples*bufSampleSize+1), // Leave room for a final `\0'
|
||||
bufSamples(bufSamples),
|
||||
bufSampleSize(bufSampleSize),
|
||||
currentBufLoc(0) {};
|
||||
BufferedSampleFormatter() = delete;
|
||||
BufferedSampleFormatter(const BufferedSampleFormatter&) = delete;
|
||||
virtual char* nextBufPos()
|
||||
{
|
||||
return &buf[(currentBufLoc++)*bufSampleSize];
|
||||
}
|
||||
};
|
||||
|
||||
class BufferedSampleFormatterShort : public BufferedSampleFormatter {
|
||||
public:
|
||||
BufferedSampleFormatterShort(size_t bufSizeInSamples) :
|
||||
BufferedSampleFormatter(bufSizeInSamples, formatStringSize) {};
|
||||
|
||||
virtual void format(float value) override
|
||||
{
|
||||
if (std::snprintf(nextBufPos(), formatStringSize+1, formatString, value) > (int)formatStringSize) {
|
||||
throw RuntimeError("Output buffer too small");
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
static constexpr char formatString[] = "%7f\n";
|
||||
static constexpr size_t formatStringSize = 9;
|
||||
};
|
||||
|
||||
class BufferedSampleFormatterLong : public BufferedSampleFormatter {
|
||||
public:
|
||||
BufferedSampleFormatterLong(size_t bufSizeInSamples) :
|
||||
BufferedSampleFormatter(bufSizeInSamples, formatStringSize),
|
||||
sampleCnt(0) {};
|
||||
|
||||
virtual void format(float value) override
|
||||
{
|
||||
if (std::snprintf(nextBufPos(), formatStringSize+1, formatString, sampleCnt, value) > (int)formatStringSize) {
|
||||
throw RuntimeError("Output buffer too small");
|
||||
}
|
||||
sampleCnt = (sampleCnt+1)%100000;
|
||||
}
|
||||
|
||||
protected:
|
||||
static constexpr char formatString[] = "%05zd: %7f\n";
|
||||
static constexpr size_t formatStringSize = 16;
|
||||
size_t sampleCnt;
|
||||
};
|
||||
|
||||
std::unique_ptr<BufferedSampleFormatter> getBufferedSampleFormatter(const std::string &format, size_t bufSizeInSamples)
|
||||
{
|
||||
if (format == "long") {
|
||||
return std::make_unique<BufferedSampleFormatterLong>(bufSizeInSamples);
|
||||
} else if (format == "short") {
|
||||
return std::make_unique<BufferedSampleFormatterShort>(bufSizeInSamples);
|
||||
} else {
|
||||
throw RuntimeError("Unknown output format '{}'", format);
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace fpga */
|
||||
} /* namespace villas */
|
||||
|
|
|
@ -36,7 +36,8 @@ static std::shared_ptr<kernel::pci::DeviceList> pciDevices;
|
|||
static auto logger = villas::logging.get("ctrl");
|
||||
|
||||
|
||||
void readFromDmaToStdOut(std::shared_ptr<villas::fpga::ip::Dma> dma)
|
||||
void readFromDmaToStdOut(std::shared_ptr<villas::fpga::ip::Dma> dma,
|
||||
std::unique_ptr<fpga::BufferedSampleFormatter> formatter)
|
||||
{
|
||||
auto &alloc = villas::HostRam::getAllocator();
|
||||
|
||||
|
@ -56,33 +57,24 @@ void readFromDmaToStdOut(std::shared_ptr<villas::fpga::ip::Dma> dma)
|
|||
|
||||
size_t cur = 0, next = 1;
|
||||
std::ios::sync_with_stdio(false);
|
||||
size_t samplecnt = 0;
|
||||
static const char outputfmt[] = "%05zd: %7f\n";
|
||||
static const size_t outputfmtSize = 16;
|
||||
char outputbuf[16][outputfmtSize] = {0};
|
||||
size_t bytesRead;
|
||||
|
||||
// Setup read transfer
|
||||
dma->read(*block[0], block[0]->getSize());
|
||||
|
||||
while (true) {
|
||||
//logger->debug("Read from stream and write to address {:p}", *block[next]);
|
||||
logger->trace("Read from stream and write to address {}:{:p}", block[next]->getAddrSpaceId(), block[next]->getOffset());
|
||||
// We could use the number of interrupts to determine if we missed a chunk of data
|
||||
dma->read(*block[next], block[next]->getSize());
|
||||
bytesRead = dma->readComplete();
|
||||
|
||||
for (size_t i = 0; i*4 < bytesRead; i++) {
|
||||
int32_t ival = mem[cur][i];
|
||||
float fval = *((float*)(&ival)); // cppcheck-suppress invalidPointerCast
|
||||
//std::cerr << std::hex << ival << ",";
|
||||
//std::cout << samplecnt++ << ": " << fval << '\n';
|
||||
if (std::snprintf(outputbuf[i], outputfmtSize+1, outputfmt, (samplecnt++%100000), fval) > (int)outputfmtSize) {
|
||||
throw RuntimeError("Output buffer too small");
|
||||
}
|
||||
formatter->format(fval);
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(outputbuf)/sizeof(outputbuf[0])-bytesRead/4; i++) {
|
||||
outputbuf[i][0] = '\0';
|
||||
}
|
||||
std::cout << *outputbuf << std::flush;
|
||||
formatter->output(std::cout);
|
||||
|
||||
cur = next;
|
||||
next = (next + 1) % (sizeof(mem) / sizeof(mem[0]));
|
||||
}
|
||||
|
@ -104,6 +96,8 @@ int main(int argc, char* argv[])
|
|||
app.add_option("-x,--connect", connectStr, "Connect a FPGA port with another or stdin/stdout");
|
||||
bool noDma = false;
|
||||
app.add_flag("--no-dma", noDma, "Do not setup DMA, only setup FPGA and Crossbar links");
|
||||
std::string outputFormat = "short";
|
||||
app.add_option("--output-format", outputFormat, "Output format (short, long)");
|
||||
|
||||
app.parse(argc, argv);
|
||||
|
||||
|
@ -117,8 +111,6 @@ int main(int argc, char* argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
auto card = fpga::setupFpgaCard(configFile, fpgaName);
|
||||
|
||||
std::vector<std::shared_ptr<fpga::ip::AuroraXilinx>> aurora_channels;
|
||||
|
@ -149,7 +141,8 @@ int main(int argc, char* argv[])
|
|||
parsedConnectString.configCrossBar(dma, aurora_channels);
|
||||
|
||||
if (!noDma) {
|
||||
readFromDmaToStdOut(std::move(dma));
|
||||
auto formatter = fpga::getBufferedSampleFormatter(outputFormat, 16);
|
||||
readFromDmaToStdOut(std::move(dma), std::move(formatter));
|
||||
}
|
||||
} catch (const RuntimeError &e) {
|
||||
logger->error("Error: {}", e.what());
|
||||
|
|
Loading…
Add table
Reference in a new issue