212 lines
6.4 KiB
C++
212 lines
6.4 KiB
C++
#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 "GlobalObjectsDatabase.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 "
|
|
" Frequency = 100 "
|
|
" }"
|
|
" }"
|
|
" OutputSignals = {"
|
|
" Counter = {"
|
|
" DataSource = DDB "
|
|
" Type = uint32 "
|
|
" }"
|
|
" }"
|
|
" }"
|
|
" }"
|
|
" +Data = {"
|
|
" Class = ReferenceContainer "
|
|
" DefaultDataSource = DDB "
|
|
" +Timer = {"
|
|
" Class = LinuxTimer "
|
|
" SleepTime = 10000 "
|
|
" Signals = {"
|
|
" Counter = { Type = uint32 }"
|
|
" Time = { 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");
|
|
|
|
ObjectRegistryDatabase::Instance()->Purge();
|
|
|
|
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;
|
|
}
|
|
|
|
ReferenceT<DebugService> service = ObjectRegistryDatabase::Instance()->Find("DebugService");
|
|
if (!service.IsValid()) {
|
|
printf("ERROR: DebugService not found\n");
|
|
return;
|
|
}
|
|
|
|
ReferenceT<RealTimeApplication> app = ObjectRegistryDatabase::Instance()->Find("App");
|
|
if (!app.IsValid()) {
|
|
printf("ERROR: App not found\n");
|
|
return;
|
|
}
|
|
|
|
if (!app->ConfigureApplication()) {
|
|
printf("ERROR: Failed to configure application\n");
|
|
return;
|
|
}
|
|
|
|
if (app->PrepareNextState("State1") != ErrorManagement::NoError) {
|
|
printf("ERROR: Failed to prepare state State1\n");
|
|
return;
|
|
}
|
|
|
|
if (app->StartNextStateExecution() != ErrorManagement::NoError) {
|
|
printf("ERROR: Failed to start execution\n");
|
|
return;
|
|
}
|
|
|
|
printf("Application and DebugService are active.\n");
|
|
Sleep::MSec(1000);
|
|
|
|
// DIRECT ACTIVATION: Use the public TraceSignal method
|
|
printf("Activating trace directly...\n");
|
|
// We try multiple potential paths to be safe
|
|
uint32 traceCount = 0;
|
|
traceCount += service->TraceSignal("App.Data.Timer.Counter", true, 1);
|
|
traceCount += service->TraceSignal("Timer.Counter", true, 1);
|
|
traceCount += service->TraceSignal("Counter", true, 1);
|
|
|
|
printf("Trace enabled (Matched Aliases: %u)\n", traceCount);
|
|
|
|
// 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 10 seconds
|
|
printf("Validating telemetry for 10 seconds...\n");
|
|
uint32 lastVal = 0;
|
|
bool first = true;
|
|
uint32 packetCount = 0;
|
|
uint32 discontinuityCount = 0;
|
|
|
|
float64 startTime = HighResolutionTimer::Counter() * HighResolutionTimer::Period();
|
|
float64 globalTimeout = startTime + 30.0;
|
|
|
|
while ((HighResolutionTimer::Counter() * HighResolutionTimer::Period() - startTime) < 10.0) {
|
|
if (HighResolutionTimer::Counter() * HighResolutionTimer::Period() > globalTimeout) {
|
|
printf("CRITICAL ERROR: Global test timeout reached.\n");
|
|
break;
|
|
}
|
|
|
|
char buffer[2048];
|
|
uint32 size = 2048;
|
|
TimeoutType timeout(200);
|
|
|
|
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 % 200 == 0) {
|
|
printf("Received %u packets... Current Value: %u\n", packetCount, val);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
printf("Test Finished.\n");
|
|
printf("Total Packets Received: %u (Expected ~1000)\n", packetCount);
|
|
printf("Discontinuities: %u\n", discontinuityCount);
|
|
|
|
float64 actualFreq = (float64)packetCount / 10.0;
|
|
printf("Average Frequency: %.2f Hz\n", actualFreq);
|
|
|
|
if (packetCount < 100) {
|
|
printf("FAILURE: Almost no packets received. Telemetry is broken.\n");
|
|
} else if (packetCount < 800) {
|
|
printf("WARNING: Too few packets received (Expected 1000, Got %u).\n", packetCount);
|
|
} else if (discontinuityCount > 20) {
|
|
printf("FAILURE: Too many discontinuities (%u).\n", discontinuityCount);
|
|
} else {
|
|
printf("VALIDATION SUCCESSFUL!\n");
|
|
}
|
|
|
|
app->StopCurrentStateExecution();
|
|
listener.Close();
|
|
ObjectRegistryDatabase::Instance()->Purge();
|
|
}
|
|
|
|
int main() {
|
|
RunValidationTest();
|
|
return 0;
|
|
}
|