4 Commits

Author SHA1 Message Date
Martino Ferrari e2f47d7410 Working on experimental features 2026-03-24 21:16:24 +01:00
Martino Ferrari 7adbecdb6e Added custom Message functionality 2026-03-04 10:08:43 +01:00
Martino Ferrari d3077e78ec implemented array support on client and server 2026-03-03 21:58:32 +01:00
Martino Ferrari a941563749 Improved overall features 2026-03-03 21:41:59 +01:00
20 changed files with 2723 additions and 1841 deletions
@@ -1,9 +1,11 @@
#ifndef DEBUGBROKERWRAPPER_H
#define DEBUGBROKERWRAPPER_H
#include "AdvancedErrorManagement.h"
#include "BrokerI.h"
#include "DataSourceI.h"
#include "DebugService.h"
#include "ErrorType.h"
#include "FastPollingMutexSem.h"
#include "HighResolutionTimer.h"
#include "MemoryMapBroker.h"
@@ -23,6 +25,7 @@
#include "MemoryMapSynchronisedMultiBufferInputBroker.h"
#include "MemoryMapSynchronisedMultiBufferOutputBroker.h"
#include "MemoryMapSynchronisedOutputBroker.h"
#include "RealTimeThreadSynchBroker.h"
namespace MARTe {
@@ -86,12 +89,11 @@ public:
StreamString 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);
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++) {
@@ -106,13 +108,18 @@ public:
StreamString signalName;
if (!dataSourceIn.GetSignalName(dsIdx, signalName))
signalName = "Unknown";
fprintf(stderr, ">> registering %s.%s [%p]\n", dsPath.Buffer(),
signalName.Buffer(), mmb);
REPORT_ERROR_STATIC(ErrorManagement::Debug, "Registering %s.%s [%p]\n",
dsPath.Buffer(), signalName.Buffer(), mmb);
uint8 dims = 0;
uint32 elems = 1;
(void)dataSourceIn.GetSignalNumberOfDimensions(dsIdx, dims);
(void)dataSourceIn.GetSignalNumberOfElements(dsIdx, elems);
// Register canonical name
StreamString dsFullName;
dsFullName.Printf("%s.%s", dsPath.Buffer(), signalName.Buffer());
service->RegisterSignal(addr, type, dsFullName.Buffer());
service->RegisterSignal(addr, type, dsFullName.Buffer(), dims, elems);
// Register alias
if (functionName != NULL_PTR(const char8 *)) {
@@ -140,29 +147,21 @@ public:
if (gamRef.IsValid()) {
StreamString absGamPath;
DebugService::GetFullObjectName(*(gamRef.operator->()), absGamPath);
// Register full path (InputSignals/OutputSignals)
// gamFullName.fPrintf(stderr, "%s.%s.%s", absGamPath.Buffer(),
// dirStr, signalName.Buffer()); signalInfoPointers[i] =
// service->RegisterSignal(addr, type, gamFullName.Buffer()); Also
// register short path (In/Out) for GUI compatibility
// Register short path (In/Out) for GUI compatibility
gamFullName.Printf("%s.%s.%s", absGamPath.Buffer(), dirStrShort,
signalName.Buffer());
signalInfoPointers[i] =
service->RegisterSignal(addr, type, gamFullName.Buffer());
signalInfoPointers[i] = service->RegisterSignal(
addr, type, gamFullName.Buffer(), dims, elems);
} else {
// Fallback to short name
// gamFullName.fPrintf(stderr, "%s.%s.%s", functionName, dirStr,
// signalName.Buffer()); signalInfoPointers[i] =
// service->RegisterSignal(addr, type, gamFullName.Buffer()); Also
// register short form
// Fallback to short form
gamFullName.Printf("%s.%s.%s", functionName, dirStrShort,
signalName.Buffer());
signalInfoPointers[i] =
service->RegisterSignal(addr, type, gamFullName.Buffer());
signalInfoPointers[i] = service->RegisterSignal(
addr, type, gamFullName.Buffer(), dims, elems);
}
} else {
signalInfoPointers[i] =
service->RegisterSignal(addr, type, dsFullName.Buffer());
signalInfoPointers[i] = service->RegisterSignal(
addr, type, dsFullName.Buffer(), dims, elems);
}
}
@@ -202,8 +201,8 @@ public:
virtual bool Init(SignalDirection direction, DataSourceI &ds,
const char8 *const name, void *gamMem) {
bool ret = BaseClass::Init(direction, ds, name, gamMem);
fprintf(stderr, ">> INIT BROKER %s %s\n", name,
direction == InputSignals ? "In" : "Out");
REPORT_ERROR_STATIC(ErrorManagement::Debug, "INIT BROKER %s %s\n", name,
direction == InputSignals ? "In" : "Out");
if (ret) {
numSignals = this->GetNumberOfCopies();
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
@@ -217,8 +216,8 @@ public:
virtual bool Init(SignalDirection direction, DataSourceI &ds,
const char8 *const name, void *gamMem, const bool optim) {
bool ret = BaseClass::Init(direction, ds, name, gamMem, false);
fprintf(stderr, ">> INIT optimized BROKER %s %s\n", name,
direction == InputSignals ? "In" : "Out");
REPORT_ERROR_STATIC(ErrorManagement::Debug, "INIT optimized BROKER %s %s\n",
name, direction == InputSignals ? "In" : "Out");
if (ret) {
numSignals = this->GetNumberOfCopies();
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers,
@@ -406,6 +405,55 @@ typedef DebugBrokerWrapper<MemoryMapSynchronisedMultiBufferOutputBroker>
DebugMemoryMapSynchronisedMultiBufferOutputBroker;
// 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>
DebugMemoryMapInputBrokerBuilder;
// LCOV_EXCL_START
@@ -429,6 +477,8 @@ typedef DebugBrokerBuilder<DebugMemoryMapAsyncOutputBroker>
DebugMemoryMapAsyncOutputBrokerBuilder;
typedef DebugBrokerBuilder<DebugMemoryMapAsyncTriggerOutputBroker>
DebugMemoryMapAsyncTriggerOutputBrokerBuilder;
typedef DebugBrokerBuilder<DebugRealTimeThreadSyncBroker>
DebugRealTimeThreadSyncBrokerBuilder;
// LCOV_EXCL_STOP
} // namespace MARTe
@@ -12,6 +12,8 @@ struct DebugSignalInfo {
void* memoryAddress;
TypeDescriptor type;
StreamString name;
uint8 numberOfDimensions;
uint32 numberOfElements;
volatile bool isTracing;
volatile bool isForcing;
uint8 forcedValue[1024];
File diff suppressed because it is too large Load Diff
@@ -16,6 +16,7 @@
namespace MARTe {
class MemoryMapBroker;
class DataSourceI;
struct SignalAlias {
StreamString name;
@@ -45,7 +46,9 @@ public:
virtual bool Initialise(StructuredDataI &data);
DebugSignalInfo *RegisterSignal(void *memoryAddress, TypeDescriptor type,
const char8 *name);
const char8 *name,
uint8 numberOfDimensions = 0,
uint32 numberOfElements = 1);
void ProcessSignal(DebugSignalInfo *signalInfo, uint32 size,
uint64 timestamp);
@@ -56,6 +59,8 @@ public:
virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info);
virtual ErrorManagement::ErrorType HandleMessage(ReferenceT<Message> &data);
bool IsPaused() const { return isPaused; }
void SetPaused(bool paused) { isPaused = paused; }
@@ -64,27 +69,51 @@ public:
uint32 ForceSignal(const char8 *name, const char8 *valueStr);
uint32 UnforceSignal(const char8 *name);
uint32 TraceSignal(const char8 *name, bool enable, uint32 decimation = 1);
bool IsInstrumented(const char8 *fullPath, bool &traceable, bool &forcable);
void Discover(BasicTCPSocket *client);
void InfoNode(const char8 *path, BasicTCPSocket *client);
void ListNodes(const char8 *path, BasicTCPSocket *client);
void ServeConfig(BasicTCPSocket *client);
void SetFullConfig(ConfigurationDatabase &config);
struct MonitoredSignal {
ReferenceT<DataSourceI> dataSource;
uint32 signalIdx;
uint32 internalID;
uint32 periodMs;
uint64 lastPollTime;
uint32 size;
StreamString path;
};
struct MonitoredState {
Reference obj;
uint32 internalID;
StreamString path;
StreamString lastState;
};
uint32 RegisterMonitorSignal(const char8 *path, uint32 periodMs);
uint32 UnmonitorSignal(const char8 *path);
private:
void HandleCommand(StreamString cmd, BasicTCPSocket *client);
void UpdateBrokersActiveStatus();
uint32 ExportTree(ReferenceContainer *container, StreamString &json);
uint32 ExportTree(ReferenceContainer *container, StreamString &json,
const char8 *pathPrefix);
void PatchRegistry();
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 Streamer(ExecutionInfo &info);
uint16 controlPort;
uint16 streamPort;
uint16 logPort;
StreamString streamIP;
bool isServer;
bool suppressTimeoutLogs;
@@ -123,6 +152,8 @@ private:
Vec<DebugSignalInfo *> signals;
Vec<SignalAlias> aliases;
Vec<BrokerInfo> brokers;
Vec<MonitoredSignal> monitoredSignals;
Vec<MonitoredState> monitoredStates;
FastPollingMutexSem mutex;
TraceRingBuffer traceBuffer;
@@ -33,6 +33,7 @@ include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)
INCLUDES += -I$(ROOT_DIR)/Source/Core/Types/Result
INCLUDES += -I$(ROOT_DIR)/Source/Core/Types/Vec
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/TCPLogger
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L0Types
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L2Objects
@@ -41,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/L4Configuration
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/L3Services
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
@@ -48,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/FileSystem/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/DataSources/RealTimeThreadSynchronisation
all: $(OBJS) $(SUBPROJ) \
$(BUILD_DIR)/DebugService$(LIBEXT) \
+18 -56
View File
@@ -5,93 +5,54 @@
+GAM1 = {
Class = IOGAM
InputSignals = {
Counter = {
DataSource = Timer
Type = uint32
Frequency = 1000
}
Time = {
DataSource = Timer
Type = uint32
}
Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }
Time = { DataSource = Timer Type = uint32 }
}
OutputSignals = {
Counter = {
DataSource = DDB
Type = uint32
}
Time = {
DataSource = DDB
Type = uint32
}
Counter = { DataSource = SyncDB Type = uint32 }
Time = { DataSource = DDB Type = uint32 }
}
}
+GAM2 = {
Class = IOGAM
InputSignals = {
Counter = {
DataSource = TimerSlow
Frequency = 1
}
Time = {
DataSource = TimerSlow
}
Counter = { DataSource = SyncDB Type = uint32 Samples = 1 }
}
OutputSignals = {
Counter = {
Type = uint32
DataSource = Logger
}
Time = {
Type = uint32
DataSource = Logger
}
Counter = { DataSource = Logger Type = uint32 }
}
}
}
+Data = {
Class = ReferenceContainer
DefaultDataSource = DDB
+Timer = {
Class = LinuxTimer
+SyncDB = {
Class = RealTimeThreadSynchronisation
Timeout = 200
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
}
Counter = { Type = uint32 }
}
}
+TimerSlow = {
+Timer = {
Class = LinuxTimer
SleepTime = 1000
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
}
Counter = { Type = uint32 }
Time = { Type = uint32 }
}
}
+Logger = {
Class = LoggerDataSource
Signals = {
CounterCopy = {
Type = uint32
}
TimeCopy = {
Type = uint32
}
CounterCopy = { Type = uint32 }
}
}
+DDB = {
AllowNoProducer = 1
Class = GAMDataSource
Signals = {
Counter= {
Type = uint32
}
Counter = { Type = uint32 }
Time = { Type = uint32 }
}
}
+DAMS = {
@@ -125,6 +86,7 @@
Class = DebugService
ControlPort = 8080
UdpPort = 8081
LogPort = 8082
StreamIP = "127.0.0.1"
}
+9 -71
View File
@@ -7,8 +7,7 @@
#include "BasicUDPSocket.h"
#include "RealTimeApplication.h"
#include "StandardParser.h"
#include "StreamString.h"
#include "GlobalObjectsDatabase.h"
#include "TestCommon.h"
#include <stdio.h>
using namespace MARTe;
@@ -31,6 +30,7 @@ void TestFullTracePipeline();
void RunValidationTest();
void TestConfigCommands();
void TestGAMSignalTracing();
void TestTreeCommand();
int main() {
signal(SIGALRM, timeout_handler);
@@ -83,9 +83,13 @@ int main() {
// TestConfigCommands(); // Skipping for now
Sleep::MSec(1000);
// printf("\n--- Test 6: GAM Signal Tracing ---\n");
// TestGAMSignalTracing();
// Sleep::MSec(1000);
printf("\n--- Test 6: TREE Command Enhancement ---\n");
TestTreeCommand();
Sleep::MSec(1000);
printf("\n--- Test 7: Custom MARTe Message (MSG) ---\n");
TestMessageCommand();
Sleep::MSec(1000);
printf("\nAll Integration Tests Finished.\n");
@@ -94,72 +98,6 @@ int main() {
// --- Test Implementation ---
const char8 * const debug_test_config =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8095 "
" UdpPort = 8096 "
" StreamIP = \"127.0.0.1\" "
"}"
"App = {"
" Class = RealTimeApplication "
" +Functions = {"
" Class = ReferenceContainer "
" +GAM1 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = DDB Type = uint32 }"
" }"
" }"
" +GAM2 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = TimerSlow Type = uint32 Frequency = 10 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = Logger Type = uint32 }"
" }"
" }"
" }"
" +Data = {"
" Class = ReferenceContainer "
" DefaultDataSource = DDB "
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } } }"
" +TimerSlow = { Class = LinuxTimer SleepTime = 100000 Signals = { Counter = { Type = uint32 } } }"
" +Logger = { Class = LoggerDataSource Signals = { Counter = { Type = uint32 } } }"
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } } }"
" +DAMS = { Class = TimingDataSource }"
" }"
" +States = {"
" Class = ReferenceContainer "
" +State1 = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread Functions = {GAM1 GAM2} } } }"
" }"
" +Scheduler = { Class = GAMScheduler TimingDataSource = DAMS }"
"}";
bool SendCommandGAM(uint16 port, const char8* cmd, StreamString &reply) {
BasicTCPSocket client;
if (!client.Open()) return false;
if (!client.Connect("127.0.0.1", port)) return false;
uint32 s = StringHelper::Length(cmd);
if (!client.Write(cmd, s)) return false;
char buffer[4096];
uint32 size = 4096;
TimeoutType timeout(2000);
if (client.Read(buffer, size, timeout)) {
reply.Write(buffer, size);
client.Close();
return true;
}
client.Close();
return false;
}
void TestGAMSignalTracing() {
printf("--- Test: GAM Signal Tracing Issue ---\n");
+5 -1
View File
@@ -1,4 +1,4 @@
OBJSX = SchedulerTest.x TraceTest.x ValidationTest.x ConfigCommandTest.x
OBJSX = SchedulerTest.x TraceTest.x ValidationTest.x ConfigCommandTest.x TreeCommandTest.x MessageCommandTest.x TestCommon.x
PACKAGE = Test/Integration
@@ -29,9 +29,13 @@ INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4LoggerService
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
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/RealTimeThreadSynchronisation
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/RealTimeThreadSynchronisation -lRealTimeThreadSynchronisation
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/TCPLogger -lTcpLogger
+72
View File
@@ -0,0 +1,72 @@
#include "TestCommon.h"
#include "ObjectRegistryDatabase.h"
#include "DebugService.h"
#include "StandardParser.h"
#include "GlobalObjectsDatabase.h"
#include <stdio.h>
using namespace MARTe;
namespace MARTe {
void TestMessageCommand() {
printf("--- Test: Custom MARTe Message (MSG) ---\n");
ObjectRegistryDatabase::Instance()->Purge();
Sleep::MSec(1000);
ConfigurationDatabase cdb;
const char8 * const msg_test_config =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8120 "
" UdpPort = 8121 "
" StreamIP = \"127.0.0.1\" "
"}";
StreamString ss = msg_test_config;
ss.Seek(0);
StandardParser parser(ss, cdb);
if (!parser.Parse()) {
printf("ERROR: Failed to parse config\n");
return;
}
// Initialize Service
ReferenceT<DebugService> service("DebugService", GlobalObjectsDatabase::Instance()->GetStandardHeap());
service->SetName("DebugService");
cdb.MoveToRoot();
if (cdb.MoveRelative("DebugService")) {
if (!service->Initialise(cdb)) {
printf("ERROR: Failed to initialize DebugService\n");
return;
}
}
ObjectRegistryDatabase::Instance()->Insert(service);
if (ObjectRegistryDatabase::Instance()->Find("DebugService").IsValid()) {
printf("DebugService successfully registered in ORD.\n");
} else {
printf("ERROR: DebugService NOT found in ORD.\n");
}
printf("Service initialized on port 8120.\n");
Sleep::MSec(500);
StreamString reply;
if (SendCommandGAM(8120, "MSG DebugService UnknownFunc 0 Key1=Val1\\nKey2=Val2\n", reply)) {
printf("MSG response received: %s", reply.Buffer());
if (StringHelper::SearchString(reply.Buffer(), "OK MSG") != NULL_PTR(const char8 *)) {
printf("SUCCESS: Asynchronous message dispatched correctly.\n");
} else {
printf("FAILURE: MSG command returned error.\n");
}
} else {
printf("ERROR: MSG command communication failed\n");
}
ObjectRegistryDatabase::Instance()->Purge();
}
} // namespace MARTe
+74
View File
@@ -0,0 +1,74 @@
#include "TestCommon.h"
#include "BasicTCPSocket.h"
#include "StringHelper.h"
#include "TimeoutType.h"
namespace MARTe {
const char8 * const debug_test_config =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8095 "
" UdpPort = 8096 "
" StreamIP = \"127.0.0.1\" "
"}"
"App = {"
" Class = RealTimeApplication "
" +Functions = {"
" Class = ReferenceContainer "
" +GAM1 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = DDB Type = uint32 }"
" }"
" }"
" +GAM2 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = TimerSlow Type = uint32 Frequency = 10 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = Logger Type = uint32 }"
" }"
" }"
" }"
" +Data = {"
" Class = ReferenceContainer "
" DefaultDataSource = DDB "
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } } }"
" +TimerSlow = { Class = LinuxTimer SleepTime = 100000 Signals = { Counter = { Type = uint32 } } }"
" +Logger = { Class = LoggerDataSource Signals = { Counter = { Type = uint32 } } }"
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } } }"
" +DAMS = { Class = TimingDataSource }"
" }"
" +States = {"
" Class = ReferenceContainer "
" +State1 = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread Functions = {GAM1 GAM2} } } }"
" }"
" +Scheduler = { Class = GAMScheduler TimingDataSource = DAMS }"
"}";
bool SendCommandGAM(uint16 port, const char8* cmd, StreamString &reply) {
BasicTCPSocket client;
if (!client.Open()) return false;
if (!client.Connect("127.0.0.1", port)) return false;
uint32 s = StringHelper::Length(cmd);
if (!client.Write(cmd, s)) return false;
char buffer[16384];
uint32 size = 16384;
TimeoutType timeout(5000);
if (client.Read(buffer, size, timeout)) {
reply.Write(buffer, size);
client.Close();
return true;
}
client.Close();
return false;
}
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef TESTCOMMON_H
#define TESTCOMMON_H
#include "CompilerTypes.h"
#include "StreamString.h"
namespace MARTe {
extern const char8 * const debug_test_config;
bool SendCommandGAM(uint16 port, const char8* cmd, StreamString &reply);
void TestMessageCommand();
}
#endif
+1 -1
View File
@@ -27,7 +27,7 @@ void TestFullTracePipeline() {
// 2. Register a mock signal
uint32 mockValue = 0;
DebugSignalInfo* sig = service.RegisterSignal(&mockValue, UnsignedInteger32Bit, "TraceTest.Signal");
DebugSignalInfo* sig = service.RegisterSignal(&mockValue, UnsignedInteger32Bit, "TraceTest.Signal", 0, 1);
assert(sig != NULL_PTR(DebugSignalInfo*));
printf("Signal registered with ID: %u\n", sig->internalID);
+176
View File
@@ -0,0 +1,176 @@
#include "BasicTCPSocket.h"
#include "ConfigurationDatabase.h"
#include "DebugService.h"
#include "GlobalObjectsDatabase.h"
#include "ObjectRegistryDatabase.h"
#include "RealTimeApplication.h"
#include "StandardParser.h"
#include "StreamString.h"
#include "TestCommon.h"
#include "IOGAM.h"
#include "LinuxTimer.h"
#include "GAMDataSource.h"
#include "TimingDataSource.h"
#include "GAMScheduler.h"
#include <stdio.h>
using namespace MARTe;
void TestTreeCommand() {
printf("--- Test: TREE Command Enhancement ---\n");
ObjectRegistryDatabase::Instance()->Purge();
Sleep::MSec(2000); // Wait for sockets from previous tests to clear
ConfigurationDatabase cdb;
// Use unique ports to avoid conflict with other tests
const char8 * const tree_test_config =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8110 "
" UdpPort = 8111 "
" StreamIP = \"127.0.0.1\" "
"}"
"App = {"
" Class = RealTimeApplication "
" +Functions = {"
" Class = ReferenceContainer "
" +GAM1 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = DDB Type = uint32 }"
" }"
" }"
" }"
" +Data = {"
" Class = ReferenceContainer "
" DefaultDataSource = DDB "
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } } }"
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } } }"
" +DAMS = { Class = TimingDataSource }"
" }"
" +States = {"
" Class = ReferenceContainer "
" +State1 = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread Functions = {GAM1} } } }"
" }"
" +Scheduler = { Class = GAMScheduler TimingDataSource = DAMS }"
"}";
StreamString ss = tree_test_config;
ss.Seek(0);
StandardParser parser(ss, cdb);
if (!parser.Parse()) {
printf("ERROR: Failed to parse config\n");
return;
}
cdb.MoveToRoot();
uint32 n = cdb.GetNumberOfChildren();
for (uint32 i = 0; i < n; i++) {
const char8 *name = cdb.GetChildName(i);
ConfigurationDatabase child;
cdb.MoveRelative(name);
cdb.Copy(child);
cdb.MoveToAncestor(1u);
StreamString className;
child.Read("Class", className);
Reference ref(className.Buffer(),
GlobalObjectsDatabase::Instance()->GetStandardHeap());
if (!ref.IsValid()) {
printf("ERROR: Could not create object %s of class %s\n", name,
className.Buffer());
continue;
}
ref->SetName(name);
if (!ref->Initialise(child)) {
printf("ERROR: Failed to initialise object %s\n", name);
continue;
}
ObjectRegistryDatabase::Instance()->Insert(ref);
}
ReferenceT<DebugService> service =
ObjectRegistryDatabase::Instance()->Find("DebugService");
if (!service.IsValid()) {
printf("ERROR: DebugService not found\n");
return;
}
service->SetFullConfig(cdb);
ReferenceT<RealTimeApplication> app =
ObjectRegistryDatabase::Instance()->Find("App");
if (!app.IsValid()) {
printf("ERROR: App not found\n");
return;
}
if (!app->ConfigureApplication()) {
printf("ERROR: ConfigureApplication failed.\n");
return;
}
if (app->PrepareNextState("State1") != ErrorManagement::NoError) {
printf("ERROR: PrepareNextState failed.\n");
return;
}
if (app->StartNextStateExecution() != ErrorManagement::NoError) {
printf("ERROR: StartNextStateExecution failed.\n");
return;
}
printf("Application started.\n");
Sleep::MSec(1000);
// Step 1: Request TREE
StreamString reply;
if (SendCommandGAM(8110, "TREE\n", reply)) {
printf("TREE response received (len=%llu)\n", reply.Size());
// ...
}
// Step 2: SERVICE_INFO
printf("\n--- Step 2: SERVICE_INFO ---\n");
reply = "";
if (SendCommandGAM(8110, "SERVICE_INFO\n", reply)) {
printf("SERVICE_INFO response: %s", reply.Buffer());
if (StringHelper::SearchString(reply.Buffer(), "TCP_CTRL:8110") != NULL_PTR(const char8 *) &&
StringHelper::SearchString(reply.Buffer(), "UDP_STREAM:8111") != NULL_PTR(const char8 *)) {
printf("SUCCESS: SERVICE_INFO returned correct ports.\n");
} else {
printf("FAILURE: SERVICE_INFO returned incorrect data.\n");
}
}
// Step 3: MONITOR
printf("\n--- Step 3: MONITOR SIGNAL ---\n");
reply = "";
if (SendCommandGAM(8110, "MONITOR SIGNAL App.Data.Timer.Counter 10\n", reply)) {
printf("MONITOR response: %s", reply.Buffer());
if (StringHelper::SearchString(reply.Buffer(), "OK MONITOR 1") != NULL_PTR(const char8 *)) {
printf("SUCCESS: Signal monitored.\n");
} else {
printf("FAILURE: Could not monitor signal.\n");
}
}
// Step 4: UNMONITOR
printf("\n--- Step 4: UNMONITOR SIGNAL ---\n");
reply = "";
if (SendCommandGAM(8110, "UNMONITOR SIGNAL App.Data.Timer.Counter\n", reply)) {
printf("UNMONITOR response: %s", reply.Buffer());
if (StringHelper::SearchString(reply.Buffer(), "OK UNMONITOR 1") != NULL_PTR(const char8 *)) {
printf("SUCCESS: Signal unmonitored.\n");
} else {
printf("FAILURE: Could not unmonitor signal.\n");
}
}
app->StopCurrentStateExecution();
ObjectRegistryDatabase::Instance()->Purge();
}
+2
View File
@@ -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/FileSystem/L1Portability
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_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/TCPLogger -lTcpLogger
+2 -1
View File
@@ -38,7 +38,7 @@ public:
// 1. Signal logic
uint32 val = 0;
service.RegisterSignal(&val, UnsignedInteger32Bit, "X.Y.Z");
service.RegisterSignal(&val, UnsignedInteger32Bit, "X.Y.Z", 0, 1);
assert(service.TraceSignal("Z", true) == 1);
assert(service.ForceSignal("Z", "123") == 1);
@@ -55,6 +55,7 @@ public:
service.HandleCommand("RESUME", NULL_PTR(BasicTCPSocket*));
service.HandleCommand("LS /", NULL_PTR(BasicTCPSocket*));
service.HandleCommand("INFO X.Y.Z", NULL_PTR(BasicTCPSocket*));
service.HandleCommand("MSG DebugService DummyFunc 0 K=V", NULL_PTR(BasicTCPSocket*));
// 3. Broker Active Status
volatile bool active = false;
+672 -1273
View File
File diff suppressed because it is too large Load Diff
+226
View File
@@ -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,
}
+498
View File
@@ -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(&current_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(&current_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
View File
@@ -51,6 +51,7 @@
"-c",
"-I../../../..//Source/Core/Types/Result",
"-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/L1Portability",
"-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/L4Configuration",
"-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/L3Services",
"-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/FileSystem/L1Portability",
"-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",
"-Wall",
"-std=c++98",
@@ -89,298 +92,5 @@
],
"directory": "/home/martino/Projects/marte_debug/Source/Components/Interfaces/DebugService",
"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"
}
]
+4 -3
View File
@@ -6,11 +6,12 @@ export MARTe2_DIR=$DIR/dependency/MARTe2
export MARTe2_Components_DIR=$DIR/dependency/MARTe2-components
export TARGET=x86-linux
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:$DIR/Build/$TARGET/Components/Interfaces/DebugService
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DIR/Build/$TARGET/Components/Interfaces/TCPLogger
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/Components
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/$TARGET/Components/DataSources/RealTimeThreadSynchronisation
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/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 Components Environment Set (MARTe2_Components_DIR=$MARTe2_Components_DIR)"