Skip to content

Commit

Permalink
feature: working on csv streaming
Browse files Browse the repository at this point in the history
  • Loading branch information
klonyyy committed Sep 20, 2024
1 parent 07d0d65 commit ea07e03
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 53 deletions.
6 changes: 3 additions & 3 deletions example/STMViewer_test/MCUViewer_project/MCUViewer_test.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ max_viewport_points_percent = 10
trigger_channel = -1
trigger_level = 0.000000
timeout = 2
probe_type = 0
target_name =
probe_type = 1
target_name = STM32G474CC
probe_speed_khz = 10000
probe_sn =
probe_sn = 506003225

[var0]
name = test.a
Expand Down
5 changes: 4 additions & 1 deletion src/Gui/Gui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ class Gui
void drawPlotsTree();
void drawAcqusitionSettingsWindow(ActiveViewType type);
void acqusitionSettingsViewer();
void drawLoggingSettings();

template <typename Settings>
void drawLoggingSettings(PlotHandlerBase* handler, Settings& settings);

void drawAboutWindow();
void drawPreferencesWindow();
void drawStatisticsAnalog(std::shared_ptr<Plot> plt);
Expand Down
67 changes: 32 additions & 35 deletions src/Gui/GuiAcqusition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ void Gui::acqusitionSettingsViewer()
drawCenteredText("Project");
ImGui::Separator();

ImGui::Text("*.elf file: ");
ImGui::Text("*.elf file: ");
ImGui::SameLine();
ImGui::InputText("##", &projectElfPath, 0, NULL, NULL);
ImGui::SameLine();
Expand All @@ -15,15 +15,15 @@ void Gui::acqusitionSettingsViewer()

PlotHandler::Settings settings = plotHandler->getSettings();

ImGui::Text("Refresh addresses on *.elf change: ");
ImGui::Text("Refresh vars on *.elf change: ");
ImGui::SameLine();
ImGui::Checkbox("##refresh", &settings.refreshAddressesOnElfChange);

ImGui::Text("Stop acqusition on *.elf change: ");
ImGui::Text("Stop on *.elf change: ");
ImGui::SameLine();
ImGui::Checkbox("##stop", &settings.stopAcqusitionOnElfChange);

ImGui::Text("Sampling [Hz]: ");
ImGui::Text("Sampling [Hz]: ");
ImGui::SameLine();
ImGui::InputScalar("##sample", ImGuiDataType_U32, &settings.sampleFrequencyHz, NULL, NULL, "%u");
ImGui::SameLine();
Expand All @@ -32,25 +32,25 @@ void Gui::acqusitionSettingsViewer()

const uint32_t minPoints = 100;
const uint32_t maxPoints = 20000;
ImGui::Text("Max points: ");
ImGui::Text("Max points: ");
ImGui::SameLine();
ImGui::InputScalar("##maxPoints", ImGuiDataType_U32, &settings.maxPoints, NULL, NULL, "%u");
ImGui::SameLine();
ImGui::HelpMarker("Max points used for a single series after which the oldest points will be overwritten.");
settings.maxPoints = std::clamp(settings.maxPoints, minPoints, maxPoints);

ImGui::Text("Max view points: ");
ImGui::Text("Max view points: ");
ImGui::SameLine();
ImGui::InputScalar("##maxViewportPoints", ImGuiDataType_U32, &settings.maxViewportPoints, NULL, NULL, "%u");
ImGui::SameLine();
ImGui::HelpMarker("Max points used for a single series that will be shown in the viewport without scroling.");
settings.maxViewportPoints = std::clamp(settings.maxViewportPoints, minPoints, settings.maxPoints);

plotHandler->setSettings(settings);

drawDebugProbes();

drawLoggingSettings();
drawLoggingSettings(plotHandler, settings);

plotHandler->setSettings(settings);
}

void Gui::drawDebugProbes()
Expand All @@ -66,7 +66,7 @@ void Gui::drawDebugProbes()
ImGui::HelpMarker("Select the debug probe type and the serial number of the probe to unlock the START button.");
ImGui::Separator();

ImGui::Text("Debug probe: ");
ImGui::Text("Debug probe: ");
ImGui::SameLine();

const char* debugProbes[] = {"STLINK", "JLINK"};
Expand All @@ -90,7 +90,7 @@ void Gui::drawDebugProbes()
}
SNptr = 0;
}
ImGui::Text("Debug probe S/N: ");
ImGui::Text("Debug probe S/N: ");
ImGui::SameLine();

if (ImGui::Combo("##debugProbeSN", &SNptr, devicesList))
Expand All @@ -113,15 +113,15 @@ void Gui::drawDebugProbes()
shouldListDevices = false;
}

