diff --git a/CMakeLists.txt b/CMakeLists.txt index d6af58bc..baf766a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ endif() project(STMViewer) -set(STMVIEWER_VERSION 0.1.1) +set(STMVIEWER_VERSION 0.1.2) set(CMAKE_BUILD_TYPE Release) set(CMAKE_CXX_STANDARD 17) @@ -34,6 +34,7 @@ if(UNIX) find_package(libusb REQUIRED) find_package(glfw3 REQUIRED) set(STLINK_LINUX ${CMAKE_CURRENT_SOURCE_DIR}/third_party/stlink/lib/linux/libstlink.a) + set(SPDLOG_LINUX ${CMAKE_CURRENT_SOURCE_DIR}/third_party/spdlog/lib/linux/libspdlog.so.1.11.0) set(INSTALL_PATH /usr/local/STMViewer) set(DESKTOP_FILE_PATH /usr/share/applications) endif() @@ -45,18 +46,23 @@ if(WIN32) set(STLINK_WINDOWS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/stlink/lib/windows/libstlink.a) set(LIBUSB_WINDOWS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libusb/lib/windows/libusb-1.0.dll) set(LIBUSB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libusb/inc/libusb-1.0) + set(SPDLOG_WINDOWS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/spdlog/lib/windows/libspdlog.dll) set(INSTALL_PATH bin) endif() + + set(PROJECT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/ElfReader/ElfReader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Gui/Gui.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/VarReader/VarReader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/TargetMemoryHandler/TargetMemoryHandler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/TargetMemoryHandler/StlinkHandler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Plot/Plot.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Variable/Variable.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/ConfigHandler/ConfigHandler.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/Plot/PlotHandler.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/src/Plot/PlotHandler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/FileHandler/NFDFileHandler.cpp) set(IMGUI_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/third_party/imgui/imgui.cpp @@ -88,12 +94,13 @@ target_compile_definitions(${EXECUTABLE} target_include_directories(${EXECUTABLE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/ElfReader ${CMAKE_CURRENT_SOURCE_DIR}/src/Gui - ${CMAKE_CURRENT_SOURCE_DIR}/src/VarReader + ${CMAKE_CURRENT_SOURCE_DIR}/src/TargetMemoryHandler ${CMAKE_CURRENT_SOURCE_DIR}/src/Plot ${CMAKE_CURRENT_SOURCE_DIR}/src/ScrollingBuffer ${CMAKE_CURRENT_SOURCE_DIR}/src/Variable ${CMAKE_CURRENT_SOURCE_DIR}/src/ConfigHandler - ${CMAKE_CURRENT_SOURCE_DIR}/src/ImguiPlugins) + ${CMAKE_CURRENT_SOURCE_DIR}/src/ImguiPlugins + ${CMAKE_CURRENT_SOURCE_DIR}/src/FileHandler) target_include_directories(${EXECUTABLE} SYSTEM PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/stlink/inc @@ -104,12 +111,13 @@ target_include_directories(${EXECUTABLE} SYSTEM PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/GLFW/inc/GLFW/ ${CMAKE_CURRENT_SOURCE_DIR}/third_party/implot/ ${CMAKE_CURRENT_SOURCE_DIR}/third_party/mINI/src/mini/ - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/nfd/src/include/) + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/nfd/src/include/ + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/spdlog/inc/) if(UNIX) - target_link_libraries(${EXECUTABLE} ${STLINK_LINUX} ${LIBUSB_LIBRARY} pthread dl GL glfw nfd) + target_link_libraries(${EXECUTABLE} ${STLINK_LINUX} ${LIBUSB_LIBRARY} ${SPDLOG_LINUX} pthread dl GL glfw nfd) elseif(WIN32) - target_link_libraries(${EXECUTABLE} ${GLFW3_WINDOWS} ${STLINK_WINDOWS} ${LIBUSB_WINDOWS} -static opengl32 nfd -static-libstdc++ -static-libgcc) + target_link_libraries(${EXECUTABLE} ${GLFW3_WINDOWS} ${STLINK_WINDOWS} ${LIBUSB_WINDOWS} ${SPDLOG_WINDOWS} -static opengl32 nfd -static-libstdc++ -static-libgcc) endif() if(WIN32) @@ -133,21 +141,27 @@ install(TARGETS ${EXECUTABLE} RUNTIME DESTINATION ${INSTALL_PATH} COMPONENT appl install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/imgui.ini DESTINATION ${INSTALL_PATH}) if(WIN32) - set_target_properties(${EXECUTABLE} PROPERTIES WIN32_EXECUTABLE TRUE) + if(PRODUCTION) + set_target_properties(${EXECUTABLE} PROPERTIES WIN32_EXECUTABLE TRUE) + endif() install(FILES ${LIBUSB_WINDOWS} ${STLINK_WINDOWS} ${GLFW3_WINDOWS} DESTINATION ${INSTALL_PATH}) set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS " SetOutPath \\\"$INSTDIR\\\\bin\\\" + CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${EXECUTABLE}.lnk\\\" \\\"$INSTDIR\\\\bin\\\\${EXECUTABLE}.exe\\\" CreateShortCut \\\"$DESKTOP\\\\${EXECUTABLE}.lnk\\\" \\\"$INSTDIR\\\\bin\\\\${EXECUTABLE}.exe\\\"") - set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "Delete \\\"$DESKTOP\\\\${EXECUTABLE}.lnk\\\"") + set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS " + Delete \\\"$SMPROGRAMS\\\\$START_MENU\\\\${EXECUTABLE}.lnk\\\" + Delete \\\"$DESKTOP\\\\${EXECUTABLE}.lnk\\\"") endif() if(UNIX) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/third_party/stlink/chips DESTINATION ${INSTALL_PATH}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/launch/icon.png DESTINATION ${INSTALL_PATH}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/launch/STMViewer.desktop PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${DESKTOP_FILE_PATH}) set(CPACK_GENERATOR "DEB") - set(CPACK_DEBIAN_PACKAGE_DEPENDS "libusb-1.0-0-dev, libglfw3-dev, libgtk-3-dev, gdb") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "libusb-1.0-0-dev, libglfw3-dev, libgtk-3-dev, gdb, libspdlog-dev") endif() set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) diff --git a/README.md b/README.md index 44f2be50..b18ff14c 100644 --- a/README.md +++ b/README.md @@ -44,4 +44,5 @@ I'm working in the motor control industry where it is crucial to visualize some 3. [implot](https://github.com/epezent/implot) 4. [mINI](https://github.com/pulzed/mINI) 5. [nfd](https://github.com/btzy/nativefiledialog-extended) +6. [spdlog](https://github.com/gabime/spdlog) diff --git a/launch/addGitVersion.sh b/launch/addGitVersion.sh new file mode 100644 index 00000000..06800b68 --- /dev/null +++ b/launch/addGitVersion.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd .. +git log --pretty=format:'#define GIT_INFO_PRESENT%n static const char* GIT_HASH = "%H";' -n 1 > src/gitversion.hpp diff --git a/launch/release.sh b/launch/release.sh index 020c9d74..524cf60f 100755 --- a/launch/release.sh +++ b/launch/release.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +./launch/addGitVersion.sh rm -rf build mkdir -p build cd build @@ -6,14 +7,14 @@ mkdir packages mkdir -p windows cd windows -cmake -DPLATFORM=WIN ../.. +cmake -DPLATFORM=WIN -DPRODUCTION=TRUE ../.. make package -j16 cp *win64.exe ../packages cd - mkdir -p linux cd linux -cmake ../.. +cmake -DPRODUCTION=TRUE ../.. make package -j16 cp *.deb ../packages cd - diff --git a/src/ConfigHandler/ConfigHandler.cpp b/src/ConfigHandler/ConfigHandler.cpp index 9d862789..e481dc47 100644 --- a/src/ConfigHandler/ConfigHandler.cpp +++ b/src/ConfigHandler/ConfigHandler.cpp @@ -1,9 +1,8 @@ #include "ConfigHandler.hpp" -#include #include -ConfigHandler::ConfigHandler(const std::string& configFilePath, PlotHandler* plotHandler) : configFilePath(configFilePath), plotHandler(plotHandler) +ConfigHandler::ConfigHandler(const std::string& configFilePath, PlotHandler* plotHandler, std::shared_ptr logger) : configFilePath(configFilePath), plotHandler(plotHandler), logger(logger) { ini = std::make_unique(); file = std::make_unique(configFilePath); @@ -57,13 +56,14 @@ bool ConfigHandler::readConfigFile(std::mapgetAddress() % 4 != 0) - std::cout << "--------- WARNING: unaligned variable address! ----------" << std::endl; + + logger->warn("--------- Unaligned variable address! ----------"); if (!newVar->getName().empty()) { vars[newVar->getName()] = newVar; newVar->setIsFound(true); - std::cout << "ADDING VARIABLE: " << newVar->getName() << std::endl; + logger->info("Adding variable: {}", newVar->getName()); } } @@ -85,8 +85,7 @@ bool ConfigHandler::readConfigFile(std::mapaddPlot(plotName); plotHandler->getPlot(plotName)->setVisibility(visibility); plotHandler->getPlot(plotName)->setType(type); - - std::cout << "ADDING PLOT: " << plotName << std::endl; + logger->info("Adding plot: {}", plotName); uint32_t seriesNumber = 0; std::string varName = ini->get(plotSeriesFieldFromID(plotNumber, seriesNumber)).get("name"); @@ -99,7 +98,7 @@ bool ConfigHandler::readConfigFile(std::mapgetPlot(plotName)->getSeries(varName)->format = displayFormatMap.at(displayFormat); - std::cout << "ADDING SERIES: " << varName << std::endl; + logger->info("Adding series: {}", varName); seriesNumber++; varName = ini->get(plotSeriesFieldFromID(plotNumber, seriesNumber)).get("name"); } diff --git a/src/ConfigHandler/ConfigHandler.hpp b/src/ConfigHandler/ConfigHandler.hpp index 9906d6b0..b54c44bc 100644 --- a/src/ConfigHandler/ConfigHandler.hpp +++ b/src/ConfigHandler/ConfigHandler.hpp @@ -7,6 +7,7 @@ #include "PlotHandler.hpp" #include "Variable.hpp" #include "ini.h" +#include "spdlog/spdlog.h" class ConfigHandler { @@ -19,7 +20,7 @@ class ConfigHandler uint32_t maxViewportPoints = 5000; } Settings; - ConfigHandler(const std::string& configFilePath, PlotHandler* plotHandler); + ConfigHandler(const std::string& configFilePath, PlotHandler* plotHandler, std::shared_ptr logger); ~ConfigHandler() = default; bool changeConfigFile(const std::string& newConfigFilePath); @@ -34,6 +35,7 @@ class ConfigHandler std::unique_ptr file; std::unique_ptr ini; + std::shared_ptr logger; }; #endif \ No newline at end of file diff --git a/src/ElfReader/ElfReader.cpp b/src/ElfReader/ElfReader.cpp index 7caf822c..08ca8caa 100644 --- a/src/ElfReader/ElfReader.cpp +++ b/src/ElfReader/ElfReader.cpp @@ -12,7 +12,7 @@ #define _UNIX #endif -ElfReader::ElfReader(std::string& filename) : elfname(filename) +ElfReader::ElfReader(std::string& filename, std::shared_ptr logger) : elfname(filename), logger(logger) { } @@ -35,7 +35,7 @@ bool ElfReader::updateVariableMap(std::mapinfo("Dividing command into smaller chunks..."); } } out += executeCommand(cmdFull.c_str()); @@ -64,9 +64,9 @@ bool ElfReader::updateVariableMap(std::mapsetAddress(atoi(temp.substr(offset, temp.find('\n', addrPos)).c_str())); std::string type = temp.substr(typePos + 7, temp.find('\n', typePos)); vars.at(varName)->setType(getTypeFromString(type)); - std::cout << "NAME: " << vars.at(varName)->getName() << std::endl; - std::cout << "ADDRESS: " << vars.at(varName)->getAddress() << std::endl; - std::cout << "TYPE: " << static_cast(vars[varName]->getType()) << std::endl; + logger->info("NAME: {}", vars.at(varName)->getName()); + logger->info("ADDRESS: {}", vars.at(varName)->getAddress()); + logger->info("TYPE: {}", static_cast(vars[varName]->getType())); } out.erase(0, temp.length()); } diff --git a/src/ElfReader/ElfReader.hpp b/src/ElfReader/ElfReader.hpp index 865c97df..9ee5086b 100644 --- a/src/ElfReader/ElfReader.hpp +++ b/src/ElfReader/ElfReader.hpp @@ -7,11 +7,12 @@ #include #include "Variable.hpp" +#include "spdlog/spdlog.h" class ElfReader { public: - ElfReader(std::string& filename); + ElfReader(std::string& filename, std::shared_ptr logger); bool updateVariableMap(std::map>& vars); Variable::type getTypeFromString(const std::string& strType); @@ -21,6 +22,7 @@ class ElfReader static constexpr uint16_t maxGdbCmdLendth = 8160; std::string& elfname; std::string executeCommand(const char* cmd); + std::shared_ptr logger; }; #endif \ No newline at end of file diff --git a/src/FileHandler/IFileHandler.hpp b/src/FileHandler/IFileHandler.hpp new file mode 100644 index 00000000..ca4fc7b1 --- /dev/null +++ b/src/FileHandler/IFileHandler.hpp @@ -0,0 +1,17 @@ +#ifndef _FILEHANDLER_HPP +#define _FILEHANDLER_HPP + +#include +#include + +class IFileHandler +{ + public: + virtual ~IFileHandler() = default; + virtual bool init() = 0; + virtual bool deinit() = 0; + virtual std::string openFile(std::pair&& filterFileNameFileExtension) = 0; + virtual std::string saveFile(std::pair&& filterFileNameFileExtension) = 0; +}; + +#endif \ No newline at end of file diff --git a/src/FileHandler/NFDFileHandler.cpp b/src/FileHandler/NFDFileHandler.cpp new file mode 100644 index 00000000..3b267b55 --- /dev/null +++ b/src/FileHandler/NFDFileHandler.cpp @@ -0,0 +1,44 @@ +#include +#include + +#include "nfd.h" + +bool NFDFileHandler::init() +{ + return NFD_Init() != NFD_ERROR; +} +bool NFDFileHandler::deinit() +{ + NFD_Quit(); + return true; +} +std::string NFDFileHandler::openFile(std::pair&& filterFileNameFileExtension) +{ + return handleFile(handleType::OPEN, filterFileNameFileExtension); +} +std::string NFDFileHandler::saveFile(std::pair&& filterFileNameFileExtension) +{ + return handleFile(handleType::SAVE, filterFileNameFileExtension); +} + +std::string NFDFileHandler::handleFile(handleType type, std::pair& filterFileNameFileExtension) +{ + nfdchar_t* outPath = nullptr; + nfdfilteritem_t filterItem[1] = {{filterFileNameFileExtension.first.c_str(), filterFileNameFileExtension.second.c_str()}}; + + nfdresult_t result = NFD_ERROR; + + if (type == handleType::SAVE) + result = NFD_SaveDialog(&outPath, filterItem, 1, NULL, NULL); + else if (type == handleType::OPEN) + result = NFD_OpenDialog(&outPath, filterItem, 1, NULL); + + if (result == NFD_OKAY) + { + std::string path = std::string(outPath); + std::replace(path.begin(), path.end(), '\\', '/'); + NFD_FreePath(outPath); + return path; + } + return std::string(""); +} \ No newline at end of file diff --git a/src/FileHandler/NFDFileHandler.hpp b/src/FileHandler/NFDFileHandler.hpp new file mode 100644 index 00000000..046b26e4 --- /dev/null +++ b/src/FileHandler/NFDFileHandler.hpp @@ -0,0 +1,24 @@ +#ifndef _NFDFILEHANDLER_HPP +#define _NFDFILEHANDLER_HPP + +#include + +class NFDFileHandler : public IFileHandler +{ + public: + bool + init() override; + bool deinit() override; + std::string openFile(std::pair&& filterFileNameFileExtension) override; + std::string saveFile(std::pair&& filterFileNameFileExtension) override; + + private: + enum class handleType + { + SAVE, + OPEN + }; + std::string handleFile(handleType type, std::pair& filterFileNameFileExtension); +}; + +#endif \ No newline at end of file diff --git a/src/Gui/Gui.cpp b/src/Gui/Gui.cpp index b7227ccd..1387b836 100644 --- a/src/Gui/Gui.cpp +++ b/src/Gui/Gui.cpp @@ -2,23 +2,20 @@ #include -#include #include #include #include "ElfReader.hpp" #include "ImguiPlugins.hpp" -#include "VarReader.hpp" #include "glfw3.h" #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" #include "implot.h" -#include "nfd.h" -Gui::Gui(PlotHandler* plotHandler, ConfigHandler* configHandler, bool& done, std::mutex* mtx) : plotHandler(plotHandler), configHandler(configHandler), done(done), mtx(mtx) +Gui::Gui(PlotHandler* plotHandler, ConfigHandler* configHandler, IFileHandler* fileHandler, bool& done, std::mutex* mtx, std::shared_ptr logger) : plotHandler(plotHandler), configHandler(configHandler), fileHandler(fileHandler), done(done), mtx(mtx), logger(logger) { - elfReader = std::make_unique(projectElfPath); + elfReader = std::make_unique(projectElfPath, logger); threadHandle = std::thread(&Gui::mainThread, this); } @@ -65,7 +62,7 @@ void Gui::mainThread() ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init(glsl_version); - NFD_Init(); + fileHandler->init(); bool show_demo_window = false; @@ -126,7 +123,7 @@ void Gui::mainThread() glfwDestroyWindow(window); glfwTerminate(); - NFD_Quit(); + fileHandler->deinit(); } void Gui::drawMenu() @@ -214,10 +211,11 @@ void Gui::drawAddVariableButton() std::shared_ptr newVar = std::make_shared(newName); newVar->setAddress(0x20000000); newVar->setType(Variable::type::U8); - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dist(0, UINT32_MAX); - newVar->setColor(static_cast(dist(gen))); + std::random_device rd{}; + std::mt19937 gen{rd()}; + std::uniform_int_distribution dist{0, UINT32_MAX}; + uint32_t randomColor = dist(gen); + newVar->setColor(randomColor); vars.emplace(newName, newVar); } } @@ -388,6 +386,7 @@ void Gui::drawPlotsTree() ImGui::Selectable(name.c_str()); if (!seriesNameToDelete.has_value()) seriesNameToDelete = showDeletePopup("Delete var", name); + ImGui::PopID(); } plt->removeSeries(seriesNameToDelete.value_or("")); @@ -429,23 +428,7 @@ void Gui::drawAcqusitionSettingsWindow() ImGui::InputText("##", &projectElfPath, 0, NULL, NULL); ImGui::SameLine(); if (ImGui::SmallButton("...")) - { - nfdchar_t* outPath; - nfdfilteritem_t filterItem[1] = {{"Executable files", "elf"}}; - nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 1, NULL); - if (result == NFD_OKAY) - { - std::cout << outPath << std::endl; - projectElfPath = std::string(outPath); - std::replace(projectElfPath.begin(), projectElfPath.end(), '\\', '/'); - NFD_FreePath(outPath); - } - else if (result == NFD_ERROR) - { - std::cout << "Error: %s\n" - << NFD_GetError() << std::endl; - } - } + openElfFile(); ImGui::Text("Sample period [ms]:"); static int one = 1; @@ -513,6 +496,22 @@ void Gui::drawPlotCurveBar(Plot* plot, ScrollingBuffer& time, std::mapgetName().c_str(), plotSize, ImPlotFlags_NoChild)) { + if (plotHandler->getViewerState() == PlotHandler::state::RUN) + { + ImPlot::SetupAxis(ImAxis_Y1, NULL, ImPlotAxisFlags_AutoFit); + ImPlot::SetupAxis(ImAxis_X1, "time[s]", 0); + const double viewportWidth = settings.samplePeriod * 0.001f * settings.maxViewportPoints; + const double min = *time.getLastElement() < viewportWidth ? 0.0f : *time.getLastElement() - viewportWidth; + const double max = min == 0.0f ? *time.getLastElement() : min + viewportWidth; + ImPlot::SetupAxisLimits(ImAxis_X1, min, max, ImPlotCond_Always); + } + else + { + ImPlot::SetupAxes("time[s]", NULL, 0, 0); + ImPlot::SetupAxisLimits(ImAxis_X1, -1, 10, ImPlotCond_Once); + ImPlot::SetupAxisLimits(ImAxis_Y1, -0.1, 0.1, ImPlotCond_Once); + } + if (ImPlot::BeginDragDropTargetPlot()) { if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) @@ -555,22 +554,6 @@ void Gui::drawPlotCurveBar(Plot* plot, ScrollingBuffer& time, std::mapsetMarkerValueX1(0.0); - if (plotHandler->getViewerState() == PlotHandler::state::RUN) - { - ImPlot::SetupAxis(ImAxis_Y1, NULL, ImPlotAxisFlags_AutoFit); - ImPlot::SetupAxis(ImAxis_X1, "time[s]", 0); - const double viewportWidth = settings.samplePeriod * 0.001f * settings.maxViewportPoints; - const double min = *time.getLastElement() < viewportWidth ? 0.0f : *time.getLastElement() - viewportWidth; - const double max = min == 0.0f ? *time.getLastElement() : min + viewportWidth; - ImPlot::SetupAxisLimits(ImAxis_X1, min, max, ImPlotCond_Always); - } - else - { - ImPlot::SetupAxes("time[s]", NULL, 0, 0); - ImPlot::SetupAxisLimits(ImAxis_X1, -1, 10, ImPlotCond_Once); - ImPlot::SetupAxisLimits(ImAxis_Y1, -0.1, 0.1, ImPlotCond_Once); - } - /* make thread safe copies of buffers - probably can be made better but it works */ mtx->lock(); time.copyData(); @@ -689,9 +672,9 @@ void Gui::drawPlotTable(Plot* plot, ScrollingBuffer& time, std::mapinfo("New value to be written: {}", newValue); if (!plotHandler->writeSeriesValue(*serPtr->var, std::stod(newValue))) - std::cout << "ERROR while writing new value!" << std::endl; + logger->error("Error while writing new value!"); } } ImGui::PopID(); @@ -814,47 +797,43 @@ bool Gui::saveProject() bool Gui::saveProjectAs() { - nfdchar_t* outPath = nullptr; - nfdfilteritem_t filterItem[1] = {{"Project files", "cfg"}}; - nfdresult_t result = NFD_SaveDialog(&outPath, filterItem, 1, NULL, NULL); - if (result == NFD_OKAY) + std::string path = fileHandler->saveFile(std::pair("Project files", "cfg")); + if (path != "") { - projectConfigPath = std::string(outPath); + projectConfigPath = path; configHandler->saveConfigFile(vars, projectElfPath, settings, projectConfigPath); - NFD_FreePath(outPath); + logger->info("Project config path: {}", projectConfigPath); return true; } - else if (result == NFD_ERROR) - { - std::cout << "Error: %s\n" - << NFD_GetError() << std::endl; - } return false; } bool Gui::openProject() { - nfdchar_t* outPath; - nfdfilteritem_t filterItem[1] = {{"Project files", "cfg"}}; - nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 1, NULL); - if (result == NFD_OKAY) + std::string path = fileHandler->openFile(std::pair("Project files", "cfg")); + if (path != "") { - projectConfigPath = std::string(outPath); - NFD_FreePath(outPath); + projectConfigPath = path; configHandler->changeConfigFile(projectConfigPath); vars.clear(); plotHandler->removeAllPlots(); configHandler->readConfigFile(vars, projectElfPath, settings); plotHandler->setSamplePeriod(settings.samplePeriod); plotHandler->setMaxPoints(settings.maxPoints); - std::replace(projectElfPath.begin(), projectElfPath.end(), '\\', '/'); - std::cout << projectConfigPath << std::endl; + logger->info("Project config path: {}", projectConfigPath); return true; } - else if (result == NFD_ERROR) + return false; +} + +bool Gui::openElfFile() +{ + std::string path = fileHandler->openFile(std::pair("Elf files", "elf")); + if (path != "") { - std::cout << "Error: %s\n" - << NFD_GetError() << std::endl; + projectElfPath = path; + logger->info("Project elf file path: {}", projectElfPath); + return true; } return false; } diff --git a/src/Gui/Gui.hpp b/src/Gui/Gui.hpp index 5422beba..e0125fe6 100644 --- a/src/Gui/Gui.hpp +++ b/src/Gui/Gui.hpp @@ -8,6 +8,7 @@ #include "ConfigHandler.hpp" #include "ElfReader.hpp" +#include "IFileHandler.hpp" #include "Plot.hpp" #include "PlotHandler.hpp" #include "imgui.h" @@ -15,7 +16,7 @@ class Gui { public: - Gui(PlotHandler* plotHandler, ConfigHandler* configHandler, bool& done, std::mutex* mtx); + Gui(PlotHandler* plotHandler, ConfigHandler* configHandler, IFileHandler* fileHandler, bool& done, std::mutex* mtx, std::shared_ptr logger); ~Gui(); private: @@ -30,6 +31,7 @@ class Gui bool showAcqusitionSettingsWindow = false; std::unique_ptr elfReader; + IFileHandler* fileHandler; bool& done; @@ -56,10 +58,13 @@ class Gui bool saveProjectAs(); void showChangeFormatPopup(const char* text, Plot& plt, const std::string& name); bool openProject(); + bool openElfFile(); void checkShortcuts(); std::optional showDeletePopup(const char* text, const std::string name); std::string intToHexString(uint32_t i); + + std::shared_ptr logger; }; #endif \ No newline at end of file diff --git a/src/Plot/Plot.cpp b/src/Plot/Plot.cpp index 5a7709f9..73793eda 100644 --- a/src/Plot/Plot.cpp +++ b/src/Plot/Plot.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/src/Plot/PlotHandler.cpp b/src/Plot/PlotHandler.cpp index 34f72947..7646f3ca 100644 --- a/src/Plot/PlotHandler.cpp +++ b/src/Plot/PlotHandler.cpp @@ -3,10 +3,11 @@ #include #include -PlotHandler::PlotHandler(bool& done, std::mutex* mtx) : done(done), mtx(mtx) +PlotHandler::PlotHandler(bool& done, std::mutex* mtx, std::shared_ptr logger) : done(done), mtx(mtx), logger(logger) { dataHandle = std::thread(&PlotHandler::dataHandler, this); - varReader = std::make_unique(); + stlinkReader = std::make_unique(); + varReader = std::make_unique(stlinkReader.get(), logger); } PlotHandler::~PlotHandler() { @@ -100,7 +101,7 @@ void PlotHandler::dataHandler() /* this part consumes most of the thread time */ for (auto& [name, ser] : plot->getSeriesMap()) - ser->var->setValue(varReader->getDouble(ser->var->getAddress(), ser->var->getType())); + ser->var->setValue(varReader->getValue(ser->var->getAddress(), ser->var->getType())); /* thread-safe part */ std::lock_guard lock(*mtx); diff --git a/src/Plot/PlotHandler.hpp b/src/Plot/PlotHandler.hpp index 8206b029..c5f979c9 100644 --- a/src/Plot/PlotHandler.hpp +++ b/src/Plot/PlotHandler.hpp @@ -8,7 +8,9 @@ #include "Plot.hpp" #include "ScrollingBuffer.hpp" -#include "VarReader.hpp" +#include "StlinkHandler.hpp" +#include "TargetMemoryHandler.hpp" +#include "spdlog/spdlog.h" class PlotHandler { @@ -19,7 +21,7 @@ class PlotHandler RUN = 1, }; - PlotHandler(bool& done, std::mutex* mtx); + PlotHandler(bool& done, std::mutex* mtx, std::shared_ptr logger); ~PlotHandler(); void addPlot(const std::string& name); @@ -66,7 +68,8 @@ class PlotHandler bool& done; state viewerState = state::STOP; state viewerStateTemp = state::STOP; - std::unique_ptr varReader; + std::unique_ptr stlinkReader; + std::unique_ptr varReader; std::map> plotsMap; @@ -76,6 +79,8 @@ class PlotHandler std::chrono::time_point start; float samplePeriodMs = 1; + + std::shared_ptr logger; }; #endif \ No newline at end of file diff --git a/src/TargetMemoryHandler/ITargetMemoryHandler.hpp b/src/TargetMemoryHandler/ITargetMemoryHandler.hpp new file mode 100644 index 00000000..ac27c0e0 --- /dev/null +++ b/src/TargetMemoryHandler/ITargetMemoryHandler.hpp @@ -0,0 +1,20 @@ +#ifndef _IVARIABLEREADER_HPP +#define _IVARIABLEREADER_HPP + +#include + +class ITargetMemoryHandler +{ + public: + virtual ~ITargetMemoryHandler() = default; + virtual bool startAcqusition() = 0; + virtual bool stopAcqusition() = 0; + virtual bool isValid() const = 0; + + virtual bool readMemory(uint32_t address, uint32_t* value) = 0; + virtual bool writeMemory(uint32_t address, uint8_t* buf, uint32_t len) = 0; + + virtual std::string getLastErrorMsg() const = 0; +}; + +#endif \ No newline at end of file diff --git a/src/TargetMemoryHandler/StlinkHandler.cpp b/src/TargetMemoryHandler/StlinkHandler.cpp new file mode 100644 index 00000000..3ef906c8 --- /dev/null +++ b/src/TargetMemoryHandler/StlinkHandler.cpp @@ -0,0 +1,61 @@ +#include "StlinkHandler.hpp" + +#include + +StlinkHandler::StlinkHandler() +{ +#if defined(unix) || defined(__unix__) || defined(__unix) + init_chipids("./chips"); +#endif +} + +bool StlinkHandler::startAcqusition() +{ + sl = stlink_open_usb(UERROR, CONNECT_HOT_PLUG, NULL, 4000); + isRunning = false; + + if (sl != nullptr) + { + if (stlink_enter_swd_mode(sl) != 0 || stlink_target_connect(sl, CONNECT_HOT_PLUG) != 0) + { + stopAcqusition(); + lastErrorMsg = "STM32 target not found!"; + return false; + } + + isRunning = true; + lastErrorMsg = ""; + return true; + } + lastErrorMsg = "STLink not found!"; + return false; +} +bool StlinkHandler::stopAcqusition() +{ + isRunning = false; + stlink_close(sl); + return true; +} +bool StlinkHandler::isValid() const +{ + return isRunning; +} + +bool StlinkHandler::readMemory(uint32_t address, uint32_t* value) +{ + if (!isRunning) + return false; + return stlink_read_debug32(sl, address, value) == 0; +} +bool StlinkHandler::writeMemory(uint32_t address, uint8_t* buf, uint32_t len) +{ + if (!isRunning) + return false; + memcpy(sl->q_buf, buf, len); + return stlink_write_mem8(sl, address, len) == 0; +} + +std::string StlinkHandler::getLastErrorMsg() const +{ + return lastErrorMsg; +} \ No newline at end of file diff --git a/src/TargetMemoryHandler/StlinkHandler.hpp b/src/TargetMemoryHandler/StlinkHandler.hpp new file mode 100644 index 00000000..a30f9427 --- /dev/null +++ b/src/TargetMemoryHandler/StlinkHandler.hpp @@ -0,0 +1,26 @@ +#ifndef _STLINKHANDLER_HPP +#define _STLINKHANDLER_HPP + +#include "ITargetMemoryHandler.hpp" +#include "stlink.h" + +class StlinkHandler : public ITargetMemoryHandler +{ + public: + StlinkHandler(); + bool startAcqusition() override; + bool stopAcqusition() override; + bool isValid() const override; + + bool readMemory(uint32_t address, uint32_t* value) override; + bool writeMemory(uint32_t address, uint8_t* buf, uint32_t len) override; + + std::string getLastErrorMsg() const override; + + private: + stlink_t* sl = nullptr; + bool isRunning = false; + std::string lastErrorMsg = ""; +}; + +#endif \ No newline at end of file diff --git a/src/TargetMemoryHandler/TargetMemoryHandler.cpp b/src/TargetMemoryHandler/TargetMemoryHandler.cpp new file mode 100644 index 00000000..d4509900 --- /dev/null +++ b/src/TargetMemoryHandler/TargetMemoryHandler.cpp @@ -0,0 +1,129 @@ +#include "TargetMemoryHandler.hpp" + +#include + +#include "iostream" + +TargetMemoryHandler::TargetMemoryHandler(ITargetMemoryHandler* memoryHandler, std::shared_ptr logger) : memoryHandler(memoryHandler), logger(logger) +{ +} + +bool TargetMemoryHandler::start() const +{ + return memoryHandler->startAcqusition(); +} +bool TargetMemoryHandler::stop() const +{ + return memoryHandler->stopAcqusition(); +} + +double TargetMemoryHandler::getValue(uint32_t address, Variable::type type) +{ + volatile uint32_t value = 0; + uint8_t shouldShift = address % 4; + + std::lock_guard lock(mtx); + + if (!memoryHandler->readMemory(address, (uint32_t*)&value)) + return 0.0; + + if (type == Variable::type::I8 || type == Variable::type::U8) + { + if (shouldShift == 0) + value = (value & 0x000000ff); + else if (shouldShift == 1) + value = (value & 0x0000ff00) >> 8; + else if (shouldShift == 2) + value = (value & 0x00ff0000) >> 16; + else if (shouldShift == 3) + value = (value & 0xff000000) >> 24; + } + else if (type == Variable::type::I16 || type == Variable::type::U16) + { + if (shouldShift == 0) + value = (value & 0x0000ffff); + else if (shouldShift == 1) + value = (value & 0x00ffff00) >> 8; + else if (shouldShift == 2) + value = (value & 0xffff0000) >> 16; + else if (shouldShift == 3) + value = (value & 0x000000ff) << 8 | (value & 0xff000000) >> 24; + } + else if (type == Variable::type::I32 || type == Variable::type::U32 || type == Variable::type::F32) + { + if (shouldShift == 0) + value = value; + else if (shouldShift == 1) + value = (value & 0x000000ff) << 24 | (value & 0xffffff00) >> 8; + else if (shouldShift == 2) + value = (value & 0x0000ffff) << 16 | (value & 0xffff0000) >> 16; + else if (shouldShift == 3) + value = (value & 0x00ffffff) << 24 | (value & 0xff000000) >> 8; + } + + if (type == Variable::type::U8) + return (double)*(uint8_t*)&value; + else if (type == Variable::type::I8) + return (double)*(int8_t*)&value; + else if (type == Variable::type::U16) + return (double)*(uint16_t*)&value; + else if (type == Variable::type::I16) + return (double)*(int16_t*)&value; + else if (type == Variable::type::U32) + return (double)*(uint32_t*)&value; + else if (type == Variable::type::I32) + return (double)*(int32_t*)&value; + else if (type == Variable::type::F32) + return (double)*(float*)&value; + else if (type == Variable::type::UNKNOWN) + return (double)*(uint32_t*)&value; + + return 0.0; +} + +bool TargetMemoryHandler::setValue(const Variable& var, double value) +{ + uint32_t address = var.getAddress(); + uint8_t buf[4] = {}; + + if (!memoryHandler->isValid()) + return false; + + auto prepareBufferAndWrite = [&](auto var, uint8_t* buf) -> int + { + for (size_t i = 0; i < sizeof(var); i++) + buf[i] = var >> 8 * i; + return memoryHandler->writeMemory(address, buf, sizeof(var)); + }; + + std::lock_guard lock(mtx); + + switch (var.getType()) + { + case Variable::type::U8: + return prepareBufferAndWrite(static_cast(value), buf); + case Variable::type::I8: + return prepareBufferAndWrite(static_cast(value), buf); + case Variable::type::U16: + return prepareBufferAndWrite(static_cast(value), buf); + case Variable::type::I16: + return prepareBufferAndWrite(static_cast(value), buf); + case Variable::type::U32: + return prepareBufferAndWrite(static_cast(value), buf); + case Variable::type::I32: + return prepareBufferAndWrite(static_cast(value), buf); + case Variable::type::F32: + { + float valf = static_cast(value); + uint32_t val = *(uint32_t*)&valf; + return prepareBufferAndWrite(val, buf); + } + default: + return false; + } +} + +std::string TargetMemoryHandler::getLastErrorMsg() const +{ + return memoryHandler->getLastErrorMsg(); +} \ No newline at end of file diff --git a/src/TargetMemoryHandler/TargetMemoryHandler.hpp b/src/TargetMemoryHandler/TargetMemoryHandler.hpp new file mode 100644 index 00000000..c21f558f --- /dev/null +++ b/src/TargetMemoryHandler/TargetMemoryHandler.hpp @@ -0,0 +1,31 @@ +#ifndef _VARREADER_HPP +#define _VARREADER_HPP + +#include +#include +#include + +#include "ITargetMemoryHandler.hpp" +#include "Variable.hpp" +#include "spdlog/spdlog.h" + +class TargetMemoryHandler +{ + public: + TargetMemoryHandler(ITargetMemoryHandler* memoryHandler, std::shared_ptr logger); + + bool start() const; + bool stop() const; + + uint32_t getValue(uint32_t address) const; + double getValue(uint32_t address, Variable::type type); + bool setValue(const Variable& var, double value); + std::string getLastErrorMsg() const; + + private: + std::mutex mtx; + std::unique_ptr memoryHandler; + std::shared_ptr logger; +}; + +#endif \ No newline at end of file diff --git a/src/VarReader/VarReader.cpp b/src/VarReader/VarReader.cpp deleted file mode 100644 index 9ccc1e4e..00000000 --- a/src/VarReader/VarReader.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "VarReader.hpp" - -#include - -#include "iostream" - -bool VarReader::start() -{ - sl = stlink_open_usb(UERROR, CONNECT_HOT_PLUG, NULL, 4000); - - if (sl != NULL) - { - std::cout << "STlink detected!" << std::endl; - - if (stlink_enter_swd_mode(sl) != 0 || stlink_target_connect(sl, CONNECT_HOT_PLUG) != 0) - { - stop(); - lastErrorMsg = "STM32 target not found!"; - return false; - } - - lastErrorMsg = ""; - return true; - } - - std::cout << "STLink not detected!" << std::endl; - lastErrorMsg = "STLink not found!"; - return false; -} -bool VarReader::stop() -{ - readerState = state::STOP; - stlink_close(sl); - return true; -} - -double VarReader::getDouble(uint32_t address, Variable::type type) -{ - volatile uint32_t value = 0; - - if (sl == nullptr) - return 0.0; - - uint8_t shouldShift = address % 4; - - std::lock_guard lock(mtx); - - stlink_read_debug32(sl, address, (uint32_t*)&value); - - if (type == Variable::type::I8 || type == Variable::type::U8) - { - if (shouldShift == 0) - value = (value & 0x000000ff); - else if (shouldShift == 1) - value = (value & 0x0000ff00) >> 8; - else if (shouldShift == 2) - value = (value & 0x00ff0000) >> 16; - else if (shouldShift == 3) - value = (value & 0xff000000) >> 24; - } - else if (type == Variable::type::I16 || type == Variable::type::U16) - { - if (shouldShift == 0) - value = (value & 0x0000ffff); - else if (shouldShift == 1) - value = (value & 0x00ffff00) >> 8; - else if (shouldShift == 2) - value = (value & 0xffff0000) >> 16; - else if (shouldShift == 3) - value = (value & 0x000000ff) << 8 | (value & 0xff000000) >> 24; - } - else if (type == Variable::type::I32 || type == Variable::type::U32 || type == Variable::type::F32) - { - if (shouldShift == 0) - value = value; - else if (shouldShift == 1) - value = (value & 0x000000ff) << 24 | (value & 0xffffff00) >> 8; - else if (shouldShift == 2) - value = (value & 0x0000ffff) << 16 | (value & 0xffff0000) >> 16; - else if (shouldShift == 3) - value = (value & 0x00ffffff) << 24 | (value & 0xff000000) >> 8; - } - - if (type == Variable::type::U8) - return (double)*(uint8_t*)&value; - else if (type == Variable::type::I8) - return (double)*(int8_t*)&value; - else if (type == Variable::type::U16) - return (double)*(uint16_t*)&value; - else if (type == Variable::type::I16) - return (double)*(int16_t*)&value; - else if (type == Variable::type::U32) - return (double)*(uint32_t*)&value; - else if (type == Variable::type::I32) - return (double)*(int32_t*)&value; - else if (type == Variable::type::F32) - return (double)*(float*)&value; - else if (type == Variable::type::UNKNOWN) - return (double)*(uint32_t*)&value; - - return 0.0; -} - -bool VarReader::setValue(const Variable& var, double value) -{ - if (sl == nullptr) - return false; - - uint32_t address = var.getAddress(); - int32_t retVal = 0; - - std::lock_guard lock(mtx); - - switch (var.getType()) - { - case Variable::type::U8: - { - sl->q_buf[0] = static_cast(value); - retVal = stlink_write_mem8(sl, address, 1); - break; - } - case Variable::type::I8: - { - sl->q_buf[0] = static_cast(value); - retVal = stlink_write_mem8(sl, address, 1); - break; - } - case Variable::type::U16: - { - sl->q_buf[0] = static_cast(value); - sl->q_buf[1] = static_cast(value) >> 8; - retVal = stlink_write_mem8(sl, address, 2); - break; - } - case Variable::type::I16: - { - sl->q_buf[0] = static_cast(value); - sl->q_buf[1] = static_cast(value) >> 8; - retVal = stlink_write_mem8(sl, address, 2); - break; - } - case Variable::type::U32: - { - sl->q_buf[0] = static_cast(value); - sl->q_buf[1] = static_cast(value) >> 8; - sl->q_buf[2] = static_cast(value) >> 16; - sl->q_buf[3] = static_cast(value) >> 24; - retVal = stlink_write_mem8(sl, address, 4); - break; - } - case Variable::type::I32: - { - sl->q_buf[0] = static_cast(value); - sl->q_buf[1] = static_cast(value) >> 8; - sl->q_buf[2] = static_cast(value) >> 16; - sl->q_buf[3] = static_cast(value) >> 24; - retVal = stlink_write_mem8(sl, address, 4); - break; - } - case Variable::type::F32: - { - float val = static_cast(value); - sl->q_buf[0] = (*(uint32_t*)&val); - sl->q_buf[1] = (*(uint32_t*)&val) >> 8; - sl->q_buf[2] = (*(uint32_t*)&val) >> 16; - sl->q_buf[3] = (*(uint32_t*)&val) >> 24; - retVal = stlink_write_mem8(sl, address, 4); - break; - } - default: - return false; - } - - return retVal == 0 ? true : false; -} - -std::string VarReader::getLastErrorMsg() const -{ - return lastErrorMsg; -} \ No newline at end of file diff --git a/src/VarReader/VarReader.hpp b/src/VarReader/VarReader.hpp deleted file mode 100644 index 21cdad0b..00000000 --- a/src/VarReader/VarReader.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _VARREADER_HPP -#define _VARREADER_HPP - -#include -#include -#include - -#include "Variable.hpp" -#include "stlink.h" - -class VarReader -{ - public: - VarReader() = default; - ~VarReader() = default; - - bool start(); - bool stop(); - - uint32_t getValue(uint32_t address) const; - double getDouble(uint32_t address, Variable::type type); - bool setValue(const Variable& var, double value); - std::string getLastErrorMsg() const; - - private: - enum class state - { - STOP = 0, - RUN = 1, - }; - state readerState = state::STOP; - stlink_t* sl; - std::mutex mtx; - std::string lastErrorMsg = {}; -}; - -#endif \ No newline at end of file diff --git a/src/Variable/Variable.cpp b/src/Variable/Variable.cpp index e2978f68..25389887 100644 --- a/src/Variable/Variable.cpp +++ b/src/Variable/Variable.cpp @@ -5,8 +5,8 @@ Variable::Variable(std::string name) : name(name) { } -template -Variable::Variable(std::string name, Variable::type type, T value) : name(name), varType(type) + +Variable::Variable(std::string name, Variable::type type, double value) : name(name), varType(type) { setValue(value); name.reserve(100); @@ -27,6 +27,16 @@ std::string Variable::getTypeStr() const return std::string(types[static_cast(varType)]); } +void Variable::setValue(double val) +{ + value = val; +} + +double Variable::getValue() const +{ + return value; +} + void Variable::setAddress(uint32_t addr) { address = addr; diff --git a/src/Variable/Variable.hpp b/src/Variable/Variable.hpp index 10d18a79..d7e1d6f9 100644 --- a/src/Variable/Variable.hpp +++ b/src/Variable/Variable.hpp @@ -27,23 +27,14 @@ class Variable }; Variable(std::string name); - template - Variable(std::string name, type type, T value); - ~Variable() = default; + Variable(std::string name, type type, double value); void setType(type varType); type getType() const; std::string getTypeStr() const; - void setValue(double val) - { - value = val; - } - - double getValue() const - { - return value; - } + void setValue(double val); + double getValue() const; void setAddress(uint32_t addr); uint32_t getAddress() const; diff --git a/src/gitversion.hpp b/src/gitversion.hpp new file mode 100644 index 00000000..4da8b1bc --- /dev/null +++ b/src/gitversion.hpp @@ -0,0 +1,2 @@ +#define GIT_INFO_PRESENT +static const char* GIT_HASH = "cb58313834791d0c5bec30cc7beaf8a45d595257"; diff --git a/src/main.cpp b/src/main.cpp index 2e30132b..18278599 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,24 +1,51 @@ +#include + #include #include "ConfigHandler.hpp" #include "Gui.hpp" +#include "NFDFileHandler.hpp" #include "PlotHandler.hpp" +#include "gitversion.hpp" +#include "spdlog/sinks/basic_file_sink.h" +#include "spdlog/spdlog.h" + +#if defined(unix) || defined(__unix__) || defined(__unix) +#define _UNIX +#endif bool done = false; std::mutex mtx; int main(int ac, char** av) { - PlotHandler plotHandler(done, &mtx); - ConfigHandler configHandler("", &plotHandler); - Gui gui(&plotHandler, &configHandler, done, &mtx); +#ifdef _UNIX + std::string logDirectory = std::string(std::getenv("HOME")) + "/STMViewer/logs/logfile.txt"; +#elif _WIN32 + std::string logDirectory = std::string(std::getenv("APPDATA")) + "/STMViewer/logs/logfile.txt"; +#else +#error "Your system is not supported!" +#endif + + spdlog::sinks_init_list sinkList = {std::make_shared(), + std::make_shared(logDirectory, true)}; + std::shared_ptr logger = std::make_shared("logger", sinkList.begin(), sinkList.end()); + + logger->info("Starting STMViewer!"); + logger->info("Version: {}.{}.{}", STMVIEWER_VERSION_MAJOR, STMVIEWER_VERSION_MINOR, STMVIEWER_VERSION_REVISION); + logger->info("Commit hash {}", GIT_HASH); + + PlotHandler plotHandler(done, &mtx, logger); + ConfigHandler configHandler("", &plotHandler, logger); + NFDFileHandler fileHandler; + Gui gui(&plotHandler, &configHandler, &fileHandler, done, &mtx, logger); while (!done) { std::this_thread::sleep_for(std::chrono::seconds(1)); } - std::cout << "CLOSING" << std::endl; - + logger->info("Closing STMViewer!"); + spdlog::shutdown(); return 0; } diff --git a/test/STMViewer_test/.cproject b/test/STMViewer_test/.cproject index fee27806..c5ff2616 100644 --- a/test/STMViewer_test/.cproject +++ b/test/STMViewer_test/.cproject @@ -35,7 +35,7 @@