Skip to content

Commit

Permalink
feature: added automatic stop on probe unplug/error
Browse files Browse the repository at this point in the history
  • Loading branch information
klonyyy committed Dec 1, 2024
1 parent 847d2e9 commit 650ba3b
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 23 deletions.
5 changes: 5 additions & 0 deletions src/DataHandler/ViewerDataHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ void ViewerDataHandler::dataHandler()

if (probeSettings.mode == IDebugProbe::Mode::HSS)
{
if (!debugProbe->isValid())
setState(state::STOP);

auto maybeEntry = debugProbe->readSingleEntry();

if (!maybeEntry.has_value())
Expand All @@ -124,6 +127,8 @@ void ViewerDataHandler::dataHandler()
uint32_t value = 0;
if (debugProbe->readMemory(address, (uint8_t*)&value, size))
rawValues[address] = value;
else
setState(state::STOP);
}
double timestamp = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - start).count();
updateVariables(timestamp, rawValues);
Expand Down
3 changes: 2 additions & 1 deletion src/MemoryReader/IDebugProbe.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _IVARIABLEREADER_HPP
#define _IVARIABLEREADER_HPP

#include <atomic>
#include <cstdint>
#include <optional>
#include <string>
Expand Down Expand Up @@ -50,7 +51,7 @@ class IDebugProbe
virtual std::vector<std::string> getConnectedDevices() = 0;

protected:
bool isRunning = false;
std::atomic<bool> isRunning = false;
std::string lastErrorMsg = "";
mutable std::mutex mtx;
};
Expand Down
28 changes: 23 additions & 5 deletions src/MemoryReader/JlinkDebugProbe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ bool JlinkDebugProbe::startAcqusition(const DebugProbeSettings& probeSettings, s
int serialNumberInt = std::atoi(probeSettings.serialNumber.c_str());
lastErrorMsg = "";
isRunning = false;
emptyMessageErrorCnt = 0;

if (JLINKARM_EMU_SelectByUSBSN(serialNumberInt) < 0)
{
Expand Down Expand Up @@ -80,6 +81,8 @@ bool JlinkDebugProbe::startAcqusition(const DebugProbeSettings& probeSettings, s

uint32_t samplePeriodUs = 1.0 / (samplingFreqency * timestampResolution);
int32_t result = JLINK_HSS_Start(variableDesc, trackedVarsCount, samplePeriodUs, JLINK_HSS_FLAG_TIMESTAMP_US);
/* 1M is arbitraty value that works across all sampling frequencies */
emptyMessageErrorThreshold = 1.0 / (timestampResolution * samplingFreqency) * 1000000;

if (result >= 0)
isRunning = true;
Expand Down Expand Up @@ -116,7 +119,6 @@ bool JlinkDebugProbe::stopAcqusition()

bool JlinkDebugProbe::isValid() const
{
std::lock_guard<std::mutex> lock(mtx);
return isRunning;
}

Expand All @@ -141,6 +143,20 @@ std::optional<IDebugProbe::varEntryType> JlinkDebugProbe::readSingleEntry()

int32_t readSize = JLINK_HSS_Read(rawBuffer, sizeof(rawBuffer));

if (readSize <= 0)
{
emptyMessageErrorCnt++;
if (emptyMessageErrorCnt > emptyMessageErrorThreshold)
{
lastErrorMsg = "Error reading HSS data!";
logger->error(lastErrorMsg);
isRunning = false;
}
return varTable.pop();
}

emptyMessageErrorCnt = 0;

for (int32_t i = 0; i < readSize; i += trackedVarsTotalSize)
{
varEntryType entry{};
Expand All @@ -156,12 +172,14 @@ std::optional<IDebugProbe::varEntryType> JlinkDebugProbe::readSingleEntry()
k += addressSizeMap[address];
}

varTable.push(entry);
if (!varTable.push(entry))
{
lastErrorMsg = "HSS FIFO overflow!";
logger->error(lastErrorMsg);
isRunning = false;
}
}

if (readSize < 0 || varTable.size() == 0)
return std::nullopt;

return varTable.pop();
}

Expand Down
3 changes: 3 additions & 0 deletions src/MemoryReader/JlinkDebugProbe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class JlinkDebugProbe : public IDebugProbe
size_t trackedVarsCount = 0;
size_t trackedVarsTotalSize = 0;

size_t emptyMessageErrorThreshold = 100000;
size_t emptyMessageErrorCnt = 0;

std::unordered_map<uint32_t, uint8_t> addressSizeMap;
RingBuffer<varEntryType, fifoSize> varTable;

Expand Down
21 changes: 6 additions & 15 deletions src/RingBuffer/RingBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
#define __RIGNBUFFER_HPP

#include <array>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>

using std::chrono::operator""ms;
#include <optional>

template <typename T, size_t capacity>
class RingBuffer
Expand All @@ -18,29 +15,25 @@ class RingBuffer
bool push(const T& item)
{
std::unique_lock<std::mutex> lock(mutex);
if (!cond_full.wait_for(lock, 100ms, [this]()
{ return size_ < capacity; }))
if (size_ == capacity)
return false;

buffer[write_idx] = item;
write_idx = (write_idx + 1) % capacity;
size_++;

cond_empty.notify_one();
return true;
}

T pop()
std::optional<T> pop()
{
std::unique_lock<std::mutex> lock(mutex);
cond_empty.wait(lock, [this]()
{ return size_ > 0; });

if (size_ == 0)
return std::nullopt;

T item = buffer[read_idx];
read_idx = (read_idx + 1) % capacity;
size_--;

cond_full.notify_one();
return item;
}

Expand All @@ -63,8 +56,6 @@ class RingBuffer
size_t size_;

std::mutex mutex;
std::condition_variable cond_empty;
std::condition_variable cond_full;
};

