From e0299638391767153257b5a1e8147b4b27330724 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Tue, 8 Nov 2022 11:44:57 -0500 Subject: [PATCH] move helper functions from villas-fpga-pipe into separate file --- fpga/include/villas/fpga/fpgaHelper.hpp | 38 ++++++++ fpga/lib/CMakeLists.txt | 1 + fpga/lib/fpgaHelper.cpp | 123 ++++++++++++++++++++++++ fpga/src/villas-fpga-pipe.cpp | 78 +-------------- 4 files changed, 165 insertions(+), 75 deletions(-) create mode 100644 fpga/include/villas/fpga/fpgaHelper.hpp create mode 100644 fpga/lib/fpgaHelper.cpp diff --git a/fpga/include/villas/fpga/fpgaHelper.hpp b/fpga/include/villas/fpga/fpgaHelper.hpp new file mode 100644 index 000000000..f9e6a1696 --- /dev/null +++ b/fpga/include/villas/fpga/fpgaHelper.hpp @@ -0,0 +1,38 @@ +/** Helper function for directly using VILLASfpga outside of VILLASnode + * + * @file + * @author Niklas Eiling + * @copyright 2022, Steffen Vogel, Niklas Eiling + * @license GNU General Public License (version 3) + * + * VILLASfpga + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#pragma once + +#include +#include + +namespace villas { +namespace fpga { + +std::shared_ptr +setupFpgaCard(const std::string &configFile, const std::string &fpgaName); + +void setupColorHandling(); + +} /* namespace fpga */ +} /* namespace villas */ diff --git a/fpga/lib/CMakeLists.txt b/fpga/lib/CMakeLists.txt index 11adf763f..8998b1799 100644 --- a/fpga/lib/CMakeLists.txt +++ b/fpga/lib/CMakeLists.txt @@ -25,6 +25,7 @@ set(SOURCES card.cpp core.cpp node.cpp + fpgaHelper.cpp ips/timer.cpp ips/switch.cpp diff --git a/fpga/lib/fpgaHelper.cpp b/fpga/lib/fpgaHelper.cpp new file mode 100644 index 000000000..ebfb5de7c --- /dev/null +++ b/fpga/lib/fpgaHelper.cpp @@ -0,0 +1,123 @@ +/** Helper function for directly using VILLASfpga outside of VILLASnode + * + * @author Niklas Eiling + * @copyright 2022, Steffen Vogel, Niklas Eiling + * @license GNU General Public License (version 3) + * + * VILLASfpga + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace villas; + +static std::shared_ptr pciDevices; +static auto logger = villas::logging.get("streamer"); + +void fpga::setupColorHandling() +{ + // Handle Control-C nicely + struct sigaction sigIntHandler; + sigIntHandler.sa_handler = [](int){ + std::cout << std::endl << rang::style::reset << rang::fgB::red; + std::cout << "Control-C detected, exiting..." << rang::style::reset << std::endl; + std::exit(1); // Will call the correct exit func, no unwinding of the stack though + }; + + sigemptyset(&sigIntHandler.sa_mask); + sigIntHandler.sa_flags = 0; + sigaction(SIGINT, &sigIntHandler, nullptr); + + // Reset color if exiting not by signal + std::atexit([](){ + std::cout << rang::style::reset; + }); +} + +std::shared_ptr +fpga::setupFpgaCard(const std::string &configFile, const std::string &fpgaName) +{ + pciDevices = std::make_shared(); + + auto vfioContainer = kernel::vfio::Container::create(); + + // Parse FPGA configuration + FILE* f = fopen(configFile.c_str(), "r"); + if (!f) + throw RuntimeError("Cannot open config file: {}", configFile); + + json_t* json = json_loadf(f, 0, nullptr); + if (!json) { + logger->error("Cannot parse JSON config"); + fclose(f); + throw RuntimeError("Cannot parse JSON config"); + } + + fclose(f); + + json_t* fpgas = json_object_get(json, "fpgas"); + if (fpgas == nullptr) { + logger->error("No section 'fpgas' found in config"); + exit(1); + } + + // Get the FPGA card plugin + auto fpgaCardFactory = plugin::registry->lookup("pcie"); + if (fpgaCardFactory == nullptr) { + logger->error("No FPGA plugin found"); + exit(1); + } + + // Create all FPGA card instances using the corresponding plugin + auto cards = fpgaCardFactory->make(fpgas, pciDevices, vfioContainer); + + std::shared_ptr card; + for (auto &fpgaCard : cards) { + if (fpgaCard->name == fpgaName) { + return fpgaCard; + } + } + + // Deallocate JSON config + json_decref(json); + + if (!card) + throw RuntimeError("FPGA card {} not found in config or not working", fpgaName); + + return card; +} + diff --git a/fpga/src/villas-fpga-pipe.cpp b/fpga/src/villas-fpga-pipe.cpp index 341180fa5..8a10f6427 100644 --- a/fpga/src/villas-fpga-pipe.cpp +++ b/fpga/src/villas-fpga-pipe.cpp @@ -41,85 +41,13 @@ #include #include #include +#include using namespace villas; static std::shared_ptr pciDevices; static auto logger = villas::logging.get("streamer"); -void setupColorHandling() -{ - // Handle Control-C nicely - struct sigaction sigIntHandler; - sigIntHandler.sa_handler = [](int){ - std::cout << std::endl << rang::style::reset << rang::fgB::red; - std::cout << "Control-C detected, exiting..." << rang::style::reset << std::endl; - std::exit(1); // Will call the correct exit func, no unwinding of the stack though - }; - - sigemptyset(&sigIntHandler.sa_mask); - sigIntHandler.sa_flags = 0; - sigaction(SIGINT, &sigIntHandler, nullptr); - - // Reset color if exiting not by signal - std::atexit([](){ - std::cout << rang::style::reset; - }); -} - -std::shared_ptr -setupFpgaCard(const std::string &configFile, const std::string &fpgaName) -{ - pciDevices = std::make_shared(); - - auto vfioContainer = kernel::vfio::Container::create(); - - // Parse FPGA configuration - FILE* f = fopen(configFile.c_str(), "r"); - if (!f) - throw RuntimeError("Cannot open config file: {}", configFile); - - json_t* json = json_loadf(f, 0, nullptr); - if (!json) { - logger->error("Cannot parse JSON config"); - fclose(f); - throw RuntimeError("Cannot parse JSON config"); - } - - fclose(f); - - json_t* fpgas = json_object_get(json, "fpgas"); - if (fpgas == nullptr) { - logger->error("No section 'fpgas' found in config"); - exit(1); - } - - // Get the FPGA card plugin - auto fpgaCardFactory = plugin::registry->lookup("pcie"); - if (fpgaCardFactory == nullptr) { - logger->error("No FPGA plugin found"); - exit(1); - } - - // Create all FPGA card instances using the corresponding plugin - auto cards = fpgaCardFactory->make(fpgas, pciDevices, vfioContainer); - - std::shared_ptr card; - for (auto &fpgaCard : cards) { - if (fpgaCard->name == fpgaName) { - return fpgaCard; - } - } - - // Deallocate JSON config - json_decref(json); - - if (!card) - throw RuntimeError("FPGA card {} not found in config or not working", fpgaName); - - return card; -} - int main(int argc, char* argv[]) { // Command Line Parser @@ -136,14 +64,14 @@ int main(int argc, char* argv[]) // Logging setup spdlog::set_level(spdlog::level::debug); - setupColorHandling(); + fpga::setupColorHandling(); if (configFile.empty()) { logger->error("No configuration file provided/ Please use -c/--config argument"); return 1; } - auto card = setupFpgaCard(configFile, fpgaName); + auto card = fpga::setupFpgaCard(configFile, fpgaName); std::vector aurora_channels; for (int i = 0; i < 4; i++) {