Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a1ecd3aba | |||
| 96d98dfc3d | |||
| b86ede99b9 |
@@ -1,16 +1,15 @@
|
|||||||
#ifndef DEBUGBROKERWRAPPER_H
|
#ifndef DEBUGBROKERWRAPPER_H
|
||||||
#define DEBUGBROKERWRAPPER_H
|
#define DEBUGBROKERWRAPPER_H
|
||||||
|
|
||||||
#include "AdvancedErrorManagement.h"
|
|
||||||
#include "BrokerI.h"
|
#include "BrokerI.h"
|
||||||
#include "DataSourceI.h"
|
#include "DataSourceI.h"
|
||||||
#include "DebugService.h"
|
#include "DebugService.h"
|
||||||
#include "ErrorType.h"
|
|
||||||
#include "FastPollingMutexSem.h"
|
#include "FastPollingMutexSem.h"
|
||||||
#include "HighResolutionTimer.h"
|
#include "HighResolutionTimer.h"
|
||||||
#include "MemoryMapBroker.h"
|
#include "MemoryMapBroker.h"
|
||||||
#include "ObjectBuilder.h"
|
#include "ObjectBuilder.h"
|
||||||
#include "ObjectRegistryDatabase.h"
|
#include "ObjectRegistryDatabase.h"
|
||||||
|
#include "Threads.h"
|
||||||
#include "Vec.h"
|
#include "Vec.h"
|
||||||
|
|
||||||
// Original broker headers
|
// Original broker headers
|
||||||
@@ -25,26 +24,94 @@
|
|||||||
#include "MemoryMapSynchronisedMultiBufferInputBroker.h"
|
#include "MemoryMapSynchronisedMultiBufferInputBroker.h"
|
||||||
#include "MemoryMapSynchronisedMultiBufferOutputBroker.h"
|
#include "MemoryMapSynchronisedMultiBufferOutputBroker.h"
|
||||||
#include "MemoryMapSynchronisedOutputBroker.h"
|
#include "MemoryMapSynchronisedOutputBroker.h"
|
||||||
#include "RealTimeThreadSynchBroker.h"
|
|
||||||
|
|
||||||
namespace MARTe {
|
namespace MARTe {
|
||||||
|
|
||||||
|
// Recursive search for any object with a given name anywhere in the registry.
|
||||||
|
// Used to find GAMs regardless of nesting level.
|
||||||
|
static Reference FindByNameRecursive(ReferenceContainer *container,
|
||||||
|
const char8 *name) {
|
||||||
|
if (container == NULL_PTR(ReferenceContainer *))
|
||||||
|
return Reference();
|
||||||
|
uint32 n = container->Size();
|
||||||
|
for (uint32 i = 0; i < n; i++) {
|
||||||
|
Reference child = container->Get(i);
|
||||||
|
if (!child.IsValid())
|
||||||
|
continue;
|
||||||
|
if (StringHelper::Compare(child->GetName(), name) == 0)
|
||||||
|
return child;
|
||||||
|
ReferenceContainer *sub =
|
||||||
|
dynamic_cast<ReferenceContainer *>(child.operator->());
|
||||||
|
if (sub != NULL_PTR(ReferenceContainer *)) {
|
||||||
|
Reference found = FindByNameRecursive(sub, name);
|
||||||
|
if (found.IsValid())
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Reference();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper for optimized signal processing within brokers.
|
* @brief Helper for optimized signal processing within brokers.
|
||||||
*/
|
*/
|
||||||
class DebugBrokerHelper {
|
class DebugBrokerHelper {
|
||||||
public:
|
public:
|
||||||
|
// Evaluate a break condition against the current live value of a signal.
|
||||||
|
// Returns true if the condition is met and execution should be paused.
|
||||||
|
// Only called when signal->breakOp != BREAK_OFF; reads memoryAddress directly.
|
||||||
|
static bool EvaluateBreak(const DebugSignalInfo *s) {
|
||||||
|
if (s->memoryAddress == NULL_PTR(void *)) return false;
|
||||||
|
float64 val = 0.0;
|
||||||
|
const TypeDescriptor &t = s->type;
|
||||||
|
if (t == Float64Bit) val = *static_cast<const float64 *>(s->memoryAddress);
|
||||||
|
else if (t == Float32Bit) val = *static_cast<const float32 *>(s->memoryAddress);
|
||||||
|
else if (t == UnsignedInteger32Bit) val = *static_cast<const uint32 *>(s->memoryAddress);
|
||||||
|
else if (t == SignedInteger32Bit) val = *static_cast<const int32 *>(s->memoryAddress);
|
||||||
|
else if (t == UnsignedInteger64Bit) val = static_cast<float64>(*static_cast<const uint64 *>(s->memoryAddress));
|
||||||
|
else if (t == SignedInteger64Bit) val = static_cast<float64>(*static_cast<const int64 *>(s->memoryAddress));
|
||||||
|
else if (t == UnsignedInteger16Bit) val = *static_cast<const uint16 *>(s->memoryAddress);
|
||||||
|
else if (t == SignedInteger16Bit) val = *static_cast<const int16 *>(s->memoryAddress);
|
||||||
|
else if (t == UnsignedInteger8Bit) val = *static_cast<const uint8 *>(s->memoryAddress);
|
||||||
|
else if (t == SignedInteger8Bit) val = *static_cast<const int8 *>(s->memoryAddress);
|
||||||
|
else return false; // unsupported type — skip
|
||||||
|
const float64 thr = s->breakThreshold;
|
||||||
|
switch (s->breakOp) {
|
||||||
|
case BREAK_GT: return val > thr;
|
||||||
|
case BREAK_LT: return val < thr;
|
||||||
|
case BREAK_EQ: return val == thr;
|
||||||
|
case BREAK_GEQ: return val >= thr;
|
||||||
|
case BREAK_LEQ: return val <= thr;
|
||||||
|
case BREAK_NEQ: return val != thr;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spin-wait point for output brokers — called from Execute() AFTER Process().
|
||||||
|
// Spins while paused, then consumes one step counter tick (if stepping).
|
||||||
|
// Input brokers must NOT call this — they complete normally to avoid blocking
|
||||||
|
// cross-thread EventSem posts (RealTimeThreadSynchBroker would time out).
|
||||||
|
static void OutputPauseAndStep(DebugService *service, const char8 *gamName) {
|
||||||
|
if (service == NULL_PTR(DebugService *)) return;
|
||||||
|
// Wait if already paused (manual PAUSE or breakpoint from a previous cycle)
|
||||||
|
while (service->IsPaused()) Sleep::MSec(10);
|
||||||
|
// Pass the OS thread name so per-thread step filtering works.
|
||||||
|
const char8 *tName = Threads::Name(Threads::Id());
|
||||||
|
service->ConsumeStepIfNeeded(gamName, tName);
|
||||||
|
while (service->IsPaused()) Sleep::MSec(10);
|
||||||
|
}
|
||||||
|
|
||||||
static void Process(DebugService *service,
|
static void Process(DebugService *service,
|
||||||
DebugSignalInfo **signalInfoPointers,
|
DebugSignalInfo **signalInfoPointers,
|
||||||
Vec<uint32> &activeIndices, Vec<uint32> &activeSizes,
|
Vec<uint32> &activeIndices, Vec<uint32> &activeSizes,
|
||||||
FastPollingMutexSem &activeMutex) {
|
FastPollingMutexSem &activeMutex,
|
||||||
|
volatile bool *anyBreakFlag,
|
||||||
|
Vec<uint32> *breakIndices) {
|
||||||
if (service == NULL_PTR(DebugService *))
|
if (service == NULL_PTR(DebugService *))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Re-establish break logic
|
// NOTE: No spin here. Spinning for paused state is handled in Execute() of
|
||||||
while (service->IsPaused()) {
|
// OUTPUT brokers only (see OutputPauseAndStep). Input brokers must not block
|
||||||
Sleep::MSec(10);
|
// because that prevents cross-thread EventSem posts from completing.
|
||||||
}
|
|
||||||
|
|
||||||
activeMutex.FastLock();
|
activeMutex.FastLock();
|
||||||
uint32 n = activeIndices.Size();
|
uint32 n = activeIndices.Size();
|
||||||
@@ -62,6 +129,23 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Conditional break check — zero cost when anyBreakFlag is false
|
||||||
|
// (single volatile read; the RT loop never pays for this when no break is set).
|
||||||
|
if (*anyBreakFlag && !service->IsPaused() &&
|
||||||
|
breakIndices != NULL_PTR(Vec<uint32> *)) {
|
||||||
|
uint32 nb = breakIndices->Size();
|
||||||
|
for (uint32 i = 0; i < nb; i++) {
|
||||||
|
uint32 idx = (*breakIndices)[i];
|
||||||
|
DebugSignalInfo *s = signalInfoPointers[idx];
|
||||||
|
if (s != NULL_PTR(DebugSignalInfo *) && s->breakOp != BREAK_OFF &&
|
||||||
|
EvaluateBreak(s)) {
|
||||||
|
service->SetPaused(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
activeMutex.FastUnLock();
|
activeMutex.FastUnLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +156,8 @@ public:
|
|||||||
uint32 numCopies, MemoryMapBrokerCopyTableEntry *copyTable,
|
uint32 numCopies, MemoryMapBrokerCopyTableEntry *copyTable,
|
||||||
const char8 *functionName, SignalDirection direction,
|
const char8 *functionName, SignalDirection direction,
|
||||||
volatile bool *anyActiveFlag, Vec<uint32> *activeIndices,
|
volatile bool *anyActiveFlag, Vec<uint32> *activeIndices,
|
||||||
Vec<uint32> *activeSizes, FastPollingMutexSem *activeMutex) {
|
Vec<uint32> *activeSizes, FastPollingMutexSem *activeMutex,
|
||||||
|
volatile bool *anyBreakFlag, Vec<uint32> *breakIndices) {
|
||||||
if (numCopies > 0) {
|
if (numCopies > 0) {
|
||||||
signalInfoPointers = new DebugSignalInfo *[numCopies];
|
signalInfoPointers = new DebugSignalInfo *[numCopies];
|
||||||
for (uint32 i = 0; i < numCopies; i++)
|
for (uint32 i = 0; i < numCopies; i++)
|
||||||
@@ -89,11 +174,12 @@ public:
|
|||||||
|
|
||||||
StreamString dsPath;
|
StreamString dsPath;
|
||||||
DebugService::GetFullObjectName(dataSourceIn, dsPath);
|
DebugService::GetFullObjectName(dataSourceIn, dsPath);
|
||||||
|
fprintf(stderr, ">> %s broker for %s [%d]\n",
|
||||||
|
direction == InputSignals ? "Input" : "Output", dsPath.Buffer(),
|
||||||
|
numCopies);
|
||||||
MemoryMapBroker *mmb = dynamic_cast<MemoryMapBroker *>(broker);
|
MemoryMapBroker *mmb = dynamic_cast<MemoryMapBroker *>(broker);
|
||||||
if (mmb == NULL_PTR(MemoryMapBroker *)) {
|
if (mmb == NULL_PTR(MemoryMapBroker *)) {
|
||||||
REPORT_ERROR_STATIC(ErrorManagement::Warning,
|
fprintf(stderr, ">> Impossible to get broker pointer!!\n");
|
||||||
"Impossible to get broker pointer for %s!!\n",
|
|
||||||
dsPath.Buffer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32 i = 0; i < numCopies; i++) {
|
for (uint32 i = 0; i < numCopies; i++) {
|
||||||
@@ -108,8 +194,8 @@ public:
|
|||||||
StreamString signalName;
|
StreamString signalName;
|
||||||
if (!dataSourceIn.GetSignalName(dsIdx, signalName))
|
if (!dataSourceIn.GetSignalName(dsIdx, signalName))
|
||||||
signalName = "Unknown";
|
signalName = "Unknown";
|
||||||
REPORT_ERROR_STATIC(ErrorManagement::Debug, "Registering %s.%s [%p]\n",
|
fprintf(stderr, ">> registering %s.%s [%p]\n", dsPath.Buffer(),
|
||||||
dsPath.Buffer(), signalName.Buffer(), mmb);
|
signalName.Buffer(), mmb);
|
||||||
|
|
||||||
uint8 dims = 0;
|
uint8 dims = 0;
|
||||||
uint32 elems = 1;
|
uint32 elems = 1;
|
||||||
@@ -128,21 +214,14 @@ public:
|
|||||||
(direction == InputSignals) ? "InputSignals" : "OutputSignals";
|
(direction == InputSignals) ? "InputSignals" : "OutputSignals";
|
||||||
const char8 *dirStrShort = (direction == InputSignals) ? "In" : "Out";
|
const char8 *dirStrShort = (direction == InputSignals) ? "In" : "Out";
|
||||||
|
|
||||||
// Try to find the GAM with different path variations
|
// Search recursively through the entire registry for the GAM by name.
|
||||||
|
// Direct Find("GAM1") only checks top-level; the GAM may be nested
|
||||||
|
// several levels deep inside a RealTimeApplication container.
|
||||||
Reference gamRef =
|
Reference gamRef =
|
||||||
ObjectRegistryDatabase::Instance()->Find(functionName);
|
FindByNameRecursive(ObjectRegistryDatabase::Instance(),
|
||||||
if (!gamRef.IsValid()) {
|
functionName);
|
||||||
// Try with "App.Functions." prefix
|
fprintf(stderr, ">> GAM lookup '%s': %s\n", functionName,
|
||||||
StreamString tryPath;
|
gamRef.IsValid() ? "FOUND" : "NOT FOUND");
|
||||||
tryPath.Printf("App.Functions.%s", functionName);
|
|
||||||
gamRef = ObjectRegistryDatabase::Instance()->Find(tryPath.Buffer());
|
|
||||||
}
|
|
||||||
if (!gamRef.IsValid()) {
|
|
||||||
// Try with "Functions." prefix
|
|
||||||
StreamString tryPath;
|
|
||||||
tryPath.Printf("Functions.%s", functionName);
|
|
||||||
gamRef = ObjectRegistryDatabase::Instance()->Find(tryPath.Buffer());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamRef.IsValid()) {
|
if (gamRef.IsValid()) {
|
||||||
StreamString absGamPath;
|
StreamString absGamPath;
|
||||||
@@ -150,24 +229,28 @@ public:
|
|||||||
// Register short path (In/Out) for GUI compatibility
|
// Register short path (In/Out) for GUI compatibility
|
||||||
gamFullName.Printf("%s.%s.%s", absGamPath.Buffer(), dirStrShort,
|
gamFullName.Printf("%s.%s.%s", absGamPath.Buffer(), dirStrShort,
|
||||||
signalName.Buffer());
|
signalName.Buffer());
|
||||||
signalInfoPointers[i] = service->RegisterSignal(
|
signalInfoPointers[i] =
|
||||||
addr, type, gamFullName.Buffer(), dims, elems);
|
service->RegisterSignal(addr, type, gamFullName.Buffer(), dims, elems);
|
||||||
} else {
|
} else {
|
||||||
// Fallback to short form
|
// Fallback to short form
|
||||||
gamFullName.Printf("%s.%s.%s", functionName, dirStrShort,
|
gamFullName.Printf("%s.%s.%s", functionName, dirStrShort,
|
||||||
signalName.Buffer());
|
signalName.Buffer());
|
||||||
signalInfoPointers[i] = service->RegisterSignal(
|
signalInfoPointers[i] =
|
||||||
addr, type, gamFullName.Buffer(), dims, elems);
|
service->RegisterSignal(addr, type, gamFullName.Buffer(), dims, elems);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
signalInfoPointers[i] = service->RegisterSignal(
|
signalInfoPointers[i] =
|
||||||
addr, type, dsFullName.Buffer(), dims, elems);
|
service->RegisterSignal(addr, type, dsFullName.Buffer(), dims, elems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register broker in DebugService for optimized control
|
// Register broker in DebugService for optimized control
|
||||||
|
bool isOutputBroker = (direction == OutputSignals);
|
||||||
service->RegisterBroker(signalInfoPointers, numCopies, mmb, anyActiveFlag,
|
service->RegisterBroker(signalInfoPointers, numCopies, mmb, anyActiveFlag,
|
||||||
activeIndices, activeSizes, activeMutex);
|
activeIndices, activeSizes, activeMutex,
|
||||||
|
anyBreakFlag, breakIndices,
|
||||||
|
(functionName != NULL_PTR(const char8 *)) ? functionName : dsPath.Buffer(),
|
||||||
|
isOutputBroker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -182,6 +265,9 @@ public:
|
|||||||
signalInfoPointers = NULL_PTR(DebugSignalInfo **);
|
signalInfoPointers = NULL_PTR(DebugSignalInfo **);
|
||||||
numSignals = 0;
|
numSignals = 0;
|
||||||
anyActive = false;
|
anyActive = false;
|
||||||
|
anyBreakActive = false;
|
||||||
|
isOutput = false;
|
||||||
|
gamName[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DebugBrokerWrapper() {
|
virtual ~DebugBrokerWrapper() {
|
||||||
@@ -191,9 +277,15 @@ public:
|
|||||||
|
|
||||||
virtual bool Execute() {
|
virtual bool Execute() {
|
||||||
bool ret = BaseClass::Execute();
|
bool ret = BaseClass::Execute();
|
||||||
if (ret && (anyActive || (service && service->IsPaused()))) {
|
if (ret && (anyActive || anyBreakActive)) {
|
||||||
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices,
|
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices,
|
||||||
activeSizes, activeMutex);
|
activeSizes, activeMutex,
|
||||||
|
&anyBreakActive, &breakIndices);
|
||||||
|
}
|
||||||
|
// Output brokers are the safe pause point: base Execute has already
|
||||||
|
// committed data / posted any cross-thread EventSems.
|
||||||
|
if (ret && isOutput) {
|
||||||
|
DebugBrokerHelper::OutputPauseAndStep(service, gamName);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -201,14 +293,17 @@ public:
|
|||||||
virtual bool Init(SignalDirection direction, DataSourceI &ds,
|
virtual bool Init(SignalDirection direction, DataSourceI &ds,
|
||||||
const char8 *const name, void *gamMem) {
|
const char8 *const name, void *gamMem) {
|
||||||
bool ret = BaseClass::Init(direction, ds, name, gamMem);
|
bool ret = BaseClass::Init(direction, ds, name, gamMem);
|
||||||
REPORT_ERROR_STATIC(ErrorManagement::Debug, "INIT BROKER %s %s\n", name,
|
fprintf(stderr, ">> INIT BROKER %s %s\n", name,
|
||||||
direction == InputSignals ? "In" : "Out");
|
direction == InputSignals ? "In" : "Out");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
numSignals = this->GetNumberOfCopies();
|
numSignals = this->GetNumberOfCopies();
|
||||||
|
isOutput = (direction == OutputSignals);
|
||||||
|
StringHelper::CopyN(gamName, name, 255u);
|
||||||
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
|
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
|
||||||
numSignals, this->copyTable, name,
|
numSignals, this->copyTable, name,
|
||||||
direction, &anyActive, &activeIndices,
|
direction, &anyActive, &activeIndices,
|
||||||
&activeSizes, &activeMutex);
|
&activeSizes, &activeMutex,
|
||||||
|
&anyBreakActive, &breakIndices);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -216,14 +311,17 @@ public:
|
|||||||
virtual bool Init(SignalDirection direction, DataSourceI &ds,
|
virtual bool Init(SignalDirection direction, DataSourceI &ds,
|
||||||
const char8 *const name, void *gamMem, const bool optim) {
|
const char8 *const name, void *gamMem, const bool optim) {
|
||||||
bool ret = BaseClass::Init(direction, ds, name, gamMem, false);
|
bool ret = BaseClass::Init(direction, ds, name, gamMem, false);
|
||||||
REPORT_ERROR_STATIC(ErrorManagement::Debug, "INIT optimized BROKER %s %s\n",
|
fprintf(stderr, ">> INIT optimized BROKER %s %s\n", name,
|
||||||
name, direction == InputSignals ? "In" : "Out");
|
direction == InputSignals ? "In" : "Out");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
numSignals = this->GetNumberOfCopies();
|
numSignals = this->GetNumberOfCopies();
|
||||||
|
isOutput = (direction == OutputSignals);
|
||||||
|
StringHelper::CopyN(gamName, name, 255u);
|
||||||
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
|
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
|
||||||
numSignals, this->copyTable, name,
|
numSignals, this->copyTable, name,
|
||||||
direction, &anyActive, &activeIndices,
|
direction, &anyActive, &activeIndices,
|
||||||
&activeSizes, &activeMutex);
|
&activeSizes, &activeMutex,
|
||||||
|
&anyBreakActive, &breakIndices);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -232,8 +330,12 @@ public:
|
|||||||
DebugSignalInfo **signalInfoPointers;
|
DebugSignalInfo **signalInfoPointers;
|
||||||
uint32 numSignals;
|
uint32 numSignals;
|
||||||
volatile bool anyActive;
|
volatile bool anyActive;
|
||||||
|
volatile bool anyBreakActive;
|
||||||
|
bool isOutput;
|
||||||
|
char8 gamName[256];
|
||||||
Vec<uint32> activeIndices;
|
Vec<uint32> activeIndices;
|
||||||
Vec<uint32> activeSizes;
|
Vec<uint32> activeSizes;
|
||||||
|
Vec<uint32> breakIndices;
|
||||||
FastPollingMutexSem activeMutex;
|
FastPollingMutexSem activeMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -245,6 +347,9 @@ public:
|
|||||||
signalInfoPointers = NULL_PTR(DebugSignalInfo **);
|
signalInfoPointers = NULL_PTR(DebugSignalInfo **);
|
||||||
numSignals = 0;
|
numSignals = 0;
|
||||||
anyActive = false;
|
anyActive = false;
|
||||||
|
anyBreakActive = false;
|
||||||
|
isOutput = false;
|
||||||
|
gamName[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DebugBrokerWrapperNoOptim() {
|
virtual ~DebugBrokerWrapperNoOptim() {
|
||||||
@@ -254,9 +359,13 @@ public:
|
|||||||
|
|
||||||
virtual bool Execute() {
|
virtual bool Execute() {
|
||||||
bool ret = BaseClass::Execute();
|
bool ret = BaseClass::Execute();
|
||||||
if (ret && (anyActive || (service && service->IsPaused()))) {
|
if (ret && (anyActive || anyBreakActive)) {
|
||||||
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices,
|
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices,
|
||||||
activeSizes, activeMutex);
|
activeSizes, activeMutex,
|
||||||
|
&anyBreakActive, &breakIndices);
|
||||||
|
}
|
||||||
|
if (ret && isOutput) {
|
||||||
|
DebugBrokerHelper::OutputPauseAndStep(service, gamName);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -266,10 +375,13 @@ public:
|
|||||||
bool ret = BaseClass::Init(direction, ds, name, gamMem);
|
bool ret = BaseClass::Init(direction, ds, name, gamMem);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
numSignals = this->GetNumberOfCopies();
|
numSignals = this->GetNumberOfCopies();
|
||||||
|
isOutput = (direction == OutputSignals);
|
||||||
|
StringHelper::CopyN(gamName, name, 255u);
|
||||||
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
|
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
|
||||||
numSignals, this->copyTable, name,
|
numSignals, this->copyTable, name,
|
||||||
direction, &anyActive, &activeIndices,
|
direction, &anyActive, &activeIndices,
|
||||||
&activeSizes, &activeMutex);
|
&activeSizes, &activeMutex,
|
||||||
|
&anyBreakActive, &breakIndices);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -278,8 +390,12 @@ public:
|
|||||||
DebugSignalInfo **signalInfoPointers;
|
DebugSignalInfo **signalInfoPointers;
|
||||||
uint32 numSignals;
|
uint32 numSignals;
|
||||||
volatile bool anyActive;
|
volatile bool anyActive;
|
||||||
|
volatile bool anyBreakActive;
|
||||||
|
bool isOutput;
|
||||||
|
char8 gamName[256];
|
||||||
Vec<uint32> activeIndices;
|
Vec<uint32> activeIndices;
|
||||||
Vec<uint32> activeSizes;
|
Vec<uint32> activeSizes;
|
||||||
|
Vec<uint32> breakIndices;
|
||||||
FastPollingMutexSem activeMutex;
|
FastPollingMutexSem activeMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -290,6 +406,8 @@ public:
|
|||||||
signalInfoPointers = NULL_PTR(DebugSignalInfo **);
|
signalInfoPointers = NULL_PTR(DebugSignalInfo **);
|
||||||
numSignals = 0;
|
numSignals = 0;
|
||||||
anyActive = false;
|
anyActive = false;
|
||||||
|
anyBreakActive = false;
|
||||||
|
gamName[0] = '\0';
|
||||||
}
|
}
|
||||||
virtual ~DebugMemoryMapAsyncOutputBroker() {
|
virtual ~DebugMemoryMapAsyncOutputBroker() {
|
||||||
if (signalInfoPointers)
|
if (signalInfoPointers)
|
||||||
@@ -297,9 +415,14 @@ public:
|
|||||||
}
|
}
|
||||||
virtual bool Execute() {
|
virtual bool Execute() {
|
||||||
bool ret = MemoryMapAsyncOutputBroker::Execute();
|
bool ret = MemoryMapAsyncOutputBroker::Execute();
|
||||||
if (ret && (anyActive || (service && service->IsPaused()))) {
|
if (ret && (anyActive || anyBreakActive)) {
|
||||||
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices,
|
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices,
|
||||||
activeSizes, activeMutex);
|
activeSizes, activeMutex,
|
||||||
|
&anyBreakActive, &breakIndices);
|
||||||
|
}
|
||||||
|
// Async output brokers are always output direction
|
||||||
|
if (ret) {
|
||||||
|
DebugBrokerHelper::OutputPauseAndStep(service, gamName);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -315,10 +438,11 @@ public:
|
|||||||
numberOfBuffersIn, cpuMaskIn, stackSizeIn);
|
numberOfBuffersIn, cpuMaskIn, stackSizeIn);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
numSignals = this->GetNumberOfCopies();
|
numSignals = this->GetNumberOfCopies();
|
||||||
|
StringHelper::CopyN(gamName, (functionName != NULL_PTR(const char8 *)) ? functionName : "", 255u);
|
||||||
DebugBrokerHelper::InitSignals(
|
DebugBrokerHelper::InitSignals(
|
||||||
this, dataSourceIn, service, signalInfoPointers, numSignals,
|
this, dataSourceIn, service, signalInfoPointers, numSignals,
|
||||||
this->copyTable, functionName, direction, &anyActive, &activeIndices,
|
this->copyTable, functionName, direction, &anyActive, &activeIndices,
|
||||||
&activeSizes, &activeMutex);
|
&activeSizes, &activeMutex, &anyBreakActive, &breakIndices);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -326,8 +450,11 @@ public:
|
|||||||
DebugSignalInfo **signalInfoPointers;
|
DebugSignalInfo **signalInfoPointers;
|
||||||
uint32 numSignals;
|
uint32 numSignals;
|
||||||
volatile bool anyActive;
|
volatile bool anyActive;
|
||||||
|
volatile bool anyBreakActive;
|
||||||
|
char8 gamName[256];
|
||||||
Vec<uint32> activeIndices;
|
Vec<uint32> activeIndices;
|
||||||
Vec<uint32> activeSizes;
|
Vec<uint32> activeSizes;
|
||||||
|
Vec<uint32> breakIndices;
|
||||||
FastPollingMutexSem activeMutex;
|
FastPollingMutexSem activeMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -340,6 +467,8 @@ public:
|
|||||||
signalInfoPointers = NULL_PTR(DebugSignalInfo **);
|
signalInfoPointers = NULL_PTR(DebugSignalInfo **);
|
||||||
numSignals = 0;
|
numSignals = 0;
|
||||||
anyActive = false;
|
anyActive = false;
|
||||||
|
anyBreakActive = false;
|
||||||
|
gamName[0] = '\0';
|
||||||
}
|
}
|
||||||
virtual ~DebugMemoryMapAsyncTriggerOutputBroker() {
|
virtual ~DebugMemoryMapAsyncTriggerOutputBroker() {
|
||||||
if (signalInfoPointers)
|
if (signalInfoPointers)
|
||||||
@@ -347,9 +476,13 @@ public:
|
|||||||
}
|
}
|
||||||
virtual bool Execute() {
|
virtual bool Execute() {
|
||||||
bool ret = MemoryMapAsyncTriggerOutputBroker::Execute();
|
bool ret = MemoryMapAsyncTriggerOutputBroker::Execute();
|
||||||
if (ret && (anyActive || (service && service->IsPaused()))) {
|
if (ret && (anyActive || anyBreakActive)) {
|
||||||
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices,
|
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices,
|
||||||
activeSizes, activeMutex);
|
activeSizes, activeMutex,
|
||||||
|
&anyBreakActive, &breakIndices);
|
||||||
|
}
|
||||||
|
if (ret) {
|
||||||
|
DebugBrokerHelper::OutputPauseAndStep(service, gamName);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -365,10 +498,11 @@ public:
|
|||||||
stackSizeIn);
|
stackSizeIn);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
numSignals = this->GetNumberOfCopies();
|
numSignals = this->GetNumberOfCopies();
|
||||||
|
StringHelper::CopyN(gamName, (functionName != NULL_PTR(const char8 *)) ? functionName : "", 255u);
|
||||||
DebugBrokerHelper::InitSignals(
|
DebugBrokerHelper::InitSignals(
|
||||||
this, dataSourceIn, service, signalInfoPointers, numSignals,
|
this, dataSourceIn, service, signalInfoPointers, numSignals,
|
||||||
this->copyTable, functionName, direction, &anyActive, &activeIndices,
|
this->copyTable, functionName, direction, &anyActive, &activeIndices,
|
||||||
&activeSizes, &activeMutex);
|
&activeSizes, &activeMutex, &anyBreakActive, &breakIndices);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -376,8 +510,11 @@ public:
|
|||||||
DebugSignalInfo **signalInfoPointers;
|
DebugSignalInfo **signalInfoPointers;
|
||||||
uint32 numSignals;
|
uint32 numSignals;
|
||||||
volatile bool anyActive;
|
volatile bool anyActive;
|
||||||
|
volatile bool anyBreakActive;
|
||||||
|
char8 gamName[256];
|
||||||
Vec<uint32> activeIndices;
|
Vec<uint32> activeIndices;
|
||||||
Vec<uint32> activeSizes;
|
Vec<uint32> activeSizes;
|
||||||
|
Vec<uint32> breakIndices;
|
||||||
FastPollingMutexSem activeMutex;
|
FastPollingMutexSem activeMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -405,55 +542,6 @@ typedef DebugBrokerWrapper<MemoryMapSynchronisedMultiBufferOutputBroker>
|
|||||||
DebugMemoryMapSynchronisedMultiBufferOutputBroker;
|
DebugMemoryMapSynchronisedMultiBufferOutputBroker;
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Specialized wrapper for RealTimeThreadSynchBroker.
|
|
||||||
* @details The RealTimeThreadSynchBroker copies data in AddSample() which is
|
|
||||||
* called from the DataSource thread, not from Execute(). We trace signals
|
|
||||||
* in Execute() after the data has been safely copied.
|
|
||||||
*/
|
|
||||||
class DebugRealTimeThreadSyncBroker : public RealTimeThreadSynchBroker {
|
|
||||||
public:
|
|
||||||
DebugRealTimeThreadSyncBroker() : RealTimeThreadSynchBroker() {
|
|
||||||
service = NULL_PTR(DebugService *);
|
|
||||||
signalInfoPointers = NULL_PTR(DebugSignalInfo **);
|
|
||||||
numSignals = 0;
|
|
||||||
anyActive = false;
|
|
||||||
}
|
|
||||||
virtual ~DebugRealTimeThreadSyncBroker() {
|
|
||||||
if (signalInfoPointers)
|
|
||||||
delete[] signalInfoPointers;
|
|
||||||
}
|
|
||||||
virtual bool Execute() {
|
|
||||||
bool ret = RealTimeThreadSynchBroker::Execute();
|
|
||||||
// Trace after data has been safely copied by AddSample
|
|
||||||
if (ret && (anyActive || (service && service->IsPaused()))) {
|
|
||||||
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices,
|
|
||||||
activeSizes, activeMutex);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
virtual bool Init(SignalDirection direction, DataSourceI &ds,
|
|
||||||
const char8 *const name, void *gamMem) {
|
|
||||||
bool ret = RealTimeThreadSynchBroker::Init(direction, ds, name, gamMem);
|
|
||||||
if (ret) {
|
|
||||||
numSignals = this->GetNumberOfCopies();
|
|
||||||
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
|
|
||||||
numSignals, this->copyTable, name,
|
|
||||||
direction, &anyActive, &activeIndices,
|
|
||||||
&activeSizes, &activeMutex);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
DebugService *service;
|
|
||||||
DebugSignalInfo **signalInfoPointers;
|
|
||||||
uint32 numSignals;
|
|
||||||
volatile bool anyActive;
|
|
||||||
Vec<uint32> activeIndices;
|
|
||||||
Vec<uint32> activeSizes;
|
|
||||||
FastPollingMutexSem activeMutex;
|
|
||||||
};
|
|
||||||
// LCOV_EXCL_START
|
|
||||||
|
|
||||||
typedef DebugBrokerBuilder<DebugMemoryMapInputBroker>
|
typedef DebugBrokerBuilder<DebugMemoryMapInputBroker>
|
||||||
DebugMemoryMapInputBrokerBuilder;
|
DebugMemoryMapInputBrokerBuilder;
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
@@ -477,8 +565,6 @@ typedef DebugBrokerBuilder<DebugMemoryMapAsyncOutputBroker>
|
|||||||
DebugMemoryMapAsyncOutputBrokerBuilder;
|
DebugMemoryMapAsyncOutputBrokerBuilder;
|
||||||
typedef DebugBrokerBuilder<DebugMemoryMapAsyncTriggerOutputBroker>
|
typedef DebugBrokerBuilder<DebugMemoryMapAsyncTriggerOutputBroker>
|
||||||
DebugMemoryMapAsyncTriggerOutputBrokerBuilder;
|
DebugMemoryMapAsyncTriggerOutputBrokerBuilder;
|
||||||
typedef DebugBrokerBuilder<DebugRealTimeThreadSyncBroker>
|
|
||||||
DebugRealTimeThreadSyncBrokerBuilder;
|
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
} // namespace MARTe
|
} // namespace MARTe
|
||||||
|
|||||||
@@ -8,6 +8,17 @@
|
|||||||
|
|
||||||
namespace MARTe {
|
namespace MARTe {
|
||||||
|
|
||||||
|
// Break condition operators stored in DebugSignalInfo::breakOp
|
||||||
|
enum BreakOp {
|
||||||
|
BREAK_OFF = 0,
|
||||||
|
BREAK_GT = 1, // >
|
||||||
|
BREAK_LT = 2, // <
|
||||||
|
BREAK_EQ = 3, // ==
|
||||||
|
BREAK_GEQ = 4, // >=
|
||||||
|
BREAK_LEQ = 5, // <=
|
||||||
|
BREAK_NEQ = 6 // !=
|
||||||
|
};
|
||||||
|
|
||||||
struct DebugSignalInfo {
|
struct DebugSignalInfo {
|
||||||
void* memoryAddress;
|
void* memoryAddress;
|
||||||
TypeDescriptor type;
|
TypeDescriptor type;
|
||||||
@@ -16,10 +27,13 @@ struct DebugSignalInfo {
|
|||||||
uint32 numberOfElements;
|
uint32 numberOfElements;
|
||||||
volatile bool isTracing;
|
volatile bool isTracing;
|
||||||
volatile bool isForcing;
|
volatile bool isForcing;
|
||||||
uint8 forcedValue[1024];
|
uint8 forcedValue[1024];
|
||||||
uint32 internalID;
|
uint32 internalID;
|
||||||
volatile uint32 decimationFactor;
|
volatile uint32 decimationFactor;
|
||||||
volatile uint32 decimationCounter;
|
volatile uint32 decimationCounter;
|
||||||
|
// Conditional break fields (zero-cost when breakOp == BREAK_OFF)
|
||||||
|
volatile uint8 breakOp; // BreakOp enum value
|
||||||
|
float64 breakThreshold; // comparison threshold
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@
|
|||||||
#include "MessageI.h"
|
#include "MessageI.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "ReferenceContainer.h"
|
#include "ReferenceContainer.h"
|
||||||
|
#include "ReferenceT.h"
|
||||||
#include "SingleThreadService.h"
|
#include "SingleThreadService.h"
|
||||||
#include "StreamString.h"
|
#include "StreamString.h"
|
||||||
#include "Vec.h"
|
#include "Vec.h"
|
||||||
@@ -31,6 +32,12 @@ struct BrokerInfo {
|
|||||||
Vec<uint32> *activeIndices;
|
Vec<uint32> *activeIndices;
|
||||||
Vec<uint32> *activeSizes;
|
Vec<uint32> *activeSizes;
|
||||||
FastPollingMutexSem *activeMutex;
|
FastPollingMutexSem *activeMutex;
|
||||||
|
// Conditional break — mirrors activeIndices but for break-enabled signals
|
||||||
|
volatile bool *anyBreakFlag;
|
||||||
|
Vec<uint32> *breakIndices;
|
||||||
|
// GAM association for step-by-GAM
|
||||||
|
StreamString gamName;
|
||||||
|
bool isOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebugService : public ReferenceContainer,
|
class DebugService : public ReferenceContainer,
|
||||||
@@ -46,8 +53,7 @@ public:
|
|||||||
virtual bool Initialise(StructuredDataI &data);
|
virtual bool Initialise(StructuredDataI &data);
|
||||||
|
|
||||||
DebugSignalInfo *RegisterSignal(void *memoryAddress, TypeDescriptor type,
|
DebugSignalInfo *RegisterSignal(void *memoryAddress, TypeDescriptor type,
|
||||||
const char8 *name,
|
const char8 *name, uint8 numberOfDimensions = 0,
|
||||||
uint8 numberOfDimensions = 0,
|
|
||||||
uint32 numberOfElements = 1);
|
uint32 numberOfElements = 1);
|
||||||
void ProcessSignal(DebugSignalInfo *signalInfo, uint32 size,
|
void ProcessSignal(DebugSignalInfo *signalInfo, uint32 size,
|
||||||
uint64 timestamp);
|
uint64 timestamp);
|
||||||
@@ -55,7 +61,10 @@ public:
|
|||||||
void RegisterBroker(DebugSignalInfo **signalPointers, uint32 numSignals,
|
void RegisterBroker(DebugSignalInfo **signalPointers, uint32 numSignals,
|
||||||
MemoryMapBroker *broker, volatile bool *anyActiveFlag,
|
MemoryMapBroker *broker, volatile bool *anyActiveFlag,
|
||||||
Vec<uint32> *activeIndices, Vec<uint32> *activeSizes,
|
Vec<uint32> *activeIndices, Vec<uint32> *activeSizes,
|
||||||
FastPollingMutexSem *activeMutex);
|
FastPollingMutexSem *activeMutex,
|
||||||
|
volatile bool *anyBreakFlag, Vec<uint32> *breakIndices,
|
||||||
|
const char8 *gamName = NULL_PTR(const char8 *),
|
||||||
|
bool isOutput = false);
|
||||||
|
|
||||||
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info);
|
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info);
|
||||||
|
|
||||||
@@ -64,17 +73,34 @@ public:
|
|||||||
bool IsPaused() const { return isPaused; }
|
bool IsPaused() const { return isPaused; }
|
||||||
void SetPaused(bool paused) { isPaused = paused; }
|
void SetPaused(bool paused) { isPaused = paused; }
|
||||||
|
|
||||||
|
// Step-by-GAM / per-thread: called by each output broker.
|
||||||
|
// threadName is the OS thread name (from Threads::Name(Threads::Id())).
|
||||||
|
// Decrements stepRemaining only when stepThreadFilter is empty or matches;
|
||||||
|
// when stepRemaining reaches 0, sets isPaused = true and records gamName.
|
||||||
|
void ConsumeStepIfNeeded(const char8 *gamName,
|
||||||
|
const char8 *threadName = NULL_PTR(const char8 *));
|
||||||
|
|
||||||
|
void GetStepStatus(BasicTCPSocket *client);
|
||||||
|
// Step n cycles; if threadName is non-null/non-empty, only that thread advances.
|
||||||
|
void Step(uint32 n, const char8 *threadName = NULL_PTR(const char8 *));
|
||||||
|
|
||||||
|
// Read the current raw value of a signal from its memory address.
|
||||||
|
void GetSignalValue(const char8 *name, BasicTCPSocket *client);
|
||||||
|
|
||||||
static bool GetFullObjectName(const Object &obj, StreamString &fullPath);
|
static bool GetFullObjectName(const Object &obj, StreamString &fullPath);
|
||||||
|
|
||||||
uint32 ForceSignal(const char8 *name, const char8 *valueStr);
|
uint32 ForceSignal(const char8 *name, const char8 *valueStr);
|
||||||
uint32 UnforceSignal(const char8 *name);
|
uint32 UnforceSignal(const char8 *name);
|
||||||
uint32 TraceSignal(const char8 *name, bool enable, uint32 decimation = 1);
|
uint32 TraceSignal(const char8 *name, bool enable, uint32 decimation = 1);
|
||||||
|
uint32 SetBreak(const char8 *name, uint8 op, float64 threshold);
|
||||||
|
uint32 ClearBreak(const char8 *name);
|
||||||
bool IsInstrumented(const char8 *fullPath, bool &traceable, bool &forcable);
|
bool IsInstrumented(const char8 *fullPath, bool &traceable, bool &forcable);
|
||||||
void Discover(BasicTCPSocket *client);
|
void Discover(BasicTCPSocket *client);
|
||||||
void InfoNode(const char8 *path, BasicTCPSocket *client);
|
void InfoNode(const char8 *path, BasicTCPSocket *client);
|
||||||
void ListNodes(const char8 *path, BasicTCPSocket *client);
|
void ListNodes(const char8 *path, BasicTCPSocket *client);
|
||||||
void ServeConfig(BasicTCPSocket *client);
|
void ServeConfig(BasicTCPSocket *client);
|
||||||
void SetFullConfig(ConfigurationDatabase &config);
|
void SetFullConfig(ConfigurationDatabase &config);
|
||||||
|
void RebuildConfigFromRegistry();
|
||||||
|
|
||||||
struct MonitoredSignal {
|
struct MonitoredSignal {
|
||||||
ReferenceT<DataSourceI> dataSource;
|
ReferenceT<DataSourceI> dataSource;
|
||||||
@@ -86,27 +112,20 @@ public:
|
|||||||
StreamString path;
|
StreamString path;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MonitoredState {
|
|
||||||
Reference obj;
|
|
||||||
uint32 internalID;
|
|
||||||
StreamString path;
|
|
||||||
StreamString lastState;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 RegisterMonitorSignal(const char8 *path, uint32 periodMs);
|
uint32 RegisterMonitorSignal(const char8 *path, uint32 periodMs);
|
||||||
uint32 UnmonitorSignal(const char8 *path);
|
uint32 UnmonitorSignal(const char8 *path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void HandleCommand(StreamString cmd, BasicTCPSocket *client);
|
void HandleCommand(StreamString cmd, BasicTCPSocket *client);
|
||||||
void UpdateBrokersActiveStatus();
|
void UpdateBrokersActiveStatus();
|
||||||
|
void UpdateBrokersBreakStatus();
|
||||||
|
void InjectTcpLoggerIfNeeded();
|
||||||
|
|
||||||
uint32 ExportTree(ReferenceContainer *container, StreamString &json,
|
uint32 ExportTree(ReferenceContainer *container, StreamString &json, const char8 *pathPrefix);
|
||||||
const char8 *pathPrefix);
|
|
||||||
void PatchRegistry();
|
void PatchRegistry();
|
||||||
|
|
||||||
void EnrichWithConfig(const char8 *path, StreamString &json);
|
void EnrichWithConfig(const char8 *path, StreamString &json);
|
||||||
static void JsonifyDatabase(ConfigurationDatabase &db, StreamString &json,
|
static void JsonifyDatabase(ConfigurationDatabase &db, StreamString &json);
|
||||||
StreamString indent = "");
|
|
||||||
|
|
||||||
ErrorManagement::ErrorType Server(ExecutionInfo &info);
|
ErrorManagement::ErrorType Server(ExecutionInfo &info);
|
||||||
ErrorManagement::ErrorType Streamer(ExecutionInfo &info);
|
ErrorManagement::ErrorType Streamer(ExecutionInfo &info);
|
||||||
@@ -118,6 +137,9 @@ private:
|
|||||||
bool isServer;
|
bool isServer;
|
||||||
bool suppressTimeoutLogs;
|
bool suppressTimeoutLogs;
|
||||||
volatile bool isPaused;
|
volatile bool isPaused;
|
||||||
|
volatile uint32 stepRemaining;
|
||||||
|
StreamString pausedAtGam;
|
||||||
|
StreamString stepThreadFilter; // empty = all threads; non-empty = only this OS thread name
|
||||||
|
|
||||||
BasicTCPSocket tcpServer;
|
BasicTCPSocket tcpServer;
|
||||||
BasicUDPSocket udpSocket;
|
BasicUDPSocket udpSocket;
|
||||||
@@ -131,7 +153,6 @@ private:
|
|||||||
if (type == StreamerType) {
|
if (type == StreamerType) {
|
||||||
return parent->Streamer(info);
|
return parent->Streamer(info);
|
||||||
}
|
}
|
||||||
printf("serve TCP\n");
|
|
||||||
return parent->Server(info);
|
return parent->Server(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,14 +174,19 @@ private:
|
|||||||
Vec<SignalAlias> aliases;
|
Vec<SignalAlias> aliases;
|
||||||
Vec<BrokerInfo> brokers;
|
Vec<BrokerInfo> brokers;
|
||||||
Vec<MonitoredSignal> monitoredSignals;
|
Vec<MonitoredSignal> monitoredSignals;
|
||||||
Vec<MonitoredState> monitoredStates;
|
|
||||||
|
|
||||||
FastPollingMutexSem mutex;
|
FastPollingMutexSem mutex;
|
||||||
TraceRingBuffer traceBuffer;
|
TraceRingBuffer traceBuffer;
|
||||||
|
|
||||||
BasicTCPSocket *activeClient;
|
BasicTCPSocket *activeClient;
|
||||||
|
|
||||||
|
// Streamer state persisted across Execute() calls (framework loops Execute)
|
||||||
|
uint8 streamerPacketBuffer[4096];
|
||||||
|
uint32 streamerPacketOffset;
|
||||||
|
uint32 streamerSequenceNumber;
|
||||||
|
|
||||||
ConfigurationDatabase fullConfig;
|
ConfigurationDatabase fullConfig;
|
||||||
|
bool manualConfigSet;
|
||||||
|
|
||||||
static DebugService *instance;
|
static DebugService *instance;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Messages
|
|||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Logger
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Logger
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4StateMachine
|
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
|
||||||
@@ -50,8 +49,6 @@ INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4LoggerService
|
|||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
|
||||||
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/DataSources/RealTimeThreadSynchronisation
|
|
||||||
|
|
||||||
|
|
||||||
all: $(OBJS) $(SUBPROJ) \
|
all: $(OBJS) $(SUBPROJ) \
|
||||||
$(BUILD_DIR)/DebugService$(LIBEXT) \
|
$(BUILD_DIR)/DebugService$(LIBEXT) \
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ TcpLogger::~TcpLogger() {
|
|||||||
clientsMutex.FastUnLock();
|
clientsMutex.FastUnLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TcpLogger::ExportData(StructuredDataI & data) {
|
||||||
|
bool ok = data.Write("Port", static_cast<uint32>(port));
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
bool TcpLogger::Initialise(StructuredDataI & data) {
|
bool TcpLogger::Initialise(StructuredDataI & data) {
|
||||||
if (!ReferenceContainer::Initialise(data)) return false;
|
if (!ReferenceContainer::Initialise(data)) return false;
|
||||||
|
|
||||||
@@ -92,64 +97,66 @@ ErrorManagement::ErrorType TcpLogger::Execute(ExecutionInfo & info) {
|
|||||||
return ErrorManagement::NoError;
|
return ErrorManagement::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (info.GetStage() == ExecutionInfo::MainStage) {
|
// Each Execute() call does one cycle. The MARTe2 framework loops Execute()
|
||||||
// 1. Check for new connections
|
// so we must NOT spin in an infinite internal loop here — doing so prevents
|
||||||
BasicTCPSocket *newClient = server.WaitConnection(1);
|
// the framework from ever delivering the TerminationStage and causes
|
||||||
if (newClient != NULL_PTR(BasicTCPSocket *)) {
|
// Stop() to time out, leaving threads running after the destructor.
|
||||||
clientsMutex.FastLock();
|
|
||||||
bool added = false;
|
// 1. Check for new connections (1 ms timeout → returns promptly)
|
||||||
for (uint32 i=0; i<MAX_CLIENTS; i++) {
|
BasicTCPSocket *newClient = server.WaitConnection(1);
|
||||||
if (activeClients[i] == NULL_PTR(BasicTCPSocket*)) {
|
if (newClient != NULL_PTR(BasicTCPSocket *)) {
|
||||||
activeClients[i] = newClient;
|
clientsMutex.FastLock();
|
||||||
added = true;
|
bool added = false;
|
||||||
break;
|
for (uint32 i=0; i<MAX_CLIENTS; i++) {
|
||||||
}
|
if (activeClients[i] == NULL_PTR(BasicTCPSocket*)) {
|
||||||
}
|
activeClients[i] = newClient;
|
||||||
clientsMutex.FastUnLock();
|
added = true;
|
||||||
if (!added) {
|
break;
|
||||||
newClient->Close();
|
|
||||||
delete newClient;
|
|
||||||
} else {
|
|
||||||
(void)newClient->SetBlocking(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
clientsMutex.FastUnLock();
|
||||||
// 2. Stream data to clients
|
if (!added) {
|
||||||
bool hadData = false;
|
newClient->Close();
|
||||||
while (readIdx != writeIdx) {
|
delete newClient;
|
||||||
hadData = true;
|
|
||||||
uint32 idx = readIdx % QUEUE_SIZE;
|
|
||||||
TcpLogEntry &entry = queue[idx];
|
|
||||||
|
|
||||||
StreamString level;
|
|
||||||
ErrorManagement::ErrorCodeToStream(entry.info.header.errorType, level);
|
|
||||||
|
|
||||||
StreamString packet;
|
|
||||||
packet.Printf("LOG %s %s\n", level.Buffer(), entry.description);
|
|
||||||
uint32 size = packet.Size();
|
|
||||||
|
|
||||||
clientsMutex.FastLock();
|
|
||||||
for (uint32 j=0; j<MAX_CLIENTS; j++) {
|
|
||||||
if (activeClients[j] != NULL_PTR(BasicTCPSocket*)) {
|
|
||||||
uint32 s = size;
|
|
||||||
if (!activeClients[j]->Write(packet.Buffer(), s)) {
|
|
||||||
activeClients[j]->Close();
|
|
||||||
delete activeClients[j];
|
|
||||||
activeClients[j] = NULL_PTR(BasicTCPSocket*);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clientsMutex.FastUnLock();
|
|
||||||
readIdx = (readIdx + 1) % QUEUE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hadData) {
|
|
||||||
(void)eventSem.Wait(TimeoutType(100));
|
|
||||||
eventSem.Reset();
|
|
||||||
} else {
|
} else {
|
||||||
Sleep::MSec(1);
|
(void)newClient->SetBlocking(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. Stream queued entries to clients
|
||||||
|
bool hadData = false;
|
||||||
|
while (readIdx != writeIdx) {
|
||||||
|
hadData = true;
|
||||||
|
uint32 idx = readIdx % QUEUE_SIZE;
|
||||||
|
TcpLogEntry &entry = queue[idx];
|
||||||
|
|
||||||
|
StreamString level;
|
||||||
|
ErrorManagement::ErrorCodeToStream(entry.info.header.errorType, level);
|
||||||
|
|
||||||
|
StreamString packet;
|
||||||
|
packet.Printf("LOG %s %s\n", level.Buffer(), entry.description);
|
||||||
|
uint32 size = packet.Size();
|
||||||
|
|
||||||
|
clientsMutex.FastLock();
|
||||||
|
for (uint32 j=0; j<MAX_CLIENTS; j++) {
|
||||||
|
if (activeClients[j] != NULL_PTR(BasicTCPSocket*)) {
|
||||||
|
uint32 s = size;
|
||||||
|
if (!activeClients[j]->Write(packet.Buffer(), s)) {
|
||||||
|
activeClients[j]->Close();
|
||||||
|
delete activeClients[j];
|
||||||
|
activeClients[j] = NULL_PTR(BasicTCPSocket*);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clientsMutex.FastUnLock();
|
||||||
|
readIdx = (readIdx + 1) % QUEUE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hadData) {
|
||||||
|
// Brief wait so we don't busy-spin; return so Stop() can take effect
|
||||||
|
(void)eventSem.Wait(TimeoutType(10));
|
||||||
|
eventSem.Reset();
|
||||||
|
}
|
||||||
return ErrorManagement::NoError;
|
return ErrorManagement::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ public:
|
|||||||
|
|
||||||
virtual bool Initialise(StructuredDataI & data);
|
virtual bool Initialise(StructuredDataI & data);
|
||||||
|
|
||||||
|
virtual bool ExportData(StructuredDataI & data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of LoggerConsumerI.
|
* @brief Implementation of LoggerConsumerI.
|
||||||
* Called by LoggerService.
|
* Called by LoggerService.
|
||||||
|
|||||||
@@ -5,23 +5,86 @@
|
|||||||
+GAM1 = {
|
+GAM1 = {
|
||||||
Class = IOGAM
|
Class = IOGAM
|
||||||
InputSignals = {
|
InputSignals = {
|
||||||
Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }
|
Counter = {
|
||||||
Time = { DataSource = Timer Type = uint32 }
|
DataSource = Timer
|
||||||
|
Type = uint32
|
||||||
|
Frequency = 1000
|
||||||
|
}
|
||||||
|
Time = {
|
||||||
|
DataSource = Timer
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
OutputSignals = {
|
OutputSignals = {
|
||||||
Counter = { DataSource = SyncDB Type = uint32 }
|
Counter = {
|
||||||
Time = { DataSource = DDB Type = uint32 }
|
DataSource = SyncDB
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
|
Time = {
|
||||||
|
DataSource = DDB
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
+CGAM = {
|
||||||
|
Class = ConstantGAM
|
||||||
|
OutputSignals = {
|
||||||
|
Test = {
|
||||||
|
DataSource = DDB2
|
||||||
|
Type = float32
|
||||||
|
Default = 0.123
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+GAM2 = {
|
+GAM2 = {
|
||||||
Class = IOGAM
|
Class = IOGAM
|
||||||
InputSignals = {
|
InputSignals = {
|
||||||
Counter = { DataSource = SyncDB Type = uint32 Samples = 1 }
|
Counter = {
|
||||||
|
DataSource = TimerSlow
|
||||||
|
Frequency = 1
|
||||||
|
}
|
||||||
|
Time = {
|
||||||
|
DataSource = TimerSlow
|
||||||
|
}
|
||||||
|
Test = {
|
||||||
|
DataSource = DDB2
|
||||||
|
Type = float32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
OutputSignals = {
|
OutputSignals = {
|
||||||
Counter = { DataSource = Logger Type = uint32 }
|
Counter = {
|
||||||
|
Type = uint32
|
||||||
|
DataSource = Logger
|
||||||
|
}
|
||||||
|
Time = {
|
||||||
|
Type = uint32
|
||||||
|
DataSource = Logger
|
||||||
|
}
|
||||||
|
ConstOut = {
|
||||||
|
DataSource = Logger
|
||||||
|
Type = float32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
+GAM3 = {
|
||||||
|
Class = IOGAM
|
||||||
|
InputSignals = {
|
||||||
|
Counter = {
|
||||||
|
Frequency = 1
|
||||||
|
Samples = 100
|
||||||
|
Type = uint32
|
||||||
|
DataSource = SyncDB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OutputSignals = {
|
||||||
|
Counter = {
|
||||||
|
DataSource = DDB3
|
||||||
|
NumberOfElements = 100
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+Data = {
|
+Data = {
|
||||||
Class = ReferenceContainer
|
Class = ReferenceContainer
|
||||||
@@ -30,31 +93,61 @@
|
|||||||
Class = RealTimeThreadSynchronisation
|
Class = RealTimeThreadSynchronisation
|
||||||
Timeout = 200
|
Timeout = 200
|
||||||
Signals = {
|
Signals = {
|
||||||
Counter = { Type = uint32 }
|
Counter = {
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+Timer = {
|
+Timer = {
|
||||||
Class = LinuxTimer
|
Class = LinuxTimer
|
||||||
SleepTime = 1000
|
|
||||||
Signals = {
|
Signals = {
|
||||||
Counter = { Type = uint32 }
|
Counter = {
|
||||||
Time = { Type = uint32 }
|
Type = uint32
|
||||||
|
}
|
||||||
|
Time = {
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+TimerSlow = {
|
||||||
|
Class = LinuxTimer
|
||||||
|
Signals = {
|
||||||
|
Counter = {
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
|
Time = {
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+Logger = {
|
+Logger = {
|
||||||
Class = LoggerDataSource
|
Class = LoggerDataSource
|
||||||
Signals = {
|
Signals = {
|
||||||
CounterCopy = { Type = uint32 }
|
CounterCopy = {
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
|
TimeCopy = {
|
||||||
|
Type = uint32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+DDB = {
|
+DDB = {
|
||||||
AllowNoProducer = 1
|
AllowNoProducer = 1
|
||||||
Class = GAMDataSource
|
Class = GAMDataSource
|
||||||
Signals = {
|
Signals = {
|
||||||
Counter = { Type = uint32 }
|
Counter= {
|
||||||
Time = { Type = uint32 }
|
Type = uint32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
+DDB2 = {
|
||||||
|
AllowNoProducer = 1
|
||||||
|
Class = GAMDataSource
|
||||||
|
}
|
||||||
|
+DDB3 = {
|
||||||
|
AllowNoProducer = 1
|
||||||
|
Class = GAMDataSource
|
||||||
|
}
|
||||||
+DAMS = {
|
+DAMS = {
|
||||||
Class = TimingDataSource
|
Class = TimingDataSource
|
||||||
}
|
}
|
||||||
@@ -71,7 +164,11 @@
|
|||||||
}
|
}
|
||||||
+Thread2 = {
|
+Thread2 = {
|
||||||
Class = RealTimeThread
|
Class = RealTimeThread
|
||||||
Functions = {GAM2}
|
Functions = {GAM2 CGAM}
|
||||||
|
}
|
||||||
|
+Thread3 = {
|
||||||
|
Class = RealTimeThread
|
||||||
|
Functions = {GAM3}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,11 +187,3 @@
|
|||||||
StreamIP = "127.0.0.1"
|
StreamIP = "127.0.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
+LoggerService = {
|
|
||||||
Class = LoggerService
|
|
||||||
CPUs = 0x1
|
|
||||||
+DebugConsumer = {
|
|
||||||
Class = TcpLogger
|
|
||||||
Port = 8082
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -27,16 +27,18 @@ const char8 * const config_command_text =
|
|||||||
" CustomGAMField = \"GAMValue\" "
|
" CustomGAMField = \"GAMValue\" "
|
||||||
" InputSignals = {"
|
" InputSignals = {"
|
||||||
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 PVName = \"PROC:VAR:1\" }"
|
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 PVName = \"PROC:VAR:1\" }"
|
||||||
|
" Time = { DataSource = Timer Type = uint32 }"
|
||||||
" }"
|
" }"
|
||||||
" OutputSignals = {"
|
" OutputSignals = {"
|
||||||
" Counter = { DataSource = DDB Type = uint32 }"
|
" Counter = { DataSource = DDB Type = uint32 }"
|
||||||
|
" Time = { DataSource = DDB Type = uint32 }"
|
||||||
" }"
|
" }"
|
||||||
" }"
|
" }"
|
||||||
" }"
|
" }"
|
||||||
" +Data = {"
|
" +Data = {"
|
||||||
" Class = ReferenceContainer "
|
" Class = ReferenceContainer "
|
||||||
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } } }"
|
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
|
||||||
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } } }"
|
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
|
||||||
" +DAMS = { Class = TimingDataSource }"
|
" +DAMS = { Class = TimingDataSource }"
|
||||||
" }"
|
" }"
|
||||||
" +States = {"
|
" +States = {"
|
||||||
@@ -97,16 +99,12 @@ void TestConfigCommands() {
|
|||||||
|
|
||||||
// Start the application to trigger broker execution and signal registration
|
// Start the application to trigger broker execution and signal registration
|
||||||
ReferenceT<RealTimeApplication> app = ObjectRegistryDatabase::Instance()->Find("App");
|
ReferenceT<RealTimeApplication> app = ObjectRegistryDatabase::Instance()->Find("App");
|
||||||
if (app.IsValid()) {
|
assert(app.IsValid());
|
||||||
if (app->ConfigureApplication()) {
|
assert(app->ConfigureApplication());
|
||||||
if (app->PrepareNextState("State1") == ErrorManagement::NoError) {
|
assert(app->PrepareNextState("State1") == ErrorManagement::NoError);
|
||||||
if (app->StartNextStateExecution() == ErrorManagement::NoError) {
|
assert(app->StartNextStateExecution() == ErrorManagement::NoError);
|
||||||
printf("Application started (for signal registration).\n");
|
printf("Application started (for signal registration).\n");
|
||||||
Sleep::MSec(500); // Wait for some cycles
|
Sleep::MSec(500); // Wait for some cycles
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReferenceT<DebugService> service = ObjectRegistryDatabase::Instance()->Find("DebugService");
|
ReferenceT<DebugService> service = ObjectRegistryDatabase::Instance()->Find("DebugService");
|
||||||
if (service.IsValid()) {
|
if (service.IsValid()) {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ void timeout_handler(int sig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ErrorProcessFunction(const MARTe::ErrorManagement::ErrorInformation &errorInfo, const char8 * const errorDescription) {
|
void ErrorProcessFunction(const MARTe::ErrorManagement::ErrorInformation &errorInfo, const char8 * const errorDescription) {
|
||||||
// printf("[MARTe Error] %s: %s\n", errorInfo.className, errorDescription);
|
printf("[MARTe Error] %s: %s\n", errorInfo.className, errorDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward declarations of other tests
|
// Forward declarations of other tests
|
||||||
@@ -80,7 +80,7 @@ int main() {
|
|||||||
Sleep::MSec(1000);
|
Sleep::MSec(1000);
|
||||||
|
|
||||||
printf("\n--- Test 5: Config & Metadata Enrichment ---\n");
|
printf("\n--- Test 5: Config & Metadata Enrichment ---\n");
|
||||||
// TestConfigCommands(); // Skipping for now
|
TestConfigCommands();
|
||||||
Sleep::MSec(1000);
|
Sleep::MSec(1000);
|
||||||
|
|
||||||
printf("\n--- Test 6: TREE Command Enhancement ---\n");
|
printf("\n--- Test 6: TREE Command Enhancement ---\n");
|
||||||
|
|||||||
@@ -31,11 +31,9 @@ INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
|
|||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
|
||||||
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/GAMs/IOGAM
|
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/GAMs/IOGAM
|
||||||
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/DataSources/LinuxTimer
|
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/DataSources/LinuxTimer
|
||||||
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/DataSources/RealTimeThreadSynchronisation
|
|
||||||
|
|
||||||
LIBRARIES += -L$(MARTe2_DIR)/Build/$(TARGET)/Core -lMARTe2
|
LIBRARIES += -L$(MARTe2_DIR)/Build/$(TARGET)/Core -lMARTe2
|
||||||
LIBRARIES += -L$(MARTe2_Components_DIR)/Build/$(TARGET)/Components/DataSources/LinuxTimer -lLinuxTimer
|
LIBRARIES += -L$(MARTe2_Components_DIR)/Build/$(TARGET)/Components/DataSources/LinuxTimer -lLinuxTimer
|
||||||
LIBRARIES += -L$(MARTe2_Components_DIR)/Build/$(TARGET)/Components/DataSources/RealTimeThreadSynchronisation -lRealTimeThreadSynchronisation
|
|
||||||
LIBRARIES += -L$(MARTe2_Components_DIR)/Build/$(TARGET)/Components/GAMs/IOGAM -lIOGAM
|
LIBRARIES += -L$(MARTe2_Components_DIR)/Build/$(TARGET)/Components/GAMs/IOGAM -lIOGAM
|
||||||
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/DebugService -lDebugService
|
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/DebugService -lDebugService
|
||||||
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/TCPLogger -lTcpLogger
|
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/TCPLogger -lTcpLogger
|
||||||
|
|||||||
@@ -39,17 +39,19 @@ void TestTreeCommand() {
|
|||||||
" Class = IOGAM "
|
" Class = IOGAM "
|
||||||
" InputSignals = {"
|
" InputSignals = {"
|
||||||
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
|
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
|
||||||
|
" Time = { DataSource = Timer Type = uint32 }"
|
||||||
" }"
|
" }"
|
||||||
" OutputSignals = {"
|
" OutputSignals = {"
|
||||||
" Counter = { DataSource = DDB Type = uint32 }"
|
" Counter = { DataSource = DDB Type = uint32 }"
|
||||||
|
" Time = { DataSource = DDB Type = uint32 }"
|
||||||
" }"
|
" }"
|
||||||
" }"
|
" }"
|
||||||
" }"
|
" }"
|
||||||
" +Data = {"
|
" +Data = {"
|
||||||
" Class = ReferenceContainer "
|
" Class = ReferenceContainer "
|
||||||
" DefaultDataSource = DDB "
|
" DefaultDataSource = DDB "
|
||||||
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } } }"
|
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
|
||||||
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } } }"
|
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
|
||||||
" +DAMS = { Class = TimingDataSource }"
|
" +DAMS = { Class = TimingDataSource }"
|
||||||
" }"
|
" }"
|
||||||
" +States = {"
|
" +States = {"
|
||||||
|
|||||||
@@ -28,10 +28,8 @@ INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4LoggerService
|
|||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
|
||||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
|
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
|
||||||
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/DataSources/RealTimeThreadSynchronisation
|
|
||||||
|
|
||||||
LIBRARIES += -L$(MARTe2_DIR)/Build/$(TARGET)/Core -lMARTe2
|
LIBRARIES += -L$(MARTe2_DIR)/Build/$(TARGET)/Core -lMARTe2
|
||||||
LIBRARIES += -L$(MARTe2_Components_DIR)/Build/$(TARGET)/Components/DataSources/RealTimeThreadSynchronisation -lRealTimeThreadSynchronisation
|
|
||||||
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/DebugService -lDebugService
|
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/DebugService -lDebugService
|
||||||
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/TCPLogger -lTcpLogger
|
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/TCPLogger -lTcpLogger
|
||||||
|
|
||||||
|
|||||||
@@ -63,14 +63,61 @@ public:
|
|||||||
Vec<uint32> sizes;
|
Vec<uint32> sizes;
|
||||||
FastPollingMutexSem mutex;
|
FastPollingMutexSem mutex;
|
||||||
DebugSignalInfo* ptrs[1] = { service.signals[0] };
|
DebugSignalInfo* ptrs[1] = { service.signals[0] };
|
||||||
service.RegisterBroker(ptrs, 1, NULL_PTR(MemoryMapBroker*), &active, &indices, &sizes, &mutex);
|
volatile bool anyBreak = false;
|
||||||
|
Vec<uint32> breakIdx;
|
||||||
|
service.RegisterBroker(ptrs, 1, NULL_PTR(MemoryMapBroker*), &active, &indices, &sizes, &mutex, &anyBreak, &breakIdx);
|
||||||
service.UpdateBrokersActiveStatus();
|
service.UpdateBrokersActiveStatus();
|
||||||
assert(active == true);
|
assert(active == true);
|
||||||
assert(indices.Size() == 1);
|
assert(indices.Size() == 1);
|
||||||
assert(indices[0] == 0);
|
assert(indices[0] == 0);
|
||||||
|
|
||||||
// Helper Process
|
// Helper Process
|
||||||
DebugBrokerHelper::Process(&service, ptrs, indices, sizes, mutex);
|
DebugBrokerHelper::Process(&service, ptrs, indices, sizes, mutex, &anyBreak, &breakIdx);
|
||||||
|
|
||||||
|
// 4. Step / per-thread filter
|
||||||
|
// STEP with no thread filter — all threads can consume
|
||||||
|
service.Step(2u, NULL_PTR(const char8 *));
|
||||||
|
assert(!service.IsPaused());
|
||||||
|
assert(service.stepRemaining == 2u);
|
||||||
|
service.ConsumeStepIfNeeded("GAM1", "ThreadA");
|
||||||
|
assert(service.stepRemaining == 1u);
|
||||||
|
assert(!service.IsPaused());
|
||||||
|
service.ConsumeStepIfNeeded("GAM1", "ThreadB");
|
||||||
|
assert(service.stepRemaining == 0u);
|
||||||
|
assert(service.IsPaused());
|
||||||
|
assert(service.pausedAtGam == "GAM1");
|
||||||
|
|
||||||
|
// STEP with a thread filter — only matching thread consumes
|
||||||
|
service.Step(2u, "ThreadA");
|
||||||
|
assert(!service.IsPaused());
|
||||||
|
assert(service.stepThreadFilter == "ThreadA");
|
||||||
|
// ThreadB should be ignored
|
||||||
|
service.ConsumeStepIfNeeded("GAMB", "ThreadB");
|
||||||
|
assert(service.stepRemaining == 2u); // unchanged
|
||||||
|
assert(!service.IsPaused());
|
||||||
|
// ThreadA consumes both credits
|
||||||
|
service.ConsumeStepIfNeeded("GAMA1", "ThreadA");
|
||||||
|
assert(service.stepRemaining == 1u);
|
||||||
|
assert(!service.IsPaused());
|
||||||
|
service.ConsumeStepIfNeeded("GAMA2", "ThreadA");
|
||||||
|
assert(service.stepRemaining == 0u);
|
||||||
|
assert(service.IsPaused());
|
||||||
|
assert(service.pausedAtGam == "GAMA2");
|
||||||
|
|
||||||
|
// STEP with unknown thread (NULL threadName arg to ConsumeStep) is also filtered out
|
||||||
|
service.Step(1u, "ThreadA");
|
||||||
|
service.ConsumeStepIfNeeded("X", NULL_PTR(const char8 *));
|
||||||
|
assert(service.stepRemaining == 1u); // not consumed
|
||||||
|
service.SetPaused(false);
|
||||||
|
service.Step(0u, NULL_PTR(const char8 *));
|
||||||
|
|
||||||
|
// 5. VALUE command (NULL client — smoke test, no crash)
|
||||||
|
service.HandleCommand("VALUE X.Y.Z", NULL_PTR(BasicTCPSocket*));
|
||||||
|
service.HandleCommand("VALUE NoSuchSignal", NULL_PTR(BasicTCPSocket*));
|
||||||
|
service.HandleCommand("STEP 1 ThreadA", NULL_PTR(BasicTCPSocket*));
|
||||||
|
assert(service.stepThreadFilter == "ThreadA");
|
||||||
|
service.HandleCommand("STEP 3", NULL_PTR(BasicTCPSocket*));
|
||||||
|
assert(service.stepThreadFilter.Size() == 0u);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -86,9 +133,9 @@ void timeout_handler(int sig) {
|
|||||||
int main() {
|
int main() {
|
||||||
signal(SIGALRM, timeout_handler);
|
signal(SIGALRM, timeout_handler);
|
||||||
alarm(10);
|
alarm(10);
|
||||||
printf("--- MARTe2 Debug Suite COVERAGE V29 ---\n");
|
printf("--- MARTe2 Debug Suite COVERAGE V30 ---\n");
|
||||||
MARTe::TestTcpLogger();
|
MARTe::TestTcpLogger();
|
||||||
MARTe::DebugServiceTest::TestAll();
|
MARTe::DebugServiceTest::TestAll();
|
||||||
printf("\nCOVERAGE V29 PASSED!\n");
|
printf("\nCOVERAGE V30 PASSED!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+2534
-558
File diff suppressed because it is too large
Load Diff
@@ -1,226 +0,0 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
use crossbeam_channel::Sender;
|
|
||||||
use eframe::egui;
|
|
||||||
use egui_plot::LineStyle;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
||||||
pub struct Signal {
|
|
||||||
#[serde(alias = "Name")]
|
|
||||||
pub name: String,
|
|
||||||
#[serde(alias = "ID")]
|
|
||||||
pub id: u32,
|
|
||||||
#[serde(rename = "type", alias = "Type")]
|
|
||||||
pub sig_type: String,
|
|
||||||
#[serde(default, alias = "Dimensions")]
|
|
||||||
pub dimensions: u8,
|
|
||||||
#[serde(default = "default_elements", alias = "Elements")]
|
|
||||||
pub elements: u32,
|
|
||||||
#[serde(default, alias = "IsState")]
|
|
||||||
pub is_state: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
pub config: Option<serde_json::Value>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_elements() -> u32 { 1 }
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct DiscoverResponse {
|
|
||||||
#[serde(rename = "Signals")]
|
|
||||||
pub signals: Vec<Signal>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
||||||
#[serde(rename_all = "PascalCase")]
|
|
||||||
pub struct TreeItem {
|
|
||||||
pub name: String,
|
|
||||||
pub class: String,
|
|
||||||
pub children: Option<Vec<TreeItem>>,
|
|
||||||
#[serde(rename = "Type")]
|
|
||||||
pub sig_type: Option<String>,
|
|
||||||
pub dimensions: Option<u8>,
|
|
||||||
pub elements: Option<u32>,
|
|
||||||
pub is_traceable: Option<bool>,
|
|
||||||
pub is_forcable: Option<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct LogEntry {
|
|
||||||
pub time: String,
|
|
||||||
pub level: String,
|
|
||||||
pub message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct TraceData {
|
|
||||||
pub values: VecDeque<[f64; 2]>,
|
|
||||||
pub last_value: f64,
|
|
||||||
pub recording_tx: Option<Sender<[f64; 2]>>,
|
|
||||||
pub recording_path: Option<String>,
|
|
||||||
pub is_monitored: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct SignalMetadata {
|
|
||||||
pub names: Vec<String>,
|
|
||||||
pub sig_type: String,
|
|
||||||
pub dimensions: u8,
|
|
||||||
pub elements: u32,
|
|
||||||
pub is_state: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ConnectionConfig {
|
|
||||||
pub ip: String,
|
|
||||||
pub tcp_port: String,
|
|
||||||
pub udp_port: String,
|
|
||||||
pub log_port: String,
|
|
||||||
pub version: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
||||||
pub enum PlotType {
|
|
||||||
Normal,
|
|
||||||
LogicAnalyzer,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
||||||
pub enum AcquisitionMode {
|
|
||||||
FreeRun,
|
|
||||||
Triggered,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
||||||
pub enum TriggerEdge {
|
|
||||||
Rising,
|
|
||||||
Falling,
|
|
||||||
Both,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
||||||
pub enum TriggerType {
|
|
||||||
Single,
|
|
||||||
Continuous,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
||||||
pub enum MarkerType {
|
|
||||||
None,
|
|
||||||
Circle,
|
|
||||||
Square,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
impl MarkerType {
|
|
||||||
pub fn to_shape(&self) -> Option<egui_plot::MarkerShape> {
|
|
||||||
match self {
|
|
||||||
MarkerType::None => None,
|
|
||||||
MarkerType::Circle => Some(egui_plot::MarkerShape::Circle),
|
|
||||||
MarkerType::Square => Some(egui_plot::MarkerShape::Square),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct SignalPlotConfig {
|
|
||||||
pub source_name: String,
|
|
||||||
pub label: String,
|
|
||||||
pub unit: String,
|
|
||||||
pub color: egui::Color32,
|
|
||||||
pub line_style: LineStyle,
|
|
||||||
pub marker_type: MarkerType,
|
|
||||||
pub gain: f64,
|
|
||||||
pub offset: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct PlotInstance {
|
|
||||||
pub id: String,
|
|
||||||
pub plot_type: PlotType,
|
|
||||||
pub signals: Vec<SignalPlotConfig>,
|
|
||||||
pub auto_bounds: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub enum InternalEvent {
|
|
||||||
Log(LogEntry),
|
|
||||||
Discovery(Vec<Signal>),
|
|
||||||
Tree(TreeItem),
|
|
||||||
CommandResponse(String),
|
|
||||||
NodeInfo(String),
|
|
||||||
Connected,
|
|
||||||
Disconnected,
|
|
||||||
InternalLog(String),
|
|
||||||
TraceRequested(String, bool), // Name, IsMonitored
|
|
||||||
ClearTrace(String),
|
|
||||||
UdpStats(u64),
|
|
||||||
UdpDropped(u32),
|
|
||||||
RecordPathChosen(String, String), // SignalName, FilePath
|
|
||||||
RecordingError(String, String), // SignalName, ErrorMessage
|
|
||||||
TelemMatched(u32), // Signal ID
|
|
||||||
ServiceConfig { udp_port: String, log_port: String },
|
|
||||||
StateUpdate(String, String), // Path, StateName
|
|
||||||
Config(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct ForcingDialog {
|
|
||||||
pub signal_path: String,
|
|
||||||
pub value: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct MonitorDialog {
|
|
||||||
pub signal_path: String,
|
|
||||||
pub period_ms: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MessageDialog {
|
|
||||||
pub destination: String,
|
|
||||||
pub function: String,
|
|
||||||
pub payload: String,
|
|
||||||
pub expect_reply: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct LogFilters {
|
|
||||||
pub show_debug: bool,
|
|
||||||
pub show_info: bool,
|
|
||||||
pub show_warning: bool,
|
|
||||||
pub show_error: bool,
|
|
||||||
pub paused: bool,
|
|
||||||
pub content_regex: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
|
||||||
pub enum BottomTab {
|
|
||||||
Logs,
|
|
||||||
State,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
|
||||||
pub enum MainTab {
|
|
||||||
Plots,
|
|
||||||
Config,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct ScopeSettings {
|
|
||||||
pub enabled: bool,
|
|
||||||
pub window_ms: f64,
|
|
||||||
pub mode: AcquisitionMode,
|
|
||||||
pub paused: bool,
|
|
||||||
pub trigger_type: TriggerType,
|
|
||||||
pub trigger_source: String,
|
|
||||||
pub trigger_edge: TriggerEdge,
|
|
||||||
pub trigger_threshold: f64,
|
|
||||||
pub pre_trigger_percent: f64,
|
|
||||||
pub trigger_active: bool,
|
|
||||||
pub last_trigger_time: f64,
|
|
||||||
pub is_armed: bool,
|
|
||||||
}
|
|
||||||
@@ -1,498 +0,0 @@
|
|||||||
use crate::models::*;
|
|
||||||
use arrow::array::Float64Array;
|
|
||||||
use arrow::datatypes::{DataType, Field, Schema};
|
|
||||||
use arrow::record_batch::RecordBatch;
|
|
||||||
use chrono::Local;
|
|
||||||
use crossbeam_channel::{Receiver, Sender};
|
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use parquet::arrow::arrow_writer::ArrowWriter;
|
|
||||||
use parquet::file::properties::WriterProperties;
|
|
||||||
use socket2::{Domain, Protocol, Socket, Type};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{BufRead, BufReader, Write};
|
|
||||||
use std::net::{TcpStream, UdpSocket};
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
pub static BASE_TELEM_TS: Lazy<Mutex<Option<u64>>> = Lazy::new(|| Mutex::new(None));
|
|
||||||
|
|
||||||
pub fn tcp_command_worker(
|
|
||||||
shared_config: Arc<Mutex<ConnectionConfig>>,
|
|
||||||
rx_cmd: Receiver<String>,
|
|
||||||
tx_events: Sender<InternalEvent>,
|
|
||||||
) {
|
|
||||||
let mut current_version = 0;
|
|
||||||
let mut current_addr = String::new();
|
|
||||||
loop {
|
|
||||||
{
|
|
||||||
let config = shared_config.lock().unwrap();
|
|
||||||
if config.version != current_version {
|
|
||||||
current_version = config.version;
|
|
||||||
current_addr = format!("{}:{}", config.ip, config.tcp_port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if current_addr.is_empty() || current_addr.starts_with(":") {
|
|
||||||
thread::sleep(std::time::Duration::from_secs(1));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Ok(mut stream) = TcpStream::connect(¤t_addr) {
|
|
||||||
let _ = stream.set_nodelay(true);
|
|
||||||
let mut reader = BufReader::new(stream.try_clone().unwrap());
|
|
||||||
let _ = tx_events.send(InternalEvent::Connected);
|
|
||||||
let stop_flag = Arc::new(Mutex::new(false));
|
|
||||||
let stop_flag_reader = stop_flag.clone();
|
|
||||||
let tx_events_inner = tx_events.clone();
|
|
||||||
thread::spawn(move || {
|
|
||||||
let mut line = String::new();
|
|
||||||
let mut json_acc = String::new();
|
|
||||||
let mut in_json = false;
|
|
||||||
while reader.read_line(&mut line).is_ok() {
|
|
||||||
if *stop_flag_reader.lock().unwrap() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let trimmed = line.trim();
|
|
||||||
if trimmed.is_empty() {
|
|
||||||
line.clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !in_json && trimmed.starts_with("{") {
|
|
||||||
in_json = true;
|
|
||||||
json_acc.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if in_json {
|
|
||||||
json_acc.push_str(trimmed);
|
|
||||||
if trimmed.contains("OK DISCOVER") {
|
|
||||||
in_json = false;
|
|
||||||
let json_clean =
|
|
||||||
json_acc.split("OK DISCOVER").next().unwrap_or("").trim();
|
|
||||||
match serde_json::from_str::<DiscoverResponse>(json_clean) {
|
|
||||||
Ok(resp) => {
|
|
||||||
let _ = tx_events_inner
|
|
||||||
.send(InternalEvent::Discovery(resp.signals));
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
let _ =
|
|
||||||
tx_events_inner.send(InternalEvent::InternalLog(format!(
|
|
||||||
"Discovery JSON Error: {} | Payload: {}",
|
|
||||||
e, json_clean
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
json_acc.clear();
|
|
||||||
} else if trimmed.contains("OK TREE") {
|
|
||||||
in_json = false;
|
|
||||||
let json_clean = json_acc.split("OK TREE").next().unwrap_or("").trim();
|
|
||||||
match serde_json::from_str::<TreeItem>(json_clean) {
|
|
||||||
Ok(resp) => {
|
|
||||||
let _ = tx_events_inner.send(InternalEvent::Tree(resp));
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
let _ = tx_events_inner.send(InternalEvent::InternalLog(
|
|
||||||
format!("Tree JSON Error: {}", e),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
json_acc.clear();
|
|
||||||
} else if trimmed.contains("OK INFO") {
|
|
||||||
in_json = false;
|
|
||||||
let json_clean = json_acc.split("OK INFO").next().unwrap_or("").trim();
|
|
||||||
let _ = tx_events_inner
|
|
||||||
.send(InternalEvent::NodeInfo(json_clean.to_string()));
|
|
||||||
json_acc.clear();
|
|
||||||
} else if trimmed.contains("OK CONFIG") {
|
|
||||||
in_json = false;
|
|
||||||
let json_clean = json_acc.split("OK CONFIG").next().unwrap_or("").trim();
|
|
||||||
match serde_json::from_str::<serde_json::Value>(json_clean) {
|
|
||||||
Ok(val) => {
|
|
||||||
let _ = tx_events_inner.send(InternalEvent::Config(val));
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
let _ = tx_events_inner.send(InternalEvent::InternalLog(
|
|
||||||
format!("Config JSON Error: {} | Payload sample: {}", e, &json_clean[..json_clean.len().min(100)]),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
json_acc.clear();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if trimmed.starts_with("OK SERVICE_INFO") {
|
|
||||||
let parts: Vec<&str> = trimmed.split_whitespace().collect();
|
|
||||||
let mut udp = String::new();
|
|
||||||
let mut log = String::new();
|
|
||||||
for p in parts {
|
|
||||||
if p.starts_with("UDP_STREAM:") {
|
|
||||||
udp = p.split(':').nth(1).unwrap_or("").to_string();
|
|
||||||
}
|
|
||||||
if p.starts_with("TCP_LOG:") {
|
|
||||||
log = p.split(':').nth(1).unwrap_or("").to_string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !udp.is_empty() || !log.is_empty() {
|
|
||||||
let _ = tx_events_inner.send(InternalEvent::ServiceConfig {
|
|
||||||
udp_port: udp,
|
|
||||||
log_port: log,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let _ = tx_events_inner
|
|
||||||
.send(InternalEvent::CommandResponse(trimmed.to_string()));
|
|
||||||
}
|
|
||||||
line.clear();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
while let Ok(cmd) = rx_cmd.recv() {
|
|
||||||
{
|
|
||||||
let config = shared_config.lock().unwrap();
|
|
||||||
if config.version != current_version {
|
|
||||||
*stop_flag.lock().unwrap() = true;
|
|
||||||
let _ = tx_events.send(InternalEvent::Disconnected);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if stream.write_all(format!("{}
|
|
||||||
", cmd).as_bytes()).is_err() {
|
|
||||||
let _ = tx_events.send(InternalEvent::Disconnected);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
thread::sleep(std::time::Duration::from_millis(100));
|
|
||||||
}
|
|
||||||
let _ = tx_events.send(InternalEvent::Disconnected);
|
|
||||||
}
|
|
||||||
thread::sleep(std::time::Duration::from_secs(2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tcp_log_worker(shared_config: Arc<Mutex<ConnectionConfig>>, tx_events: Sender<InternalEvent>) {
|
|
||||||
let mut current_version = 0;
|
|
||||||
let mut current_addr = String::new();
|
|
||||||
loop {
|
|
||||||
{
|
|
||||||
let config = shared_config.lock().unwrap();
|
|
||||||
if config.version != current_version {
|
|
||||||
current_version = config.version;
|
|
||||||
current_addr = format!("{}:{}", config.ip, config.log_port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if current_addr.is_empty() || current_addr.starts_with(":") {
|
|
||||||
thread::sleep(std::time::Duration::from_secs(1));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Ok(stream) = TcpStream::connect(¤t_addr) {
|
|
||||||
let mut reader = BufReader::new(stream);
|
|
||||||
let mut line = String::new();
|
|
||||||
while reader.read_line(&mut line).is_ok() {
|
|
||||||
if shared_config.lock().unwrap().version != current_version {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let trimmed = line.trim();
|
|
||||||
if trimmed.starts_with("LOG ") {
|
|
||||||
let parts: Vec<&str> = trimmed[4..].splitn(2, ' ').collect();
|
|
||||||
if parts.len() == 2 {
|
|
||||||
let _ = tx_events.send(InternalEvent::Log(LogEntry {
|
|
||||||
time: Local::now().format("%H:%M:%S%.3f").to_string(),
|
|
||||||
level: parts[0].to_string(),
|
|
||||||
message: parts[1].to_string(),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
line.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
thread::sleep(std::time::Duration::from_secs(2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn recording_worker(
|
|
||||||
rx: Receiver<[f64; 2]>,
|
|
||||||
path: String,
|
|
||||||
signal_name: String,
|
|
||||||
tx_events: Sender<InternalEvent>,
|
|
||||||
) {
|
|
||||||
let file = match File::create(&path) {
|
|
||||||
Ok(f) => f,
|
|
||||||
Err(e) => {
|
|
||||||
let _ = tx_events.send(InternalEvent::RecordingError(
|
|
||||||
signal_name,
|
|
||||||
format!("File Error: {}", e),
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let schema = Arc::new(Schema::new(vec![
|
|
||||||
Field::new("timestamp", DataType::Float64, false),
|
|
||||||
Field::new("value", DataType::Float64, false),
|
|
||||||
]));
|
|
||||||
let mut writer = match ArrowWriter::try_new(
|
|
||||||
file,
|
|
||||||
schema.clone(),
|
|
||||||
Some(WriterProperties::builder().build()),
|
|
||||||
) {
|
|
||||||
Ok(w) => w,
|
|
||||||
Err(e) => {
|
|
||||||
let _ = tx_events.send(InternalEvent::RecordingError(
|
|
||||||
signal_name,
|
|
||||||
format!("Parquet Error: {}", e),
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let (mut t_acc, mut v_acc) = (Vec::with_capacity(1000), Vec::with_capacity(1000));
|
|
||||||
while let Ok([t, v]) = rx.recv() {
|
|
||||||
t_acc.push(t);
|
|
||||||
v_acc.push(v);
|
|
||||||
if t_acc.len() >= 1000 {
|
|
||||||
let batch = RecordBatch::try_new(
|
|
||||||
schema.clone(),
|
|
||||||
vec![
|
|
||||||
Arc::new(Float64Array::from(t_acc.clone())),
|
|
||||||
Arc::new(Float64Array::from(v_acc.clone())),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let _ = writer.write(&batch);
|
|
||||||
t_acc.clear();
|
|
||||||
v_acc.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !t_acc.is_empty() {
|
|
||||||
let batch = RecordBatch::try_new(
|
|
||||||
schema.clone(),
|
|
||||||
vec![
|
|
||||||
Arc::new(Float64Array::from(t_acc)),
|
|
||||||
Arc::new(Float64Array::from(v_acc)),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let _ = writer.write(&batch);
|
|
||||||
}
|
|
||||||
let _ = writer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn udp_worker(
|
|
||||||
shared_config: Arc<Mutex<ConnectionConfig>>,
|
|
||||||
id_to_meta: Arc<Mutex<HashMap<u32, SignalMetadata>>>,
|
|
||||||
traced_data: Arc<Mutex<HashMap<String, TraceData>>>,
|
|
||||||
tx_events: Sender<InternalEvent>,
|
|
||||||
) {
|
|
||||||
let mut current_version = 0;
|
|
||||||
let mut socket: Option<UdpSocket> = None;
|
|
||||||
let mut last_seq: Option<u32> = None;
|
|
||||||
let mut last_warning_time = std::time::Instant::now();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let (ver, port) = {
|
|
||||||
let config = shared_config.lock().unwrap();
|
|
||||||
(config.version, config.udp_port.clone())
|
|
||||||
};
|
|
||||||
if ver != current_version || socket.is_none() {
|
|
||||||
current_version = ver;
|
|
||||||
{
|
|
||||||
let mut base = BASE_TELEM_TS.lock().unwrap();
|
|
||||||
*base = None;
|
|
||||||
}
|
|
||||||
if port.is_empty() {
|
|
||||||
socket = None;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let port_num: u16 = port.parse().unwrap_or(8081);
|
|
||||||
let s = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).ok();
|
|
||||||
let mut bound = false;
|
|
||||||
if let Some(sock) = s {
|
|
||||||
let _ = sock.set_reuse_address(true);
|
|
||||||
#[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
|
|
||||||
let _ = sock.set_reuse_port(true);
|
|
||||||
let _ = sock.set_recv_buffer_size(10 * 1024 * 1024);
|
|
||||||
let addr = format!("0.0.0.0:{}", port_num)
|
|
||||||
.parse::<std::net::SocketAddr>()
|
|
||||||
.unwrap();
|
|
||||||
if sock.bind(&addr.into()).is_ok() {
|
|
||||||
socket = Some(sock.into());
|
|
||||||
bound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !bound {
|
|
||||||
thread::sleep(std::time::Duration::from_secs(5));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let _ = socket
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.set_read_timeout(Some(std::time::Duration::from_millis(500)));
|
|
||||||
last_seq = None;
|
|
||||||
}
|
|
||||||
let s = if let Some(sock) = socket.as_ref() {
|
|
||||||
sock
|
|
||||||
} else {
|
|
||||||
thread::sleep(std::time::Duration::from_secs(1));
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
let mut buf = [0u8; 4096];
|
|
||||||
let mut total_packets = 0u64;
|
|
||||||
loop {
|
|
||||||
if shared_config.lock().unwrap().version != current_version {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if let Ok(n) = s.recv(&mut buf) {
|
|
||||||
total_packets += 1;
|
|
||||||
if (total_packets % 500) == 0 {
|
|
||||||
let _ = tx_events.send(InternalEvent::UdpStats(total_packets));
|
|
||||||
}
|
|
||||||
if n < 20 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if u32::from_le_bytes(buf[0..4].try_into().unwrap()) != 0xDA7A57AD {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let seq = u32::from_le_bytes(buf[4..8].try_into().unwrap());
|
|
||||||
if let Some(last) = last_seq {
|
|
||||||
if seq != last + 1 && seq > last {
|
|
||||||
let _ = tx_events.send(InternalEvent::UdpDropped(seq - last - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
last_seq = Some(seq);
|
|
||||||
let count = u32::from_le_bytes(buf[16..20].try_into().unwrap());
|
|
||||||
|
|
||||||
let mut offset = 20;
|
|
||||||
let mut local_updates: HashMap<String, Vec<[f64; 2]>> = HashMap::new();
|
|
||||||
let mut last_values: HashMap<String, f64> = HashMap::new();
|
|
||||||
let metas = id_to_meta.lock().unwrap();
|
|
||||||
|
|
||||||
if metas.is_empty() && count > 0 && last_warning_time.elapsed().as_secs() > 5 {
|
|
||||||
let _ = tx_events.send(InternalEvent::InternalLog(
|
|
||||||
"UDP received but Metadata empty. Still discovering?".to_string(),
|
|
||||||
));
|
|
||||||
last_warning_time = std::time::Instant::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..count {
|
|
||||||
if offset + 16 > n {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let id = u32::from_le_bytes(buf[offset..offset + 4].try_into().unwrap());
|
|
||||||
let ts_raw =
|
|
||||||
u64::from_le_bytes(buf[offset + 4..offset + 12].try_into().unwrap());
|
|
||||||
let size =
|
|
||||||
u32::from_le_bytes(buf[offset + 12..offset + 16].try_into().unwrap());
|
|
||||||
offset += 16;
|
|
||||||
|
|
||||||
if offset + size as usize > n {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let data_slice = &buf[offset..offset + size as usize];
|
|
||||||
|
|
||||||
let mut base_ts_guard = BASE_TELEM_TS.lock().unwrap();
|
|
||||||
if base_ts_guard.is_none() {
|
|
||||||
*base_ts_guard = Some(ts_raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
let base = base_ts_guard.unwrap();
|
|
||||||
let ts_s = if ts_raw >= base {
|
|
||||||
(ts_raw - base) as f64 / 1000000.0
|
|
||||||
} else {
|
|
||||||
0.0
|
|
||||||
};
|
|
||||||
drop(base_ts_guard);
|
|
||||||
|
|
||||||
if let Some(meta) = metas.get(&id) {
|
|
||||||
let _ = tx_events.send(InternalEvent::TelemMatched(id));
|
|
||||||
|
|
||||||
if meta.is_state {
|
|
||||||
let state_name = String::from_utf8_lossy(data_slice)
|
|
||||||
.trim_matches(char::from(0))
|
|
||||||
.to_string();
|
|
||||||
for name in &meta.names {
|
|
||||||
let _ = tx_events.send(InternalEvent::StateUpdate(name.clone(), state_name.clone()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let t = meta.sig_type.as_str();
|
|
||||||
let type_size = if meta.elements > 0 { size / meta.elements } else { size };
|
|
||||||
|
|
||||||
for i in 0..meta.elements {
|
|
||||||
let elem_offset = (i * type_size) as usize;
|
|
||||||
if elem_offset + type_size as usize > data_slice.len() { break; }
|
|
||||||
let elem_data = &data_slice[elem_offset..elem_offset + type_size as usize];
|
|
||||||
|
|
||||||
let val = match type_size {
|
|
||||||
1 => {
|
|
||||||
if t.contains('u') {
|
|
||||||
elem_data[0] as f64
|
|
||||||
} else {
|
|
||||||
(elem_data[0] as i8) as f64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2 => {
|
|
||||||
let b = elem_data[0..2].try_into().unwrap();
|
|
||||||
if t.contains('u') {
|
|
||||||
u16::from_le_bytes(b) as f64
|
|
||||||
} else {
|
|
||||||
i16::from_le_bytes(b) as f64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4 => {
|
|
||||||
let b = elem_data[0..4].try_into().unwrap();
|
|
||||||
if t.contains("float") {
|
|
||||||
f32::from_le_bytes(b) as f64
|
|
||||||
} else if t.contains('u') {
|
|
||||||
u32::from_le_bytes(b) as f64
|
|
||||||
} else {
|
|
||||||
i32::from_le_bytes(b) as f64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8 => {
|
|
||||||
let b = elem_data[0..8].try_into().unwrap();
|
|
||||||
if t.contains("float") {
|
|
||||||
f64::from_le_bytes(b)
|
|
||||||
} else if t.contains('u') {
|
|
||||||
u64::from_le_bytes(b) as f64
|
|
||||||
} else {
|
|
||||||
i64::from_le_bytes(b) as f64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => 0.0,
|
|
||||||
};
|
|
||||||
|
|
||||||
for name in &meta.names {
|
|
||||||
let target_name = if meta.elements > 1 {
|
|
||||||
format!("{}[{}]", name, i)
|
|
||||||
} else {
|
|
||||||
name.clone()
|
|
||||||
};
|
|
||||||
local_updates
|
|
||||||
.entry(target_name.clone())
|
|
||||||
.or_default()
|
|
||||||
.push([ts_s, val]);
|
|
||||||
last_values.insert(target_name, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
offset += size as usize;
|
|
||||||
}
|
|
||||||
drop(metas);
|
|
||||||
if !local_updates.is_empty() {
|
|
||||||
let mut data_map = traced_data.lock().unwrap();
|
|
||||||
for (name, new_points) in local_updates {
|
|
||||||
if let Some(entry) = data_map.get_mut(&name) {
|
|
||||||
for point in new_points {
|
|
||||||
entry.values.push_back(point);
|
|
||||||
if let Some(tx) = &entry.recording_tx {
|
|
||||||
let _ = tx.send(point);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(lv) = last_values.get(&name) {
|
|
||||||
entry.last_value = *lv;
|
|
||||||
}
|
|
||||||
while entry.values.len() > 100000 {
|
|
||||||
entry.values.pop_front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+293
-3
@@ -51,7 +51,6 @@
|
|||||||
"-c",
|
"-c",
|
||||||
"-I../../../..//Source/Core/Types/Result",
|
"-I../../../..//Source/Core/Types/Result",
|
||||||
"-I../../../..//Source/Core/Types/Vec",
|
"-I../../../..//Source/Core/Types/Vec",
|
||||||
"-I../../../..//Source/Components/Interfaces/TCPLogger",
|
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L0Types",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L0Types",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L1Portability",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L1Portability",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L2Objects",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L2Objects",
|
||||||
@@ -60,7 +59,6 @@
|
|||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Logger",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Logger",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Configuration",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Configuration",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L5GAMs",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L5GAMs",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4StateMachine",
|
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L1Portability",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L1Portability",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L3Services",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L3Services",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4Messages",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4Messages",
|
||||||
@@ -68,7 +66,6 @@
|
|||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L5GAMs",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L5GAMs",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L1Portability",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L1Portability",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L3Streams",
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L3Streams",
|
||||||
"-I/home/martino/Projects/marte_debug/dependency/MARTe2-components/Source/Components/DataSources/RealTimeThreadSynchronisation",
|
|
||||||
"-fPIC",
|
"-fPIC",
|
||||||
"-Wall",
|
"-Wall",
|
||||||
"-std=c++98",
|
"-std=c++98",
|
||||||
@@ -92,5 +89,298 @@
|
|||||||
],
|
],
|
||||||
"directory": "/home/martino/Projects/marte_debug/Source/Components/Interfaces/DebugService",
|
"directory": "/home/martino/Projects/marte_debug/Source/Components/Interfaces/DebugService",
|
||||||
"output": "../../../..//Build/x86-linux/Components/Interfaces/DebugService/DebugService.o"
|
"output": "../../../..//Build/x86-linux/Components/Interfaces/DebugService/DebugService.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "UnitTests.cpp",
|
||||||
|
"arguments": [
|
||||||
|
"g++",
|
||||||
|
"-c",
|
||||||
|
"-I../../Source/Core/Types/Result",
|
||||||
|
"-I../../Source/Core/Types/Vec",
|
||||||
|
"-I../../Source/Components/Interfaces/DebugService",
|
||||||
|
"-I../../Source/Components/Interfaces/TCPLogger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L0Types",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L2Objects",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L3Streams",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Logger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Configuration",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L3Services",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4LoggerService",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L3Streams",
|
||||||
|
"-fPIC",
|
||||||
|
"-Wall",
|
||||||
|
"-std=c++98",
|
||||||
|
"-Werror",
|
||||||
|
"-Wno-invalid-offsetof",
|
||||||
|
"-Wno-unused-variable",
|
||||||
|
"-fno-strict-aliasing",
|
||||||
|
"-frtti",
|
||||||
|
"-DMARTe2_TEST_ENVIRONMENT=GTest",
|
||||||
|
"-DARCHITECTURE=x86_gcc",
|
||||||
|
"-DENVIRONMENT=Linux",
|
||||||
|
"-DUSE_PTHREAD",
|
||||||
|
"-pthread",
|
||||||
|
"-Wno-deprecated-declarations",
|
||||||
|
"-Wno-unused-value",
|
||||||
|
"-g",
|
||||||
|
"-ggdb",
|
||||||
|
"UnitTests.cpp",
|
||||||
|
"-o",
|
||||||
|
"../../Build/x86-linux/Test/UnitTests/UnitTests/UnitTests.o"
|
||||||
|
],
|
||||||
|
"directory": "/home/martino/Projects/marte_debug/Test/UnitTests",
|
||||||
|
"output": "../../Build/x86-linux/Test/UnitTests/UnitTests/UnitTests.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "SchedulerTest.cpp",
|
||||||
|
"arguments": [
|
||||||
|
"g++",
|
||||||
|
"-c",
|
||||||
|
"-I../../Source/Core/Types/Result",
|
||||||
|
"-I../../Source/Core/Types/Vec",
|
||||||
|
"-I../../Source/Components/Interfaces/DebugService",
|
||||||
|
"-I../../Source/Components/Interfaces/TCPLogger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L0Types",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L2Objects",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L3Streams",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Logger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Configuration",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L6App",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L3Services",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4LoggerService",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L3Streams",
|
||||||
|
"-fPIC",
|
||||||
|
"-Wall",
|
||||||
|
"-std=c++98",
|
||||||
|
"-Werror",
|
||||||
|
"-Wno-invalid-offsetof",
|
||||||
|
"-Wno-unused-variable",
|
||||||
|
"-fno-strict-aliasing",
|
||||||
|
"-frtti",
|
||||||
|
"-DMARTe2_TEST_ENVIRONMENT=GTest",
|
||||||
|
"-DARCHITECTURE=x86_gcc",
|
||||||
|
"-DENVIRONMENT=Linux",
|
||||||
|
"-DUSE_PTHREAD",
|
||||||
|
"-pthread",
|
||||||
|
"-Wno-deprecated-declarations",
|
||||||
|
"-Wno-unused-value",
|
||||||
|
"-g",
|
||||||
|
"-ggdb",
|
||||||
|
"SchedulerTest.cpp",
|
||||||
|
"-o",
|
||||||
|
"../../Build/x86-linux/Test/Integration/Integration/SchedulerTest.o"
|
||||||
|
],
|
||||||
|
"directory": "/home/martino/Projects/marte_debug/Test/Integration",
|
||||||
|
"output": "../../Build/x86-linux/Test/Integration/Integration/SchedulerTest.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "TraceTest.cpp",
|
||||||
|
"arguments": [
|
||||||
|
"g++",
|
||||||
|
"-c",
|
||||||
|
"-I../../Source/Core/Types/Result",
|
||||||
|
"-I../../Source/Core/Types/Vec",
|
||||||
|
"-I../../Source/Components/Interfaces/DebugService",
|
||||||
|
"-I../../Source/Components/Interfaces/TCPLogger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L0Types",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L2Objects",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L3Streams",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Logger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Configuration",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L6App",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L3Services",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4LoggerService",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L3Streams",
|
||||||
|
"-fPIC",
|
||||||
|
"-Wall",
|
||||||
|
"-std=c++98",
|
||||||
|
"-Werror",
|
||||||
|
"-Wno-invalid-offsetof",
|
||||||
|
"-Wno-unused-variable",
|
||||||
|
"-fno-strict-aliasing",
|
||||||
|
"-frtti",
|
||||||
|
"-DMARTe2_TEST_ENVIRONMENT=GTest",
|
||||||
|
"-DARCHITECTURE=x86_gcc",
|
||||||
|
"-DENVIRONMENT=Linux",
|
||||||
|
"-DUSE_PTHREAD",
|
||||||
|
"-pthread",
|
||||||
|
"-Wno-deprecated-declarations",
|
||||||
|
"-Wno-unused-value",
|
||||||
|
"-g",
|
||||||
|
"-ggdb",
|
||||||
|
"TraceTest.cpp",
|
||||||
|
"-o",
|
||||||
|
"../../Build/x86-linux/Test/Integration/Integration/TraceTest.o"
|
||||||
|
],
|
||||||
|
"directory": "/home/martino/Projects/marte_debug/Test/Integration",
|
||||||
|
"output": "../../Build/x86-linux/Test/Integration/Integration/TraceTest.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "ValidationTest.cpp",
|
||||||
|
"arguments": [
|
||||||
|
"g++",
|
||||||
|
"-c",
|
||||||
|
"-I../../Source/Core/Types/Result",
|
||||||
|
"-I../../Source/Core/Types/Vec",
|
||||||
|
"-I../../Source/Components/Interfaces/DebugService",
|
||||||
|
"-I../../Source/Components/Interfaces/TCPLogger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L0Types",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L2Objects",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L3Streams",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Logger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Configuration",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L6App",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L3Services",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4LoggerService",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L3Streams",
|
||||||
|
"-fPIC",
|
||||||
|
"-Wall",
|
||||||
|
"-std=c++98",
|
||||||
|
"-Werror",
|
||||||
|
"-Wno-invalid-offsetof",
|
||||||
|
"-Wno-unused-variable",
|
||||||
|
"-fno-strict-aliasing",
|
||||||
|
"-frtti",
|
||||||
|
"-DMARTe2_TEST_ENVIRONMENT=GTest",
|
||||||
|
"-DARCHITECTURE=x86_gcc",
|
||||||
|
"-DENVIRONMENT=Linux",
|
||||||
|
"-DUSE_PTHREAD",
|
||||||
|
"-pthread",
|
||||||
|
"-Wno-deprecated-declarations",
|
||||||
|
"-Wno-unused-value",
|
||||||
|
"-g",
|
||||||
|
"-ggdb",
|
||||||
|
"ValidationTest.cpp",
|
||||||
|
"-o",
|
||||||
|
"../../Build/x86-linux/Test/Integration/Integration/ValidationTest.o"
|
||||||
|
],
|
||||||
|
"directory": "/home/martino/Projects/marte_debug/Test/Integration",
|
||||||
|
"output": "../../Build/x86-linux/Test/Integration/Integration/ValidationTest.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "ConfigCommandTest.cpp",
|
||||||
|
"arguments": [
|
||||||
|
"g++",
|
||||||
|
"-c",
|
||||||
|
"-I../../Source/Core/Types/Result",
|
||||||
|
"-I../../Source/Core/Types/Vec",
|
||||||
|
"-I../../Source/Components/Interfaces/DebugService",
|
||||||
|
"-I../../Source/Components/Interfaces/TCPLogger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L0Types",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L2Objects",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L3Streams",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Logger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Configuration",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L6App",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L3Services",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4LoggerService",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L3Streams",
|
||||||
|
"-fPIC",
|
||||||
|
"-Wall",
|
||||||
|
"-std=c++98",
|
||||||
|
"-Werror",
|
||||||
|
"-Wno-invalid-offsetof",
|
||||||
|
"-Wno-unused-variable",
|
||||||
|
"-fno-strict-aliasing",
|
||||||
|
"-frtti",
|
||||||
|
"-DMARTe2_TEST_ENVIRONMENT=GTest",
|
||||||
|
"-DARCHITECTURE=x86_gcc",
|
||||||
|
"-DENVIRONMENT=Linux",
|
||||||
|
"-DUSE_PTHREAD",
|
||||||
|
"-pthread",
|
||||||
|
"-Wno-deprecated-declarations",
|
||||||
|
"-Wno-unused-value",
|
||||||
|
"-g",
|
||||||
|
"-ggdb",
|
||||||
|
"ConfigCommandTest.cpp",
|
||||||
|
"-o",
|
||||||
|
"../../Build/x86-linux/Test/Integration/Integration/ConfigCommandTest.o"
|
||||||
|
],
|
||||||
|
"directory": "/home/martino/Projects/marte_debug/Test/Integration",
|
||||||
|
"output": "../../Build/x86-linux/Test/Integration/Integration/ConfigCommandTest.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "IntegrationTests.cpp",
|
||||||
|
"arguments": [
|
||||||
|
"g++",
|
||||||
|
"-c",
|
||||||
|
"-I../../Source/Core/Types/Result",
|
||||||
|
"-I../../Source/Core/Types/Vec",
|
||||||
|
"-I../../Source/Components/Interfaces/DebugService",
|
||||||
|
"-I../../Source/Components/Interfaces/TCPLogger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L0Types",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L2Objects",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L3Streams",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Logger",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L4Configuration",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/BareMetal/L6App",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L3Services",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4Messages",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L4LoggerService",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/Scheduler/L5GAMs",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L1Portability",
|
||||||
|
"-I/home/martino/Projects/marte_debug/dependency/MARTe2/Source/Core/FileSystem/L3Streams",
|
||||||
|
"-fPIC",
|
||||||
|
"-Wall",
|
||||||
|
"-std=c++98",
|
||||||
|
"-Werror",
|
||||||
|
"-Wno-invalid-offsetof",
|
||||||
|
"-Wno-unused-variable",
|
||||||
|
"-fno-strict-aliasing",
|
||||||
|
"-frtti",
|
||||||
|
"-DMARTe2_TEST_ENVIRONMENT=GTest",
|
||||||
|
"-DARCHITECTURE=x86_gcc",
|
||||||
|
"-DENVIRONMENT=Linux",
|
||||||
|
"-DUSE_PTHREAD",
|
||||||
|
"-pthread",
|
||||||
|
"-Wno-deprecated-declarations",
|
||||||
|
"-Wno-unused-value",
|
||||||
|
"-g",
|
||||||
|
"-ggdb",
|
||||||
|
"IntegrationTests.cpp",
|
||||||
|
"-o",
|
||||||
|
"../../Build/x86-linux/Test/Integration/Integration/IntegrationTests.o"
|
||||||
|
],
|
||||||
|
"directory": "/home/martino/Projects/marte_debug/Test/Integration",
|
||||||
|
"output": "../../Build/x86-linux/Test/Integration/Integration/IntegrationTests.o"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -6,12 +6,11 @@ export MARTe2_DIR=$DIR/dependency/MARTe2
|
|||||||
export MARTe2_Components_DIR=$DIR/dependency/MARTe2-components
|
export MARTe2_Components_DIR=$DIR/dependency/MARTe2-components
|
||||||
export TARGET=x86-linux
|
export TARGET=x86-linux
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_DIR/Build/$TARGET/Core
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_DIR/Build/$TARGET/Core
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/Components
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/DataSources/RealTimeThreadSynchronisation
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DIR/Build/$TARGET/Components/Interfaces/DebugService
|
||||||
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DIR/Build/$TARGET/Components/Interfaces/TCPLogger
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/DataSources/LinuxTimer
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/DataSources/LinuxTimer
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/DataSources/LoggerDataSource
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/DataSources/LoggerDataSource
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/GAMs/IOGAM
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/GAMs/IOGAM
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DIR/Build/$TARGET/Components/Interfaces/DebugService
|
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DIR/Build/$TARGET/Components/Interfaces/TCPLogger
|
|
||||||
echo "MARTe2 Environment Set (MARTe2_DIR=$MARTe2_DIR)"
|
echo "MARTe2 Environment Set (MARTe2_DIR=$MARTe2_DIR)"
|
||||||
echo "MARTe2 Components Environment Set (MARTe2_Components_DIR=$MARTe2_Components_DIR)"
|
echo "MARTe2 Components Environment Set (MARTe2_Components_DIR=$MARTe2_Components_DIR)"
|
||||||
|
|||||||
+34
-7
@@ -11,13 +11,16 @@ fi
|
|||||||
|
|
||||||
# 2. Paths
|
# 2. Paths
|
||||||
MARTE_EX="${MARTe2_DIR}/Build/${TARGET}/App/MARTeApp.ex"
|
MARTE_EX="${MARTe2_DIR}/Build/${TARGET}/App/MARTeApp.ex"
|
||||||
DEBUG_LIB="$(pwd)/Build/libmarte_dev.so"
|
BUILD_DIR="$(pwd)/Build/${TARGET}"
|
||||||
|
|
||||||
|
# Our plugin libraries
|
||||||
|
DEBUG_LIB="${BUILD_DIR}/Components/Interfaces/DebugService/libDebugService.so"
|
||||||
|
TCPLOGGER_LIB="${BUILD_DIR}/Components/Interfaces/TCPLogger/libTcpLogger.so"
|
||||||
|
|
||||||
# Component library base search path
|
# Component library base search path
|
||||||
COMPONENTS_BUILD_DIR="${MARTe2_Components_DIR}/Build/${TARGET}/Components"
|
COMPONENTS_BUILD_DIR="${MARTe2_Components_DIR}/Build/${TARGET}/Components"
|
||||||
|
|
||||||
# DYNAMICALLY FIND ALL COMPONENT DIRS
|
# DYNAMICALLY FIND ALL COMPONENT DIRS and add to LD_LIBRARY_PATH
|
||||||
# MARTe2 Loader needs the specific directories containing .so files in LD_LIBRARY_PATH
|
|
||||||
ALL_COMPONENT_DIRS=$(find "$COMPONENTS_BUILD_DIR" -type d)
|
ALL_COMPONENT_DIRS=$(find "$COMPONENTS_BUILD_DIR" -type d)
|
||||||
for dir in $ALL_COMPONENT_DIRS; do
|
for dir in $ALL_COMPONENT_DIRS; do
|
||||||
if ls "$dir"/*.so >/dev/null 2>&1; then
|
if ls "$dir"/*.so >/dev/null 2>&1; then
|
||||||
@@ -26,15 +29,39 @@ for dir in $ALL_COMPONENT_DIRS; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Ensure our build dir and core dir are included
|
# Ensure our build dir and core dir are included
|
||||||
export LD_LIBRARY_PATH="$(pwd)/Build:${MARTe2_DIR}/Build/${TARGET}/Core:${LD_LIBRARY_PATH}"
|
export LD_LIBRARY_PATH="${BUILD_DIR}/Components/Interfaces/DebugService:${BUILD_DIR}/Components/Interfaces/TCPLogger:${MARTe2_DIR}/Build/${TARGET}/Core:${LD_LIBRARY_PATH}"
|
||||||
|
|
||||||
# 3. Cleanup
|
# 3. Cleanup
|
||||||
echo "Cleaning up lingering processes..."
|
echo "Cleaning up lingering processes..."
|
||||||
pkill -9 MARTeApp.ex
|
pkill -9 MARTeApp.ex
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
# 4. Launch Application
|
# 4. Validate libraries exist
|
||||||
|
for lib in "$DEBUG_LIB" "$TCPLOGGER_LIB"; do
|
||||||
|
if [ ! -f "$lib" ]; then
|
||||||
|
echo "ERROR: Library not found: $lib"
|
||||||
|
echo "Run: make -f Makefile.gcc core"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 5. Launch Application
|
||||||
echo "Launching standard MARTeApp.ex with debug_test.cfg..."
|
echo "Launching standard MARTeApp.ex with debug_test.cfg..."
|
||||||
# PRELOAD ensures our DebugService class is available to the registry early
|
# LD_PRELOAD ensures our classes are registered before the config is parsed.
|
||||||
export LD_PRELOAD="${DEBUG_LIB}"
|
# MARTeApp.ex does not use dlopen for plugins — preloading is the standard approach.
|
||||||
|
# All required component .so files are collected via the find loop into LD_PRELOAD too.
|
||||||
|
PRELOAD_LIBS="${DEBUG_LIB}:${TCPLOGGER_LIB}"
|
||||||
|
|
||||||
|
# Collect any additional component .so files referenced by the config
|
||||||
|
for lib in \
|
||||||
|
"${COMPONENTS_BUILD_DIR}/DataSources/RealTimeThreadSynchronisation/RealTimeThreadSynchronisation.so" \
|
||||||
|
"${COMPONENTS_BUILD_DIR}/DataSources/LinuxTimer/LinuxTimer.so" \
|
||||||
|
"${COMPONENTS_BUILD_DIR}/DataSources/LoggerDataSource/LoggerDataSource.so" \
|
||||||
|
"${COMPONENTS_BUILD_DIR}/GAMs/IOGAM/IOGAM.so"; do
|
||||||
|
if [ -f "$lib" ]; then
|
||||||
|
PRELOAD_LIBS="${PRELOAD_LIBS}:${lib}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
export LD_PRELOAD="${PRELOAD_LIBS}"
|
||||||
"$MARTE_EX" -f Test/Configurations/debug_test.cfg -l RealTimeLoader -s State1
|
"$MARTE_EX" -f Test/Configurations/debug_test.cfg -l RealTimeLoader -s State1
|
||||||
|
|||||||
Reference in New Issue
Block a user