Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement startup behavior for EInit events #298

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ file_list.txt
# IDE files
/.vscode/
/.vs/
/.idea/
2 changes: 2 additions & 0 deletions src/core/eventconn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ EMGMResponse CEventConnection::connect(CFunctionBlock *paDstFB, CStringDictionar

if(cgInvalidEventID != nEIID){
retval = CConnection::addDestination(CConnectionPoint(paDstFB, nEIID));
paDstFB->addInputEventConnection(nEIID);
}
return retval;
}
Expand All @@ -48,6 +49,7 @@ EMGMResponse CEventConnection::disconnect(CFunctionBlock *paDstFB, CStringDictio

if(cgInvalidEventID != nEIID){
retval = CConnection::removeDestination(CConnectionPoint(paDstFB, nEIID));
paDstFB->removeInputEventConnection(nEIID);
}
return retval;
}
Expand Down
15 changes: 15 additions & 0 deletions src/core/funcbloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ bool CFunctionBlock::initialize() {
#ifdef FORTE_SUPPORT_MONITORING
setupEventMonitoringData();
#endif //FORTE_SUPPORT_MONITORING
if (getFBInterfaceSpec().mEITypeNames != nullptr) {
mInputEventConnectionCount = std::make_unique<size_t[]>(getFBInterfaceSpec().mNumEIs);
}
return true;
}

Expand Down Expand Up @@ -671,6 +674,18 @@ size_t CFunctionBlock::getToStringBufferSize() const {

}

void CFunctionBlock::triggerEventsOfType(TEventTypeID paEventTypeId) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move to E_TRIG FB

//most of the FBs will only have the basic event type -> mEITypes == nullptr
if (getFBInterfaceSpec().mEITypeNames != nullptr) {
for (TEventID eventId = 0; eventId < getFBInterfaceSpec().mNumEIs; eventId++) {
if (getEIType(eventId) == paEventTypeId && !isInputEventConnected(eventId)) {
getResource()->getResourceEventExecution()->startEventChain(CConnectionPoint(this, eventId));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the eventchain execution thread which was used to triggere the R_TRIG fb and add the events to the internal event list.

}
}
}
}


