Compare commits
1 Commits
scope
...
experimental
| Author | SHA1 | Date | |
|---|---|---|---|
| e2f47d7410 |
@@ -1,9 +1,11 @@
|
|||||||
#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"
|
||||||
@@ -23,6 +25,7 @@
|
|||||||
#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 {
|
||||||
|
|
||||||
@@ -86,12 +89,11 @@ 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 *)) {
|
||||||
fprintf(stderr, ">> Impossible to get broker pointer!!\n");
|
REPORT_ERROR_STATIC(ErrorManagement::Warning,
|
||||||
|
"Impossible to get broker pointer for %s!!\n",
|
||||||
|
dsPath.Buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32 i = 0; i < numCopies; i++) {
|
for (uint32 i = 0; i < numCopies; i++) {
|
||||||
@@ -106,8 +108,8 @@ public:
|
|||||||
StreamString signalName;
|
StreamString signalName;
|
||||||
if (!dataSourceIn.GetSignalName(dsIdx, signalName))
|
if (!dataSourceIn.GetSignalName(dsIdx, signalName))
|
||||||
signalName = "Unknown";
|
signalName = "Unknown";
|
||||||
fprintf(stderr, ">> registering %s.%s [%p]\n", dsPath.Buffer(),
|
REPORT_ERROR_STATIC(ErrorManagement::Debug, "Registering %s.%s [%p]\n",
|
||||||
signalName.Buffer(), mmb);
|
dsPath.Buffer(), signalName.Buffer(), mmb);
|
||||||
|
|
||||||
uint8 dims = 0;
|
uint8 dims = 0;
|
||||||
uint32 elems = 1;
|
uint32 elems = 1;
|
||||||
@@ -148,18 +150,18 @@ 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] =
|
signalInfoPointers[i] = service->RegisterSignal(
|
||||||
service->RegisterSignal(addr, type, gamFullName.Buffer(), dims, elems);
|
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] =
|
signalInfoPointers[i] = service->RegisterSignal(
|
||||||
service->RegisterSignal(addr, type, gamFullName.Buffer(), dims, elems);
|
addr, type, gamFullName.Buffer(), dims, elems);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
signalInfoPointers[i] =
|
signalInfoPointers[i] = service->RegisterSignal(
|
||||||
service->RegisterSignal(addr, type, dsFullName.Buffer(), dims, elems);
|
addr, type, dsFullName.Buffer(), dims, elems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +201,7 @@ 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);
|
||||||
fprintf(stderr, ">> INIT BROKER %s %s\n", name,
|
REPORT_ERROR_STATIC(ErrorManagement::Debug, "INIT BROKER %s %s\n", name,
|
||||||
direction == InputSignals ? "In" : "Out");
|
direction == InputSignals ? "In" : "Out");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
numSignals = this->GetNumberOfCopies();
|
numSignals = this->GetNumberOfCopies();
|
||||||
@@ -214,8 +216,8 @@ 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);
|
||||||
fprintf(stderr, ">> INIT optimized BROKER %s %s\n", name,
|
REPORT_ERROR_STATIC(ErrorManagement::Debug, "INIT optimized BROKER %s %s\n",
|
||||||
direction == InputSignals ? "In" : "Out");
|
name, direction == InputSignals ? "In" : "Out");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
numSignals = this->GetNumberOfCopies();
|
numSignals = this->GetNumberOfCopies();
|
||||||
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
|
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
|
||||||
@@ -403,6 +405,55 @@ 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
|
||||||
@@ -426,6 +477,8 @@ 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
|
||||||
|
|||||||
@@ -1,22 +1,47 @@
|
|||||||
|
#include "AdvancedErrorManagement.h"
|
||||||
|
#include "AnyType.h"
|
||||||
#include "BasicTCPSocket.h"
|
#include "BasicTCPSocket.h"
|
||||||
#include "ClassRegistryItem.h"
|
#include "ClassRegistryItem.h"
|
||||||
#include "ConfigurationDatabase.h"
|
#include "ConfigurationDatabase.h"
|
||||||
#include "DataSourceI.h"
|
#include "DataSourceI.h"
|
||||||
#include "DebugBrokerWrapper.h"
|
#include "DebugBrokerWrapper.h"
|
||||||
#include "DebugService.h"
|
#include "DebugService.h"
|
||||||
|
#include "ErrorType.h"
|
||||||
#include "GAM.h"
|
#include "GAM.h"
|
||||||
#include "GlobalObjectsDatabase.h"
|
#include "GlobalObjectsDatabase.h"
|
||||||
#include "HighResolutionTimer.h"
|
#include "HighResolutionTimer.h"
|
||||||
|
#include "Matrix.h"
|
||||||
#include "Message.h"
|
#include "Message.h"
|
||||||
#include "ObjectBuilder.h"
|
#include "ObjectBuilder.h"
|
||||||
#include "ObjectRegistryDatabase.h"
|
#include "ObjectRegistryDatabase.h"
|
||||||
|
#include "RealTimeApplication.h"
|
||||||
|
#include "ReferenceT.h"
|
||||||
|
#include "StateMachine.h"
|
||||||
#include "StreamString.h"
|
#include "StreamString.h"
|
||||||
#include "TimeoutType.h"
|
#include "TimeoutType.h"
|
||||||
#include "TypeConversion.h"
|
#include "TypeConversion.h"
|
||||||
#include "ReferenceT.h"
|
#include "TypeDescriptor.h"
|
||||||
|
|
||||||
namespace MARTe {
|
namespace MARTe {
|
||||||
|
|
||||||
|
// Proxy to access private members of RealTimeApplication
|
||||||
|
class RealTimeApplicationProxy : public ReferenceContainer {
|
||||||
|
public:
|
||||||
|
// ReferenceContainer members
|
||||||
|
LinkedListHolderT<ReferenceContainerNode> list;
|
||||||
|
FastPollingMutexSem mux;
|
||||||
|
TimeoutType muxTimeout;
|
||||||
|
|
||||||
|
// MessageI members (approximate alignment)
|
||||||
|
void *messageI_vtable;
|
||||||
|
uint8 messageFilters_padding[sizeof(
|
||||||
|
ReferenceContainer)]; // MessageFilterPool is a ReferenceContainer
|
||||||
|
|
||||||
|
// RealTimeApplication members
|
||||||
|
StreamString stateNameHolder[2];
|
||||||
|
uint32 index;
|
||||||
|
};
|
||||||
|
|
||||||
DebugService *DebugService::instance = (DebugService *)0;
|
DebugService *DebugService::instance = (DebugService *)0;
|
||||||
|
|
||||||
static void EscapeJson(const char8 *src, StreamString &dst) {
|
static void EscapeJson(const char8 *src, StreamString &dst) {
|
||||||
@@ -79,6 +104,176 @@ static bool FindPathInContainer(ReferenceContainer *container,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void JsonifyScalar(const AnyType &at, StreamString &json) {
|
||||||
|
if (at.GetDataPointer() == NULL_PTR(void *)) {
|
||||||
|
json += "null";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char8 buf[1024];
|
||||||
|
AnyType st(CharString, 0u, buf);
|
||||||
|
st.SetNumberOfElements(0, 1024);
|
||||||
|
if (TypeConvert(st, at)) {
|
||||||
|
TypeDescriptor td = at.GetTypeDescriptor();
|
||||||
|
if (td.IsNumericType() || td == BooleanType) {
|
||||||
|
if (buf[0] == '\0')
|
||||||
|
json += "0";
|
||||||
|
else
|
||||||
|
json += buf;
|
||||||
|
} else {
|
||||||
|
json += "\"";
|
||||||
|
EscapeJson(buf, json);
|
||||||
|
json += "\"";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
json += "null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void JsonifyDatabaseInternal(ConfigurationDatabase &db,
|
||||||
|
StreamString &json) {
|
||||||
|
json += "{";
|
||||||
|
uint32 n = db.GetNumberOfChildren();
|
||||||
|
for (uint32 i = 0u; i < n; i++) {
|
||||||
|
const char8 *name = db.GetChildName(i);
|
||||||
|
json += "\"";
|
||||||
|
EscapeJson(name, json);
|
||||||
|
json += "\": ";
|
||||||
|
if (db.MoveRelative(name)) {
|
||||||
|
ConfigurationDatabase child;
|
||||||
|
db.Copy(child);
|
||||||
|
child.MoveToRoot();
|
||||||
|
JsonifyDatabaseInternal(child, json);
|
||||||
|
db.MoveToAncestor(1u);
|
||||||
|
} else {
|
||||||
|
AnyType at = db.GetType(name);
|
||||||
|
uint32 nDims = at.GetNumberOfDimensions();
|
||||||
|
if (nDims == 0u) {
|
||||||
|
JsonifyScalar(at, json);
|
||||||
|
} else if (nDims == 1u) {
|
||||||
|
uint32 nElements = at.GetNumberOfElements(0u);
|
||||||
|
json += "[";
|
||||||
|
for (uint32 j = 0u; j < nElements; j++) {
|
||||||
|
JsonifyScalar(at[j], json);
|
||||||
|
if (j < nElements - 1u)
|
||||||
|
json += ", ";
|
||||||
|
}
|
||||||
|
json += "]";
|
||||||
|
} else if (nDims == 2u) {
|
||||||
|
uint32 nRows = at.GetNumberOfElements(0u);
|
||||||
|
uint32 nCols = at.GetNumberOfElements(1u);
|
||||||
|
json += "[";
|
||||||
|
for (uint32 r = 0u; r < nRows; r++) {
|
||||||
|
json += "[";
|
||||||
|
for (uint32 c = 0u; c < nCols; c++) {
|
||||||
|
JsonifyScalar(at[r][c], json);
|
||||||
|
if (c < nCols - 1u)
|
||||||
|
json += ", ";
|
||||||
|
}
|
||||||
|
json += "]";
|
||||||
|
if (r < nRows - 1u)
|
||||||
|
json += ", ";
|
||||||
|
}
|
||||||
|
json += "]";
|
||||||
|
} else {
|
||||||
|
json += "\"Unsupported dimensions\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < n - 1)
|
||||||
|
json += ", ";
|
||||||
|
}
|
||||||
|
json += "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void JsonifyObjectSafe(Reference ref, StreamString &json, uint32 depth,
|
||||||
|
Vec<Object *> &visited) {
|
||||||
|
if (!ref.IsValid() || depth > 8) {
|
||||||
|
json += "null";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32 i = 0u; i < visited.Size(); i++) {
|
||||||
|
if (visited[i] == ref.operator->()) {
|
||||||
|
json += "\"<circular>\"";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visited.Push(ref.operator->());
|
||||||
|
|
||||||
|
json += "{\n";
|
||||||
|
const char8 *className = "Unknown";
|
||||||
|
const ClassProperties *cp = ref->GetClassProperties();
|
||||||
|
if (cp != NULL_PTR(const ClassProperties *)) {
|
||||||
|
className = cp->GetName();
|
||||||
|
}
|
||||||
|
json += "\"Class\": \"";
|
||||||
|
EscapeJson(className, json);
|
||||||
|
json += "\"";
|
||||||
|
|
||||||
|
ConfigurationDatabase db;
|
||||||
|
bool exported = false;
|
||||||
|
|
||||||
|
// CRITICAL: Avoid objects that are known to cause real-time interference
|
||||||
|
// or crashes when introspected live.
|
||||||
|
bool safeToExport = true;
|
||||||
|
if (StringHelper::Compare(className, "RealTimeThreadSynchronisation") == 0 ||
|
||||||
|
StringHelper::Compare(className, "SyncDB") == 0) {
|
||||||
|
safeToExport = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (safeToExport) {
|
||||||
|
ClassRegistryItem *cri = ClassRegistryDatabase::Instance()->Find(className);
|
||||||
|
if (cri != NULL_PTR(ClassRegistryItem *)) {
|
||||||
|
if (cri->GetIntrospection() != NULL_PTR(const Introspection *)) {
|
||||||
|
exported = ref->ExportMetadata(db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exported) {
|
||||||
|
exported = ref->ExportData(db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exported) {
|
||||||
|
db.MoveToRoot();
|
||||||
|
uint32 n = db.GetNumberOfChildren();
|
||||||
|
for (uint32 i = 0u; i < n; i++) {
|
||||||
|
const char8 *name = db.GetChildName(i);
|
||||||
|
json += ",\n\"";
|
||||||
|
EscapeJson(name, json);
|
||||||
|
json += "\": ";
|
||||||
|
|
||||||
|
if (db.MoveRelative(name)) {
|
||||||
|
ConfigurationDatabase sub;
|
||||||
|
db.Copy(sub);
|
||||||
|
sub.MoveToRoot();
|
||||||
|
JsonifyDatabaseInternal(sub, json);
|
||||||
|
db.MoveToAncestor(1u);
|
||||||
|
} else {
|
||||||
|
JsonifyScalar(db.GetType(name), json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReferenceContainer *container =
|
||||||
|
dynamic_cast<ReferenceContainer *>(ref.operator->());
|
||||||
|
if (container) {
|
||||||
|
uint32 n = container->Size();
|
||||||
|
if (n > 25)
|
||||||
|
n = 25; // Even tighter breadth limit
|
||||||
|
for (uint32 i = 0u; i < n; i++) {
|
||||||
|
Reference child = container->Get(i);
|
||||||
|
if (child.IsValid()) {
|
||||||
|
json += ",\n\"+";
|
||||||
|
EscapeJson(child->GetName(), json);
|
||||||
|
json += "\": ";
|
||||||
|
JsonifyObjectSafe(child, json, depth + 1, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
json += "\n}";
|
||||||
|
(void)visited.Remove(visited.Size() - 1u);
|
||||||
|
}
|
||||||
|
|
||||||
CLASS_REGISTER(DebugService, "1.0")
|
CLASS_REGISTER(DebugService, "1.0")
|
||||||
|
|
||||||
DebugService::DebugService()
|
DebugService::DebugService()
|
||||||
@@ -113,6 +308,53 @@ DebugService::~DebugService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DiscoverStatesRecursive(ReferenceContainer *container,
|
||||||
|
Vec<DebugService::MonitoredState> &monitoredStates) {
|
||||||
|
if (container == NULL_PTR(ReferenceContainer *)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32 n = container->Size();
|
||||||
|
for (uint32 i = 0u; i < n; i++) {
|
||||||
|
Reference ref = container->Get(i);
|
||||||
|
if (ref.IsValid()) {
|
||||||
|
bool alreadyMonitored = false;
|
||||||
|
for (uint32 j = 0u; j < monitoredStates.Size(); j++) {
|
||||||
|
if (monitoredStates[j].obj == ref) {
|
||||||
|
alreadyMonitored = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alreadyMonitored) {
|
||||||
|
bool isStateful = false;
|
||||||
|
if (dynamic_cast<RealTimeApplication *>(ref.operator->()) !=
|
||||||
|
NULL_PTR(RealTimeApplication *)) {
|
||||||
|
isStateful = true;
|
||||||
|
} else if (dynamic_cast<StateMachine *>(ref.operator->()) !=
|
||||||
|
NULL_PTR(StateMachine *)) {
|
||||||
|
isStateful = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStateful) {
|
||||||
|
DebugService::MonitoredState ms;
|
||||||
|
ms.obj = ref;
|
||||||
|
ms.internalID = 0x90000000 | monitoredStates.Size();
|
||||||
|
DebugService::GetFullObjectName(*(ref.operator->()), ms.path);
|
||||||
|
ms.lastState = "";
|
||||||
|
monitoredStates.Push(ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReferenceContainer *sub =
|
||||||
|
dynamic_cast<ReferenceContainer *>(ref.operator->());
|
||||||
|
if (sub != NULL_PTR(ReferenceContainer *)) {
|
||||||
|
DiscoverStatesRecursive(sub, monitoredStates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool DebugService::Initialise(StructuredDataI &data) {
|
bool DebugService::Initialise(StructuredDataI &data) {
|
||||||
if (!ReferenceContainer::Initialise(data))
|
if (!ReferenceContainer::Initialise(data))
|
||||||
return false;
|
return false;
|
||||||
@@ -157,24 +399,23 @@ bool DebugService::Initialise(StructuredDataI &data) {
|
|||||||
suppressTimeoutLogs = (suppress == 1);
|
suppressTimeoutLogs = (suppress == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to capture full configuration autonomously if data is a
|
// Copy local branch as fallback
|
||||||
// ConfigurationDatabase
|
const char *name = data.GetName();
|
||||||
ConfigurationDatabase *cdb = dynamic_cast<ConfigurationDatabase *>(&data);
|
data.MoveToRoot();
|
||||||
if (cdb != NULL_PTR(ConfigurationDatabase *)) {
|
(void)data.Copy(fullConfig);
|
||||||
// Save current position
|
if (!data.MoveRelative(name)) {
|
||||||
StreamString currentPath;
|
REPORT_ERROR(ErrorManagement::FatalError, "Impossible to move back...");
|
||||||
// In MARTe2 ConfigurationDatabase there isn't a direct GetCurrentPath,
|
return false;
|
||||||
// but we can at least try to copy from root if we are at root.
|
|
||||||
// For now, we rely on explicit SetFullConfig or documentary injection.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy local branch as fallback
|
|
||||||
(void)data.Copy(fullConfig);
|
|
||||||
|
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
|
monitoredStates.Clear();
|
||||||
|
|
||||||
if (!traceBuffer.Init(8 * 1024 * 1024))
|
if (!traceBuffer.Init(8 * 1024 * 1024))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
PatchRegistry();
|
PatchRegistry();
|
||||||
|
|
||||||
ConfigurationDatabase threadData;
|
ConfigurationDatabase threadData;
|
||||||
threadData.Write("Timeout", (uint32)1000);
|
threadData.Write("Timeout", (uint32)1000);
|
||||||
threadService.Initialise(threadData);
|
threadService.Initialise(threadData);
|
||||||
@@ -230,7 +471,7 @@ void DebugService::PatchRegistry() {
|
|||||||
PatchItemInternal("MemoryMapMultiBufferOutputBroker", b7);
|
PatchItemInternal("MemoryMapMultiBufferOutputBroker", b7);
|
||||||
DebugMemoryMapSynchronisedMultiBufferInputBrokerBuilder *b8 =
|
DebugMemoryMapSynchronisedMultiBufferInputBrokerBuilder *b8 =
|
||||||
new DebugMemoryMapSynchronisedMultiBufferInputBrokerBuilder();
|
new DebugMemoryMapSynchronisedMultiBufferInputBrokerBuilder();
|
||||||
PatchItemInternal("MemoryMapSynchronisedMultiBufferInputBroker", b8);
|
PatchItemInternal("MemoryMapMultiBufferInputBroker", b8);
|
||||||
DebugMemoryMapSynchronisedMultiBufferOutputBrokerBuilder *b9 =
|
DebugMemoryMapSynchronisedMultiBufferOutputBrokerBuilder *b9 =
|
||||||
new DebugMemoryMapSynchronisedMultiBufferOutputBrokerBuilder();
|
new DebugMemoryMapSynchronisedMultiBufferOutputBrokerBuilder();
|
||||||
PatchItemInternal("MemoryMapSynchronisedMultiBufferOutputBroker", b9);
|
PatchItemInternal("MemoryMapSynchronisedMultiBufferOutputBroker", b9);
|
||||||
@@ -240,6 +481,9 @@ void DebugService::PatchRegistry() {
|
|||||||
DebugMemoryMapAsyncTriggerOutputBrokerBuilder *b11 =
|
DebugMemoryMapAsyncTriggerOutputBrokerBuilder *b11 =
|
||||||
new DebugMemoryMapAsyncTriggerOutputBrokerBuilder();
|
new DebugMemoryMapAsyncTriggerOutputBrokerBuilder();
|
||||||
PatchItemInternal("MemoryMapAsyncTriggerOutputBroker", b11);
|
PatchItemInternal("MemoryMapAsyncTriggerOutputBroker", b11);
|
||||||
|
DebugRealTimeThreadSyncBrokerBuilder *b12 =
|
||||||
|
new DebugRealTimeThreadSyncBrokerBuilder();
|
||||||
|
PatchItemInternal("RealTimeThreadSyncBroker", b12);
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugSignalInfo *DebugService::RegisterSignal(void *memoryAddress,
|
DebugSignalInfo *DebugService::RegisterSignal(void *memoryAddress,
|
||||||
@@ -247,7 +491,7 @@ DebugSignalInfo *DebugService::RegisterSignal(void *memoryAddress,
|
|||||||
const char8 *name,
|
const char8 *name,
|
||||||
uint8 numberOfDimensions,
|
uint8 numberOfDimensions,
|
||||||
uint32 numberOfElements) {
|
uint32 numberOfElements) {
|
||||||
printf("<debug> registering: %s\n", name);
|
REPORT_ERROR(ErrorManagement::Debug, "registering: %s", name);
|
||||||
mutex.FastLock();
|
mutex.FastLock();
|
||||||
DebugSignalInfo *res = NULL_PTR(DebugSignalInfo *);
|
DebugSignalInfo *res = NULL_PTR(DebugSignalInfo *);
|
||||||
uint32 sigIdx = 0xFFFFFFFF;
|
uint32 sigIdx = 0xFFFFFFFF;
|
||||||
@@ -369,8 +613,11 @@ ErrorManagement::ErrorType DebugService::Execute(ExecutionInfo &info) {
|
|||||||
return ErrorManagement::FatalError;
|
return ErrorManagement::FatalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorManagement::ErrorType DebugService::HandleMessage(ReferenceT<Message> &data) {
|
ErrorManagement::ErrorType
|
||||||
printf("<debug> DebugService received custom message: Function=%s\n", (const char8*)data->GetFunction());
|
DebugService::HandleMessage(ReferenceT<Message> &data) {
|
||||||
|
REPORT_ERROR(ErrorManagement::Debug,
|
||||||
|
"DebugService received custom message: Function=%s",
|
||||||
|
(const char8 *)data->GetFunction());
|
||||||
return ErrorManagement::NoError;
|
return ErrorManagement::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,20 +699,89 @@ ErrorManagement::ErrorType DebugService::Streamer(ExecutionInfo &info) {
|
|||||||
uint8 packetBuffer[4096];
|
uint8 packetBuffer[4096];
|
||||||
uint32 packetOffset = 0;
|
uint32 packetOffset = 0;
|
||||||
uint32 sequenceNumber = 0;
|
uint32 sequenceNumber = 0;
|
||||||
|
uint64 lastStatePollTime = 0;
|
||||||
|
|
||||||
while (info.GetStage() == ExecutionInfo::MainStage) {
|
while (info.GetStage() == ExecutionInfo::MainStage) {
|
||||||
// Poll monitored signals
|
|
||||||
uint64 currentTimeMs = (uint64)((float64)HighResolutionTimer::Counter() *
|
uint64 currentTimeMs = (uint64)((float64)HighResolutionTimer::Counter() *
|
||||||
HighResolutionTimer::Period() * 1000.0);
|
HighResolutionTimer::Period() * 1000.0);
|
||||||
|
|
||||||
|
// Poll states every 100ms
|
||||||
|
if (currentTimeMs >= (lastStatePollTime + 100u)) {
|
||||||
|
lastStatePollTime = currentTimeMs;
|
||||||
|
mutex.FastLock();
|
||||||
|
for (uint32 i = 0; i < monitoredStates.Size(); i++) {
|
||||||
|
StreamString currentState;
|
||||||
|
RealTimeApplication *app = dynamic_cast<RealTimeApplication *>(
|
||||||
|
monitoredStates[i].obj.operator->());
|
||||||
|
StateMachine *sm =
|
||||||
|
dynamic_cast<StateMachine *>(monitoredStates[i].obj.operator->());
|
||||||
|
|
||||||
|
if (app != NULL_PTR(RealTimeApplication *)) {
|
||||||
|
// Look for child RealTimeState objects and check if their GetIndex()
|
||||||
|
// matches app's But wait, RealTimeState is not easily accessible
|
||||||
|
// here. Let's use the proxy but with more padding to be safe, or
|
||||||
|
// better: use the public GetIndex() and then we need a way to get the
|
||||||
|
// state names.
|
||||||
|
|
||||||
|
// Re-attempting proxy with what is most likely the layout:
|
||||||
|
// [ReferenceContainer][MessageI][RealTimeApplication]
|
||||||
|
// MessageI has virtual destructor -> vtable (8 bytes)
|
||||||
|
// MessageI has MessageFilterPool -> ReferenceContainer (40 bytes)
|
||||||
|
|
||||||
|
struct RTAP {
|
||||||
|
uint8 padding[sizeof(ReferenceContainer) + 8 +
|
||||||
|
sizeof(ReferenceContainer)];
|
||||||
|
StreamString stateNameHolder[2];
|
||||||
|
uint32 index;
|
||||||
|
};
|
||||||
|
|
||||||
|
RTAP *proxy = reinterpret_cast<RTAP *>(app);
|
||||||
|
uint32 idx = app->GetIndex();
|
||||||
|
if (idx < 2u) {
|
||||||
|
currentState = proxy->stateNameHolder[idx];
|
||||||
|
}
|
||||||
|
if (currentState.Size() == 0) {
|
||||||
|
// Maybe index is 1 but we only have 1 state? Or alignment still
|
||||||
|
// off. Try the other index if it's empty
|
||||||
|
currentState = proxy->stateNameHolder[1u - idx];
|
||||||
|
}
|
||||||
|
} else if (sm != NULL_PTR(StateMachine *)) {
|
||||||
|
Reference s = sm->GetCurrentState();
|
||||||
|
if (s.IsValid()) {
|
||||||
|
currentState = s->GetName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentState.Size() > 0u &&
|
||||||
|
currentState != monitoredStates[i].lastState) {
|
||||||
|
monitoredStates[i].lastState = currentState;
|
||||||
|
uint64 ts = (uint64)((float64)HighResolutionTimer::Counter() *
|
||||||
|
HighResolutionTimer::Period() * 1000000.0);
|
||||||
|
|
||||||
|
char8 stateBuf[64];
|
||||||
|
memset(stateBuf, 0, 64);
|
||||||
|
strncpy(stateBuf, currentState.Buffer(), 63);
|
||||||
|
traceBuffer.Push(monitoredStates[i].internalID, ts, (uint8 *)stateBuf,
|
||||||
|
64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex.FastUnLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poll monitored signals
|
||||||
mutex.FastLock();
|
mutex.FastLock();
|
||||||
for (uint32 i = 0; i < monitoredSignals.Size(); i++) {
|
for (uint32 i = 0; i < monitoredSignals.Size(); i++) {
|
||||||
if (currentTimeMs >= (monitoredSignals[i].lastPollTime + monitoredSignals[i].periodMs)) {
|
if (currentTimeMs >=
|
||||||
|
(monitoredSignals[i].lastPollTime + monitoredSignals[i].periodMs)) {
|
||||||
monitoredSignals[i].lastPollTime = currentTimeMs;
|
monitoredSignals[i].lastPollTime = currentTimeMs;
|
||||||
uint64 ts = (uint64)((float64)HighResolutionTimer::Counter() *
|
uint64 ts = (uint64)((float64)HighResolutionTimer::Counter() *
|
||||||
HighResolutionTimer::Period() * 1000000.0);
|
HighResolutionTimer::Period() * 1000000.0);
|
||||||
|
|
||||||
void *address = NULL_PTR(void *);
|
void *address = NULL_PTR(void *);
|
||||||
if (monitoredSignals[i].dataSource->GetSignalMemoryBuffer(monitoredSignals[i].signalIdx, 0, address)) {
|
if (monitoredSignals[i].dataSource->GetSignalMemoryBuffer(
|
||||||
traceBuffer.Push(monitoredSignals[i].internalID, ts, (uint8 *)address, monitoredSignals[i].size);
|
monitoredSignals[i].signalIdx, 0, address)) {
|
||||||
|
traceBuffer.Push(monitoredSignals[i].internalID, ts, (uint8 *)address,
|
||||||
|
monitoredSignals[i].size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -575,9 +891,9 @@ void DebugService::HandleCommand(StreamString cmd, BasicTCPSocket *client) {
|
|||||||
(void)client->Write(resp.Buffer(), s);
|
(void)client->Write(resp.Buffer(), s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (token == "DISCOVER")
|
} else if (token == "DISCOVER") {
|
||||||
Discover(client);
|
Discover(client);
|
||||||
else if (token == "MSG") {
|
} else if (token == "MSG") {
|
||||||
StreamString dest, func, waitStr;
|
StreamString dest, func, waitStr;
|
||||||
if (cmd.GetToken(dest, delims, term) &&
|
if (cmd.GetToken(dest, delims, term) &&
|
||||||
cmd.GetToken(func, delims, term) &&
|
cmd.GetToken(func, delims, term) &&
|
||||||
@@ -633,7 +949,7 @@ void DebugService::HandleCommand(StreamString cmd, BasicTCPSocket *client) {
|
|||||||
uint32 eqPos = (uint32)(eq - line.Buffer());
|
uint32 eqPos = (uint32)(eq - line.Buffer());
|
||||||
(void)line.Seek(0u);
|
(void)line.Seek(0u);
|
||||||
|
|
||||||
char8* keyBuf = new char8[eqPos + 1];
|
char8 *keyBuf = new char8[eqPos + 1];
|
||||||
uint32 keyReadSize = eqPos;
|
uint32 keyReadSize = eqPos;
|
||||||
if (line.Read(keyBuf, keyReadSize)) {
|
if (line.Read(keyBuf, keyReadSize)) {
|
||||||
keyBuf[eqPos] = '\0';
|
keyBuf[eqPos] = '\0';
|
||||||
@@ -643,7 +959,7 @@ void DebugService::HandleCommand(StreamString cmd, BasicTCPSocket *client) {
|
|||||||
|
|
||||||
(void)line.Seek(eqPos + 1u);
|
(void)line.Seek(eqPos + 1u);
|
||||||
uint32 valLen = line.Size() - eqPos - 1u;
|
uint32 valLen = line.Size() - eqPos - 1u;
|
||||||
char8* valBuf = new char8[valLen + 1];
|
char8 *valBuf = new char8[valLen + 1];
|
||||||
uint32 valReadSize = valLen;
|
uint32 valReadSize = valLen;
|
||||||
if (line.Read(valBuf, valReadSize)) {
|
if (line.Read(valBuf, valReadSize)) {
|
||||||
valBuf[valLen] = '\0';
|
valBuf[valLen] = '\0';
|
||||||
@@ -657,7 +973,6 @@ void DebugService::HandleCommand(StreamString cmd, BasicTCPSocket *client) {
|
|||||||
(void)msgConfig.MoveToAncestor(1u);
|
(void)msgConfig.MoveToAncestor(1u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line = "";
|
line = "";
|
||||||
@@ -667,13 +982,14 @@ void DebugService::HandleCommand(StreamString cmd, BasicTCPSocket *client) {
|
|||||||
ErrorManagement::ErrorType err = ErrorManagement::ParametersError;
|
ErrorManagement::ErrorType err = ErrorManagement::ParametersError;
|
||||||
if (msg->Initialise(msgConfig)) {
|
if (msg->Initialise(msgConfig)) {
|
||||||
// Find destination object in the global database
|
// Find destination object in the global database
|
||||||
Reference destObj = ObjectRegistryDatabase::Instance()->Find(dest.Buffer());
|
Reference destObj =
|
||||||
|
ObjectRegistryDatabase::Instance()->Find(dest.Buffer());
|
||||||
if (destObj.IsValid()) {
|
if (destObj.IsValid()) {
|
||||||
Object* sender = this;
|
Object *sender = this;
|
||||||
// Double check if we are in the registry to be a valid sender
|
// Double check if we are in the registry to be a valid sender
|
||||||
StreamString myPath;
|
StreamString myPath;
|
||||||
if (!GetFullObjectName(*this, myPath)) {
|
if (!GetFullObjectName(*this, myPath)) {
|
||||||
sender = NULL_PTR(Object*);
|
sender = NULL_PTR(Object *);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait) {
|
if (wait) {
|
||||||
@@ -683,14 +999,18 @@ void DebugService::HandleCommand(StreamString cmd, BasicTCPSocket *client) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
printf("<debug> MSG: Destination object %s not found in ORD\n", dest.Buffer());
|
REPORT_ERROR(ErrorManagement::Warning,
|
||||||
|
"MSG: Destination object %s not found in ORD",
|
||||||
|
dest.Buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != ErrorManagement::NoError) {
|
if (err != ErrorManagement::NoError) {
|
||||||
printf("<debug> MSG: MessageI dispatch failed.\n");
|
REPORT_ERROR(ErrorManagement::Warning,
|
||||||
|
"MSG: MessageI dispatch failed.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("<debug> MSG: Message initialization failed\n");
|
REPORT_ERROR(ErrorManagement::Warning,
|
||||||
|
"MSG: Message initialization failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client) {
|
if (client) {
|
||||||
@@ -704,11 +1024,11 @@ void DebugService::HandleCommand(StreamString cmd, BasicTCPSocket *client) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (token == "SERVICE_INFO") {
|
||||||
else if (token == "SERVICE_INFO") {
|
|
||||||
if (client) {
|
if (client) {
|
||||||
StreamString resp;
|
StreamString resp;
|
||||||
resp.Printf("OK SERVICE_INFO TCP_CTRL:%u UDP_STREAM:%u TCP_LOG:%u STATE:%s\n",
|
resp.Printf(
|
||||||
|
"OK SERVICE_INFO TCP_CTRL:%u UDP_STREAM:%u TCP_LOG:%u STATE:%s\n",
|
||||||
controlPort, streamPort, logPort, isPaused ? "PAUSED" : "RUNNING");
|
controlPort, streamPort, logPort, isPaused ? "PAUSED" : "RUNNING");
|
||||||
uint32 s = resp.Size();
|
uint32 s = resp.Size();
|
||||||
(void)client->Write(resp.Buffer(), s);
|
(void)client->Write(resp.Buffer(), s);
|
||||||
@@ -717,7 +1037,8 @@ void DebugService::HandleCommand(StreamString cmd, BasicTCPSocket *client) {
|
|||||||
StreamString subToken;
|
StreamString subToken;
|
||||||
if (cmd.GetToken(subToken, delims, term) && subToken == "SIGNAL") {
|
if (cmd.GetToken(subToken, delims, term) && subToken == "SIGNAL") {
|
||||||
StreamString name, period;
|
StreamString name, period;
|
||||||
if (cmd.GetToken(name, delims, term) && cmd.GetToken(period, delims, term)) {
|
if (cmd.GetToken(name, delims, term) &&
|
||||||
|
cmd.GetToken(period, delims, term)) {
|
||||||
uint32 p = 100;
|
uint32 p = 100;
|
||||||
AnyType pVal(UnsignedInteger32Bit, 0u, &p);
|
AnyType pVal(UnsignedInteger32Bit, 0u, &p);
|
||||||
AnyType pStr(CharString, 0u, period.Buffer());
|
AnyType pStr(CharString, 0u, period.Buffer());
|
||||||
@@ -763,7 +1084,8 @@ void DebugService::HandleCommand(StreamString cmd, BasicTCPSocket *client) {
|
|||||||
StreamString json;
|
StreamString json;
|
||||||
json = "{\"Name\": \"Root\", \"Class\": \"ObjectRegistryDatabase\", "
|
json = "{\"Name\": \"Root\", \"Class\": \"ObjectRegistryDatabase\", "
|
||||||
"\"Children\": [\n";
|
"\"Children\": [\n";
|
||||||
(void)ExportTree(ObjectRegistryDatabase::Instance(), json, NULL_PTR(const char8 *));
|
(void)ExportTree(ObjectRegistryDatabase::Instance(), json,
|
||||||
|
NULL_PTR(const char8 *));
|
||||||
json += "\n]}\nOK TREE\n";
|
json += "\n]}\nOK TREE\n";
|
||||||
uint32 s = json.Size();
|
uint32 s = json.Size();
|
||||||
if (client)
|
if (client)
|
||||||
@@ -851,44 +1173,18 @@ void DebugService::EnrichWithConfig(const char8 *path, StreamString &json) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DebugService::JsonifyDatabase(ConfigurationDatabase &db,
|
void DebugService::JsonifyDatabase(ConfigurationDatabase &db,
|
||||||
StreamString &json) {
|
StreamString &json,
|
||||||
json += "{";
|
StreamString indent) {
|
||||||
uint32 n = db.GetNumberOfChildren();
|
JsonifyDatabaseInternal(db, json);
|
||||||
for (uint32 i = 0u; i < n; i++) {
|
|
||||||
const char8 *name = db.GetChildName(i);
|
|
||||||
json += "\"";
|
|
||||||
EscapeJson(name, json);
|
|
||||||
json += "\": ";
|
|
||||||
if (db.MoveRelative(name)) {
|
|
||||||
ConfigurationDatabase child;
|
|
||||||
db.Copy(child);
|
|
||||||
JsonifyDatabase(child, json);
|
|
||||||
db.MoveToAncestor(1u);
|
|
||||||
} else {
|
|
||||||
AnyType at = db.GetType(name);
|
|
||||||
char8 buf[1024];
|
|
||||||
AnyType st(CharString, 0u, buf);
|
|
||||||
st.SetNumberOfElements(0, 1024);
|
|
||||||
if (TypeConvert(st, at)) {
|
|
||||||
json += "\"";
|
|
||||||
EscapeJson(buf, json);
|
|
||||||
json += "\"";
|
|
||||||
} else {
|
|
||||||
json += "null";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i < n - 1)
|
|
||||||
json += ", ";
|
|
||||||
}
|
|
||||||
json += "}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugService::ServeConfig(BasicTCPSocket *client) {
|
void DebugService::ServeConfig(BasicTCPSocket *client) {
|
||||||
if (client == NULL_PTR(BasicTCPSocket *))
|
if (client == NULL_PTR(BasicTCPSocket *))
|
||||||
return;
|
return;
|
||||||
StreamString json;
|
StreamString json;
|
||||||
fullConfig.MoveToRoot();
|
Reference ref = ObjectRegistryDatabase::Instance();
|
||||||
JsonifyDatabase(fullConfig, json);
|
Vec<Object *> visited;
|
||||||
|
JsonifyObjectSafe(ref, json, 0, visited);
|
||||||
json += "\nOK CONFIG\n";
|
json += "\nOK CONFIG\n";
|
||||||
uint32 s = json.Size();
|
uint32 s = json.Size();
|
||||||
(void)client->Write(json.Buffer(), s);
|
(void)client->Write(json.Buffer(), s);
|
||||||
@@ -1009,7 +1305,8 @@ uint32 DebugService::ExportTree(ReferenceContainer *container,
|
|||||||
(void)ds->GetSignalNumberOfElements(j, elems);
|
(void)ds->GetSignalNumberOfElements(j, elems);
|
||||||
|
|
||||||
StreamString signalFullPath;
|
StreamString signalFullPath;
|
||||||
signalFullPath.Printf("%s.%s", currentPath.Buffer(), sname.Buffer());
|
signalFullPath.Printf("%s.%s", currentPath.Buffer(),
|
||||||
|
sname.Buffer());
|
||||||
bool traceable = false;
|
bool traceable = false;
|
||||||
bool forcable = false;
|
bool forcable = false;
|
||||||
(void)IsInstrumented(signalFullPath.Buffer(), traceable, forcable);
|
(void)IsInstrumented(signalFullPath.Buffer(), traceable, forcable);
|
||||||
@@ -1099,6 +1396,138 @@ uint32 DebugService::ExportTree(ReferenceContainer *container,
|
|||||||
return validCount;
|
return validCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugService::ListNodes(const char8 *path, BasicTCPSocket *client) {
|
||||||
|
if (!client)
|
||||||
|
return;
|
||||||
|
Reference ref =
|
||||||
|
(path == NULL_PTR(const char8 *) || StringHelper::Length(path) == 0 ||
|
||||||
|
StringHelper::Compare(path, "/") == 0)
|
||||||
|
? ObjectRegistryDatabase::Instance()
|
||||||
|
: ObjectRegistryDatabase::Instance()->Find(path);
|
||||||
|
if (ref.IsValid()) {
|
||||||
|
StreamString out;
|
||||||
|
out.Printf("Nodes under %s:\n", path ? path : "/");
|
||||||
|
ReferenceContainer *container =
|
||||||
|
dynamic_cast<ReferenceContainer *>(ref.operator->());
|
||||||
|
if (container) {
|
||||||
|
for (uint32 i = 0; i < container->Size(); i++) {
|
||||||
|
Reference child = container->Get(i);
|
||||||
|
if (child.IsValid())
|
||||||
|
out.Printf(" %s [%s]\n", child->GetName(),
|
||||||
|
child->GetClassProperties()->GetName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char *okMsg = "OK LS\n";
|
||||||
|
out += okMsg;
|
||||||
|
uint32 s = out.Size();
|
||||||
|
(void)client->Write(out.Buffer(), s);
|
||||||
|
} else {
|
||||||
|
const char *msg = "ERROR: Path not found\n";
|
||||||
|
uint32 s = StringHelper::Length(msg);
|
||||||
|
(void)client->Write(msg, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugService::Discover(BasicTCPSocket *client) {
|
||||||
|
if (client) {
|
||||||
|
mutex.FastLock();
|
||||||
|
// Automatically add all state machines and realtime application states if
|
||||||
|
// not already there
|
||||||
|
DiscoverStatesRecursive(ObjectRegistryDatabase::Instance(),
|
||||||
|
monitoredStates);
|
||||||
|
|
||||||
|
// Force immediate state push on next poll cycle
|
||||||
|
for (uint32 i = 0u; i < monitoredStates.Size(); i++) {
|
||||||
|
monitoredStates[i].lastState = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamString header = "{\n \"Signals\": [\n";
|
||||||
|
uint32 s = header.Size();
|
||||||
|
(void)client->Write(header.Buffer(), s);
|
||||||
|
uint32 total = 0;
|
||||||
|
for (uint32 i = 0; i < aliases.Size(); i++) {
|
||||||
|
if (total > 0) {
|
||||||
|
uint32 commaSize = 2;
|
||||||
|
(void)client->Write(",\n", commaSize);
|
||||||
|
}
|
||||||
|
StreamString line;
|
||||||
|
DebugSignalInfo *sig = signals[aliases[i].signalIndex];
|
||||||
|
const char8 *typeName =
|
||||||
|
TypeDescriptor::GetTypeNameFromTypeDescriptor(sig->type);
|
||||||
|
line.Printf(" {\"name\": \"%s\", \"id\": %d, \"type\": \"%s\", "
|
||||||
|
"\"dimensions\": %u, \"elements\": %u",
|
||||||
|
aliases[i].name.Buffer(), sig->internalID,
|
||||||
|
typeName ? typeName : "Unknown", sig->numberOfDimensions,
|
||||||
|
sig->numberOfElements);
|
||||||
|
EnrichWithConfig(aliases[i].name.Buffer(), line);
|
||||||
|
line += "}";
|
||||||
|
s = line.Size();
|
||||||
|
(void)client->Write(line.Buffer(), s);
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export monitored signals not already in aliases
|
||||||
|
for (uint32 i = 0; i < monitoredSignals.Size(); i++) {
|
||||||
|
bool found = false;
|
||||||
|
for (uint32 j = 0; j < aliases.Size(); j++) {
|
||||||
|
if (aliases[j].name == monitoredSignals[i].path) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
if (total > 0) {
|
||||||
|
uint32 commaSize = 2;
|
||||||
|
(void)client->Write(",\n", commaSize);
|
||||||
|
}
|
||||||
|
StreamString line;
|
||||||
|
const char8 *typeName = TypeDescriptor::GetTypeNameFromTypeDescriptor(
|
||||||
|
monitoredSignals[i].dataSource->GetSignalType(
|
||||||
|
monitoredSignals[i].signalIdx));
|
||||||
|
|
||||||
|
uint8 dims = 0;
|
||||||
|
uint32 elems = 1;
|
||||||
|
(void)monitoredSignals[i].dataSource->GetSignalNumberOfDimensions(
|
||||||
|
monitoredSignals[i].signalIdx, dims);
|
||||||
|
(void)monitoredSignals[i].dataSource->GetSignalNumberOfElements(
|
||||||
|
monitoredSignals[i].signalIdx, elems);
|
||||||
|
|
||||||
|
line.Printf(" {\"name\": \"%s\", \"id\": %u, \"type\": \"%s\", "
|
||||||
|
"\"dimensions\": %u, \"elements\": %u",
|
||||||
|
monitoredSignals[i].path.Buffer(),
|
||||||
|
monitoredSignals[i].internalID,
|
||||||
|
typeName ? typeName : "Unknown", dims, elems);
|
||||||
|
EnrichWithConfig(monitoredSignals[i].path.Buffer(), line);
|
||||||
|
line += "}";
|
||||||
|
s = line.Size();
|
||||||
|
(void)client->Write(line.Buffer(), s);
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export discovered states
|
||||||
|
for (uint32 i = 0; i < monitoredStates.Size(); i++) {
|
||||||
|
if (total > 0) {
|
||||||
|
uint32 commaSize = 2;
|
||||||
|
(void)client->Write(",\n", commaSize);
|
||||||
|
}
|
||||||
|
StreamString line;
|
||||||
|
line.Printf(" {\"name\": \"%s\", \"id\": %u, \"type\": \"string\", "
|
||||||
|
"\"is_state\": true}",
|
||||||
|
monitoredStates[i].path.Buffer(),
|
||||||
|
monitoredStates[i].internalID);
|
||||||
|
s = line.Size();
|
||||||
|
(void)client->Write(line.Buffer(), s);
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex.FastUnLock();
|
||||||
|
StreamString footer = " ]\n}\nOK DISCOVER\n";
|
||||||
|
s = footer.Size();
|
||||||
|
(void)client->Write(footer.Buffer(), s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32 DebugService::ForceSignal(const char8 *name, const char8 *valueStr) {
|
uint32 DebugService::ForceSignal(const char8 *name, const char8 *valueStr) {
|
||||||
mutex.FastLock();
|
mutex.FastLock();
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
@@ -1139,7 +1568,6 @@ uint32 DebugService::TraceSignal(const char8 *name, bool enable,
|
|||||||
mutex.FastLock();
|
mutex.FastLock();
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
for (uint32 i = 0; i < aliases.Size(); i++) {
|
for (uint32 i = 0; i < aliases.Size(); i++) {
|
||||||
printf("<debug>%s\n", aliases[i].name.Buffer());
|
|
||||||
if (aliases[i].name == name ||
|
if (aliases[i].name == name ||
|
||||||
SuffixMatch(aliases[i].name.Buffer(), name)) {
|
SuffixMatch(aliases[i].name.Buffer(), name)) {
|
||||||
DebugSignalInfo *s = signals[aliases[i].signalIndex];
|
DebugSignalInfo *s = signals[aliases[i].signalIndex];
|
||||||
@@ -1150,7 +1578,7 @@ uint32 DebugService::TraceSignal(const char8 *name, bool enable,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
printf("<!!> signal %s not found\n", name);
|
REPORT_ERROR(ErrorManagement::Warning, "<!!> signal %s not found");
|
||||||
}
|
}
|
||||||
UpdateBrokersActiveStatus();
|
UpdateBrokersActiveStatus();
|
||||||
mutex.FastUnLock();
|
mutex.FastUnLock();
|
||||||
@@ -1260,104 +1688,4 @@ uint32 DebugService::UnmonitorSignal(const char8 *path) {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugService::Discover(BasicTCPSocket *client) {
|
|
||||||
if (client) {
|
|
||||||
StreamString header = "{\n \"Signals\": [\n";
|
|
||||||
uint32 s = header.Size();
|
|
||||||
(void)client->Write(header.Buffer(), s);
|
|
||||||
mutex.FastLock();
|
|
||||||
uint32 total = 0;
|
|
||||||
for (uint32 i = 0; i < aliases.Size(); i++) {
|
|
||||||
if (total > 0) {
|
|
||||||
uint32 commaSize = 2;
|
|
||||||
(void)client->Write(",\n", commaSize);
|
|
||||||
}
|
|
||||||
StreamString line;
|
|
||||||
DebugSignalInfo *sig = signals[aliases[i].signalIndex];
|
|
||||||
const char8 *typeName =
|
|
||||||
TypeDescriptor::GetTypeNameFromTypeDescriptor(sig->type);
|
|
||||||
line.Printf(" {\"name\": \"%s\", \"id\": %d, \"type\": \"%s\", \"dimensions\": %u, \"elements\": %u",
|
|
||||||
aliases[i].name.Buffer(), sig->internalID,
|
|
||||||
typeName ? typeName : "Unknown", sig->numberOfDimensions, sig->numberOfElements);
|
|
||||||
EnrichWithConfig(aliases[i].name.Buffer(), line);
|
|
||||||
line += "}";
|
|
||||||
s = line.Size();
|
|
||||||
(void)client->Write(line.Buffer(), s);
|
|
||||||
total++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export monitored signals not already in aliases
|
|
||||||
for (uint32 i = 0; i < monitoredSignals.Size(); i++) {
|
|
||||||
bool found = false;
|
|
||||||
for (uint32 j = 0; j < aliases.Size(); j++) {
|
|
||||||
if (aliases[j].name == monitoredSignals[i].path) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
if (total > 0) {
|
|
||||||
uint32 commaSize = 2;
|
|
||||||
(void)client->Write(",\n", commaSize);
|
|
||||||
}
|
|
||||||
StreamString line;
|
|
||||||
const char8 *typeName = TypeDescriptor::GetTypeNameFromTypeDescriptor(
|
|
||||||
monitoredSignals[i].dataSource->GetSignalType(
|
|
||||||
monitoredSignals[i].signalIdx));
|
|
||||||
|
|
||||||
uint8 dims = 0;
|
|
||||||
uint32 elems = 1;
|
|
||||||
(void)monitoredSignals[i].dataSource->GetSignalNumberOfDimensions(monitoredSignals[i].signalIdx, dims);
|
|
||||||
(void)monitoredSignals[i].dataSource->GetSignalNumberOfElements(monitoredSignals[i].signalIdx, elems);
|
|
||||||
|
|
||||||
line.Printf(" {\"name\": \"%s\", \"id\": %u, \"type\": \"%s\", \"dimensions\": %u, \"elements\": %u",
|
|
||||||
monitoredSignals[i].path.Buffer(),
|
|
||||||
monitoredSignals[i].internalID,
|
|
||||||
typeName ? typeName : "Unknown", dims, elems);
|
|
||||||
EnrichWithConfig(monitoredSignals[i].path.Buffer(), line);
|
|
||||||
line += "}";
|
|
||||||
s = line.Size();
|
|
||||||
(void)client->Write(line.Buffer(), s);
|
|
||||||
total++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex.FastUnLock();
|
|
||||||
StreamString footer = " ]\n}\nOK DISCOVER\n";
|
|
||||||
s = footer.Size();
|
|
||||||
(void)client->Write(footer.Buffer(), s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugService::ListNodes(const char8 *path, BasicTCPSocket *client) {
|
|
||||||
if (!client)
|
|
||||||
return;
|
|
||||||
Reference ref =
|
|
||||||
(path == NULL_PTR(const char8 *) || StringHelper::Length(path) == 0 ||
|
|
||||||
StringHelper::Compare(path, "/") == 0)
|
|
||||||
? ObjectRegistryDatabase::Instance()
|
|
||||||
: ObjectRegistryDatabase::Instance()->Find(path);
|
|
||||||
if (ref.IsValid()) {
|
|
||||||
StreamString out;
|
|
||||||
out.Printf("Nodes under %s:\n", path ? path : "/");
|
|
||||||
ReferenceContainer *container =
|
|
||||||
dynamic_cast<ReferenceContainer *>(ref.operator->());
|
|
||||||
if (container) {
|
|
||||||
for (uint32 i = 0; i < container->Size(); i++) {
|
|
||||||
Reference child = container->Get(i);
|
|
||||||
if (child.IsValid())
|
|
||||||
out.Printf(" %s [%s]\n", child->GetName(),
|
|
||||||
child->GetClassProperties()->GetName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const char *okMsg = "OK LS\n";
|
|
||||||
out += okMsg;
|
|
||||||
uint32 s = out.Size();
|
|
||||||
(void)client->Write(out.Buffer(), s);
|
|
||||||
} else {
|
|
||||||
const char *msg = "ERROR: Path not found\n";
|
|
||||||
uint32 s = StringHelper::Length(msg);
|
|
||||||
(void)client->Write(msg, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MARTe
|
} // namespace MARTe
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ 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, uint8 numberOfDimensions = 0,
|
const char8 *name,
|
||||||
|
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);
|
||||||
@@ -85,6 +86,13 @@ 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);
|
||||||
|
|
||||||
@@ -92,11 +100,13 @@ private:
|
|||||||
void HandleCommand(StreamString cmd, BasicTCPSocket *client);
|
void HandleCommand(StreamString cmd, BasicTCPSocket *client);
|
||||||
void UpdateBrokersActiveStatus();
|
void UpdateBrokersActiveStatus();
|
||||||
|
|
||||||
uint32 ExportTree(ReferenceContainer *container, StreamString &json, const char8 *pathPrefix);
|
uint32 ExportTree(ReferenceContainer *container, StreamString &json,
|
||||||
|
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);
|
||||||
@@ -143,6 +153,7 @@ 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;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ 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
|
||||||
@@ -49,6 +50,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
|
||||||
|
|
||||||
|
|
||||||
all: $(OBJS) $(SUBPROJ) \
|
all: $(OBJS) $(SUBPROJ) \
|
||||||
$(BUILD_DIR)/DebugService$(LIBEXT) \
|
$(BUILD_DIR)/DebugService$(LIBEXT) \
|
||||||
|
|||||||
@@ -5,67 +5,22 @@
|
|||||||
+GAM1 = {
|
+GAM1 = {
|
||||||
Class = IOGAM
|
Class = IOGAM
|
||||||
InputSignals = {
|
InputSignals = {
|
||||||
Counter = {
|
Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }
|
||||||
DataSource = Timer
|
Time = { DataSource = Timer Type = uint32 }
|
||||||
Type = uint32
|
|
||||||
Frequency = 1000
|
|
||||||
}
|
|
||||||
Time = {
|
|
||||||
DataSource = Timer
|
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
OutputSignals = {
|
OutputSignals = {
|
||||||
Counter = {
|
Counter = { DataSource = SyncDB Type = uint32 }
|
||||||
DataSource = SyncDB
|
Time = { DataSource = DDB Type = uint32 }
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
Time = {
|
|
||||||
DataSource = DDB
|
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+GAM2 = {
|
+GAM2 = {
|
||||||
Class = IOGAM
|
Class = IOGAM
|
||||||
InputSignals = {
|
InputSignals = {
|
||||||
Counter = {
|
Counter = { DataSource = SyncDB Type = uint32 Samples = 1 }
|
||||||
DataSource = TimerSlow
|
|
||||||
Frequency = 1
|
|
||||||
}
|
|
||||||
Time = {
|
|
||||||
DataSource = TimerSlow
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
OutputSignals = {
|
OutputSignals = {
|
||||||
Counter = {
|
Counter = { DataSource = Logger Type = uint32 }
|
||||||
Type = uint32
|
|
||||||
DataSource = Logger
|
|
||||||
}
|
}
|
||||||
Time = {
|
|
||||||
Type = uint32
|
|
||||||
DataSource = Logger
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+GAM3 = {
|
|
||||||
Class = IOGAM
|
|
||||||
InputSignals = {
|
|
||||||
Counter = {
|
|
||||||
Frequency = 1
|
|
||||||
Samples = 100
|
|
||||||
Type = uint32
|
|
||||||
DataSource = SyncDB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OutputSignals = {
|
|
||||||
Counter = {
|
|
||||||
DataSource = DDB3
|
|
||||||
NumberOfElements = 100
|
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+Data = {
|
+Data = {
|
||||||
@@ -75,57 +30,31 @@
|
|||||||
Class = RealTimeThreadSynchronisation
|
Class = RealTimeThreadSynchronisation
|
||||||
Timeout = 200
|
Timeout = 200
|
||||||
Signals = {
|
Signals = {
|
||||||
Counter = {
|
Counter = { Type = uint32 }
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+Timer = {
|
+Timer = {
|
||||||
Class = LinuxTimer
|
Class = LinuxTimer
|
||||||
|
SleepTime = 1000
|
||||||
Signals = {
|
Signals = {
|
||||||
Counter = {
|
Counter = { Type = uint32 }
|
||||||
Type = uint32
|
Time = { Type = uint32 }
|
||||||
}
|
|
||||||
Time = {
|
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+TimerSlow = {
|
|
||||||
Class = LinuxTimer
|
|
||||||
Signals = {
|
|
||||||
Counter = {
|
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
Time = {
|
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+Logger = {
|
+Logger = {
|
||||||
Class = LoggerDataSource
|
Class = LoggerDataSource
|
||||||
Signals = {
|
Signals = {
|
||||||
CounterCopy = {
|
CounterCopy = { Type = uint32 }
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
TimeCopy = {
|
|
||||||
Type = uint32
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+DDB = {
|
+DDB = {
|
||||||
AllowNoProducer = 1
|
AllowNoProducer = 1
|
||||||
Class = GAMDataSource
|
Class = GAMDataSource
|
||||||
Signals = {
|
Signals = {
|
||||||
Counter= {
|
Counter = { Type = uint32 }
|
||||||
Type = uint32
|
Time = { Type = uint32 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
+DDB3 = {
|
|
||||||
AllowNoProducer = 1
|
|
||||||
Class = GAMDataSource
|
|
||||||
}
|
|
||||||
+DAMS = {
|
+DAMS = {
|
||||||
Class = TimingDataSource
|
Class = TimingDataSource
|
||||||
}
|
}
|
||||||
@@ -144,10 +73,6 @@
|
|||||||
Class = RealTimeThread
|
Class = RealTimeThread
|
||||||
Functions = {GAM2}
|
Functions = {GAM2}
|
||||||
}
|
}
|
||||||
+Thread3 = {
|
|
||||||
Class = RealTimeThread
|
|
||||||
Functions = {GAM3}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,11 @@ 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
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ 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
|
||||||
|
|
||||||
|
|||||||
+480
-1367
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,226 @@
|
|||||||
|
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,
|
||||||
|
}
|
||||||
@@ -0,0 +1,498 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-293
@@ -51,6 +51,7 @@
|
|||||||
"-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",
|
||||||
@@ -59,6 +60,7 @@
|
|||||||
"-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",
|
||||||
@@ -66,6 +68,7 @@
|
|||||||
"-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",
|
||||||
@@ -89,298 +92,5 @@
|
|||||||
],
|
],
|
||||||
"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,11 +6,12 @@ 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
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/Components
|
||||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DIR/Build/$TARGET/Components/Interfaces/DebugService
|
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/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)"
|
||||||
|
|||||||
Reference in New Issue
Block a user