#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 "MessageI.h" #include #include 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 = 100000 " // 100ms " 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 = FastScheduler " " TimingDataSource = DAMS " " }" "}"; void TestSchedulerControl() { printf("--- MARTe2 Scheduler Control Test ---\n"); ConfigurationDatabase cdb; StreamString ss = config_text; ss.Seek(0); StandardParser parser(ss, cdb); assert(parser.Parse()); assert(ObjectRegistryDatabase::Instance()->Initialise(cdb)); ReferenceT service = ObjectRegistryDatabase::Instance()->Find("DebugService"); assert(service.IsValid()); ReferenceT app = ObjectRegistryDatabase::Instance()->Find("App"); assert(app.IsValid()); if (app->PrepareNextState("State1") != ErrorManagement::NoError) { printf("ERROR: Failed to prepare State1\n"); return; } if (app->StartNextStateExecution() != ErrorManagement::NoError) { printf("ERROR: Failed to start execution\n"); return; } printf("Application started. Waiting for cycles...\n"); Sleep::MSec(1000); // Enable Trace First { BasicTCPSocket tClient; if (tClient.Connect("127.0.0.1", 8080)) { const char* cmd = "TRACE Root.App.Data.Timer.Counter 1\n"; uint32 s = StringHelper::Length(cmd); tClient.Write(cmd, s); tClient.Close(); } else { printf("WARNING: Could not connect to DebugService to enable trace.\n"); } } BasicUDPSocket listener; listener.Open(); listener.Listen(8081); // Read current value uint32 valBeforePause = 0; char buffer[2048]; uint32 size = 2048; TimeoutType timeout(500); if (listener.Read(buffer, size, timeout)) { // [Header][ID][Size][Value] valBeforePause = *(uint32*)(&buffer[28]); printf("Value before/at pause: %u\n", valBeforePause); } else { printf("WARNING: No data received before pause.\n"); } // Send PAUSE printf("Sending PAUSE command...\n"); BasicTCPSocket client; if (client.Connect("127.0.0.1", 8080)) { const char* cmd = "PAUSE\n"; uint32 s = StringHelper::Length(cmd); client.Write(cmd, s); client.Close(); } else { printf("ERROR: Could not connect to DebugService to send PAUSE.\n"); } Sleep::MSec(2000); // Wait 2 seconds // Read again - should be same or very close if paused uint32 valAfterWait = 0; size = 2048; // Reset size while(listener.Read(buffer, size, TimeoutType(10))) { valAfterWait = *(uint32*)(&buffer[28]); size = 2048; } printf("Value after 2s wait (drained): %u\n", valAfterWait); // Check if truly paused if (valAfterWait > valBeforePause + 5) { printf("FAILURE: Counter increased significantly while paused! (%u -> %u)\n", valBeforePause, valAfterWait); } else { printf("SUCCESS: Counter held steady (or close) during pause.\n"); } // Resume printf("Sending RESUME command...\n"); { BasicTCPSocket rClient; if (rClient.Connect("127.0.0.1", 8080)) { const char* cmd = "RESUME\n"; uint32 s = StringHelper::Length(cmd); rClient.Write(cmd, s); rClient.Close(); } } Sleep::MSec(1000); // Check if increasing uint32 valAfterResume = 0; size = 2048; if (listener.Read(buffer, size, timeout)) { valAfterResume = *(uint32*)(&buffer[28]); printf("Value after resume: %u\n", valAfterResume); } if (valAfterResume > valAfterWait) { printf("SUCCESS: Execution resumed.\n"); } else { printf("FAILURE: Execution did not resume.\n"); } app->StopCurrentStateExecution(); } int main() { TestSchedulerControl(); return 0; }