#endif
66 changes: 66 additions & 0 deletions src/RingBuffer/RingBufferBlocking.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once
#include <array>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>

using std::chrono::operator""ms;

template <typename T, size_t capacity>
class RingBufferBlocking
{
public:
explicit RingBufferBlocking() : read_idx(0), write_idx(0), size_(0) {}

bool push(const T& item)
{
std::unique_lock<std::mutex> lock(mutex);
if (!cond_full.wait_for(lock, 100ms, [this]()
{ return size_ < capacity; }))
return false;

buffer[write_idx] = item;
write_idx = (write_idx + 1) % capacity;
size_++;

cond_empty.notify_one();
return true;
}

T pop()
{
std::unique_lock<std::mutex> lock(mutex);
cond_empty.wait(lock, [this]()
{ return size_ > 0; });

T item = buffer[read_idx];
read_idx = (read_idx + 1) % capacity;
size_--;

cond_full.notify_one();
return item;
}

size_t size()
{
std::unique_lock<std::mutex> lock(mutex);
return size_;
}

void clear()
{
while (size_)
pop();
}

private:
std::array<T, capacity> buffer;
size_t read_idx;
size_t write_idx;
size_t size_;

std::mutex mutex;
std::condition_variable cond_empty;
std::condition_variable cond_full;
};
4 changes: 2 additions & 2 deletions src/TraceReader/TraceReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <vector>

#include "ITraceProbe.hpp"
#include "RingBuffer.hpp"
#include "RingBufferBlocking.hpp"
#include "spdlog/spdlog.h"

class TraceReader
Expand Down Expand Up @@ -88,7 +88,7 @@ class TraceReader
std::atomic<bool> isRunning{false};
std::string lastErrorMsg = "";
std::array<uint32_t, channels> previousEntry{};
RingBuffer<std::pair<std::array<uint32_t, channels>, double>, 2000> traceTable;
RingBufferBlocking<std::pair<std::array<uint32_t, channels>, double>, 2000> traceTable;
std::thread readerHandle;

std::shared_ptr<ITraceProbe> TraceProbe;
Expand Down

0 comments on commit 650ba3b

Please sign in to comment.