//********************************** below here are CTF Tracing specific functions **********************************************************
#ifdef FORTE_TRACE_CTF
void CFunctionBlock::traceInputEvent(TEventID paEIID){
Expand Down
32 changes: 30 additions & 2 deletions src/core/funcbloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ class CAdapter;
class CTimerHandler;
class CDevice;

typedef CFunctionBlock *TFunctionBlockPtr;

namespace forte {
namespace core {
class CFBContainer;
Expand All @@ -63,6 +61,8 @@ typedef CAdapter *TAdapterPtr;

typedef TPortId TDataIOID; //!< \ingroup CORE Type for holding an data In- or output ID

typedef CStringDictionary::TStringId TEventTypeID;

/*!\ingroup CORE\brief Structure to hold all data of adapters instantiated in the function block.
*/
struct SAdapterInstanceDef {
Expand Down Expand Up @@ -414,6 +414,23 @@ class CFunctionBlock : public forte::core::CFBContainer {
virtual void traceInstanceData() {}
#endif //FORTE_TRACE_CTF

void addInputEventConnection(TEventID paEIID) {
if (getFBInterfaceSpec().mEITypeNames != nullptr) {
mInputEventConnectionCount[paEIID]++;
}
}

void removeInputEventConnection(TEventID paEIID) {
if (mInputEventConnectionCount != nullptr && mInputEventConnectionCount[paEIID] > 0) {
mInputEventConnectionCount[paEIID]--;
}
}

/*!\brief This function will trigger unconnected event ports of a certain EventType
* \param paEventTypeId ID of event type to be triggered
*/
void triggerEventsOfType(TEventTypeID paEventTypeId);

protected:

/*!\brief The main constructor for a function block.
Expand Down Expand Up @@ -506,6 +523,12 @@ class CFunctionBlock : public forte::core::CFBContainer {
}
}
#endif //FORTE_TRACE_CTF
/* !\brief checks if an input event pin is connected
*
*/
[[nodiscard]] bool isInputEventConnected(TEventID paEIID) const {
return mInputEventConnectionCount != nullptr && mInputEventConnectionCount[paEIID] > 0;
}

/*!\brief Set the initial values of data inputs, outputs, and internal vars.
*
Expand Down Expand Up @@ -672,6 +695,11 @@ class CFunctionBlock : public forte::core::CFBContainer {
*/
bool mDeletable;

/*!\brief Stores the number of input connections for each event pin
*/
std::unique_ptr<size_t[]> mInputEventConnectionCount;


#ifdef FORTE_SUPPORT_MONITORING
friend class forte::core::CMonitoringHandler;
#endif //FORTE_SUPPORT_MONITORING
Expand Down
6 changes: 3 additions & 3 deletions src/core/resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,16 +341,16 @@ EMGMResponse CResource::readValue(forte::core::TNameIdentifier &paNameList, std:
#ifdef FORTE_SUPPORT_QUERY_CMD

EMGMResponse CResource::queryAllFBTypes(std::string & paValue){
appedTypeNameList(paValue, CTypeLib::getFBLibStart());
appendTypeNameList(paValue, CTypeLib::getFBLibStart());
return EMGMResponse::Ready;
}

EMGMResponse CResource::queryAllAdapterTypes(std::string & paValue){
appedTypeNameList(paValue, CTypeLib::getAdapterLibStart());
appendTypeNameList(paValue, CTypeLib::getAdapterLibStart());
return EMGMResponse::Ready;
}

void CResource::appedTypeNameList(std::string & paValue, CTypeLib::CTypeEntry *paTypeListStart) {
void CResource::appendTypeNameList(std::string & paValue, CTypeLib::CTypeEntry *paTypeListStart) {
if(paTypeListStart != nullptr) {
for(; paTypeListStart != nullptr; paTypeListStart = paTypeListStart->mNext) {
paValue += paTypeListStart->getTypeName();
Expand Down
2 changes: 1 addition & 1 deletion src/core/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ class CResource : public CFunctionBlock{
*/
static EMGMResponse queryAllAdapterTypes(std::string& paValue);

static void appedTypeNameList(std::string & paValue, CTypeLib::CTypeEntry *paTypeListStart);
static void appendTypeNameList(std::string & paValue, CTypeLib::CTypeEntry *paTypeListStart);

/*!\brief Retrieve the list of FB instances
*
Expand Down
1 change: 1 addition & 0 deletions src/stdfblib/events/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ forte_add_sourcefile_hcpp(GEN_E_DEMUX_fbt GEN_E_MUX_fbt)
forte_add_sourcefile_hcpp(ATimeOut_adp E_TimeOut_fbt ARTimeOut_adp E_RTimeOut_fbt E_T_FF_fbt)
forte_add_sourcefile_hcpp(E_TRAIN_fbt)
forte_add_sourcefile_hcpp(E_PULSE_fbt E_TP_fbt E_TON_fbt E_TOF_fbt E_TONOF_fbt)
forte_add_sourcefile_hcpp(E_TRIG_fbt)
121 changes: 121 additions & 0 deletions src/stdfblib/events/E_TRIG_fbt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*************************************************************************
*** FORTE Library Element
***
*** This file was generated using the 4DIAC FORTE Export Filter V1.0.x NG!
***
*** Name: E_TRIG
*** Description: Service Interface Function Block Type
*** Version:
*** 1.0: 2025-01-08/mario - -
*************************************************************************/

#include "E_TRIG_fbt.h"
#ifdef FORTE_ENABLE_GENERATED_SOURCE_CPP
#include "E_TRIG_fbt_gen.cpp"
#endif

#include "iec61131_functions.h"
#include "forte_array_common.h"
#include "forte_array.h"
#include "forte_array_fixed.h"
#include "forte_array_variable.h"

#include "resource.h"

DEFINE_FIRMWARE_FB(FORTE_E_TRIG, g_nStringIdE_TRIG)

const CStringDictionary::TStringId FORTE_E_TRIG::scmDataInputNames[] = {g_nStringIdEVENTTYPE};
const CStringDictionary::TStringId FORTE_E_TRIG::scmDataInputTypeIds[] = {g_nStringIdSTRING};
const TDataIOID FORTE_E_TRIG::scmEIWith[] = {0, scmWithListDelimiter};
const TForteInt16 FORTE_E_TRIG::scmEIWithIndexes[] = {0};
const CStringDictionary::TStringId FORTE_E_TRIG::scmEventInputNames[] = {g_nStringIdREQ};
const TForteInt16 FORTE_E_TRIG::scmEOWithIndexes[] = {-1};
const CStringDictionary::TStringId FORTE_E_TRIG::scmEventOutputNames[] = {g_nStringIdCNF};
const SFBInterfaceSpec FORTE_E_TRIG::scmFBInterfaceSpec = {
1, scmEventInputNames, nullptr, scmEIWith, scmEIWithIndexes,
1, scmEventOutputNames, nullptr, nullptr, scmEOWithIndexes,
1, scmDataInputNames, scmDataInputTypeIds,
0, nullptr, nullptr,
0, nullptr,
0, nullptr
};

FORTE_E_TRIG::FORTE_E_TRIG(const CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer) :
CFunctionBlock(paContainer, scmFBInterfaceSpec, paInstanceNameId),
var_EVENTTYPE(""_STRING),
conn_CNF(this, 0),
conn_EVENTTYPE(nullptr) {
};

void FORTE_E_TRIG::setInitialValues() {
var_EVENTTYPE = ""_STRING;
}

void FORTE_E_TRIG::executeEvent(const TEventID paEIID, CEventChainExecutionThread *const paECET) {
switch(paEIID) {
case scmEventREQID:
const TEventTypeID eventTypeId = CStringDictionary::getInstance().getId(var_EVENTTYPE.c_str());
if (eventTypeId != CStringDictionary::scmInvalidStringId) {
triggerEvents(getResource(), eventTypeId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the paECET for triggereEvents so that you do not need to use the external events everywhere.

sendOutputEvent(scmEventCNFID, paECET);
}
break;
}
}

void FORTE_E_TRIG::readInputData(const TEventID paEIID) {
switch(paEIID) {
case scmEventREQID: {
readData(0, var_EVENTTYPE, conn_EVENTTYPE);
break;
}
default:
break;
}
}

void FORTE_E_TRIG::writeOutputData(TEventID) {
// nothing to do
}

CIEC_ANY *FORTE_E_TRIG::getDI(const size_t paIndex) {
switch(paIndex) {
case 0: return &var_EVENTTYPE;
}
return nullptr;
}

CIEC_ANY *FORTE_E_TRIG::getDO(size_t) {
return nullptr;
}

CEventConnection *FORTE_E_TRIG::getEOConUnchecked(const TPortId paIndex) {
switch(paIndex) {
case 0: return &conn_CNF;
}
return nullptr;
}

CDataConnection **FORTE_E_TRIG::getDIConUnchecked(const TPortId paIndex) {
switch(paIndex) {
case 0: return &conn_EVENTTYPE;
}
return nullptr;
}

CDataConnection *FORTE_E_TRIG::getDOConUnchecked(TPortId) {
return nullptr;
}

void FORTE_E_TRIG::triggerEvents(forte::core::CFBContainer* paContainer, TEventTypeID paEventType) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paContainer is not really needed you could call the getResoruce here.

if (paContainer != nullptr) {
if (paContainer->isFB()) {
static_cast<CFunctionBlock*>(paContainer)->triggerEventsOfType(paEventType);
}
if (paContainer->isDynamicContainer()) {
for (auto child: paContainer->getChildren()) {
triggerEvents(child, paEventType);
}
}
}
}
70 changes: 70 additions & 0 deletions src/stdfblib/events/E_TRIG_fbt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*************************************************************************
*** FORTE Library Element
***
*** This file was generated using the 4DIAC FORTE Export Filter V1.0.x NG!
***
*** Name: E_TRIG
*** Description: Service Interface Function Block Type
*** Version:
*** 1.0: 2025-01-08/mario - -
*************************************************************************/

#pragma once

#include "funcbloc.h"
#include "forte_string.h"
#include "iec61131_functions.h"
#include "forte_array_common.h"
#include "forte_array.h"
#include "forte_array_fixed.h"
#include "forte_array_variable.h"

class FORTE_E_TRIG final : public CFunctionBlock {
DECLARE_FIRMWARE_FB(FORTE_E_TRIG)

private:
static const CStringDictionary::TStringId scmDataInputNames[];
static const CStringDictionary::TStringId scmDataInputTypeIds[];
static const TEventID scmEventREQID = 0;
static const TDataIOID scmEIWith[];
static const TForteInt16 scmEIWithIndexes[];
static const CStringDictionary::TStringId scmEventInputNames[];
static const TEventID scmEventCNFID = 0;
static const TForteInt16 scmEOWithIndexes[];
static const CStringDictionary::TStringId scmEventOutputNames[];

static const SFBInterfaceSpec scmFBInterfaceSpec;

void executeEvent(TEventID paEIID, CEventChainExecutionThread *const paECET) override;

void readInputData(TEventID paEIID) override;
void writeOutputData(TEventID paEIID) override;
void setInitialValues() override;

void triggerEvents(forte::core::CFBContainer* paContainer, TEventTypeID paEventType);

public:
FORTE_E_TRIG(CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer);

CIEC_STRING var_EVENTTYPE;

CEventConnection conn_CNF;

CDataConnection *conn_EVENTTYPE;

CIEC_ANY *getDI(size_t) override;
CIEC_ANY *getDO(size_t) override;
CEventConnection *getEOConUnchecked(TPortId) override;
CDataConnection **getDIConUnchecked(TPortId) override;
CDataConnection *getDOConUnchecked(TPortId) override;

void evt_REQ(const CIEC_STRING &paEVENTTYPE) {
var_EVENTTYPE = paEVENTTYPE;
executeEvent(scmEventREQID, nullptr);
}

void operator()(const CIEC_STRING &paEVENTTYPE) {
evt_REQ(paEVENTTYPE);
}
};

Loading