Start from scope plugin
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
# Data source
|
||||
record(waveform,"$(P)Plugin-Scope${INDEX}-DataSource"){
|
||||
field(DESC, "Data source name")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(${PORT},$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt8ArrayIn/plugin.scope${INDEX}.source?")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "1024")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
record(waveform,"$(P)Plugin-Scope${INDEX}-TriggSource"){
|
||||
field(DESC, "Trigger source name")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(${PORT},$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt8ArrayIn/plugin.scope${INDEX}.trigg?")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "1024")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
record(waveform,"$(P)Plugin-Scope${INDEX}-NextTimeSource"){
|
||||
field(DESC, "Trigger source name")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "asynInt8ArrayIn")
|
||||
field(INP, "@asyn(${PORT},$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt8ArrayIn/plugin.scope${INDEX}.nexttime?")
|
||||
field(FTVL, "CHAR")
|
||||
field(NELM, "1024")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
# result
|
||||
record(waveform,"$(P)Plugin-Scope${INDEX}-Data-Act"){
|
||||
info(asyn:FIFO, "1000")
|
||||
field(DESC, "Result data")
|
||||
field(PINI, "1")
|
||||
field(DTYP, "${RESULT_DTYP}")
|
||||
field(INP, "@asyn(${PORT},$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=-1)/TYPE=${RESULT_DTYP}/plugin.scope${INDEX}.resultdata?")
|
||||
field(FTVL, "${RESULT_FTVL}")
|
||||
field(NELM, "${RESULT_NELM}")
|
||||
field(SCAN, "I/O Intr")
|
||||
field(TSE, "0")
|
||||
}
|
||||
|
||||
record(bo,"$(P)Plugin-Scope${INDEX}-Enable"){
|
||||
field(DESC, "FFT Enable")
|
||||
field(DTYP,"asynInt32")
|
||||
field(OUT, "@asyn(${PORT},$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt32/plugin.scope${INDEX}.enable=")
|
||||
field(ZNAM,"FALSE")
|
||||
field(ONAM,"TRUE")
|
||||
field(DOL, "0")
|
||||
field(VAL, "0")
|
||||
}
|
||||
|
||||
record(ai,"$(P)Plugin-Scope${INDEX}-MissTriggCntAct"){
|
||||
field(PINI, "1")
|
||||
field(DESC, "Missed trigger counter")
|
||||
field(DTYP,"asynInt32")
|
||||
field(INP, "@asyn(${PORT},$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt32/plugin.scope${INDEX}.missed?")
|
||||
field(SCAN, "I/O Intr")
|
||||
}
|
||||
|
||||
record(ai,"$(P)Plugin-Scope${INDEX}-ScanToTriggSamples"){
|
||||
field(PINI, "1")
|
||||
field(DESC, "Samples between now and trigger []")
|
||||
field(DTYP,"asynFloat64")
|
||||
field(INP, "@asyn(${PORT},$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynFloat64/plugin.scope${INDEX}.scantotrigg?")
|
||||
field(SCAN, "I/O Intr")
|
||||
}
|
||||
|
||||
record(ai,"$(P)Plugin-Scope${INDEX}-TriggCntAct"){
|
||||
field(PINI, "1")
|
||||
field(DESC, "Trigger counter")
|
||||
field(DTYP,"asynInt32")
|
||||
field(INP, "@asyn(${PORT},$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt32/plugin.scope${INDEX}.count?")
|
||||
field(SCAN, "I/O Intr")
|
||||
}
|
||||
|
||||
#record(bo,"$(P)Plugin-Scope${INDEX}-Trigg"){
|
||||
# field(DESC, "FFT Trigg measurement")
|
||||
# field(DTYP,"asynInt32")
|
||||
# field(OUT, "@asyn(${PORT},$(ADDR=0),$(TIMEOUT=1000))T_SMP_MS=$(T_SMP_MS=1000)/TYPE=asynInt32/plugin.scope${INDEX}.trigg")
|
||||
# field(ZNAM,"FALSE")
|
||||
# field(ONAM,"TRUE")
|
||||
# field(DOL, "0")
|
||||
# field(VAL, "0")
|
||||
#}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2019 European Spallation Source ERIC
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcPluginScope.cpp
|
||||
*
|
||||
* Created on: Sept 21, 2020
|
||||
* Author: anderssandstrom
|
||||
*
|
||||
\*************************************************************************/
|
||||
|
||||
// Needed to get headers in ecmc right...
|
||||
#define ECMC_IS_PLUGIN
|
||||
#define ECMC_EXAMPLE_PLUGIN_VERSION 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ecmcPluginDefs.h"
|
||||
#include "ecmcScopeDefs.h"
|
||||
#include "ecmcScopeWrap.h"
|
||||
|
||||
static int lastEcmcError = 0;
|
||||
static char* lastConfStr = NULL;
|
||||
|
||||
/** Optional.
|
||||
* Will be called once after successfull load into ecmc.
|
||||
* Return value other than 0 will be considered error.
|
||||
* configStr can be used for configuration parameters.
|
||||
**/
|
||||
int scopeConstruct(char *configStr)
|
||||
{
|
||||
//This module is allowed to load several times so no need to check if loaded
|
||||
|
||||
// create FFT object and register data callback
|
||||
lastConfStr = strdup(configStr);
|
||||
return createScope(configStr);
|
||||
}
|
||||
|
||||
/** Optional function.
|
||||
* Will be called once at unload.
|
||||
**/
|
||||
void scopeDestruct(void)
|
||||
{
|
||||
deleteAllScopes();
|
||||
if(lastConfStr){
|
||||
free(lastConfStr);
|
||||
}
|
||||
}
|
||||
|
||||
/** Optional function.
|
||||
* Will be called each realtime cycle if definded
|
||||
* ecmcError: Error code of ecmc. Makes it posible for
|
||||
* this plugin to react on ecmc errors
|
||||
* Return value other than 0 will be considered to be an error code in ecmc.
|
||||
**/
|
||||
int scopeRealtime(int ecmcError)
|
||||
{
|
||||
lastEcmcError = ecmcError;
|
||||
return executeScopes();
|
||||
}
|
||||
|
||||
/** Link to data source here since all sources should be availabe at this stage
|
||||
* (for example ecmc PLC variables are defined only at enter of realtime)
|
||||
**/
|
||||
int scopeEnterRT(){
|
||||
return linkDataToScopes();
|
||||
}
|
||||
|
||||
/** Optional function.
|
||||
* Will be called once just before leaving realtime mode
|
||||
* Return value other than 0 will be considered error.
|
||||
**/
|
||||
int scopeExitRT(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// // Plc function for clear of buffers
|
||||
// double scope_clear(double index) {
|
||||
// return (double)clearScope((int)index);
|
||||
// }
|
||||
|
||||
// Plc function for enable
|
||||
double scope_enable(double index, double enable) {
|
||||
return (double)enableScope((int)index, (int)enable);
|
||||
}
|
||||
|
||||
// // Plc function for trigg new measurement (will clear buffers)
|
||||
// double scope_trigg(double index) {
|
||||
// return (double)triggScope((int)index);
|
||||
// }
|
||||
|
||||
// Register data for plugin so ecmc know what to use
|
||||
struct ecmcPluginData pluginDataDef = {
|
||||
// Allways use ECMC_PLUG_VERSION_MAGIC
|
||||
.ifVersion = ECMC_PLUG_VERSION_MAGIC,
|
||||
// Name
|
||||
.name = "ecmcPlugin_Scope",
|
||||
// Description
|
||||
.desc = "Scope plugin for use with ecmc.",
|
||||
// Option description
|
||||
.optionDesc = "\n "ECMC_PLUGIN_DBG_PRINT_OPTION_CMD"<1/0> : Enables/disables printouts from plugin, default = disabled.\n"
|
||||
" "ECMC_PLUGIN_SOURCE_OPTION_CMD"<source> : Ec source variable (example: ec0.s1.mm.CH1_ARRAY).\n"
|
||||
" "ECMC_PLUGIN_RESULT_ELEMENTS_OPTION_CMD"<Result buffer size> : Data points to collect, default = 4096.\n"
|
||||
" "ECMC_PLUGIN_SOURCE_NEXTTIME_OPTION_CMD"<nexttime> : Ec next sync time for source (example: ec0.s1.NEXTTIME)\n"
|
||||
" "ECMC_PLUGIN_TRIGG_OPTION_CMD"<trigger> : Ec trigg time (example: ec0.s2.LATCH_POS).\n"
|
||||
" "ECMC_PLUGIN_ENABLE_OPTION_CMD"<1/0> : Enable data acq, defaults to enabled.\n"
|
||||
,
|
||||
// Plugin version
|
||||
.version = ECMC_EXAMPLE_PLUGIN_VERSION,
|
||||
// Optional construct func, called once at load. NULL if not definded.
|
||||
.constructFnc = scopeConstruct,
|
||||
// Optional destruct func, called once at unload. NULL if not definded.
|
||||
.destructFnc = scopeDestruct,
|
||||
// Optional func that will be called each rt cycle. NULL if not definded.
|
||||
.realtimeFnc = scopeRealtime,
|
||||
// Optional func that will be called once just before enter realtime mode
|
||||
.realtimeEnterFnc = scopeEnterRT,
|
||||
// Optional func that will be called once just before exit realtime mode
|
||||
.realtimeExitFnc = scopeExitRT,
|
||||
// PLC funcs
|
||||
.funcs[0] =
|
||||
{ /*----fft_clear----*/
|
||||
// Function name (this is the name you use in ecmc plc-code)
|
||||
.funcName = "scope_enable",
|
||||
// Function description
|
||||
.funcDesc = "scope_enable(index,enable) : Enable/disaable scope[index].",
|
||||
/**
|
||||
* 12 different prototypes allowed (only doubles since reg in plc).
|
||||
* Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||
**/
|
||||
.funcArg0 = NULL,
|
||||
.funcArg1 = NULL,
|
||||
.funcArg2 = scope_enable,
|
||||
.funcArg3 = NULL,
|
||||
.funcArg4 = NULL,
|
||||
.funcArg5 = NULL,
|
||||
.funcArg6 = NULL,
|
||||
.funcArg7 = NULL,
|
||||
.funcArg8 = NULL,
|
||||
.funcArg9 = NULL,
|
||||
.funcArg10 = NULL,
|
||||
.funcGenericObj = NULL,
|
||||
},
|
||||
.consts[0] = {0}, // last element set all to zero..
|
||||
};
|
||||
|
||||
ecmc_plugin_register(pluginDataDef);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif // ifdef __cplusplus
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,131 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2019 European Spallation Source ERIC
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcScope.h
|
||||
*
|
||||
* Created on: Mar 22, 2020
|
||||
* Author: anderssandstrom
|
||||
*
|
||||
\*************************************************************************/
|
||||
#ifndef ECMC_SCOPE_H_
|
||||
#define ECMC_SCOPE_H_
|
||||
|
||||
#include <stdexcept>
|
||||
#include "ecmcDataItem.h"
|
||||
#include "ecmcAsynPortDriver.h"
|
||||
#include "ecmcScopeDefs.h"
|
||||
#include "inttypes.h"
|
||||
#include <string>
|
||||
|
||||
typedef enum {
|
||||
ECMC_SCOPE_STATE_INVALID, /**Invalid. */
|
||||
ECMC_SCOPE_STATE_WAIT_TRIGG, /**Waiting for trigger. */
|
||||
ECMC_SCOPE_STATE_WAIT_NEXT, /**Waiting analog. (trigger newer than next ai time)*/
|
||||
ECMC_SCOPE_STATE_COLLECT, /**Filling buffer (waiting for data). */
|
||||
} ecmcScopeState;
|
||||
|
||||
class ecmcScope {
|
||||
public:
|
||||
|
||||
/** ecmc Scope class
|
||||
* This object can throw:
|
||||
* - bad_alloc
|
||||
* - invalid_argument
|
||||
* - runtime_error
|
||||
* - out_of_range
|
||||
*/
|
||||
ecmcScope(int scopeIndex, // index of this object
|
||||
char* configStr);
|
||||
~ecmcScope();
|
||||
|
||||
// Add data to buffer (called from "external" callback)
|
||||
// void dataUpdatedCallback(uint8_t* data,
|
||||
// size_t size,
|
||||
// ecmcEcDataType dt);
|
||||
// Call just before realtime because then all data sources should be available
|
||||
void connectToDataSources();
|
||||
void setEnable(int enable);
|
||||
//void clearBuffers();
|
||||
void triggScope();
|
||||
void execute();
|
||||
|
||||
private:
|
||||
void parseConfigStr(char *configStr);
|
||||
void addDataToBuffer(double data);
|
||||
bool sourceDataTypeSupported(ecmcEcDataType dt);
|
||||
void initAsyn();
|
||||
int64_t timeDiff();
|
||||
asynParamType getResultAsynDTFromEcDT(ecmcEcDataType ecDT);
|
||||
void setWaitForNextTrigg();
|
||||
|
||||
|
||||
uint8_t* resultDataBuffer_;
|
||||
uint8_t* lastScanSourceDataBuffer_;
|
||||
size_t resultDataBufferBytes_;
|
||||
size_t bytesInResultBuffer_;
|
||||
ecmcDataItem *sourceDataItem_;
|
||||
ecmcDataItemInfo *sourceDataItemInfo_;
|
||||
ecmcDataItem *sourceDataNexttimeItem_;
|
||||
ecmcDataItemInfo *sourceDataNexttimeItemInfo_;
|
||||
ecmcDataItem *sourceTriggItem_;
|
||||
ecmcDataItemInfo *sourceTriggItemInfo_;
|
||||
|
||||
int dataSourceLinked_; // To avoid link several times
|
||||
int objectId_; // Unique object id
|
||||
int triggOnce_;
|
||||
int firstTrigg_;
|
||||
|
||||
uint64_t triggTime_;
|
||||
uint64_t oldTriggTime_;
|
||||
uint64_t sourceNexttime_;
|
||||
int64_t sourceSampleRateNS_; // nanoseconds
|
||||
ecmcScopeState scopeState_;
|
||||
uint64_t ecmcSmapleTimeNS_;
|
||||
int64_t sourceElementsPerSample_;
|
||||
size_t elementsInResultBuffer_;
|
||||
double samplesSinceLastTrigg_;
|
||||
|
||||
// Config options
|
||||
char* cfgDataSourceStr_; // Config: data source string
|
||||
char* cfgDataNexttimeStr_; // Config: data source string
|
||||
char* cfgTriggStr_; // Config: trigg string
|
||||
int cfgDbgMode_; // Config: allow dbg printouts
|
||||
size_t cfgBufferElementCount_; // Config: Data set size
|
||||
int cfgEnable_; // Config: Enable data acq./calc.
|
||||
|
||||
int missedTriggs_;
|
||||
int triggerCounter_;
|
||||
|
||||
// Asyn
|
||||
ecmcAsynDataItem *sourceStrParam_;
|
||||
ecmcAsynDataItem *triggStrParam_;
|
||||
ecmcAsynDataItem *enbaleParam_;
|
||||
ecmcAsynDataItem *resultParam_;
|
||||
ecmcAsynDataItem *sourceNexttimeStrParam_;
|
||||
ecmcAsynDataItem *asynMissedTriggs_;
|
||||
ecmcAsynDataItem *asynTriggerCounter_;
|
||||
ecmcAsynDataItem *asynTimeTrigg2Sample_;
|
||||
|
||||
|
||||
// Some generic utility functions
|
||||
static uint8_t getUint8(uint8_t* data);
|
||||
static int8_t getInt8(uint8_t* data);
|
||||
static uint16_t getUint16(uint8_t* data);
|
||||
static int16_t getInt16(uint8_t* data);
|
||||
static uint32_t getUint32(uint8_t* data);
|
||||
static int32_t getInt32(uint8_t* data);
|
||||
static uint64_t getUint64(uint8_t* data);
|
||||
static int64_t getInt64(uint8_t* data);
|
||||
static float getFloat32(uint8_t* data);
|
||||
static double getFloat64(uint8_t* data);
|
||||
static size_t getEcDataTypeByteSize(ecmcEcDataType dt);
|
||||
static void printEcDataArray(uint8_t* data,
|
||||
size_t size,
|
||||
ecmcEcDataType dt,
|
||||
int objId);
|
||||
static std::string to_string(int value);
|
||||
};
|
||||
|
||||
#endif /* ECMC_SCOPE_H_ */
|
||||
@@ -0,0 +1,28 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2019 European Spallation Source ERIC
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcScopeDefs.h
|
||||
*
|
||||
* Created on: Sept 21, 2020
|
||||
* Author: anderssandstrom
|
||||
* Credits to https://github.com/sgreg/dynamic-loading
|
||||
*
|
||||
\*************************************************************************/
|
||||
|
||||
#ifndef ECMC_SCOPE_DEFS_H_
|
||||
#define ECMC_SCOPE_DEFS_H_
|
||||
|
||||
// Options
|
||||
#define ECMC_PLUGIN_DBG_PRINT_OPTION_CMD "DBG_PRINT="
|
||||
#define ECMC_PLUGIN_SOURCE_OPTION_CMD "SOURCE="
|
||||
#define ECMC_PLUGIN_SOURCE_NEXTTIME_OPTION_CMD "SOURCE_NEXTTIME="
|
||||
#define ECMC_PLUGIN_TRIGG_OPTION_CMD "TRIGG="
|
||||
#define ECMC_PLUGIN_RESULT_ELEMENTS_OPTION_CMD "RESULT_ELEMENTS="
|
||||
#define ECMC_PLUGIN_ENABLE_OPTION_CMD "ENABLE="
|
||||
|
||||
// Default size (must be n²)
|
||||
#define ECMC_PLUGIN_DEFAULT_BUFFER_SIZE 4096
|
||||
|
||||
#endif /* ECMC_SCOPE_DEFS_H_ */
|
||||
@@ -0,0 +1,121 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2019 European Spallation Source ERIC
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcScopeWrap.cpp
|
||||
*
|
||||
* Created on: Sept 21, 2020
|
||||
* Author: anderssandstrom
|
||||
* Credits to https://github.com/sgreg/dynamic-loading
|
||||
*
|
||||
\*************************************************************************/
|
||||
|
||||
// Needed to get headers in ecmc right...
|
||||
#define ECMC_IS_PLUGIN
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include "ecmcScopeWrap.h"
|
||||
#include "ecmcScope.h"
|
||||
#include "ecmcScopeDefs.h"
|
||||
|
||||
#define ECMC_PLUGIN_PORTNAME_PREFIX "PLUGIN.SCOPE"
|
||||
#define ECMC_PLUGIN_SCOPE_ERROR_CODE 1
|
||||
|
||||
static std::vector<ecmcScope*> scopes;
|
||||
static int scopeObjCounter = 0;
|
||||
|
||||
int createScope(char* configStr) {
|
||||
|
||||
// create new ecmcFFT object
|
||||
ecmcScope* scope = NULL;
|
||||
|
||||
try {
|
||||
scope = new ecmcScope(scopeObjCounter, configStr);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
if(scope) {
|
||||
delete scope;
|
||||
}
|
||||
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
|
||||
scopes.push_back(scope);
|
||||
scopeObjCounter++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void deleteAllScopes() {
|
||||
for(std::vector<ecmcScope*>::iterator pscope = scopes.begin(); pscope != scopes.end(); ++pscope) {
|
||||
if(*pscope) {
|
||||
delete (*pscope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int linkDataToScopes() {
|
||||
for(std::vector<ecmcScope*>::iterator pscope = scopes.begin(); pscope != scopes.end(); ++pscope) {
|
||||
if(*pscope) {
|
||||
try {
|
||||
(*pscope)->connectToDataSources();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Plugin will unload.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enableScope(int scopeIndex, int enable) {
|
||||
try {
|
||||
scopes.at(scopeIndex)->setEnable(enable);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Scope index out of range.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// int clearScope(int scopeIndex) {
|
||||
// try {
|
||||
// scopes.at(scopeIndex)->clearBuffers();
|
||||
// }
|
||||
// catch(std::exception& e) {
|
||||
// printf("Exception: %s. Scope index out of range.\n",e.what());
|
||||
// return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
int triggScope(int scopeIndex) {
|
||||
try {
|
||||
scopes.at(scopeIndex)->triggScope();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Scope index out of range.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int executeScopes() {
|
||||
try {
|
||||
for(std::vector<ecmcScope*>::iterator pscope = scopes.begin(); pscope != scopes.end(); ++pscope) {
|
||||
if(*pscope) {
|
||||
(*pscope)->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s.\n",e.what());
|
||||
return ECMC_PLUGIN_SCOPE_ERROR_CODE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2019 European Spallation Source ERIC
|
||||
* ecmc is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*
|
||||
* ecmcScopeWrap.h
|
||||
*
|
||||
* Created on: Sept 21, 2020
|
||||
* Author: anderssandstrom
|
||||
*
|
||||
\*************************************************************************/
|
||||
#ifndef ECMC_SCOPE_WRAP_H_
|
||||
#define ECMC_SCOPE_WRAP_H_
|
||||
#include "ecmcScopeDefs.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif // ifdef __cplusplus
|
||||
|
||||
int createScope(char *configStr);
|
||||
|
||||
int enableScope(int scopeIndex, int enable);
|
||||
|
||||
//int clearScope(int scopeIndex);
|
||||
|
||||
int triggScope(int scopeIndex);
|
||||
|
||||
|
||||
int executeScopes();
|
||||
|
||||
/** \brief Link data to _all_ scope objects
|
||||
*
|
||||
* This tells the Scope lib to connect to ecmc to find it's data source.\n
|
||||
* This function should be called just before entering realtime since then all\n
|
||||
* data sources in ecmc will be definded (plc sources are compiled just before runtime\n
|
||||
* so are only fist accesible now).\n
|
||||
* \return 0 if success or otherwise an error code.\n
|
||||
*/
|
||||
int linkDataToScopes();
|
||||
|
||||
/** \brief Deletes all created scope objects\n
|
||||
*
|
||||
* Should be called when destructs.\n
|
||||
*/
|
||||
|
||||
void deleteAllScopes();
|
||||
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif // ifdef __cplusplus
|
||||
|
||||
#endif /* ECMC_SCOPE_WRAP_H_ */
|
||||
Reference in New Issue
Block a user