[563446] Replaced E_STOPWATCH with a pure basic FB
With the new NOW_MONOTONIC functions it is now possible to implement the
E_STOPWATCH as pure basic FB with just ST algorithms.
Bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=563446
Change-Id: Iea9de2895325c8427230465b85133c408d4749c9
Signed-off-by: Alois Zoitl <alois.zoitl@gmx.at>
diff --git a/src/modules/utils/CMakeLists.txt b/src/modules/utils/CMakeLists.txt
index 2c242c4..c139fd3 100644
--- a/src/modules/utils/CMakeLists.txt
+++ b/src/modules/utils/CMakeLists.txt
@@ -16,16 +16,7 @@
# FORTE UTILITY FBs
#############################################################################
-if(NOT "${FORTE_ARCHITECTURE}" STREQUAL "VxWorks") #the compiler used to test vxworks doesn't support ++11
- if(CYGWIN)
- forte_add_definition("-std=gnu++11")
- else(CYGWIN)
- forte_add_definition("-std=c++11")
- endif(CYGWIN)
-
- forte_add_sourcefile_hcpp(E_STOPWATCH)
-endif(NOT "${FORTE_ARCHITECTURE}" STREQUAL "VxWorks")
-
+forte_add_sourcefile_hcpp(E_STOPWATCH)
forte_add_sourcefile_hcpp(OUT_ANY_CONSOLE GEN_F_MUX GEN_CSV_WRITER GEN_APPEND_STRING)
forte_add_sourcefile_hcpp(GEN_ARRAY2VALUES GEN_VALUES2ARRAY GEN_ARRAY2ARRAY GET_AT_INDEX SET_AT_INDEX)
forte_add_sourcefile_hcpp(FB_RANDOM GET_STRUCT_VALUE)
diff --git a/src/modules/utils/E_STOPWATCH.cpp b/src/modules/utils/E_STOPWATCH.cpp
index 55c9666..646a5f5 100644
--- a/src/modules/utils/E_STOPWATCH.cpp
+++ b/src/modules/utils/E_STOPWATCH.cpp
@@ -1,91 +1,111 @@
-/*******************************************************************************
- * Copyright (c) 2018 fortiss GmbH
+/*******************************************************************************
+ * Copyright (c) 2018 fortiss GmbH
+ * 2020 Johannes Kepler University Linz
+ *
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Ben Schneider
- * - initial API and implementation and/or initial documentation
- *******************************************************************************/
-
-#include "E_STOPWATCH.h"
-#ifdef FORTE_ENABLE_GENERATED_SOURCE_CPP
-#include "E_STOPWATCH_gen.cpp"
-#endif
-
-DEFINE_FIRMWARE_FB(FORTE_E_STOPWATCH, g_nStringIdE_STOPWATCH)
-
-const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anDataOutputNames[] = {g_nStringIdTD};
-
-const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anDataOutputTypeIds[] = {g_nStringIdTIME};
-
-const TForteInt16 FORTE_E_STOPWATCH::scm_anEIWithIndexes[] = {-1, -1};
-const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anEventInputNames[] = {g_nStringIdSTART, g_nStringIdSTOP};
-
-const TDataIOID FORTE_E_STOPWATCH::scm_anEOWith[] = {0, 255};
-const TForteInt16 FORTE_E_STOPWATCH::scm_anEOWithIndexes[] = {0, -1};
-const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anEventOutputNames[] = {g_nStringIdEO};
-
-const SFBInterfaceSpec FORTE_E_STOPWATCH::scm_stFBInterfaceSpec = {
- 2, scm_anEventInputNames, 0, scm_anEIWithIndexes,
- 1, scm_anEventOutputNames, scm_anEOWith, scm_anEOWithIndexes, 0, 0, 0,
- 1, scm_anDataOutputNames, scm_anDataOutputTypeIds,
- 0, 0
-};
-
-void FORTE_E_STOPWATCH::writeElapsedTimeToTD(){
-
- mCurrentTime = static_cast<int>(chrono::duration_cast<chrono::microseconds>(m_end - m_begin).count());
- TD().setFromMicroSeconds(mCurrentTime);
-}
-
-void FORTE_E_STOPWATCH::enterStateSTART(void){
- m_nECCState = scm_nStateSTART;
-}
-
-void FORTE_E_STOPWATCH::enterStateMeasure(void){
- m_nECCState = scm_nStateMeasure;
- m_begin = chrono::high_resolution_clock::now();
-}
-
-void FORTE_E_STOPWATCH::enterStateStopped(void){
- m_nECCState = scm_nStateStopped;
- m_end = chrono::high_resolution_clock::now();
- writeElapsedTimeToTD();
- sendOutputEvent( scm_nEventEOID);
-}
-
-void FORTE_E_STOPWATCH::executeEvent(int pa_nEIID){
- bool bTransitionCleared;
- do{
- bTransitionCleared = true;
- switch(m_nECCState){
- case scm_nStateSTART:
- if(scm_nEventSTARTID == pa_nEIID)
- enterStateMeasure();
- else
- bTransitionCleared = false; //no transition cleared
- break;
- case scm_nStateMeasure:
- if(scm_nEventSTOPID == pa_nEIID)
- enterStateStopped();
- else
- bTransitionCleared = false; //no transition cleared
- break;
- case scm_nStateStopped:
- if(1)
- enterStateSTART();
- else
- bTransitionCleared = false; //no transition cleared
- break;
- default:
- DEVLOG_ERROR("The state is not in the valid range! The state value is: %d. The max value can be: 2.", m_nECCState.operator TForteUInt16 ());
- m_nECCState = 0; //0 is always the initial state
- break;
- }
- pa_nEIID = cg_nInvalidEventID; // we have to clear the event after the first check in order to ensure correct behavior
- }while(bTransitionCleared);
-}
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ben Schneider - initial API and implementation and/or initial documentation
+ * Alois Zoitl - Changed to a full basic FB implementation utilizing the new
+ * NOW_MONOTONIC function
+ *******************************************************************************/
+
+#include "E_STOPWATCH.h"
+#ifdef FORTE_ENABLE_GENERATED_SOURCE_CPP
+#include "E_STOPWATCH_gen.cpp"
+#endif
+
+
+DEFINE_FIRMWARE_FB(FORTE_E_STOPWATCH, g_nStringIdE_STOPWATCH)
+
+
+const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anDataOutputNames[] = {g_nStringIdTD};
+
+const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anDataOutputTypeIds[] = {g_nStringIdTIME};
+
+const TDataIOID FORTE_E_STOPWATCH::scm_anEIWith[] = {};
+const TForteInt16 FORTE_E_STOPWATCH::scm_anEIWithIndexes[] = {-1, -1};
+const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anEventInputNames[] = {g_nStringIdSTART, g_nStringIdSTOP};
+
+const TDataIOID FORTE_E_STOPWATCH::scm_anEOWith[] = {0, 255};
+const TForteInt16 FORTE_E_STOPWATCH::scm_anEOWithIndexes[] = {0};
+const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anEventOutputNames[] = {g_nStringIdEO};
+
+
+const SFBInterfaceSpec FORTE_E_STOPWATCH::scm_stFBInterfaceSpec = {
+ 2, scm_anEventInputNames, scm_anEIWith, scm_anEIWithIndexes,
+ 1, scm_anEventOutputNames, scm_anEOWith, scm_anEOWithIndexes,
+ 0, 0, 0,
+ 1, scm_anDataOutputNames, scm_anDataOutputTypeIds,
+ 0, 0
+};
+
+const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anInternalsNames[] = {g_nStringIdstartTime};
+const CStringDictionary::TStringId FORTE_E_STOPWATCH::scm_anInternalsTypeIds[] = {g_nStringIdTIME};
+
+const SInternalVarsInformation FORTE_E_STOPWATCH::scm_stInternalVars = {1, scm_anInternalsNames, scm_anInternalsTypeIds};
+
+
+
+void FORTE_E_STOPWATCH::alg_captureStartTime(void) {
+ st_startTime() = NOW_MONOTONIC();
+}
+
+void FORTE_E_STOPWATCH::alg_calcDiff(void) {
+ st_TD() = (NOW_MONOTONIC() - st_startTime());
+}
+
+
+void FORTE_E_STOPWATCH::enterStateSTART(void) {
+ m_nECCState = scm_nStateSTART;
+}
+
+void FORTE_E_STOPWATCH::enterStateMeasure(void) {
+ m_nECCState = scm_nStateMeasure;
+ alg_captureStartTime();
+}
+
+void FORTE_E_STOPWATCH::enterStateSTOP(void) {
+ m_nECCState = scm_nStateSTOP;
+ alg_calcDiff();
+ sendOutputEvent(scm_nEventEOID);
+}
+
+
+void FORTE_E_STOPWATCH::executeEvent(int pa_nEIID){
+ bool bTransitionCleared;
+ do {
+ bTransitionCleared = true;
+ switch(m_nECCState) {
+ case scm_nStateSTART:
+ if(scm_nEventSTARTID == pa_nEIID)
+ enterStateMeasure();
+ else
+ bTransitionCleared = false; //no transition cleared
+ break;
+ case scm_nStateMeasure:
+ if(scm_nEventSTOPID == pa_nEIID)
+ enterStateSTOP();
+ else
+ bTransitionCleared = false; //no transition cleared
+ break;
+ case scm_nStateSTOP:
+ if(1)
+ enterStateSTART();
+ else
+ bTransitionCleared = false; //no transition cleared
+ break;
+ default:
+ DEVLOG_ERROR("The state is not in the valid range! The state value is: %d. The max value can be: 3.", m_nECCState.operator TForteUInt16 ());
+ m_nECCState = 0; // 0 is always the initial state
+ break;
+ }
+ pa_nEIID = cg_nInvalidEventID; // we have to clear the event after the first check in order to ensure correct behavior
+ } while(bTransitionCleared);
+}
+
+
diff --git a/src/modules/utils/E_STOPWATCH.h b/src/modules/utils/E_STOPWATCH.h
index ed39b80..b443e15 100644
--- a/src/modules/utils/E_STOPWATCH.h
+++ b/src/modules/utils/E_STOPWATCH.h
@@ -1,71 +1,87 @@
-/*******************************************************************************
- * Copyright (c) 2018 fortiss GmbH
+/*******************************************************************************
+ * Copyright (c) 2018 fortiss GmbH
+ * 2020 Johannes Kepler University Linz
+ *
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Ben Schneider
- * - initial API and implementation and/or initial documentation
- *******************************************************************************/
-
-#ifndef _E_STOPWATCH_H_
-#define _E_STOPWATCH_H_
-
-#include <basicfb.h>
-#include <forte_time.h>
-
-#include <chrono>
-using namespace std;
-
-class FORTE_E_STOPWATCH: public CBasicFB{
- DECLARE_FIRMWARE_FB(FORTE_E_STOPWATCH)
-
-private:
- chrono::time_point <chrono::high_resolution_clock> m_begin, m_end;
- int mCurrentTime = 0;
-
- static const CStringDictionary::TStringId scm_anDataOutputNames[];
- static const CStringDictionary::TStringId scm_anDataOutputTypeIds[];
- CIEC_TIME &TD() {
- return *static_cast<CIEC_TIME*>(getDO(0));
- };
-
- static const TEventID scm_nEventSTARTID = 0;
- static const TEventID scm_nEventSTOPID = 1;
- static const TForteInt16 scm_anEIWithIndexes[];
- static const CStringDictionary::TStringId scm_anEventInputNames[];
-
- static const TEventID scm_nEventEOID = 0;
- static const TForteInt16 scm_anEOWithIndexes[];
- static const TDataIOID scm_anEOWith[];
- static const CStringDictionary::TStringId scm_anEventOutputNames[];
-
- static const SFBInterfaceSpec scm_stFBInterfaceSpec;
-
- FORTE_BASIC_FB_DATA_ARRAY(1, 0, 1, 0, 0);
- static const TForteInt16 scm_nStateSTART = 0;
- static const TForteInt16 scm_nStateMeasure = 1;
- static const TForteInt16 scm_nStateStopped = 2;
-
- void enterStateSTART(void);
- void enterStateMeasure(void);
- void enterStateStopped(void);
-
- virtual void executeEvent(int pa_nEIID);
-
- void writeElapsedTimeToTD(void);
-
-public:
- FORTE_E_STOPWATCH(CStringDictionary::TStringId pa_nInstanceNameId, CResource *pa_poSrcRes) :
- CBasicFB(pa_poSrcRes, &scm_stFBInterfaceSpec, pa_nInstanceNameId,
- 0, m_anFBConnData, m_anFBVarsData){
- };
-
- virtual ~FORTE_E_STOPWATCH(){};
-
-};
-
-#endif //close the ifdef sequence from the beginning of the file
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Ben Schneider - initial API and implementation and/or initial documentation
+ * Alois Zoitl - Changed to a full basic FB implementation utilizing the new
+ * NOW_MONOTONIC function
+ *******************************************************************************/
+
+#ifndef _E_STOPWATCH_H_
+#define _E_STOPWATCH_H_
+
+#include "basicfb.h"
+#include "forte_time.h"
+#include "forte_array_at.h"
+
+
+class FORTE_E_STOPWATCH: public CBasicFB {
+ DECLARE_FIRMWARE_FB(FORTE_E_STOPWATCH)
+
+private:
+
+ static const CStringDictionary::TStringId scm_anDataOutputNames[];
+ static const CStringDictionary::TStringId scm_anDataOutputTypeIds[];
+
+ static const TEventID scm_nEventSTARTID = 0;
+ static const TEventID scm_nEventSTOPID = 1;
+
+ static const TDataIOID scm_anEIWith[];
+ static const TForteInt16 scm_anEIWithIndexes[];
+ static const CStringDictionary::TStringId scm_anEventInputNames[];
+
+ static const TEventID scm_nEventEOID = 0;
+
+ static const TDataIOID scm_anEOWith[];
+ static const TForteInt16 scm_anEOWithIndexes[];
+ static const CStringDictionary::TStringId scm_anEventOutputNames[];
+
+
+ static const SFBInterfaceSpec scm_stFBInterfaceSpec;
+
+ static const CStringDictionary::TStringId scm_anInternalsNames[];
+ static const CStringDictionary::TStringId scm_anInternalsTypeIds[];
+ static const SInternalVarsInformation scm_stInternalVars;
+
+ CIEC_TIME &st_TD() {
+ return *static_cast<CIEC_TIME*>(getDO(0));
+ }
+
+ CIEC_TIME &st_startTime() {
+ return *static_cast<CIEC_TIME*>(getVarInternal(0));
+ }
+
+
+ void alg_captureStartTime(void);
+ void alg_calcDiff(void);
+
+ static const TForteInt16 scm_nStateSTART = 0;
+ static const TForteInt16 scm_nStateMeasure = 1;
+ static const TForteInt16 scm_nStateSTOP = 2;
+
+ void enterStateSTART(void);
+ void enterStateMeasure(void);
+ void enterStateSTOP(void);
+
+ virtual void executeEvent(int pa_nEIID);
+
+ FORTE_BASIC_FB_DATA_ARRAY(1, 0, 1, 1, 0);
+
+public:
+ FORTE_E_STOPWATCH(CStringDictionary::TStringId pa_nInstanceNameId, CResource *pa_poSrcRes) :
+ CBasicFB(pa_poSrcRes, &scm_stFBInterfaceSpec, pa_nInstanceNameId, &scm_stInternalVars, m_anFBConnData, m_anFBVarsData) {
+ };
+
+ virtual ~FORTE_E_STOPWATCH(){};
+};
+
+#endif // _E_STOPWATCH_H_
+
+