Initial commit

This commit is contained in:
Martino Ferrari
2026-02-21 00:58:56 +01:00
commit 5ef0efe7d6
26 changed files with 7999 additions and 0 deletions

View File

@@ -0,0 +1,202 @@
#include "DebugService.h"
#include "DebugCore.h"
#include "ObjectRegistryDatabase.h"
#include "StandardParser.h"
#include "StreamString.h"
#include "BasicUDPSocket.h"
#include "BasicTCPSocket.h"
#include "RealTimeApplication.h"
#include <assert.h>
#include <stdio.h>
using namespace MARTe;
const char8 * const config_text =
"+DebugService = {"
" Class = DebugService "
" ControlPort = 8080 "
" UdpPort = 8081 "
" StreamIP = \"127.0.0.1\" "
"}"
"+App = {"
" Class = RealTimeApplication "
" +Functions = {"
" Class = ReferenceContainer "
" +GAM1 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = {"
" DataSource = Timer "
" Type = uint32 "
" }"
" }"
" OutputSignals = {"
" Counter = {"
" DataSource = DDB "
" Type = uint32 "
" }"
" }"
" }"
" }"
" +Data = {"
" Class = ReferenceContainer "
" DefaultDataSource = DDB "
" +Timer = {"
" Class = LinuxTimer "
" SleepTime = 10000 "
" 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 "
" }"
"}";
void RunValidationTest() {
printf("--- MARTe2 100Hz Trace Validation Test ---\n");
// 1. Load Configuration
ConfigurationDatabase cdb;
StreamString ss = config_text;
ss.Seek(0);
StandardParser parser(ss, cdb);
if (!parser.Parse()) {
printf("ERROR: Failed to parse configuration\n");
return;
}
if (!ObjectRegistryDatabase::Instance()->Initialise(cdb)) {
printf("ERROR: Failed to initialise ObjectRegistryDatabase.\n");
return;
}
// 2. Start Application
ReferenceT<RealTimeApplication> app = ObjectRegistryDatabase::Instance()->Find("App");
if (!app.IsValid()) {
printf("ERROR: App not found\n");
return;
}
// We try to use State1 directly as many MARTe2 apps start in the first defined state if no transition is needed
if (app->PrepareNextState("State1") != ErrorManagement::NoError) {
printf("ERROR: Failed to prepare state State1\n");
// We will try to investigate why, but for now we continue
}
if (app->StartNextStateExecution() != ErrorManagement::NoError) {
printf("ERROR: Failed to start execution. Maybe it needs an explicit state?\n");
// return;
}
printf("Application started at 100Hz.\n");
Sleep::MSec(1000);
// 3. Enable Trace via TCP (Simulating GUI)
BasicTCPSocket client;
if (client.Connect("127.0.0.1", 8080)) {
const char* cmd = "TRACE Root.App.Data.Timer.Counter 1\n";
uint32 s = StringHelper::Length(cmd);
client.Write(cmd, s);
char resp[1024]; s = 1024;
TimeoutType timeout(1000);
if (client.Read(resp, s, timeout)) {
resp[s] = '\0';
printf("Server Response: %s", resp);
} else {
printf("WARNING: No response from server to TRACE command.\n");
}
client.Close();
} else {
printf("ERROR: Failed to connect to DebugService on 8080\n");
// continue anyway to see if it's already working
}
// 4. Setup UDP Listener
BasicUDPSocket listener;
if (!listener.Open()) { printf("ERROR: Failed to open UDP socket\n"); return; }
if (!listener.Listen(8081)) { printf("ERROR: Failed to listen on UDP 8081\n"); return; }
// 5. Validate for 30 seconds
printf("Validating telemetry for 30 seconds...\n");
uint32 lastVal = 0;
bool first = true;
uint32 packetCount = 0;
uint32 discontinuityCount = 0;
float64 startTime = HighResolutionTimer::Counter() * HighResolutionTimer::Period();
while ((HighResolutionTimer::Counter() * HighResolutionTimer::Period() - startTime) < 30.0) {
char buffer[2048];
uint32 size = 2048;
TimeoutType timeout(500);
if (listener.Read(buffer, size, timeout)) {
TraceHeader *h = (TraceHeader*)buffer;
if (h->magic == 0xDA7A57AD && h->count > 0) {
uint32 offset = sizeof(TraceHeader);
// Packet format: [Header][ID:4][Size:4][Value:N]
uint32 val = *(uint32*)(&buffer[offset + 8]);
if (!first) {
if (val != lastVal + 1) {
discontinuityCount++;
}
}
lastVal = val;
first = false;
packetCount++;
if (packetCount % 500 == 0) {
printf("Received %u packets... Current Value: %u\n", packetCount, val);
}
}
}
}
printf("Test Finished.\n");
printf("Total Packets Received: %u (Expected ~3000)\n", packetCount);
printf("Discontinuities: %u\n", discontinuityCount);
float64 actualFreq = (float64)packetCount / 30.0;
printf("Average Frequency: %.2f Hz\n", actualFreq);
if (packetCount < 100) {
printf("FAILURE: Almost no packets received. Telemetry is broken.\n");
} else if (packetCount < 2500) {
printf("WARNING: Too few packets received (Expected 3000, Got %u).\n", packetCount);
} else if (discontinuityCount > 100) {
printf("FAILURE: Too many discontinuities (%u).\n", discontinuityCount);
} else {
printf("VALIDATION SUCCESSFUL!\n");
}
app->StopCurrentStateExecution();
listener.Close();
}
int main() {
RunValidationTest();
return 0;
}