diff --git a/fpga/include/villas/fpga/utils.hpp b/fpga/include/villas/fpga/utils.hpp index 2af117954..26051b3cc 100644 --- a/fpga/include/villas/fpga/utils.hpp +++ b/fpga/include/villas/fpga/utils.hpp @@ -17,8 +17,13 @@ namespace fpga { std::shared_ptr setupFpgaCard(const std::string &configFile, const std::string &fpgaName); +std::shared_ptr +createCard(json_t *config, std::list> &cards, + std::filesystem::path &searchPath, + std::shared_ptr vfioContainer, + std::string card_name = "anonymous Card"); int createCards(json_t *config, std::list> &cards, - std::filesystem::path &searchPath); + std::filesystem::path &searchPath, std::shared_ptr vfioContainer = nullptr); std::shared_ptr>> getAuroraChannels(std::shared_ptr card); @@ -55,81 +60,82 @@ protected: int dstAsInt; }; -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 buf; - const size_t bufSamples; - const size_t bufSampleSize; - size_t currentBufLoc; + 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; + } - 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]; - } -}; + protected: + std::vector buf; + const size_t bufSamples; + const size_t bufSampleSize; + size_t currentBufLoc; -class BufferedSampleFormatterShort : public BufferedSampleFormatter { -public: - BufferedSampleFormatterShort(size_t bufSizeInSamples) : - BufferedSampleFormatter(bufSizeInSamples, formatStringSize) {}; + 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]; + } + }; - virtual void format(float value) override - { - size_t chars; - if ((chars = std::snprintf(nextBufPos(), formatStringSize+1, formatString, value)) > (int)formatStringSize) { - throw RuntimeError("Output buffer too small. Expected " + std::to_string(formatStringSize) + - " characters, got " + std::to_string(chars)); - } - } + class BufferedSampleFormatterShort : public BufferedSampleFormatter { + public: + BufferedSampleFormatterShort(size_t bufSizeInSamples) + : BufferedSampleFormatter(bufSizeInSamples, formatStringSize){}; -protected: - static constexpr char formatString[] = "%013.6f\n"; - static constexpr size_t formatStringSize = 14; -}; + virtual void format(float value) override { + size_t chars; + if ((chars = std::snprintf(nextBufPos(), formatStringSize + 1, + formatString, value)) > + (int)formatStringSize) { + throw RuntimeError("Output buffer too small. Expected " + + std::to_string(formatStringSize) + + " characters, got " + std::to_string(chars)); + } + } -class BufferedSampleFormatterLong : public BufferedSampleFormatter { -public: - BufferedSampleFormatterLong(size_t bufSizeInSamples) : - BufferedSampleFormatter(bufSizeInSamples, formatStringSize), - sampleCnt(0) {}; + protected: + static constexpr char formatString[] = "%013.6f\n"; + static constexpr size_t formatStringSize = 14; + }; - 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; - } + class BufferedSampleFormatterLong : public BufferedSampleFormatter { + public: + BufferedSampleFormatterLong(size_t bufSizeInSamples) + : BufferedSampleFormatter(bufSizeInSamples, formatStringSize), + sampleCnt(0){}; -protected: - static constexpr char formatString[] = "%05zd: %013.6f\n"; - static constexpr size_t formatStringSize = 22; - size_t sampleCnt; -}; + 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: %013.6f\n"; + static constexpr size_t formatStringSize = 22; + size_t sampleCnt; + }; -std::unique_ptr getBufferedSampleFormatter(const std::string &format, size_t bufSizeInSamples); + std::unique_ptr + getBufferedSampleFormatter(const std::string &format, + size_t bufSizeInSamples); } // namespace fpga } // namespace villas diff --git a/fpga/lib/pcie_card.cpp b/fpga/lib/pcie_card.cpp index cdad33c44..fdc078c76 100644 --- a/fpga/lib/pcie_card.cpp +++ b/fpga/lib/pcie_card.cpp @@ -48,7 +48,7 @@ PCIeCardFactory::make(json_t *json_card, std::string card_name, if (ret != 0) throw ConfigError(json_card, err, "", "Failed to parse card"); - auto card = std::unique_ptr(make()); + auto card = std::shared_ptr(make()); // Populate generic properties card->name = std::string(card_name); diff --git a/fpga/lib/utils.cpp b/fpga/lib/utils.cpp index 42f1918c5..2a766ce76 100644 --- a/fpga/lib/utils.cpp +++ b/fpga/lib/utils.cpp @@ -225,11 +225,46 @@ void fpga::setupColorHandling() }); } +std::shared_ptr +fpga::createCard(json_t *config, std::list> &cards, + std::filesystem::path &searchPath, + std::shared_ptr vfioContainer, + std::string card_name) { + auto configDir = std::filesystem::path().parent_path(); + + const char *interfaceName; + json_error_t err; + logger->info("Found config for FPGA card {}", card_name); + int ret = + json_unpack_ex(config, &err, 0, "{s: s}", "interface", &interfaceName); + if (ret) { + throw ConfigError(config, err, "interface", + "Failed to parse interface name for card {}", card_name); + } + std::string interfaceNameStr(interfaceName); + if (interfaceNameStr == "pcie") { + auto card = fpga::PCIeCardFactory::make(config, std::string(card_name), + vfioContainer, searchPath); + if (card) { + cards.push_back(card); + return card; + } + return nullptr; + } else if (interfaceNameStr == "platform") { + throw RuntimeError("Platform interface not implemented yet"); + } else { + throw RuntimeError("Unknown interface type {}", interfaceNameStr); + } +} + int fpga::createCards(json_t *config, std::list> &cards, - std::filesystem::path &searchPath) { + std::filesystem::path &searchPath, + std::shared_ptr vfioContainer) { int numFpgas = 0; - auto vfioContainer = std::make_shared(); + if (vfioContainer == nullptr) { + vfioContainer = std::make_shared(); + } auto configDir = std::filesystem::path().parent_path(); json_t *fpgas = json_object_get(config, "fpgas"); @@ -241,28 +276,9 @@ int fpga::createCards(json_t *config, const char *card_name; json_t *json_card; json_object_foreach(fpgas, card_name, json_card) { - const char *interfaceName; - json_error_t err; - logger->info("Found config for FPGA card {}", card_name); - int ret = json_unpack_ex(json_card, &err, 0, "{s: s}", "interface", - &interfaceName); - if (ret) { - throw ConfigError(json_card, err, "interface", - "Failed to parse interface name for card {}", - card_name); - } - std::string interfaceNameStr(interfaceName); - if (interfaceNameStr == "pcie") { - auto card = fpga::PCIeCardFactory::make(json_card, std::string(card_name), - vfioContainer, searchPath); - if (card) { - cards.push_back(std::move(card)); - numFpgas++; - } - } else if (interfaceNameStr == "platform") { - throw RuntimeError("Platform interface not implemented yet"); - } else { - throw RuntimeError("Unknown interface type {}", interfaceNameStr); + if (createCard(json_card, cards, searchPath, vfioContainer, card_name) != + nullptr) { + numFpgas++; } } return numFpgas;