ImGui::Text("SWD speed [kHz]: ");
ImGui::Text("SWD speed [kHz]: ");
ImGui::SameLine();

if (ImGui::InputScalar("##speed", ImGuiDataType_U32, &probeSettings.speedkHz, NULL, NULL, "%u"))
modified = true;

if (probeSettings.debugProbe == 1)
{
ImGui::Text("Target name: ");
ImGui::Text("Target name: ");
ImGui::SameLine();

if (ImGui::InputText("##device", &probeSettings.device, 0, NULL, NULL))
Expand All @@ -134,7 +134,7 @@ void Gui::drawDebugProbes()
modified = true;
}

ImGui::Text("Mode: ");
ImGui::Text("Mode: ");
ImGui::SameLine();

const char* probeModes[] = {"NORMAL", "HSS"};
Expand Down Expand Up @@ -163,28 +163,24 @@ void Gui::drawDebugProbes()
ImGui::PopID();
}

void Gui::drawLoggingSettings()
template <typename Settings>
void Gui::drawLoggingSettings(PlotHandlerBase* handler, Settings& settings)
{
static bool logging = false;
static std::string directory = "";

PlotHandler::Settings settings = plotHandler->getSettings();

ImGui::PushID("logging");
ImGui::Dummy(ImVec2(-1, 5));
drawCenteredText("Logging");
ImGui::SameLine();
ImGui::HelpMarker("Log all registered variables values to a selected log file");
ImGui::HelpMarker("Log all registered variables values to a selected log file.");
ImGui::Separator();

/* CSV streamer */
ImGui::Text("Log to file: ");
ImGui::Text("Log to file: ");
ImGui::SameLine();
ImGui::Checkbox("##logging", &logging);
ImGui::Checkbox("##logging", &settings.shouldLog);

ImGui::BeginDisabled(!logging);
ImGui::BeginDisabled(!settings.shouldLog);

ImGui::Text("Logfile directory: ");
ImGui::Text("Logfile directory: ");
ImGui::SameLine();
ImGui::InputText("##", &settings.logFilePath, 0, NULL, NULL);
ImGui::SameLine();
Expand All @@ -193,37 +189,38 @@ void Gui::drawLoggingSettings()

ImGui::EndDisabled();
ImGui::PopID();
plotHandler->setSettings(settings);
}

void Gui::acqusitionSettingsTrace()
{
TracePlotHandler::Settings settings = tracePlotHandler->getSettings();

ImGui::Text("Max points: ");
ImGui::Text("Max points: ");
ImGui::SameLine();
ImGui::InputScalar("##maxPoints", ImGuiDataType_U32, &settings.maxPoints, NULL, NULL, "%u");
ImGui::SameLine();
ImGui::HelpMarker("Max points used for a single series after which the oldest points will be overwritten.");
settings.maxPoints = std::clamp(settings.maxPoints, static_cast<uint32_t>(100), static_cast<uint32_t>(20000));

ImGui::Text("Viewport width [%%]: ");
ImGui::Text("Viewport width [%%]: ");
ImGui::SameLine();
ImGui::InputScalar("##maxViewportPoints", ImGuiDataType_U32, &settings.maxViewportPointsPercent, NULL, NULL, "%u");
ImGui::SameLine();
ImGui::HelpMarker("The percentage of trace time visible during collect. Expressed in percent since the sample period is not constant.");
settings.maxViewportPointsPercent = std::clamp(settings.maxViewportPointsPercent, static_cast<uint32_t>(1), static_cast<uint32_t>(100));

ImGui::Text("Timeout [s]: ");
ImGui::Text("Timeout [s]: ");
ImGui::SameLine();
ImGui::InputScalar("##timeout", ImGuiDataType_U32, &settings.timeout, NULL, NULL, "%u");
ImGui::SameLine();
ImGui::HelpMarker("Timeout is the period after which trace will be stopped due to no trace data being received.");
settings.timeout = std::clamp(settings.timeout, static_cast<uint32_t>(1), static_cast<uint32_t>(999999));

tracePlotHandler->setSettings(settings);

drawTraceProbes();

drawLoggingSettings(tracePlotHandler, settings);

tracePlotHandler->setSettings(settings);
}

void Gui::drawTraceProbes()
Expand All @@ -239,7 +236,7 @@ void Gui::drawTraceProbes()
ImGui::HelpMarker("Select the debug probe type and the serial number of the probe to unlock the START button.");
ImGui::Separator();

ImGui::Text("Debug probe: ");
ImGui::Text("Debug probe: ");
ImGui::SameLine();

const char* debugProbes[] = {"STLINK", "JLINK"};
Expand All @@ -263,7 +260,7 @@ void Gui::drawTraceProbes()
}
SNptr = 0;
}
ImGui::Text("Debug probe S/N: ");
ImGui::Text("Debug probe S/N: ");
ImGui::SameLine();

