/** * @file JAConditionalSignalUpdateGAM.cpp * @brief Source file for class JAConditionalSignalUpdateGAM * @date Jan, 2019 * @author rhari * * @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 definition of all the methods for * the class JAConditionalSignalUpdateGAM (public, protected, and private). Be aware that some * methods, such as those inline could be defined on the header file, instead. */ /*---------------------------------------------------------------------------*/ /* Standard header includes */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Project header includes */ /*---------------------------------------------------------------------------*/ #include "JAConditionalSignalUpdateGAM.h" #include "AdvancedErrorManagement.h" /*---------------------------------------------------------------------------*/ /* Static definitions */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Method definitions */ /*---------------------------------------------------------------------------*/ JAConditionalSignalUpdateGAM::JAConditionalSignalUpdateGAM() { inputSignals = NULL_PTR(void **); inputSignalTypes = NULL_PTR(MARTe::TypeDescriptor *); values = NULL_PTR(MARTe::uint32 *); valuesCount = 0u; outputSignals = NULL_PTR(MARTe::uint32 **); defaultValues = NULL_PTR(MARTe::uint32 **); needsReset = false; expectedValues = NULL_PTR(MARTe::uint32 *); expectedValuesCount = 0u; operation = And; comparators = NULL_PTR(ComparisonMode *); } JAConditionalSignalUpdateGAM::~JAConditionalSignalUpdateGAM() { if (outputSignals != NULL_PTR(MARTe::uint32 **)) { delete[] outputSignals; } if (inputSignals != NULL_PTR(void **)) { delete[] inputSignals; } if (inputSignalTypes != NULL_PTR(MARTe::TypeDescriptor *)) { delete[] inputSignalTypes; } if (values != NULL_PTR(MARTe::uint32 *)) { delete[] values; } if (comparators != NULL_PTR(ComparisonMode *)) { delete[] comparators; } if (defaultValues != NULL_PTR(MARTe::uint32 **)) { delete[] defaultValues; } } bool JAConditionalSignalUpdateGAM::Initialise(MARTe::StructuredDataI & data) { using namespace MARTe; bool ok = GAM::Initialise(data); if (ok) { // Read expected values. AnyType valuesArray = data.GetType("ExpectedValues"); if (valuesArray.GetDataPointer() != NULL) { expectedValuesCount = valuesArray.GetNumberOfElements(0u); expectedValues = new uint32[expectedValuesCount]; Vector valuesVector(expectedValues, expectedValuesCount); ok = (data.Read("ExpectedValues", valuesVector)); } } if (ok) { // Read comparators. AnyType comparatorsArray = data.GetType("Comparators"); if (comparatorsArray.GetDataPointer() != NULL) { uint32 count; if (ok) { count = comparatorsArray.GetNumberOfElements(0u); ok = count == expectedValuesCount; } if (ok) { comparators = new ComparisonMode[count]; StreamString* comp = new StreamString[count]; Vector compVector(comp, count); ok = (data.Read("Comparators", compVector)); if (ok) { for (uint32 i = 0; i < count; ++i) { if (comp[i] == "EQUALS") { comparators[i] = Equals; } else if (comp[i] == "NOT") { comparators[i] = Not; } else if (comp[i] == "GREATER") { comparators[i] = Greater; } else if (comp[i] == "EQUALS_OR_GREATER") { comparators[i] = EqualsOrGreater; } else if (comp[i] == "LESS") { comparators[i] = Less; } else if (comp[i] == "EQUALS_OR_LESS") { comparators[i] = EqualsOrLess; } else { ok = false; REPORT_ERROR(ErrorManagement::ParametersError, "Comparator %s is not defined.", comp[i].Buffer()); } } } delete[] comp; } else { REPORT_ERROR(ErrorManagement::ParametersError, "Expected values and operators shall have the same " "number of elements."); } } else { // Create default comparators (equals) when they aren't provided in the configuration. comparators = new ComparisonMode[expectedValuesCount]; for (uint32 i = 0; i < expectedValuesCount; ++i) { comparators[i] = Equals; } } } if (ok) { MARTe::StreamString operationStr; if (data.Read("Operation", operationStr)) { if (operationStr == "AND") { operation = And; } else if (operationStr == "OR") { operation = Or; } else if (operationStr == "NOR") { operation = Nor; } else if (operationStr == "XOR") { operation = Xor; } else { ok = false; REPORT_ERROR(ErrorManagement::ParametersError, "Operation %s is not defined", operationStr.Buffer()); } } } if (ok) { // Read output signal values to be set. AnyType valuesArray = data.GetType("Values"); ok = (valuesArray.GetDataPointer() != NULL); if (ok) { valuesCount = valuesArray.GetNumberOfElements(0u); ok = valuesCount > 0u; } if (ok) { values = new uint32[valuesCount]; Vector valuesVector(values, valuesCount); ok = (data.Read("Values", valuesVector)); } if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "Values shall be defined."); } } return ok; } bool JAConditionalSignalUpdateGAM::Setup() { using namespace MARTe; bool ok = numberOfInputSignals == (expectedValuesCount + numberOfOutputSignals); if (ok) { inputSignals = new void*[expectedValuesCount]; defaultValues = new uint32*[numberOfOutputSignals]; uint32 i; for (i = 0u; i < expectedValuesCount; i++) { inputSignals[i] = GetInputSignalMemory(i); } for (; i < numberOfInputSignals; i++) { defaultValues[i - expectedValuesCount] = reinterpret_cast(GetInputSignalMemory(i)); } } else { REPORT_ERROR(ErrorManagement::ParametersError, "Number of input signals shall be equal to number " "of expected values plus number of output signals."); } if (ok) { inputSignalTypes = new TypeDescriptor[expectedValuesCount]; uint32 i; for (i = 0u; (i < expectedValuesCount) && (ok); i++) { inputSignalTypes[i] = GetSignalType(InputSignals, i); ok = ((inputSignalTypes[i] == UnsignedInteger32Bit) || (inputSignalTypes[i] == UnsignedInteger16Bit)); if (!ok) { StreamString signalName; (void) GetSignalName(InputSignals, i, signalName); REPORT_ERROR(ErrorManagement::ParametersError, "Signal %s shall be defined as uint32 or uint16", signalName.Buffer()); } } } if (ok) { ok = numberOfOutputSignals == valuesCount; if (ok) { ok = numberOfOutputSignals > 0u; if (ok) { outputSignals = new uint32*[numberOfOutputSignals]; uint32 i; for (i = 0u; i < numberOfOutputSignals; i++) { outputSignals[i] = reinterpret_cast(GetOutputSignalMemory(i)); } } else { REPORT_ERROR(ErrorManagement::ParametersError, "At least one output signal shall be defined"); } } else { REPORT_ERROR(ErrorManagement::ParametersError, "Number of output signals shall be the same as " "number of provided values."); } } return ok; } bool JAConditionalSignalUpdateGAM::PrepareNextState(const MARTe::char8 * const currentStateName, const MARTe::char8 * const nextStateName) { needsReset = false; return true; } bool JAConditionalSignalUpdateGAM::Execute() { if (!needsReset) { bool eventDetected = expectedValuesCount == 0; if (!eventDetected) { if (operation == Or) { MARTe::uint32 j; for (j = 0; (j < expectedValuesCount) && (!eventDetected); j++) { eventDetected = Compare(j); } } else if (operation == Nor) { MARTe::uint32 j; for (j = 0; (j < expectedValuesCount) && (!eventDetected); j++) { eventDetected = Compare(j); } eventDetected = !eventDetected; } else if (operation == And) { MARTe::uint32 j; eventDetected = Compare(0); for (j = 1; (j < expectedValuesCount); j++) { eventDetected &= Compare(j); } } else if (operation == Xor) { MARTe::uint32 j; MARTe::uint32 eventDetectedUint32; if (inputSignalTypes[0] == MARTe::UnsignedInteger32Bit) { eventDetectedUint32 = *static_cast(inputSignals[0]); } else { eventDetectedUint32 = *static_cast(inputSignals[0]); } for (j = 1; (j < expectedValuesCount); j++) { eventDetectedUint32 ^= Compare(j); } eventDetected = (eventDetectedUint32 == 1u); } } if (eventDetected) { needsReset = true; MARTe::uint32 i; for (i = 0u; i < numberOfOutputSignals; ++i) { *outputSignals[i] = values[i]; MARTe::StreamString signalName; (void) GetSignalName(MARTe::OutputSignals, i, signalName); } } else { MARTe::uint32 i; for (i = 0u; i < numberOfOutputSignals; ++i) { *outputSignals[i] = *defaultValues[i]; } } } return true; } bool JAConditionalSignalUpdateGAM::Compare(MARTe::uint32 index) { if (inputSignalTypes[index] == MARTe::UnsignedInteger32Bit) { return Compare(index); } return Compare(index); } CLASS_REGISTER(JAConditionalSignalUpdateGAM, "1.0")