Initial release
This commit is contained in:
@@ -0,0 +1 @@
|
||||
include Makefile.inc
|
||||
@@ -0,0 +1,58 @@
|
||||
#############################################################
|
||||
#
|
||||
# Copyright 2015 F4E | European Joint Undertaking for ITER
|
||||
# and the Development of Fusion Energy ('Fusion for Energy')
|
||||
#
|
||||
# Licensed under the EUPL, Version 1.1 or - as soon they
|
||||
# will be approved by the European Commission - subsequent
|
||||
# versions of the EUPL (the "Licence");
|
||||
# You may not use this work except in compliance with the
|
||||
# Licence.
|
||||
# You may obtain a copy of the Licence at:
|
||||
#
|
||||
# http://ec.europa.eu/idabc/eupl
|
||||
#
|
||||
# Unless required by applicable law or agreed to in
|
||||
# writing, software distributed under the Licence is
|
||||
# distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
# express or implied.
|
||||
# See the Licence for the specific language governing
|
||||
# permissions and limitations under the Licence.
|
||||
#
|
||||
#############################################################
|
||||
|
||||
OBJSX = UDPStreamerTest.x UDPStreamerGTest.x
|
||||
|
||||
PACKAGE=Components/DataSources
|
||||
ROOT_DIR=../../../..
|
||||
MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults
|
||||
|
||||
include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)
|
||||
|
||||
INCLUDES += -I.
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L0Types
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L2Objects
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L3Streams
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Messages
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4StateMachine
|
||||
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_DIR)/Lib/gtest-1.7.0/include
|
||||
INCLUDES += -I$(ROOT_DIR)/Common/UDP
|
||||
INCLUDES += -I$(ROOT_DIR)/Source/Components/DataSources/UDPStreamer
|
||||
|
||||
all: $(OBJS) \
|
||||
$(BUILD_DIR)/UDPStreamerTest$(LIBEXT)
|
||||
echo $(OBJS)
|
||||
|
||||
include depends.$(TARGET)
|
||||
|
||||
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
|
||||
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* @file UDPStreamerGTest.cpp
|
||||
* @brief Source file for class UDPStreamerGTest
|
||||
* @date 13/05/2026
|
||||
* @author Martino Ferrari
|
||||
*
|
||||
* @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
|
||||
* the Development of Fusion Energy ('Fusion for Energy').
|
||||
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
|
||||
* by the European Commission - subsequent versions of the EUPL (the "Licence")
|
||||
* You may not use this work except in compliance with the Licence.
|
||||
* You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
|
||||
*
|
||||
* @warning Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the Licence is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the Licence permissions and limitations under the Licence.
|
||||
*
|
||||
* @details This source file contains the GTest wrapper for all UDPStreamer tests.
|
||||
*/
|
||||
|
||||
#define DLL_API
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Standard header includes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "gtest/gtest.h"
|
||||
#include <limits.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Project header includes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "UDPStreamerTest.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Method definitions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
TEST(UDPStreamerGTest, TestConstructor) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestConstructor());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_Valid) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_Valid());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_DefaultPort) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_DefaultPort());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_InvalidMaxPayloadSize) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_InvalidMaxPayloadSize());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_ZeroStackSize) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_ZeroStackSize());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_AutoMode_Valid) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_AutoMode_Valid());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_AutoMode_MissingRefreshRate) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_AutoMode_MissingRefreshRate());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_UnknownPublishingMode) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_UnknownPublishingMode());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestGetBrokerName_Output) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestGetBrokerName_Output());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestGetBrokerName_Input) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestGetBrokerName_Input());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestAllocateMemory) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestAllocateMemory());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_BasicSignals) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_BasicSignals());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_Quantized) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_Quantized());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_InvalidQuantOnInteger) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_InvalidQuantOnInteger());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_UnknownQuantType) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_UnknownQuantType());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_TimeModePacket) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_TimeModePacket());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_TimeModeFullArray) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_TimeModeFullArray());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_TimeModeFirstSample) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_TimeModeFirstSample());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_MissingSamplingRate) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_MissingSamplingRate());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_InvalidTimeSignal) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_InvalidTimeSignal());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_FullArrayMismatch) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSetConfiguredDatabase_FullArrayMismatch());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestPrepareNextState) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestPrepareNextState());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestSynchronise_NoClient) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestSynchronise_NoClient());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestExecute_ConnectDataDisconnect) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestExecute_ConnectDataDisconnect());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestExecute_Fragmentation) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestExecute_Fragmentation());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestQuantization_Uint16Extremes) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestQuantization_Uint16Extremes());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestQuantization_Uint8Clamping) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestQuantization_Uint8Clamping());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestGetPort) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestGetPort());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestGetMaxPayloadSize) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestGetMaxPayloadSize());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestIsClientConnected_InitiallyFalse) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestIsClientConnected_InitiallyFalse());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestHighFrequency_AllocateMemory) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestHighFrequency_AllocateMemory());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestHighFrequency_Fragmentation) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestHighFrequency_Fragmentation());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestHighFrequency_DataIntegrity) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestHighFrequency_DataIntegrity());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_MulticastMode_Valid) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_MulticastMode_Valid());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_MulticastMode_DefaultDataPort) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_MulticastMode_DefaultDataPort());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestInitialise_MulticastMode_InvalidDataPort) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestInitialise_MulticastMode_InvalidDataPort());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestPrepareNextState_Multicast) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestPrepareNextState_Multicast());
|
||||
}
|
||||
|
||||
TEST(UDPStreamerGTest, TestExecute_MulticastConnectDataDisconnect) {
|
||||
UDPStreamerTest test;
|
||||
ASSERT_TRUE(test.TestExecute_MulticastConnectDataDisconnect());
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
* @file UDPStreamerTest.h
|
||||
* @brief Header file for class UDPStreamerTest
|
||||
* @date 13/05/2026
|
||||
* @author Martino Ferrari
|
||||
*
|
||||
* @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
|
||||
* the Development of Fusion Energy ('Fusion for Energy').
|
||||
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
|
||||
* by the European Commission - subsequent versions of the EUPL (the "Licence")
|
||||
* You may not use this work except in compliance with the Licence.
|
||||
* You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
|
||||
*
|
||||
* @warning Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the Licence is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the Licence permissions and limitations under the Licence.
|
||||
*
|
||||
* @details This header file contains the declaration of the class UDPStreamerTest
|
||||
* with all of its public, protected and private members. It may also include
|
||||
* definitions for inline methods which need to be visible to the compiler.
|
||||
*/
|
||||
|
||||
#ifndef UDPSTREAMERTEST_H_
|
||||
#define UDPSTREAMERTEST_H_
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Standard header includes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Project header includes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Class declaration */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Tests the UDPStreamer DataSource public methods.
|
||||
*/
|
||||
class UDPStreamerTest {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Tests the default constructor.
|
||||
*/
|
||||
bool TestConstructor();
|
||||
|
||||
/**
|
||||
* @brief Tests Initialise with a fully valid configuration.
|
||||
*/
|
||||
bool TestInitialise_Valid();
|
||||
|
||||
/**
|
||||
* @brief Tests that a missing Port uses the default (44500).
|
||||
*/
|
||||
bool TestInitialise_DefaultPort();
|
||||
|
||||
/**
|
||||
* @brief Tests that MaxPayloadSize below the minimum is rejected.
|
||||
*/
|
||||
bool TestInitialise_InvalidMaxPayloadSize();
|
||||
|
||||
/**
|
||||
* @brief Tests that StackSize = 0 is rejected.
|
||||
*/
|
||||
bool TestInitialise_ZeroStackSize();
|
||||
|
||||
/**
|
||||
* @brief Tests GetBrokerName returns the correct broker for OutputSignals.
|
||||
*/
|
||||
bool TestGetBrokerName_Output();
|
||||
|
||||
/**
|
||||
* @brief Tests GetBrokerName returns empty string for InputSignals.
|
||||
*/
|
||||
bool TestGetBrokerName_Input();
|
||||
|
||||
/**
|
||||
* @brief Tests AllocateMemory allocates readyBuffer, scratchBuffer, wireBuffer.
|
||||
*/
|
||||
bool TestAllocateMemory();
|
||||
|
||||
/**
|
||||
* @brief Tests SetConfiguredDatabase with basic signal types.
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_BasicSignals();
|
||||
|
||||
/**
|
||||
* @brief Tests SetConfiguredDatabase with a quantized float signal.
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_Quantized();
|
||||
|
||||
/**
|
||||
* @brief Tests that quantization on a non-float signal is rejected.
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_InvalidQuantOnInteger();
|
||||
|
||||
/**
|
||||
* @brief Tests that an unknown QuantizedType is rejected.
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_UnknownQuantType();
|
||||
|
||||
/**
|
||||
* @brief Tests TimeMode = PacketTime (default).
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_TimeModePacket();
|
||||
|
||||
/**
|
||||
* @brief Tests TimeMode = FullArray with a matching time signal.
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_TimeModeFullArray();
|
||||
|
||||
/**
|
||||
* @brief Tests TimeMode = FirstSample with a scalar time signal.
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_TimeModeFirstSample();
|
||||
|
||||
/**
|
||||
* @brief Tests that FirstSample without SamplingRate is rejected.
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_MissingSamplingRate();
|
||||
|
||||
/**
|
||||
* @brief Tests that TimeSignal pointing to a non-existent signal is rejected.
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_InvalidTimeSignal();
|
||||
|
||||
/**
|
||||
* @brief Tests that FullArray TimeMode with mismatched element counts is rejected.
|
||||
*/
|
||||
bool TestSetConfiguredDatabase_FullArrayMismatch();
|
||||
|
||||
/**
|
||||
* @brief Tests PrepareNextState starts the thread and opens the socket.
|
||||
*/
|
||||
bool TestPrepareNextState();
|
||||
|
||||
/**
|
||||
* @brief Tests Synchronise when no client is connected (must return true, no crash).
|
||||
*/
|
||||
bool TestSynchronise_NoClient();
|
||||
|
||||
/**
|
||||
* @brief Tests the full CONNECT → CONFIG → DATA → DISCONNECT flow via loopback UDP.
|
||||
*/
|
||||
bool TestExecute_ConnectDataDisconnect();
|
||||
|
||||
/**
|
||||
* @brief Tests that DATA packets are fragmented correctly for large payloads.
|
||||
*/
|
||||
bool TestExecute_Fragmentation();
|
||||
|
||||
/**
|
||||
* @brief Tests uint16 quantization: verifies that 0 maps to 0 and max maps to 65535.
|
||||
*/
|
||||
bool TestQuantization_Uint16Extremes();
|
||||
|
||||
/**
|
||||
* @brief Tests uint8 quantization: verifies clamping of out-of-range values.
|
||||
*/
|
||||
bool TestQuantization_Uint8Clamping();
|
||||
|
||||
/**
|
||||
* @brief Tests PublishingMode = "Auto" with a valid MinRefreshRate.
|
||||
*/
|
||||
bool TestInitialise_AutoMode_Valid();
|
||||
|
||||
/**
|
||||
* @brief Tests that PublishingMode = "Auto" without MinRefreshRate is rejected.
|
||||
*/
|
||||
bool TestInitialise_AutoMode_MissingRefreshRate();
|
||||
|
||||
/**
|
||||
* @brief Tests that an unknown PublishingMode string is rejected.
|
||||
*/
|
||||
bool TestInitialise_UnknownPublishingMode();
|
||||
|
||||
/**
|
||||
* @brief Tests the GetPort() accessor.
|
||||
*/
|
||||
bool TestGetPort();
|
||||
|
||||
/**
|
||||
* @brief Tests the GetMaxPayloadSize() accessor.
|
||||
*/
|
||||
bool TestGetMaxPayloadSize();
|
||||
|
||||
/**
|
||||
* @brief Tests that IsClientConnected() returns false before any CONNECT.
|
||||
*/
|
||||
bool TestIsClientConnected_InitiallyFalse();
|
||||
|
||||
/**
|
||||
* @brief Tests AllocateMemory with 4 high-frequency int16[1000] packed channels (1 MSps).
|
||||
*/
|
||||
bool TestHighFrequency_AllocateMemory();
|
||||
|
||||
/**
|
||||
* @brief Tests that 4 int16[1000] channels produce exactly 6 fragments at MaxPayloadSize=1400.
|
||||
* Payload: 8 (HRT) + 8 (T0/uint64) + 4×2000 (int16[1000]) = 8016 bytes;
|
||||
* chunk = 1383 bytes → ceil(8016/1383) = 6 fragments.
|
||||
*/
|
||||
bool TestHighFrequency_Fragmentation();
|
||||
|
||||
/**
|
||||
* @brief Tests full CONNECT→DATA→DISCONNECT cycle with high-frequency packed signals.
|
||||
* Reassembles all fragments and verifies the total payload size.
|
||||
*/
|
||||
bool TestHighFrequency_DataIntegrity();
|
||||
|
||||
/**
|
||||
* @brief Tests Initialise with MulticastGroup and explicit DataPort.
|
||||
*/
|
||||
bool TestInitialise_MulticastMode_Valid();
|
||||
|
||||
/**
|
||||
* @brief Tests that DataPort defaults to Port+1 when MulticastGroup is set but DataPort is absent.
|
||||
*/
|
||||
bool TestInitialise_MulticastMode_DefaultDataPort();
|
||||
|
||||
/**
|
||||
* @brief Tests that DataPort equal to Port is rejected.
|
||||
*/
|
||||
bool TestInitialise_MulticastMode_InvalidDataPort();
|
||||
|
||||
/**
|
||||
* @brief Tests PrepareNextState in multicast mode: TCP listener opens, data socket connects.
|
||||
*/
|
||||
bool TestPrepareNextState_Multicast();
|
||||
|
||||
/**
|
||||
* @brief Tests full TCP CONNECT → CONFIG → DATA via multicast → DISCONNECT on loopback.
|
||||
*/
|
||||
bool TestExecute_MulticastConnectDataDisconnect();
|
||||
};
|
||||
|
||||
#endif /* UDPSTREAMERTEST_H_ */
|
||||
@@ -0,0 +1,569 @@
|
||||
/**
|
||||
* Test MARTe2 application for UDPStreamer DataSource.
|
||||
*
|
||||
* Three independent RT threads demonstrate all four UDPStreamer time modes:
|
||||
*
|
||||
* Thread1 – "Streamer" port 44500 TCP control / 44503 UDP multicast 239.0.0.1
|
||||
* (scalar signals, auto-accumulated to arrays[10], multicast mode,
|
||||
* 100 Hz flush = 10 samples per packet, 1 kHz source)
|
||||
* Counter – uint32 cycle counter
|
||||
* Time – uint32 time in microseconds (LinuxTimer, 1 kHz)
|
||||
* Sine1 – float32, 1 Hz, quantised to uint16 on wire (PacketTime)
|
||||
* Sine2 – float32, 0.3 Hz, raw float32 on wire (PacketTime)
|
||||
*
|
||||
* Thread2 – "FastStreamer" port 44501 (packed arrays, FirstSample + LastSample)
|
||||
* Time – uint32 scalar anchor (5 kHz LinuxTimer)
|
||||
* Ch1 – float32[1000], 1 kHz sine (TimeMode = FirstSample)
|
||||
* Ch2 – float32[1000], 10 kHz sine (TimeMode = LastSample)
|
||||
* Both channels use Time as the anchor and SamplingRate = 5 000 000 Hz so
|
||||
* the WebUI reconstructs the 200 ns per-sample timestamps.
|
||||
*
|
||||
* Thread3 – "FullArrStreamer" port 44502 (packed arrays, FullArray)
|
||||
* TimeArray – uint64[1000] per-sample timestamps in ns generated by TimeArrayGAM
|
||||
* Ch3 – float32[1000], 3 kHz sine (TimeMode = FullArray)
|
||||
* Ch4 – float32[1000], 500 Hz sine (TimeMode = FullArray)
|
||||
* The WebUI uses the explicit timestamp for each sample rather than
|
||||
* reconstructing them from a scalar anchor.
|
||||
*/
|
||||
$TestApp = {
|
||||
Class = RealTimeApplication
|
||||
+Functions = {
|
||||
Class = ReferenceContainer
|
||||
|
||||
// ── Copy Counter + Time from LinuxTimer into the inter-GAM DDB ──────
|
||||
+TimerGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = {
|
||||
DataSource = Timer
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
Frequency = 1000
|
||||
DataSource = Timer
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = {
|
||||
DataSource = DDB
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
DataSource = DDB
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 5 kHz fast timer for packed-array threads ────────────────────────
|
||||
+FastTimerGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Time = {
|
||||
Frequency = 5000
|
||||
DataSource = FastTimer
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Time = {
|
||||
DataSource = DDB2
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 1 Hz sinusoidal signal ───────────────────────────────────────────
|
||||
+SineGAM1 = {
|
||||
Class = WaveformSin
|
||||
Amplitude = 10.0
|
||||
Frequency = 1.0
|
||||
Phase = 0.0
|
||||
Offset = 0.0
|
||||
InputSignals = {
|
||||
Time = {
|
||||
DataSource = DDB
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Sine1 = {
|
||||
DataSource = DDB
|
||||
Type = float32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 0.3 Hz sinusoidal signal (phase-shifted) ─────────────────────────
|
||||
+SineGAM2 = {
|
||||
Class = WaveformSin
|
||||
Amplitude = 5.0
|
||||
Frequency = 0.3
|
||||
Phase = 1.0472
|
||||
Offset = 0.0
|
||||
InputSignals = {
|
||||
Time = {
|
||||
DataSource = DDB
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Sine2 = {
|
||||
DataSource = DDB
|
||||
Type = float32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 1 kHz sine burst – channel 1 (FirstSample anchor) ───────────────
|
||||
+SineGAM3 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 1000.0
|
||||
Amplitude = 1.0
|
||||
Phase = 0.0
|
||||
Offset = 0.0
|
||||
SamplingRate = 5000000.0
|
||||
OutputSignals = {
|
||||
Ch1 = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 10 kHz sine burst – channel 2 (LastSample anchor) ───────────────
|
||||
+SineGAM4 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 10000.0
|
||||
Amplitude = 0.5
|
||||
Phase = 1.5708
|
||||
Offset = 0.0
|
||||
SamplingRate = 5000000.0
|
||||
OutputSignals = {
|
||||
Ch2 = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Route scalar signals → Streamer ──────────────────────────────────
|
||||
+StreamerGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = {
|
||||
DataSource = DDB
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
DataSource = DDB
|
||||
Type = uint32
|
||||
}
|
||||
Sine1 = {
|
||||
DataSource = DDB
|
||||
Type = float32
|
||||
}
|
||||
Sine2 = {
|
||||
DataSource = DDB
|
||||
Type = float32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = {
|
||||
DataSource = Streamer
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
DataSource = Streamer
|
||||
Type = uint32
|
||||
}
|
||||
Sine1 = {
|
||||
DataSource = Streamer
|
||||
Type = float32
|
||||
}
|
||||
Sine2 = {
|
||||
DataSource = Streamer
|
||||
Type = float32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Route packed arrays → FastStreamer (FirstSample + LastSample) ────
|
||||
+FastStreamerGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Time = {
|
||||
DataSource = DDB2
|
||||
Type = uint32
|
||||
}
|
||||
Ch1 = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
Ch2 = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Time = {
|
||||
DataSource = FastStreamer
|
||||
Type = uint32
|
||||
}
|
||||
Ch1 = {
|
||||
DataSource = FastStreamer
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
Ch2 = {
|
||||
DataSource = FastStreamer
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 3 kHz sine burst – channel 3 (FullArray anchor) ─────────────────
|
||||
+SineGAM5 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 3000.0
|
||||
Amplitude = 2.0
|
||||
Phase = 0.0
|
||||
Offset = 0.0
|
||||
SamplingRate = 5000000.0
|
||||
OutputSignals = {
|
||||
Ch3 = {
|
||||
DataSource = DDB3
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 500 Hz sine burst – channel 4 (FullArray anchor) ─────────────────
|
||||
+SineGAM6 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 500.0
|
||||
Amplitude = 3.0
|
||||
Phase = 0.7854
|
||||
Offset = 0.0
|
||||
SamplingRate = 5000000.0
|
||||
OutputSignals = {
|
||||
Ch4 = {
|
||||
DataSource = DDB3
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Build per-sample time array for FullArray channels ────────────────
|
||||
// TimeArrayGAM expands the scalar LinuxTimer Time (uint32, µs) into a
|
||||
// uint64[1000] array in nanoseconds where element[k] = Time_ns + k * period_ns.
|
||||
// Using ns preserves sub-µs resolution at sampling rates > 1 MHz.
|
||||
+TimeArrayGAM1 = {
|
||||
Class = TimeArrayGAM
|
||||
SamplingRate = 5000000.0
|
||||
Anchor = FirstSample
|
||||
InputSignals = {
|
||||
Time = {
|
||||
DataSource = DDB3
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
TimeArray = {
|
||||
DataSource = DDB3
|
||||
Type = uint64
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Fast timer for FullArray thread ───────────────────────────────────
|
||||
+FullArrTimerGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Time = {
|
||||
Frequency = 5000
|
||||
DataSource = FullArrTimer
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Time = {
|
||||
DataSource = DDB3
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Route FullArray channels → FullArrStreamer ─────────────────────
|
||||
+FullArrStreamerGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
TimeArray = {
|
||||
DataSource = DDB3
|
||||
Type = uint64
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
Ch3 = {
|
||||
DataSource = DDB3
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
Ch4 = {
|
||||
DataSource = DDB3
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
TimeArray = {
|
||||
DataSource = FullArrStreamer
|
||||
Type = uint64
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
Ch3 = {
|
||||
DataSource = FullArrStreamer
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
Ch4 = {
|
||||
DataSource = FullArrStreamer
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+Data = {
|
||||
Class = ReferenceContainer
|
||||
DefaultDataSource = DDB
|
||||
|
||||
+DDB = {
|
||||
Class = GAMDataSource
|
||||
}
|
||||
+DDB2 = {
|
||||
Class = GAMDataSource
|
||||
}
|
||||
+DDB3 = {
|
||||
Class = GAMDataSource
|
||||
}
|
||||
|
||||
// ── 1 kHz real-time clock (Thread1) ──────────────────────────────────
|
||||
+Timer = {
|
||||
Class = LinuxTimer
|
||||
SleepNature = "Default"
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 5 kHz fast timer (Thread2 – FirstSample / LastSample) ────────────
|
||||
+FastTimer = {
|
||||
Class = LinuxTimer
|
||||
SleepNature = "Default"
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 5 kHz fast timer (Thread3 – FullArray) ───────────────────────────
|
||||
+FullArrTimer = {
|
||||
Class = LinuxTimer
|
||||
SleepNature = "Default"
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Streamer: scalar signals, PacketTime (port 44500) ─────────────────
|
||||
// Multicast mode: clients connect via TCP on port 44500 to receive the
|
||||
// CONFIG packet, then join 239.0.0.1:44503 to receive DATA datagrams.
|
||||
// Auto publishing ensures data is sent every RT cycle (1 kHz = 1 ms
|
||||
// temporal resolution) but never faster, so the rate is bounded.
|
||||
+Streamer = {
|
||||
Class = UDPStreamer
|
||||
Port = 44500
|
||||
MulticastGroup = "239.0.0.1"
|
||||
DataPort = 44503
|
||||
MaxPayloadSize = 1400
|
||||
PublishingMode = "Accumulate"
|
||||
MinRefreshRate = 100
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
Unit = "us"
|
||||
}
|
||||
Sine1 = {
|
||||
Type = float32
|
||||
Unit = "V"
|
||||
RangeMin = -10.0
|
||||
RangeMax = 10.0
|
||||
QuantizedType = "uint16"
|
||||
}
|
||||
Sine2 = {
|
||||
Type = float32
|
||||
Unit = "V"
|
||||
RangeMin = -5.0
|
||||
RangeMax = 5.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── FastStreamer: packed arrays, FirstSample + LastSample (port 44501)
|
||||
//
|
||||
// Ch1 uses TimeMode = FirstSample:
|
||||
// Time is the timestamp of sample [0]; later samples are extrapolated
|
||||
// forward: t[k] = Time + k / SamplingRate.
|
||||
//
|
||||
// Ch2 uses TimeMode = LastSample:
|
||||
// Time is the timestamp of sample [N-1]; earlier samples are
|
||||
// extrapolated backward: t[k] = Time - (N-1-k) / SamplingRate.
|
||||
//
|
||||
// Both modes produce identical wall-clock placements for a fixed-rate
|
||||
// signal and are shown here side-by-side for comparison.
|
||||
+FastStreamer = {
|
||||
Class = UDPStreamer
|
||||
Port = 44501
|
||||
MaxPayloadSize = 1400
|
||||
Signals = {
|
||||
Time = {
|
||||
Type = uint32
|
||||
Unit = "us"
|
||||
}
|
||||
Ch1 = {
|
||||
Type = float32
|
||||
Unit = "V"
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
TimeMode = FirstSample
|
||||
TimeSignal = Time
|
||||
SamplingRate = 5000000.0
|
||||
}
|
||||
Ch2 = {
|
||||
Type = float32
|
||||
Unit = "V"
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
TimeMode = LastSample
|
||||
TimeSignal = Time
|
||||
SamplingRate = 5000000.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── FullArrStreamer: packed arrays, FullArray (port 44502) ─────────────
|
||||
//
|
||||
// TimeMode = FullArray: the TimeSignal (TimeArray) has the same
|
||||
// NumberOfElements as the data channel. Each sample pair
|
||||
// (TimeArray[k], Ch3[k]) provides its own independent timestamp.
|
||||
// This mode handles non-uniform sampling and explicit per-sample clocks.
|
||||
+FullArrStreamer = {
|
||||
Class = UDPStreamer
|
||||
Port = 44502
|
||||
MaxPayloadSize = 1400
|
||||
Signals = {
|
||||
TimeArray = {
|
||||
Type = uint64
|
||||
Unit = "ns"
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
Ch3 = {
|
||||
Type = float32
|
||||
Unit = "V"
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
TimeMode = FullArray
|
||||
TimeSignal = TimeArray
|
||||
}
|
||||
Ch4 = {
|
||||
Type = float32
|
||||
Unit = "V"
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
TimeMode = FullArray
|
||||
TimeSignal = TimeArray
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+Timings = {
|
||||
Class = TimingDataSource
|
||||
}
|
||||
}
|
||||
|
||||
+States = {
|
||||
Class = ReferenceContainer
|
||||
+Running = {
|
||||
Class = RealTimeState
|
||||
+Threads = {
|
||||
Class = ReferenceContainer
|
||||
// Thread1: scalar signals at 1 kHz
|
||||
+Thread1 = {
|
||||
Class = RealTimeThread
|
||||
CPUs = 0x1
|
||||
Functions = {TimerGAM SineGAM1 SineGAM2 StreamerGAM}
|
||||
}
|
||||
// Thread2: packed arrays at 5 kHz (FirstSample + LastSample)
|
||||
+Thread2 = {
|
||||
Class = RealTimeThread
|
||||
CPUs = 0x2
|
||||
Functions = {FastTimerGAM SineGAM3 SineGAM4 FastStreamerGAM}
|
||||
}
|
||||
// Thread3: packed arrays at 5 kHz (FullArray with explicit timestamps)
|
||||
+Thread3 = {
|
||||
Class = RealTimeThread
|
||||
CPUs = 0x4
|
||||
Functions = {FullArrTimerGAM SineGAM5 SineGAM6 TimeArrayGAM1 FullArrStreamerGAM}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+Scheduler = {
|
||||
Class = GAMScheduler
|
||||
TimingDataSource = Timings
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
/**
|
||||
* Combined integration test configuration.
|
||||
*
|
||||
* Exercises all components in the repo simultaneously:
|
||||
* - SineArrayGAM — array sine wave generation
|
||||
* - TimeArrayGAM — per-sample timestamp arrays
|
||||
* - UDPStreamer — UDPS wire protocol (ports 44500, 44501, 44502)
|
||||
* - DebugService — live signal tracing / forcing / breakpoints (ports 8080-8082)
|
||||
* TcpLogger is auto-injected by DebugService on port 8082 (log port).
|
||||
*
|
||||
* Three real-time threads:
|
||||
*
|
||||
* Thread1 1 kHz — scalar signals → UDPStreamer port 44500 (Accumulate/multicast)
|
||||
* Counter, Time, Sine1 (1 Hz), Sine2 (0.3 Hz)
|
||||
*
|
||||
* Thread2 5 kHz — packed arrays → UDPStreamer port 44501
|
||||
* Ch1 float32[1000] @ 1 kHz (TimeMode = FirstSample)
|
||||
* Ch2 float32[1000] @ 10 kHz (TimeMode = LastSample)
|
||||
*
|
||||
* Thread3 5 kHz — FullArray + explicit timestamps → UDPStreamer port 44502
|
||||
* Ch3 float32[1000] @ 3 kHz (TimeMode = FullArray)
|
||||
* Ch4 float32[1000] @ 500 Hz (TimeMode = FullArray)
|
||||
*/
|
||||
|
||||
$App = {
|
||||
Class = RealTimeApplication
|
||||
|
||||
+Functions = {
|
||||
Class = ReferenceContainer
|
||||
|
||||
// ── Thread1: 1 kHz scalar signals ────────────────────────────────────
|
||||
|
||||
+TimerGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = {
|
||||
DataSource = Timer
|
||||
Type = uint32
|
||||
Frequency = 1000
|
||||
}
|
||||
Time = {
|
||||
DataSource = Timer
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = { DataSource = DDB1 Type = uint32 }
|
||||
Time = { DataSource = DDB1 Type = uint32 }
|
||||
}
|
||||
}
|
||||
|
||||
+SineGAM1 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 1.0
|
||||
Amplitude = 5.0
|
||||
Phase = 0.0
|
||||
Offset = 0.0
|
||||
SamplingRate = 1000.0
|
||||
OutputSignals = {
|
||||
Sine1 = { DataSource = DDB1 Type = float32 }
|
||||
}
|
||||
}
|
||||
|
||||
+SineGAM2 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 0.3
|
||||
Amplitude = 3.0
|
||||
Phase = 1.0472
|
||||
Offset = 0.0
|
||||
SamplingRate = 1000.0
|
||||
OutputSignals = {
|
||||
Sine2 = { DataSource = DDB1 Type = float32 }
|
||||
}
|
||||
}
|
||||
|
||||
+StreamerGAM1 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = { DataSource = DDB1 Type = uint32 }
|
||||
Time = { DataSource = DDB1 Type = uint32 }
|
||||
Sine1 = { DataSource = DDB1 Type = float32 }
|
||||
Sine2 = { DataSource = DDB1 Type = float32 }
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = { DataSource = Streamer1 Type = uint32 }
|
||||
Time = { DataSource = Streamer1 Type = uint32 }
|
||||
Sine1 = { DataSource = Streamer1 Type = float32 }
|
||||
Sine2 = { DataSource = Streamer1 Type = float32 }
|
||||
}
|
||||
}
|
||||
|
||||
// ── Thread2: 5 kHz packed arrays (FirstSample / LastSample) ──────────
|
||||
|
||||
+FastTimerGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Time = {
|
||||
DataSource = FastTimer
|
||||
Type = uint32
|
||||
Frequency = 5000
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Time = { DataSource = DDB2 Type = uint32 }
|
||||
}
|
||||
}
|
||||
|
||||
+SineGAM3 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 1000.0
|
||||
Amplitude = 1.0
|
||||
Phase = 0.0
|
||||
Offset = 0.0
|
||||
SamplingRate = 5000000.0
|
||||
OutputSignals = {
|
||||
Ch1 = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+SineGAM4 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 10000.0
|
||||
Amplitude = 0.5
|
||||
Phase = 1.5708
|
||||
Offset = 0.0
|
||||
SamplingRate = 5000000.0
|
||||
OutputSignals = {
|
||||
Ch2 = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+StreamerGAM2 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Time = { DataSource = DDB2 Type = uint32 }
|
||||
Ch1 = { DataSource = DDB2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
Ch2 = { DataSource = DDB2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
}
|
||||
OutputSignals = {
|
||||
Time = { DataSource = Streamer2 Type = uint32 }
|
||||
Ch1 = { DataSource = Streamer2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
Ch2 = { DataSource = Streamer2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
}
|
||||
}
|
||||
|
||||
// ── Thread3: 5 kHz FullArray with per-sample timestamps ──────────────
|
||||
|
||||
+FullArrTimerGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Time = {
|
||||
DataSource = FullArrTimer
|
||||
Type = uint32
|
||||
Frequency = 5000
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Time = { DataSource = DDB3 Type = uint32 }
|
||||
}
|
||||
}
|
||||
|
||||
+SineGAM5 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 3000.0
|
||||
Amplitude = 2.0
|
||||
Phase = 0.0
|
||||
Offset = 0.0
|
||||
SamplingRate = 5000000.0
|
||||
OutputSignals = {
|
||||
Ch3 = {
|
||||
DataSource = DDB3
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+SineGAM6 = {
|
||||
Class = SineArrayGAM
|
||||
Frequency = 500.0
|
||||
Amplitude = 3.0
|
||||
Phase = 0.7854
|
||||
Offset = 0.0
|
||||
SamplingRate = 5000000.0
|
||||
OutputSignals = {
|
||||
Ch4 = {
|
||||
DataSource = DDB3
|
||||
Type = float32
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+TimeArrayGAM1 = {
|
||||
Class = TimeArrayGAM
|
||||
SamplingRate = 5000000.0
|
||||
Anchor = FirstSample
|
||||
InputSignals = {
|
||||
Time = { DataSource = DDB3 Type = uint32 }
|
||||
}
|
||||
OutputSignals = {
|
||||
TimeArray = {
|
||||
DataSource = DDB3
|
||||
Type = uint64
|
||||
NumberOfDimensions = 1
|
||||
NumberOfElements = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+StreamerGAM3 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
TimeArray = { DataSource = DDB3 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
Ch3 = { DataSource = DDB3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
Ch4 = { DataSource = DDB3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
}
|
||||
OutputSignals = {
|
||||
TimeArray = { DataSource = Streamer3 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
Ch3 = { DataSource = Streamer3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
Ch4 = { DataSource = Streamer3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+Data = {
|
||||
Class = ReferenceContainer
|
||||
DefaultDataSource = DDB1
|
||||
|
||||
+DDB1 = { Class = GAMDataSource }
|
||||
+DDB2 = { Class = GAMDataSource }
|
||||
+DDB3 = { Class = GAMDataSource }
|
||||
|
||||
// ── Timers (one per thread) ───────────────────────────────────────────
|
||||
+Timer = {
|
||||
Class = LinuxTimer
|
||||
SleepNature = "Default"
|
||||
Signals = {
|
||||
Counter = { Type = uint32 }
|
||||
Time = { Type = uint32 }
|
||||
}
|
||||
}
|
||||
|
||||
+FastTimer = {
|
||||
Class = LinuxTimer
|
||||
SleepNature = "Default"
|
||||
Signals = {
|
||||
Counter = { Type = uint32 }
|
||||
Time = { Type = uint32 }
|
||||
}
|
||||
}
|
||||
|
||||
+FullArrTimer = {
|
||||
Class = LinuxTimer
|
||||
SleepNature = "Default"
|
||||
Signals = {
|
||||
Counter = { Type = uint32 }
|
||||
Time = { Type = uint32 }
|
||||
}
|
||||
}
|
||||
|
||||
// ── UDPStreamer instances ─────────────────────────────────────────────
|
||||
|
||||
// Thread1: scalar signals, Accumulate mode, multicast output
|
||||
+Streamer1 = {
|
||||
Class = UDPStreamer
|
||||
Port = 44500
|
||||
MulticastGroup = "239.0.0.1"
|
||||
DataPort = 44503
|
||||
MaxPayloadSize = 1400
|
||||
PublishingMode = "Accumulate"
|
||||
MinRefreshRate = 100
|
||||
Signals = {
|
||||
Counter = { Type = uint32 }
|
||||
Time = { Type = uint32 Unit = "us" }
|
||||
Sine1 = { Type = float32 Unit = "V" RangeMin = -5.0 RangeMax = 5.0 }
|
||||
Sine2 = { Type = float32 Unit = "V" RangeMin = -3.0 RangeMax = 3.0 }
|
||||
}
|
||||
}
|
||||
|
||||
// Thread2: packed arrays, FirstSample + LastSample
|
||||
+Streamer2 = {
|
||||
Class = UDPStreamer
|
||||
Port = 44501
|
||||
MaxPayloadSize = 1400
|
||||
Signals = {
|
||||
Time = { Type = uint32 Unit = "us" }
|
||||
Ch1 = {
|
||||
Type = float32 Unit = "V"
|
||||
NumberOfDimensions = 1 NumberOfElements = 1000
|
||||
TimeMode = FirstSample TimeSignal = Time SamplingRate = 5000000.0
|
||||
}
|
||||
Ch2 = {
|
||||
Type = float32 Unit = "V"
|
||||
NumberOfDimensions = 1 NumberOfElements = 1000
|
||||
TimeMode = LastSample TimeSignal = Time SamplingRate = 5000000.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Thread3: packed arrays, FullArray (per-sample timestamps)
|
||||
+Streamer3 = {
|
||||
Class = UDPStreamer
|
||||
Port = 44502
|
||||
MaxPayloadSize = 1400
|
||||
Signals = {
|
||||
TimeArray = {
|
||||
Type = uint64 Unit = "ns"
|
||||
NumberOfDimensions = 1 NumberOfElements = 1000
|
||||
}
|
||||
Ch3 = {
|
||||
Type = float32 Unit = "V"
|
||||
NumberOfDimensions = 1 NumberOfElements = 1000
|
||||
TimeMode = FullArray TimeSignal = TimeArray
|
||||
}
|
||||
Ch4 = {
|
||||
Type = float32 Unit = "V"
|
||||
NumberOfDimensions = 1 NumberOfElements = 1000
|
||||
TimeMode = FullArray TimeSignal = TimeArray
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+Timings = { Class = TimingDataSource }
|
||||
}
|
||||
|
||||
+States = {
|
||||
Class = ReferenceContainer
|
||||
+Running = {
|
||||
Class = RealTimeState
|
||||
+Threads = {
|
||||
Class = ReferenceContainer
|
||||
|
||||
+Thread1 = {
|
||||
Class = RealTimeThread
|
||||
CPUs = 0x1
|
||||
Functions = {TimerGAM SineGAM1 SineGAM2 StreamerGAM1}
|
||||
}
|
||||
|
||||
+Thread2 = {
|
||||
Class = RealTimeThread
|
||||
CPUs = 0x2
|
||||
Functions = {FastTimerGAM SineGAM3 SineGAM4 StreamerGAM2}
|
||||
}
|
||||
|
||||
+Thread3 = {
|
||||
Class = RealTimeThread
|
||||
CPUs = 0x4
|
||||
Functions = {FullArrTimerGAM SineGAM5 SineGAM6 TimeArrayGAM1 StreamerGAM3}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+Scheduler = {
|
||||
Class = GAMScheduler
|
||||
TimingDataSource = Timings
|
||||
}
|
||||
}
|
||||
|
||||
// ── DebugService ──────────────────────────────────────────────────────────────
|
||||
// Patches the broker registry at startup so every signal is traceable.
|
||||
// TcpLogger is auto-injected on LogPort (9090) — no explicit DataSource needed.
|
||||
// Connect the debugger web UI (./run_combined_test.sh -d) to:
|
||||
// Host=127.0.0.1 TCP=8080 UDP=8081 Log=9090
|
||||
+DebugService = {
|
||||
Class = DebugService
|
||||
ControlPort = 8080
|
||||
StreamPort = 8081
|
||||
LogPort = 9090
|
||||
StreamIP = "127.0.0.1"
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
+App = {
|
||||
Class = RealTimeApplication
|
||||
+Functions = {
|
||||
Class = ReferenceContainer
|
||||
+GAM1 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = {
|
||||
DataSource = Timer
|
||||
Type = uint32
|
||||
Frequency = 1000
|
||||
}
|
||||
Time = {
|
||||
DataSource = Timer
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = {
|
||||
DataSource = SyncDB
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
DataSource = DDB
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+CGAM = {
|
||||
Class = ConstantGAM
|
||||
OutputSignals = {
|
||||
Test = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
Default = 0.123
|
||||
}
|
||||
}
|
||||
}
|
||||
+GAM2 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = {
|
||||
DataSource = TimerSlow
|
||||
Frequency = 1
|
||||
}
|
||||
Time = {
|
||||
DataSource = TimerSlow
|
||||
}
|
||||
Test = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
DataSource = Logger
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
DataSource = Logger
|
||||
}
|
||||
ConstOut = {
|
||||
DataSource = Logger
|
||||
Type = float32
|
||||
}
|
||||
}
|
||||
}
|
||||
+GAM3 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = {
|
||||
Frequency = 1
|
||||
Samples = 100
|
||||
Type = uint32
|
||||
DataSource = SyncDB
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = {
|
||||
DataSource = DDB3
|
||||
NumberOfElements = 100
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+Data = {
|
||||
Class = ReferenceContainer
|
||||
DefaultDataSource = DDB
|
||||
+SyncDB = {
|
||||
Class = RealTimeThreadSynchronisation
|
||||
Timeout = 200
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+Timer = {
|
||||
Class = LinuxTimer
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+TimerSlow = {
|
||||
Class = LinuxTimer
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+Logger = {
|
||||
Class = LoggerDataSource
|
||||
Signals = {
|
||||
CounterCopy = {
|
||||
Type = uint32
|
||||
}
|
||||
TimeCopy = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+DDB = {
|
||||
AllowNoProducer = 1
|
||||
Class = GAMDataSource
|
||||
Signals = {
|
||||
Counter= {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+DDB2 = {
|
||||
AllowNoProducer = 1
|
||||
Class = GAMDataSource
|
||||
}
|
||||
+DDB3 = {
|
||||
AllowNoProducer = 1
|
||||
Class = GAMDataSource
|
||||
}
|
||||
+DAMS = {
|
||||
Class = TimingDataSource
|
||||
}
|
||||
}
|
||||
+States = {
|
||||
Class = ReferenceContainer
|
||||
+State1 = {
|
||||
Class = RealTimeState
|
||||
+Threads = {
|
||||
Class = ReferenceContainer
|
||||
+Thread1 = {
|
||||
Class = RealTimeThread
|
||||
Functions = {GAM1}
|
||||
}
|
||||
+Thread2 = {
|
||||
Class = RealTimeThread
|
||||
Functions = {GAM2 CGAM}
|
||||
}
|
||||
+Thread3 = {
|
||||
Class = RealTimeThread
|
||||
Functions = {GAM3}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+Scheduler = {
|
||||
Class = GAMScheduler
|
||||
TimingDataSource = DAMS
|
||||
}
|
||||
}
|
||||
|
||||
+DebugService = {
|
||||
Class = DebugService
|
||||
ControlPort = 8080
|
||||
UdpPort = 8081
|
||||
LogPort = 8082
|
||||
StreamIP = "127.0.0.1"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
+App = {
|
||||
Class = RealTimeApplication
|
||||
+Functions = {
|
||||
Class = ReferenceContainer
|
||||
+GAM1 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = {
|
||||
DataSource = Timer
|
||||
Type = uint32
|
||||
Frequency = 1000
|
||||
}
|
||||
Time = {
|
||||
DataSource = Timer
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = {
|
||||
DataSource = SyncDB
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
DataSource = DDB
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+CGAM = {
|
||||
Class = ConstantGAM
|
||||
OutputSignals = {
|
||||
Test = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
Default = 0.123
|
||||
}
|
||||
}
|
||||
}
|
||||
+GAM2 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = {
|
||||
DataSource = TimerSlow
|
||||
Frequency = 1
|
||||
}
|
||||
Time = {
|
||||
DataSource = TimerSlow
|
||||
}
|
||||
Test = {
|
||||
DataSource = DDB2
|
||||
Type = float32
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
DataSource = Logger
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
DataSource = Logger
|
||||
}
|
||||
ConstOut = {
|
||||
DataSource = Logger
|
||||
Type = float32
|
||||
}
|
||||
}
|
||||
}
|
||||
+GAM3 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Counter = {
|
||||
Frequency = 1
|
||||
Samples = 100
|
||||
Type = uint32
|
||||
DataSource = SyncDB
|
||||
}
|
||||
}
|
||||
OutputSignals = {
|
||||
Counter = {
|
||||
DataSource = DDB3
|
||||
NumberOfElements = 100
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+Data = {
|
||||
Class = ReferenceContainer
|
||||
DefaultDataSource = DDB
|
||||
+SyncDB = {
|
||||
Class = RealTimeThreadSynchronisation
|
||||
Timeout = 200
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+Timer = {
|
||||
Class = LinuxTimer
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+TimerSlow = {
|
||||
Class = LinuxTimer
|
||||
Signals = {
|
||||
Counter = {
|
||||
Type = uint32
|
||||
}
|
||||
Time = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+Logger = {
|
||||
Class = LoggerDataSource
|
||||
Signals = {
|
||||
CounterCopy = {
|
||||
Type = uint32
|
||||
}
|
||||
TimeCopy = {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+DDB = {
|
||||
AllowNoProducer = 1
|
||||
Class = GAMDataSource
|
||||
Signals = {
|
||||
Counter= {
|
||||
Type = uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
+DDB2 = {
|
||||
AllowNoProducer = 1
|
||||
Class = GAMDataSource
|
||||
}
|
||||
+DDB3 = {
|
||||
AllowNoProducer = 1
|
||||
Class = GAMDataSource
|
||||
}
|
||||
+DAMS = {
|
||||
Class = TimingDataSource
|
||||
}
|
||||
}
|
||||
+States = {
|
||||
Class = ReferenceContainer
|
||||
+State1 = {
|
||||
Class = RealTimeState
|
||||
+Threads = {
|
||||
Class = ReferenceContainer
|
||||
+Thread1 = {
|
||||
Class = RealTimeThread
|
||||
Functions = {GAM1}
|
||||
}
|
||||
+Thread2 = {
|
||||
Class = RealTimeThread
|
||||
Functions = {GAM2 CGAM}
|
||||
}
|
||||
+Thread3 = {
|
||||
Class = RealTimeThread
|
||||
Functions = {GAM3}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+Scheduler = {
|
||||
Class = GAMScheduler
|
||||
TimingDataSource = DAMS
|
||||
}
|
||||
}
|
||||
|
||||
+DebugService = {
|
||||
Class = WebDebugService
|
||||
HttpPort = 8090
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Main_TestAll.cpp
|
||||
*
|
||||
* Created on: 31/10/2016
|
||||
* Author: Andre Neto
|
||||
*/
|
||||
|
||||
#include "ErrorManagement.h"
|
||||
#include "Object.h"
|
||||
#include "StreamString.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <limits.h>
|
||||
|
||||
void MainGTestComponentsErrorProcessFunction(const MARTe::ErrorManagement::ErrorInformation& errorInfo,
|
||||
const char* const errorDescription)
|
||||
{
|
||||
MARTe::StreamString errorCodeStr;
|
||||
MARTe::ErrorManagement::ErrorCodeToStream(errorInfo.header.errorType, errorCodeStr);
|
||||
printf("[%s - %s:%d]: %s\n", errorCodeStr.Buffer(), errorInfo.fileName, errorInfo.header.lineNumber, errorDescription);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
|
||||
SetErrorProcessFunction(&MainGTestComponentsErrorProcessFunction);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#############################################################
|
||||
#
|
||||
# Copyright 2015 F4E | European Joint Undertaking for ITER
|
||||
# and the Development of Fusion Energy ('Fusion for Energy')
|
||||
#
|
||||
# Licensed under the EUPL, Version 1.1 or - as soon they
|
||||
# will be approved by the European Commission - subsequent
|
||||
# versions of the EUPL (the "Licence");
|
||||
# You may not use this work except in compliance with the
|
||||
# Licence.
|
||||
# You may obtain a copy of the Licence at:
|
||||
#
|
||||
# http://ec.europa.eu/idabc/eupl
|
||||
#
|
||||
# Unless required by applicable law or agreed to in
|
||||
# writing, software distributed under the Licence is
|
||||
# distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
# express or implied.
|
||||
# See the Licence for the specific language governing
|
||||
# permissions and limitations under the Licence.
|
||||
#
|
||||
#############################################################
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
LIBRARIES += $(MARTe2_DIR)/Lib/gtest-1.7.0/libgtest.a -lpthread
|
||||
|
||||
LIBRARIES += -L$(MARTe2_DIR)/Build/$(TARGET)/Core -lMARTe2
|
||||
LIBRARIES += -ldl
|
||||
|
||||
|
||||
#Look for all the statically linked files
|
||||
LIBRARIES_STATIC+=$(shell find $(ROOT_DIR)/Build/$(TARGET) -name "*.a")
|
||||
@@ -0,0 +1,55 @@
|
||||
#############################################################
|
||||
#
|
||||
# Copyright 2015 F4E | European Joint Undertaking for ITER
|
||||
# and the Development of Fusion Energy ('Fusion for Energy')
|
||||
#
|
||||
# Licensed under the EUPL, Version 1.1 or - as soon they
|
||||
# will be approved by the European Commission - subsequent
|
||||
# versions of the EUPL (the "Licence");
|
||||
# You may not use this work except in compliance with the
|
||||
# Licence.
|
||||
# You may obtain a copy of the Licence at:
|
||||
#
|
||||
# http://ec.europa.eu/idabc/eupl
|
||||
#
|
||||
# Unless required by applicable law or agreed to in
|
||||
# writing, software distributed under the Licence is
|
||||
# distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
# express or implied.
|
||||
# See the Licence for the specific language governing
|
||||
# permissions and limitations under the Licence.
|
||||
#
|
||||
#############################################################
|
||||
|
||||
PACKAGE=
|
||||
ROOT_DIR=../..
|
||||
MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults
|
||||
|
||||
include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)
|
||||
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L0Types
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L2Objects
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L3Streams
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Messages
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
|
||||
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_DIR)/Lib/gtest-1.7.0/include
|
||||
INCLUDES += -I$(ROOT_DIR)/Common/UDP
|
||||
INCLUDES += -I$(ROOT_DIR)/Source/Components/DataSources/UDPStreamer
|
||||
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/DebugService
|
||||
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/TCPLogger
|
||||
INCLUDES += -I$(ROOT_DIR)/Test/Components/DataSources/UDPStreamer
|
||||
|
||||
all: $(BUILD_DIR)/MainGTest$(EXEEXT)
|
||||
|
||||
include depends.$(TARGET)
|
||||
|
||||
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
|
||||
@@ -0,0 +1,101 @@
|
||||
../../Build/x86-linux//GTest/MainGTest.o: MainGTest.cpp \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Introspection.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/IntrospectionEntry.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TypeDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/IteratorT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Iterator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SortFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SearchFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/LoadableLibrary.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticList.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItemT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-internal.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-port.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-message.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-string.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-death-test.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-param-test.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-printers.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_prod.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h
|
||||
@@ -0,0 +1,101 @@
|
||||
MainGTest.o: MainGTest.cpp \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Introspection.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/IntrospectionEntry.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TypeDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/IteratorT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Iterator.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SortFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SearchFilter.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/LoadableLibrary.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticList.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItemT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilderT.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-internal.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-port.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-message.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-string.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-death-test.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-param-test.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-printers.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_prod.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
|
||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h
|
||||
@@ -0,0 +1,161 @@
|
||||
#include "BasicTCPSocket.h"
|
||||
#include "DebugService.h"
|
||||
#include "ObjectRegistryDatabase.h"
|
||||
#include "StandardParser.h"
|
||||
#include "StreamString.h"
|
||||
#include "GlobalObjectsDatabase.h"
|
||||
#include "RealTimeApplication.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace MARTe;
|
||||
|
||||
const char8 * const config_command_text =
|
||||
"DebugService = {"
|
||||
" Class = DebugService "
|
||||
" ControlPort = 8100 "
|
||||
" UdpPort = 8101 "
|
||||
" StreamIP = \"127.0.0.1\" "
|
||||
" MyCustomField = \"HelloConfig\" "
|
||||
"}"
|
||||
"App = {"
|
||||
" Class = RealTimeApplication "
|
||||
" +Functions = {"
|
||||
" Class = ReferenceContainer "
|
||||
" +GAM1 = {"
|
||||
" Class = IOGAM "
|
||||
" CustomGAMField = \"GAMValue\" "
|
||||
" InputSignals = {"
|
||||
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 PVName = \"PROC:VAR:1\" }"
|
||||
" Time = { DataSource = Timer Type = uint32 }"
|
||||
" }"
|
||||
" OutputSignals = {"
|
||||
" Counter = { DataSource = DDB Type = uint32 }"
|
||||
" Time = { DataSource = DDB Type = uint32 }"
|
||||
" }"
|
||||
" }"
|
||||
" }"
|
||||
" +Data = {"
|
||||
" Class = ReferenceContainer "
|
||||
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
|
||||
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
|
||||
" +DAMS = { Class = TimingDataSource }"
|
||||
" }"
|
||||
" +States = {"
|
||||
" Class = ReferenceContainer "
|
||||
" +State1 = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread Functions = {GAM1} } } }"
|
||||
" }"
|
||||
" +Scheduler = { Class = GAMScheduler TimingDataSource = DAMS }"
|
||||
"}";
|
||||
|
||||
static bool SendCommandAndGetReply(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(2000000); // 2s
|
||||
if (client.Read(buffer, size, timeout)) {
|
||||
reply.Write(buffer, size);
|
||||
client.Close();
|
||||
return true;
|
||||
}
|
||||
client.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
void TestConfigCommands() {
|
||||
printf("--- MARTe2 Config & Metadata Enrichment Test ---\n");
|
||||
|
||||
ObjectRegistryDatabase::Instance()->Purge();
|
||||
|
||||
ConfigurationDatabase cdb;
|
||||
StreamString ss = config_command_text;
|
||||
ss.Seek(0);
|
||||
StandardParser parser(ss, cdb);
|
||||
assert(parser.Parse());
|
||||
|
||||
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());
|
||||
ref->SetName(name);
|
||||
assert(ref->Initialise(child));
|
||||
ObjectRegistryDatabase::Instance()->Insert(ref);
|
||||
}
|
||||
|
||||
printf("Application and DebugService (port 8100) initialised.\n");
|
||||
|
||||
// Start the application to trigger broker execution and signal registration
|
||||
ReferenceT<RealTimeApplication> app = ObjectRegistryDatabase::Instance()->Find("App");
|
||||
assert(app.IsValid());
|
||||
assert(app->ConfigureApplication());
|
||||
assert(app->PrepareNextState("State1") == ErrorManagement::NoError);
|
||||
assert(app->StartNextStateExecution() == ErrorManagement::NoError);
|
||||
printf("Application started (for signal registration).\n");
|
||||
Sleep::MSec(500); // Wait for some cycles
|
||||
|
||||
ReferenceT<DebugService> service = ObjectRegistryDatabase::Instance()->Find("DebugService");
|
||||
if (service.IsValid()) {
|
||||
service->SetFullConfig(cdb);
|
||||
}
|
||||
|
||||
Sleep::MSec(1000);
|
||||
|
||||
// 1. Test CONFIG command
|
||||
{
|
||||
printf("Testing CONFIG command...\n");
|
||||
StreamString reply;
|
||||
assert(SendCommandAndGetReply(8100, "CONFIG\n", reply));
|
||||
printf("\n%s\n", reply.Buffer());
|
||||
// Verify it contains some key parts of the config
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "MyCustomField") != NULL_PTR(const char8*));
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "HelloConfig") != NULL_PTR(const char8*));
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "PROC:VAR:1") != NULL_PTR(const char8*));
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "OK CONFIG") != NULL_PTR(const char8*));
|
||||
printf("SUCCESS: CONFIG command validated.\n");
|
||||
}
|
||||
|
||||
// 2. Test INFO on object with enrichment
|
||||
{
|
||||
printf("Testing INFO on App.Functions.GAM1...\n");
|
||||
StreamString reply;
|
||||
assert(SendCommandAndGetReply(8100, "INFO App.Functions.GAM1\n", reply));
|
||||
// Check standard MARTe fields (Name, Class)
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "\"Name\": \"GAM1\"") != NULL_PTR(const char8*));
|
||||
// Check enriched fields from fullConfig
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "\"CustomGAMField\": \"GAMValue\"") != NULL_PTR(const char8*));
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "OK INFO") != NULL_PTR(const char8*));
|
||||
printf("SUCCESS: Object metadata enrichment validated.\n");
|
||||
}
|
||||
|
||||
// 3. Test INFO on signal with enrichment
|
||||
{
|
||||
printf("Testing INFO on App.Functions.GAM1.In.Counter...\n");
|
||||
StreamString reply;
|
||||
assert(SendCommandAndGetReply(8100, "INFO App.Functions.GAM1.In.Counter\n", reply));
|
||||
|
||||
// Check enriched fields from signal configuration
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "\"Frequency\": \"1000\"") != NULL_PTR(const char8*));
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "\"PVName\": \"PROC:VAR:1\"") != NULL_PTR(const char8*));
|
||||
assert(StringHelper::SearchString(reply.Buffer(), "OK INFO") != NULL_PTR(const char8*));
|
||||
printf("SUCCESS: Signal metadata enrichment validated.\n");
|
||||
}
|
||||
|
||||
if (app.IsValid()) {
|
||||
app->StopCurrentStateExecution();
|
||||
}
|
||||
|
||||
ObjectRegistryDatabase::Instance()->Purge();
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
#include "ClassRegistryDatabase.h"
|
||||
#include "ConfigurationDatabase.h"
|
||||
#include "DebugService.h"
|
||||
#include "ObjectRegistryDatabase.h"
|
||||
#include "ErrorManagement.h"
|
||||
#include "BasicTCPSocket.h"
|
||||
#include "BasicUDPSocket.h"
|
||||
#include "RealTimeApplication.h"
|
||||
#include "StandardParser.h"
|
||||
#include "TestCommon.h"
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace MARTe;
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void timeout_handler(int sig) {
|
||||
printf("Test timed out!\n");
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
void ErrorProcessFunction(const MARTe::ErrorManagement::ErrorInformation &errorInfo, const char8 * const errorDescription) {
|
||||
printf("[MARTe Error] %s: %s\n", errorInfo.className, errorDescription);
|
||||
}
|
||||
|
||||
// Forward declarations of other tests
|
||||
void TestSchedulerControl();
|
||||
void TestFullTracePipeline();
|
||||
void RunValidationTest();
|
||||
void TestConfigCommands();
|
||||
void TestGAMSignalTracing();
|
||||
void TestTreeCommand();
|
||||
|
||||
int main() {
|
||||
signal(SIGALRM, timeout_handler);
|
||||
alarm(180);
|
||||
|
||||
MARTe::ErrorManagement::SetErrorProcessFunction(&ErrorProcessFunction);
|
||||
|
||||
printf("MARTe2 Debug Suite Integration Tests\n");
|
||||
|
||||
printf("\n--- Test 1: Registry Patching ---\n");
|
||||
{
|
||||
ObjectRegistryDatabase::Instance()->Purge();
|
||||
DebugService service;
|
||||
ConfigurationDatabase serviceData;
|
||||
serviceData.Write("ControlPort", (uint32)9090);
|
||||
service.Initialise(serviceData);
|
||||
printf("DebugService initialized and Registry Patched.\n");
|
||||
|
||||
ClassRegistryItem *item =
|
||||
ClassRegistryDatabase::Instance()->Find("MemoryMapInputBroker");
|
||||
if (item != NULL_PTR(ClassRegistryItem *)) {
|
||||
Object *obj = item->GetObjectBuilder()->Build(
|
||||
GlobalObjectsDatabase::Instance()->GetStandardHeap());
|
||||
if (obj != NULL_PTR(Object *)) {
|
||||
printf("Instantiated Broker Class: %s\n",
|
||||
obj->GetClassProperties()->GetName());
|
||||
printf("Success: Broker patched and instantiated.\n");
|
||||
} else {
|
||||
printf("Failed to build broker\n");
|
||||
}
|
||||
} else {
|
||||
printf("MemoryMapInputBroker not found in registry\n");
|
||||
}
|
||||
}
|
||||
Sleep::MSec(1000);
|
||||
|
||||
printf("\n--- Test 2: Full Trace Pipeline ---\n");
|
||||
TestFullTracePipeline();
|
||||
Sleep::MSec(1000);
|
||||
|
||||
printf("\n--- Test 3: Scheduler Control ---\n");
|
||||
TestSchedulerControl();
|
||||
Sleep::MSec(1000);
|
||||
|
||||
printf("\n--- Test 4: 1kHz Lossless Trace Validation ---\n");
|
||||
RunValidationTest();
|
||||
Sleep::MSec(1000);
|
||||
|
||||
printf("\n--- Test 5: Config & Metadata Enrichment ---\n");
|
||||
TestConfigCommands();
|
||||
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");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --- Test Implementation ---
|
||||
|
||||
void TestGAMSignalTracing() {
|
||||
printf("--- Test: GAM Signal Tracing Issue ---\n");
|
||||
|
||||
ObjectRegistryDatabase::Instance()->Purge();
|
||||
|
||||
ConfigurationDatabase cdb;
|
||||
StreamString ss = debug_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: Discover signals
|
||||
{
|
||||
StreamString reply;
|
||||
if (SendCommandGAM(8095, "DISCOVER\n", reply)) {
|
||||
printf("DISCOVER response received (len=%llu)\n", reply.Size());
|
||||
} else {
|
||||
printf("ERROR: DISCOVER failed\n");
|
||||
}
|
||||
}
|
||||
Sleep::MSec(500);
|
||||
|
||||
// Step 2: Trace a DataSource signal (Timer.Counter)
|
||||
printf("\n--- Step 1: Trace DataSource signal (Timer.Counter) ---\n");
|
||||
{
|
||||
StreamString reply;
|
||||
if (SendCommandGAM(8095, "TRACE App.Data.Timer.Counter 1\n", reply)) {
|
||||
printf("TRACE response: %s", reply.Buffer());
|
||||
} else {
|
||||
printf("ERROR: TRACE failed\n");
|
||||
}
|
||||
}
|
||||
Sleep::MSec(500);
|
||||
|
||||
// Step 3: Trace a GAM input signal (GAM1.In.Counter)
|
||||
printf("\n--- Step 2: Trace GAM input signal (GAM1.In.Counter) ---\n");
|
||||
{
|
||||
StreamString reply;
|
||||
if (SendCommandGAM(8095, "TRACE App.Functions.GAM1.In.Counter 1\n", reply)) {
|
||||
printf("TRACE response: %s", reply.Buffer());
|
||||
} else {
|
||||
printf("ERROR: TRACE failed\n");
|
||||
}
|
||||
}
|
||||
Sleep::MSec(500);
|
||||
|
||||
// Step 4: Try to trace another DataSource signal (TimerSlow.Counter)
|
||||
printf("\n--- Step 3: Try to trace another signal (TimerSlow.Counter) ---\n");
|
||||
{
|
||||
StreamString reply;
|
||||
if (SendCommandGAM(8095, "TRACE App.Data.TimerSlow.Counter 1\n", reply)) {
|
||||
printf("TRACE response: %s", reply.Buffer());
|
||||
} else {
|
||||
printf("ERROR: TRACE failed\n");
|
||||
}
|
||||
}
|
||||
Sleep::MSec(500);
|
||||
|
||||
// Step 5: Check if we can still trace more signals
|
||||
printf("\n--- Step 4: Try to trace Logger.Counter ---\n");
|
||||
{
|
||||
StreamString reply;
|
||||
if (SendCommandGAM(8095, "TRACE App.Data.Logger.Counter 1\n", reply)) {
|
||||
printf("TRACE response: %s", reply.Buffer());
|
||||
} else {
|
||||
printf("ERROR: TRACE failed\n");
|
||||
}
|
||||
}
|
||||
Sleep::MSec(500);
|
||||
|
||||
// Verify UDP is still receiving data
|
||||
BasicUDPSocket listener;
|
||||
listener.Open();
|
||||
listener.Listen(8096);
|
||||
|
||||
char buffer[1024];
|
||||
uint32 size = 1024;
|
||||
TimeoutType timeout(1000);
|
||||
int packetCount = 0;
|
||||
while (listener.Read(buffer, size, timeout)) {
|
||||
packetCount++;
|
||||
size = 1024;
|
||||
}
|
||||
|
||||
printf("\n--- Results ---\n");
|
||||
if (packetCount > 0) {
|
||||
printf("SUCCESS: Received %d UDP packets.\n", packetCount);
|
||||
} else {
|
||||
printf("FAILURE: No UDP packets received. Possible deadlock or crash.\n");
|
||||
}
|
||||
|
||||
app->StopCurrentStateExecution();
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
include Makefile.inc
|
||||
@@ -0,0 +1,43 @@
|
||||
OBJSX = SchedulerTest.x TraceTest.x ValidationTest.x ConfigCommandTest.x TreeCommandTest.x MessageCommandTest.x TestCommon.x
|
||||
|
||||
PACKAGE = Test/Integration
|
||||
|
||||
ROOT_DIR = ../..
|
||||
|
||||
MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults
|
||||
|
||||
include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)
|
||||
|
||||
INCLUDES += -I$(ROOT_DIR)/Common/UDP
|
||||
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/DebugService
|
||||
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
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L3Streams
|
||||
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/BareMetal/L6App
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
|
||||
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
|
||||
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
|
||||
|
||||
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/GAMs/IOGAM -lIOGAM
|
||||
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/DebugService -lDebugService
|
||||
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/TCPLogger -lTcpLogger
|
||||
|
||||
all: $(OBJS) $(BUILD_DIR)/IntegrationTests$(EXEEXT)
|
||||
echo $(OBJS)
|
||||
|
||||
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
|
||||
@@ -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
|
||||
@@ -0,0 +1,253 @@
|
||||
#include "BasicTCPSocket.h"
|
||||
#include "BasicUDPSocket.h"
|
||||
#include "DebugService.h"
|
||||
#include "ObjectRegistryDatabase.h"
|
||||
#include "RealTimeApplication.h"
|
||||
#include "StandardParser.h"
|
||||
#include "StreamString.h"
|
||||
#include "GlobalObjectsDatabase.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace MARTe;
|
||||
|
||||
const char8 * const scheduler_config_text =
|
||||
"DebugService = {"
|
||||
" Class = DebugService "
|
||||
" ControlPort = 8098 "
|
||||
" UdpPort = 8099 "
|
||||
" StreamIP = \"127.0.0.1\" "
|
||||
"}"
|
||||
"App = {"
|
||||
" Class = RealTimeApplication "
|
||||
" +Functions = {"
|
||||
" Class = ReferenceContainer "
|
||||
" +GAM1 = {"
|
||||
" Class = IOGAM "
|
||||
" InputSignals = {"
|
||||
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
|
||||
" Time = { DataSource = Timer Type = uint32 }"
|
||||
" }"
|
||||
" OutputSignals = {"
|
||||
" Counter = { DataSource = DDB Type = uint32 }"
|
||||
" Time = { DataSource = DDB Type = uint32 }"
|
||||
" }"
|
||||
" }"
|
||||
" }"
|
||||
" +Data = {"
|
||||
" Class = ReferenceContainer "
|
||||
" DefaultDataSource = DDB "
|
||||
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
|
||||
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { 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 TestSchedulerControl() {
|
||||
printf("--- MARTe2 Scheduler Control Test ---\n");
|
||||
|
||||
ObjectRegistryDatabase::Instance()->Purge();
|
||||
|
||||
ConfigurationDatabase cdb;
|
||||
StreamString ss = scheduler_config_text;
|
||||
ss.Seek(0);
|
||||
StandardParser parser(ss, cdb);
|
||||
if (!parser.Parse()) {
|
||||
printf("ERROR: Failed to parse configuration\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 in registry\n");
|
||||
return;
|
||||
}
|
||||
service->SetFullConfig(cdb);
|
||||
|
||||
ReferenceT<RealTimeApplication> app =
|
||||
ObjectRegistryDatabase::Instance()->Find("App");
|
||||
if (!app.IsValid()) {
|
||||
printf("ERROR: App not found in registry\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!app->ConfigureApplication()) {
|
||||
printf("ERROR: ConfigureApplication failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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(2000);
|
||||
|
||||
// Enable Trace First - with retry logic
|
||||
{
|
||||
bool connected = false;
|
||||
for (int retry=0; retry<10 && !connected; retry++) {
|
||||
BasicTCPSocket tClient;
|
||||
if (tClient.Open()) {
|
||||
if (tClient.Connect("127.0.0.1", 8098)) {
|
||||
connected = true;
|
||||
const char *cmd = "TRACE App.Data.Timer.Counter 1\n";
|
||||
uint32 s = StringHelper::Length(cmd);
|
||||
tClient.Write(cmd, s);
|
||||
tClient.Close();
|
||||
} else {
|
||||
printf("[SchedulerTest] Connect failed (retry %d)\n", retry);
|
||||
Sleep::MSec(500);
|
||||
}
|
||||
} else {
|
||||
printf("[SchedulerTest] Open failed (retry %d)\n", retry);
|
||||
Sleep::MSec(500);
|
||||
}
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
printf("WARNING: Could not connect to DebugService to enable trace.\n");
|
||||
}
|
||||
}
|
||||
|
||||
BasicUDPSocket listener;
|
||||
listener.Open();
|
||||
listener.Listen(8099);
|
||||
|
||||
// Read current value
|
||||
uint32 valBeforePause = 0;
|
||||
char buffer[2048];
|
||||
uint32 size = 2048;
|
||||
TimeoutType timeout(1000);
|
||||
if (listener.Read(buffer, size, timeout)) {
|
||||
// [Header][ID][Size][Value]
|
||||
valBeforePause = *(uint32 *)(&buffer[sizeof(TraceHeader) + 16]);
|
||||
printf("Value before/at pause: %u\n", valBeforePause);
|
||||
} else {
|
||||
printf("WARNING: No data received before pause.\n");
|
||||
}
|
||||
|
||||
// Send PAUSE
|
||||
printf("Sending PAUSE command...\n");
|
||||
{
|
||||
bool connected = false;
|
||||
for (int retry=0; retry<10 && !connected; retry++) {
|
||||
BasicTCPSocket client;
|
||||
if (client.Open()) {
|
||||
if (client.Connect("127.0.0.1", 8098)) {
|
||||
connected = true;
|
||||
const char *cmd = "PAUSE\n";
|
||||
uint32 s = StringHelper::Length(cmd);
|
||||
client.Write(cmd, s);
|
||||
client.Close();
|
||||
} else {
|
||||
Sleep::MSec(200);
|
||||
}
|
||||
} else {
|
||||
Sleep::MSec(200);
|
||||
}
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
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(100))) {
|
||||
valAfterWait = *(uint32 *)(&buffer[sizeof(TraceHeader) + 16]);
|
||||
size = 2048;
|
||||
}
|
||||
|
||||
printf("Value after 2s wait (drained): %u\n", valAfterWait);
|
||||
|
||||
// Check if truly paused
|
||||
if (valAfterWait > valBeforePause + 10) {
|
||||
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");
|
||||
{
|
||||
bool connected = false;
|
||||
for (int retry=0; retry<10 && !connected; retry++) {
|
||||
BasicTCPSocket rClient;
|
||||
if (rClient.Open()) {
|
||||
if (rClient.Connect("127.0.0.1", 8098)) {
|
||||
connected = true;
|
||||
const char *cmd = "RESUME\n";
|
||||
uint32 s = StringHelper::Length(cmd);
|
||||
rClient.Write(cmd, s);
|
||||
rClient.Close();
|
||||
} else {
|
||||
Sleep::MSec(200);
|
||||
}
|
||||
} else {
|
||||
Sleep::MSec(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Sleep::MSec(1000);
|
||||
|
||||
// Check if increasing
|
||||
uint32 valAfterResume = 0;
|
||||
size = 2048;
|
||||
if (listener.Read(buffer, size, timeout)) {
|
||||
valAfterResume = *(uint32 *)(&buffer[sizeof(TraceHeader) + 16]);
|
||||
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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "BasicTCPSocket.h"
|
||||
#include "BasicUDPSocket.h"
|
||||
#include "DebugService.h"
|
||||
#include "ObjectRegistryDatabase.h"
|
||||
#include "StandardParser.h"
|
||||
#include "StreamString.h"
|
||||
#include "HighResolutionTimer.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace MARTe;
|
||||
|
||||
void TestFullTracePipeline() {
|
||||
printf("Starting Full Trace Pipeline Test...\n");
|
||||
|
||||
ObjectRegistryDatabase::Instance()->Purge();
|
||||
|
||||
// 1. Setup Service
|
||||
DebugService service;
|
||||
ConfigurationDatabase config;
|
||||
config.Write("ControlPort", (uint16)8082);
|
||||
config.Write("StreamPort", (uint16)8083);
|
||||
config.Write("LogPort", (uint16)8084);
|
||||
config.Write("StreamIP", "127.0.0.1");
|
||||
assert(service.Initialise(config));
|
||||
Sleep::MSec(500);
|
||||
|
||||
// 2. Register a mock signal
|
||||
uint32 mockValue = 0;
|
||||
DebugSignalInfo* sig = service.RegisterSignal(&mockValue, UnsignedInteger32Bit, "TraceTest.Signal", 0, 1);
|
||||
assert(sig != NULL_PTR(DebugSignalInfo*));
|
||||
printf("Signal registered with ID: %u\n", sig->internalID);
|
||||
|
||||
// 3. Enable Trace manually
|
||||
sig->isTracing = true;
|
||||
sig->decimationFactor = 1;
|
||||
|
||||
// 4. Setup a local UDP listener
|
||||
BasicUDPSocket listener;
|
||||
assert(listener.Open());
|
||||
assert(listener.Listen(8083));
|
||||
|
||||
// 5. Simulate cycles
|
||||
printf("Simulating cycles...\n");
|
||||
for (int i=0; i<50; i++) {
|
||||
mockValue = 1000 + i;
|
||||
uint64 ts = (uint64)((float64)HighResolutionTimer::Counter() * HighResolutionTimer::Period() * 1000000.0);
|
||||
service.ProcessSignal(sig, sizeof(uint32), ts);
|
||||
Sleep::MSec(10);
|
||||
}
|
||||
|
||||
// 6. Try to read from UDP
|
||||
char buffer[2048];
|
||||
uint32 size = 2048;
|
||||
TimeoutType timeout(1000); // 1s
|
||||
if (listener.Read(buffer, size, timeout)) {
|
||||
printf("SUCCESS: Received %u bytes over UDP!\n", size);
|
||||
|
||||
TraceHeader *h = (TraceHeader*)buffer;
|
||||
printf("Header: Magic=0x%X, Count=%u, Seq=%u\n", h->magic, h->count, h->seq);
|
||||
|
||||
uint32 offset = sizeof(TraceHeader);
|
||||
if (size >= offset + 16) {
|
||||
uint32 recId = *(uint32*)(&buffer[offset]);
|
||||
uint64 recTs = *(uint64*)(&buffer[offset + 4]);
|
||||
uint32 recSize = *(uint32*)(&buffer[offset + 12]);
|
||||
printf("Data: ID=%u, TS=%llu, Size=%u\n", recId, (unsigned long long)recTs, recSize);
|
||||
if (size >= offset + 16 + recSize) {
|
||||
if (recSize == 4) {
|
||||
uint32 recVal = *(uint32*)(&buffer[offset + 16]);
|
||||
printf("Value=%u\n", recVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("FAILURE: No UDP packets received.\n");
|
||||
}
|
||||
|
||||
listener.Close();
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
#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 }"
|
||||
" Time = { DataSource = Timer Type = uint32 }"
|
||||
" }"
|
||||
" OutputSignals = {"
|
||||
" Counter = { DataSource = DDB Type = uint32 }"
|
||||
" Time = { DataSource = DDB Type = uint32 }"
|
||||
" }"
|
||||
" }"
|
||||
" }"
|
||||
" +Data = {"
|
||||
" Class = ReferenceContainer "
|
||||
" DefaultDataSource = DDB "
|
||||
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
|
||||
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { 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();
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
#include "BasicTCPSocket.h"
|
||||
#include "BasicUDPSocket.h"
|
||||
#include "DebugService.h"
|
||||
#include "ObjectRegistryDatabase.h"
|
||||
#include "RealTimeApplication.h"
|
||||
#include "StandardParser.h"
|
||||
#include "StreamString.h"
|
||||
#include "GlobalObjectsDatabase.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace MARTe;
|
||||
|
||||
const char8 * const validation_config =
|
||||
"DebugService = {"
|
||||
" Class = DebugService "
|
||||
" ControlPort = 8085 "
|
||||
" UdpPort = 8086 "
|
||||
" StreamIP = \"127.0.0.1\" "
|
||||
"}"
|
||||
"App = {"
|
||||
" Class = RealTimeApplication "
|
||||
" +Functions = {"
|
||||
" Class = ReferenceContainer "
|
||||
" +GAM1 = {"
|
||||
" Class = IOGAM "
|
||||
" InputSignals = {"
|
||||
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
|
||||
" Time = { DataSource = Timer Type = uint32 }"
|
||||
" }"
|
||||
" OutputSignals = {"
|
||||
" Counter = { DataSource = DDB Type = uint32 }"
|
||||
" Time = { DataSource = DDB Type = uint32 }"
|
||||
" }"
|
||||
" }"
|
||||
" }"
|
||||
" +Data = {"
|
||||
" Class = ReferenceContainer "
|
||||
" DefaultDataSource = DDB "
|
||||
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
|
||||
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { 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 1kHz Lossless Trace Validation Test ---\n");
|
||||
|
||||
ObjectRegistryDatabase::Instance()->Purge();
|
||||
|
||||
ConfigurationDatabase cdb;
|
||||
StreamString ss = validation_config;
|
||||
ss.Seek(0);
|
||||
StandardParser parser(ss, cdb);
|
||||
assert(parser.Parse());
|
||||
|
||||
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());
|
||||
ref->SetName(name);
|
||||
assert(ref->Initialise(child));
|
||||
ObjectRegistryDatabase::Instance()->Insert(ref);
|
||||
}
|
||||
|
||||
Reference serviceGeneric = ObjectRegistryDatabase::Instance()->Find("DebugService");
|
||||
Reference appGeneric = ObjectRegistryDatabase::Instance()->Find("App");
|
||||
|
||||
if (!serviceGeneric.IsValid() || !appGeneric.IsValid()) {
|
||||
printf("ERROR: Objects NOT FOUND in ValidationTest\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DebugService *service = dynamic_cast<DebugService*>(serviceGeneric.operator->());
|
||||
RealTimeApplication *app = dynamic_cast<RealTimeApplication*>(appGeneric.operator->());
|
||||
|
||||
assert(service);
|
||||
assert(app);
|
||||
|
||||
service->SetFullConfig(cdb);
|
||||
|
||||
if (!app->ConfigureApplication()) {
|
||||
printf("ERROR: ConfigureApplication failed in ValidationTest.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
assert(app->PrepareNextState("State1") == ErrorManagement::NoError);
|
||||
assert(app->StartNextStateExecution() == ErrorManagement::NoError);
|
||||
|
||||
printf("Application started at 1kHz. Enabling Traces...\n");
|
||||
Sleep::MSec(1000);
|
||||
|
||||
if (service->TraceSignal("App.Data.Timer.Counter", true, 1) == 0) {
|
||||
printf("ERROR: Failed to enable trace for App.Data.Timer.Counter\n");
|
||||
}
|
||||
|
||||
BasicUDPSocket listener;
|
||||
listener.Open();
|
||||
listener.Listen(8086);
|
||||
|
||||
printf("Validating for 10 seconds...\n");
|
||||
uint32 totalPackets = 0;
|
||||
uint32 totalSamples = 0;
|
||||
uint32 discontinuities = 0;
|
||||
uint32 lastValue = 0xFFFFFFFF;
|
||||
|
||||
uint64 start = HighResolutionTimer::Counter();
|
||||
float64 elapsed = 0;
|
||||
while (elapsed < 10.0) {
|
||||
char buffer[2048];
|
||||
uint32 size = 2048;
|
||||
if (listener.Read(buffer, size, TimeoutType(100))) {
|
||||
totalPackets++;
|
||||
TraceHeader *h = (TraceHeader*)buffer;
|
||||
uint32 offset = sizeof(TraceHeader);
|
||||
for (uint32 i=0; i<h->count; i++) {
|
||||
uint32 recId = *(uint32*)(&buffer[offset]);
|
||||
uint32 recSize = *(uint32*)(&buffer[offset + 12]);
|
||||
if (recSize == 4) {
|
||||
uint32 val = *(uint32*)(&buffer[offset + 16]);
|
||||
totalSamples++;
|
||||
if (lastValue != 0xFFFFFFFF && val != lastValue + 1) {
|
||||
discontinuities++;
|
||||
}
|
||||
lastValue = val;
|
||||
}
|
||||
offset += (16 + recSize);
|
||||
}
|
||||
}
|
||||
elapsed = (float64)(HighResolutionTimer::Counter() - start) * HighResolutionTimer::Period();
|
||||
}
|
||||
|
||||
printf("\n--- Test Results ---\n");
|
||||
printf("Total UDP Packets: %u\n", totalPackets);
|
||||
printf("Total Counter Samples: %u\n", totalSamples);
|
||||
printf("Counter Discontinuities: %u\n", discontinuities);
|
||||
|
||||
if (totalSamples < 9000) {
|
||||
printf("FAILURE: Underflow - samples missing (%u).\n", totalSamples);
|
||||
} else if (discontinuities > 50) {
|
||||
printf("FAILURE: Excessive discontinuities detected! (%u)\n", discontinuities);
|
||||
} else {
|
||||
printf("VALIDATION SUCCESSFUL: 1kHz Lossless Tracing Verified.\n");
|
||||
}
|
||||
|
||||
app->StopCurrentStateExecution();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
all:
|
||||
$(MAKE) -C GTest -f Makefile.gcc
|
||||
$(MAKE) -C Integration -f Makefile.gcc
|
||||
|
||||
clean:
|
||||
$(MAKE) -C GTest -f Makefile.gcc clean
|
||||
$(MAKE) -C Integration -f Makefile.gcc clean
|
||||
|
||||
.PHONY: all clean
|
||||
@@ -0,0 +1 @@
|
||||
# Test top-level Makefile.inc
|
||||
Reference in New Issue
Block a user