if (ImGui::Combo("##debugProbeSN", &SNptr, devicesList))
Expand All @@ -286,15 +283,15 @@ void Gui::drawTraceProbes()
shouldListDevices = false;
}

ImGui::Text("SWD speed [kHz]: ");
ImGui::Text("SWD speed [kHz]: ");
ImGui::SameLine();

if (ImGui::InputScalar("##speed", ImGuiDataType_U32, &probeSettings.speedkHz, NULL, NULL, "%u"))
modified = true;

if (probeSettings.debugProbe == 1)
{
ImGui::Text("Target name: ");
ImGui::Text("Target name: ");
ImGui::SameLine();

if (ImGui::InputText("##device", &probeSettings.device, 0, NULL, NULL))
Expand Down
15 changes: 11 additions & 4 deletions src/PlotHandler/PlotHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,16 @@ void PlotHandler::dataHandler()
std::chrono::time_point<std::chrono::steady_clock> start;
uint32_t timer = 0;
double lastT = 0.0;
std::vector<double> csvValues;
csvValues.reserve(maxVariablesOnSinglePlot);

while (!done)
{
if (viewerState == state::RUN)
{
auto finish = std::chrono::steady_clock::now();
double period = std::chrono::duration_cast<std::chrono::duration<double>>(finish - start).count();
csvValues.clear();

if (probeSettings.mode == IDebugProbe::Mode::HSS)
{
Expand All @@ -90,9 +93,13 @@ void PlotHandler::dataHandler()
double value = varReader->castToProperType(values[ser->var->getAddress()], ser->var->getType());
ser->var->setValue(value);
plot->addPoint(name, value);
csvValues.push_back(ser->var->getValue());
}
plot->addTimePoint(timestamp);
}

if (settings.shouldLog)
csvStreamer.writeLine(period, csvValues);
/* filter sampling frequency */
averageSamplingPeriod = samplingPeriodFilter.filter((period - lastT));
lastT = period;
Expand All @@ -101,8 +108,6 @@ void PlotHandler::dataHandler()

else if (period > ((1.0 / settings.sampleFrequencyHz) * timer))
{
std::vector<double> values;
values.reserve(100);
for (auto& [key, plot] : plotsMap)
{
if (!plot->getVisibility())
Expand All @@ -123,12 +128,14 @@ void PlotHandler::dataHandler()
for (auto& [name, ser] : plot->getSeriesMap())
{
plot->addPoint(name, ser->var->getValue());
values.push_back(ser->var->getValue());
csvValues.push_back(ser->var->getValue());
}
plot->addTimePoint(period);
}

if (settings.shouldLog)
csvStreamer.writeLine(period, csvValues);
/* filter sampling frequency */
csvStreamer.writeLine(period, values);
averageSamplingPeriod = samplingPeriodFilter.filter((period - lastT));
lastT = period;
timer++;
Expand Down
6 changes: 3 additions & 3 deletions src/PlotHandler/PlotHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <string>
#include <thread>

#include "CSVStreamer.hpp"
#include "IDebugProbe.hpp"
#include "MemoryReader.hpp"
#include "MovingAverage.hpp"
Expand All @@ -29,6 +28,7 @@ class PlotHandler : public PlotHandlerBase
uint32_t maxViewportPoints = 5000;
bool refreshAddressesOnElfChange = false;
bool stopAcqusitionOnElfChange = false;
bool shouldLog = false;
std::string logFilePath = "";
} Settings;

Expand All @@ -52,13 +52,13 @@ class PlotHandler : public PlotHandlerBase
return 0.0;
}

CSVStreamer csvStreamer;

private:
void dataHandler();
std::vector<std::pair<uint32_t, uint8_t>> createAddressSizeVector();

private:
static constexpr size_t maxVariablesOnSinglePlot = 100;

std::unique_ptr<MemoryReader> varReader;
IDebugProbe::DebugProbeSettings probeSettings{};
Settings settings{};
Expand Down
2 changes: 2 additions & 0 deletions src/PlotHandler/PlotHandlerBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "ScrollingBuffer.hpp"
#include "StlinkDebugProbe.hpp"
#include "spdlog/spdlog.h"
#include "CSVStreamer.hpp"

class PlotHandlerBase
{
Expand Down Expand Up @@ -56,6 +57,7 @@ class PlotHandlerBase
iterator end();

protected:
CSVStreamer csvStreamer;
std::atomic<bool>& done;
std::atomic<state> viewerState = state::STOP;
std::map<std::string, std::shared_ptr<Plot>> plotsMap;
Expand Down
Loading

0 comments on commit ea07e03

Please sign in to comment.