This commit is contained in:
2024-03-04 21:30:23 +01:00
parent e7d90c550a
commit 16f1795e32
9 changed files with 160 additions and 47 deletions

View File

@@ -45,20 +45,52 @@ ${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=./cfg/axis.yaml,LIMIT=1
#
require ecmc_plugin_daq sandst_a "PLUGIN_ID=0"
ecmcAddDAQArray("test",PLUGIN.DAQ.test)
ecmcAddDAQChannel(123)
ecmcAddDAQItem(ec0.s13.ONE,0)
ecmcAddDAQItem(ax1.actpos,0)
ecmcAddDAQItem(ec0.s13.positionActual01,0)
ecmcAddDAQItem(ec0.s13.ONE,0)
ecmcAddDAQItem(ax1.setpos,0)
ecmcAddDAQChannel(12)
ecmcAddDAQItem(ec0.s13.positionActual01,0)
ecmcAddDAQItem(ec0.s13.positionActual01,0)
ecmcAddDAQItem(ec0.s13.positionActual01,0)
ecmcAddDAQItem(ec0.s13.ONE,0)
ecmcAddDAQItem(ec0.s13.ONE,0)
ecmcAddDAQItem(ax1.setpos,0)
#ecmcAddDAQArray("test",PLUGIN.DAQ.test)
#ecmcAddDAQChannel(123)
#ecmcAddDAQItem(ec0.s13.ONE,0)
#ecmcAddDAQItem(ax1.actpos,0)
#ecmcAddDAQItem(ec0.s13.positionActual01,0)
#ecmcAddDAQItem(ec0.s13.ONE,0)
#ecmcAddDAQItem(ax1.setpos,0)
#ecmcAddDAQChannel(12)
#ecmcAddDAQItem(ec0.s13.positionActual01,0)
#ecmcAddDAQItem(ec0.s13.positionActual01,0)
#ecmcAddDAQItem(ec0.s13.positionActual01,0)
#ecmcAddDAQItem(ec0.s13.ONE,0)
#ecmcAddDAQItem(ec0.s13.ONE,0)
#ecmcAddDAQItem(ax1.setpos,0)
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqArray.cmd, "NAME=Testing1"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqChannel.cmd, "TYPE=1234"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.ONE,FORMAT=2"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.positionActual01"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.positionActual01"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqChannel.cmd, "TYPE=4321"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.ONE,FORMAT=2"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.positionActual01"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcLoadDaqArrayRecords.cmd "NAME=Testing1"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqArray.cmd, "NAME=Testing2"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqChannel.cmd, "TYPE=1234"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.ONE,FORMAT=2"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.positionActual01"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.positionActual01"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqChannel.cmd, "TYPE=4321"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.ONE,FORMAT=2"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ec0.s13.positionActual01"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcAddDaqDataItem.cmd, "PARAM=ax1.setpos"
${SCRIPTEXEC} ${ecmc_plugin_daq_DIR}ecmcLoadDaqArrayRecords.cmd "NAME=Testing2"
##############################################################################
## Configure diagnostics:

View File

@@ -229,17 +229,24 @@ class ecmcDAQChannelItem {
return data;
}
/* Returns true if all data have been retruned with getData().
*/
bool empty(){
return dataIndexToReturn_ >= dataElementCount_;
}
size_t getDataElementCount(){
size_t getDataElementCount(){
return dataElementCount_;
}
int validate() {
if(dataElementCount_==0) {
throw std::runtime_error("Error: DAQ-data item element count 0");
}
return 0;
}
ecmcDataItem* dataItem_;
ecmcDataItemInfo* dataItemInfo_;
std::string name_;

View File

@@ -202,6 +202,22 @@ void ecmcDAQDataArray::initAsyn() {
return;
}
int ecmcDAQDataArray::validate() {
if(dataElementCount_==0) {
throw std::runtime_error("Error: DAQ-Array element count 0");
}
if(channelCounter_==0) {
throw std::runtime_error("Error: DAQ-Array channel count 0");
}
for(std::vector<ecmcDAQDataChannel*>::iterator pDataCh = dataChannels_.begin(); pDataCh != dataChannels_.end(); ++pDataCh) {
if(!(*pDataCh)) {
throw std::runtime_error( "Channel empty..");
}
(*pDataCh)->validate();
}
return 0;
}
size_t ecmcDAQDataArray::getArraySize() {
return totalElementCount_;
}

View File

@@ -31,6 +31,7 @@ class ecmcDAQDataArray : public asynPortDriver {
void addDataItemToChannel(const char* name, int format);
void setEnable(int enable);
size_t getArraySize();
int validate();
private:
void buildArrayHeader();

View File

@@ -43,7 +43,7 @@ void ecmcDAQDataChannel::connectToDataSources() {
for(std::vector<ecmcDAQChannelItem*>::iterator pDataItem = dataItems_.begin(); pDataItem != dataItems_.end(); ++pDataItem) {
if(!(*pDataItem)) {
throw std::runtime_error( "Channel empty..");
throw std::runtime_error( "Data item empty..");
}
(*pDataItem)->connectToSource();
dataElementCount_ = dataElementCount_ + (*pDataItem)->getDataElementCount();
@@ -93,3 +93,20 @@ double ecmcDAQDataChannel::getData(int first){
bool ecmcDAQDataChannel::empty(){
return returnedDataCounter_>=dataElementCount_;
}
int ecmcDAQDataChannel::validate() {
if(dataElementCount_==0) {
throw std::runtime_error("Error: DAQ-Channel element count 0");
}
if(itemCounter_==0) {
throw std::runtime_error("Error: DAQ-Channel data item count 0");
}
for(std::vector<ecmcDAQChannelItem*>::iterator pDataItem = dataItems_.begin(); pDataItem != dataItems_.end(); ++pDataItem) {
if(!(*pDataItem)) {
throw std::runtime_error( "Data item empty..");
}
(*pDataItem)->validate();
}
return 0;
}

View File

@@ -28,6 +28,7 @@ class ecmcDAQDataChannel {
double getData(int first);
bool empty();
double getType();
int validate();
private:
std::vector<ecmcDAQChannelItem*> dataItems_;

View File

@@ -23,13 +23,30 @@
#include <epicsExport.h>
#include <iocsh.h>
#define ECMC_PLUGIN_PORTNAME_PREFIX "PLUGIN.DAQ"
#define ECMC_PLUGIN_DAQ_ERROR_CODE 1
static std::vector<ecmcDAQDataArray*> arrays;
static int arrayCounter = 0;
ecmcDAQDataArray* getDAQArrayFromName(const char *name) {
// Find group by name
for(std::vector<ecmcDAQDataArray*>::iterator array = arrays.begin(); array != arrays.end(); ++array) {
bool found = strcmp(name, (*array)->getName().c_str()) == 0;
if(found) {
return (*array);
}
}
return NULL;
}
int createDAQArray(const char* name, const char* portName ) {
// Check if already exists
ecmcDAQDataArray array = getDAQArrayFromName(name);
if(array){
printf("Error: DAQ-Array %s already defined.\n",name);
return ECMC_PLUGIN_DAQ_ERROR_CODE;
}
// create new ecmcFFT object
ecmcDAQDataArray* array = NULL;
@@ -51,21 +68,10 @@ int createDAQArray(const char* name, const char* portName ) {
return 0;
}
ecmcDAQDataArray* getDAQArrayFromName(const char *name) {
// Find group by name
for(std::vector<ecmcDAQDataArray*>::iterator array = arrays.begin(); array != arrays.end(); ++array) {
bool found = strcmp(name, (*array)->getName().c_str()) == 0;
if(found) {
return (*array);
}
}
return NULL;
}
int getDAQDataArrayNelm(const char *name){
ecmcDAQDataArray array = getDAQArrayFromName(name);
if(!array){
printf("Error: DAQ-Array %s not found.\n",name);
return -1;
}
return array->getArraySize();
@@ -119,6 +125,20 @@ int linkDataToDAQs() {
return 0;
}
int validateDAQs() {
for(std::vector<ecmcDAQDataArray*>::iterator pDAQArray = arrays.begin(); pDAQArray != arrays.end(); ++pDAQArray) {
if(*pDAQArray) {
try {
(*pDAQArray)->validate();
}
catch(std::exception& e) {
printf("Exception: %s. Plugin will unload.\n",e.what());
return ECMC_PLUGIN_DAQ_ERROR_CODE;
}
}
}
return 0;
}
//int enableDAQ(int scopeIndex, int enable) {
// try {
// arrays.at(scopeIndex)->setEnable(enable);
@@ -283,11 +303,11 @@ static void initCallFunc_2(const iocshArgBuf *args) {
/**
* EPICS iocsh shell command: ecmcAddDAQItem
* EPICS iocsh shell command: ecmcDAQReadNelm
*/
void ecmcDAQReadNelmHelp() {
printf("\n");
printf(" Use ecmcDAQReadNELM(<name>,<result_var_name>)\n");
printf(" Use ecmcDAQReadNelm(<name>,<result_var_name>)\n");
printf(" <name> : Name of DAQ array object.\n");
printf(" <result_var_name> : Variable for return value.\n");
printf("\n");
@@ -337,12 +357,42 @@ static const iocshFuncDef initFuncDef_3 = { "ecmcDAQReadNelm", 2, initArgs_3}
static void initCallFunc_3(const iocshArgBuf *args) {
ecmcDAQReadNelm(args[0].sval,args[1].sval);
}
/**
* EPICS iocsh shell command: ecmcDAQConnectToDataSource
*/
int ecmcDAQConnectToDataSource() {
try {
linkDataToDAQs();
}
catch(std::exception& e) {
printf("Exception: %s. Connect data sources failed.\n",e.what());
exit(EXIT_FAILURE);
}
return asynSuccess;
}
static const iocshArg initArg0_4 =
{ "dummy", iocshArgInt };
static const iocshArg *const initArgs_4[] = { &initArg0_4};
static const iocshFuncDef initFuncDef_4 = { "ecmcDAQConnectToDataSource", 1, initArgs_4};
static void initCallFunc_4(const iocshArgBuf *args) {
ecmcDAQConnectToDataSource(args[0].ival);
}
// Register
void ecmcDAQPlgRegister(void) {
iocshRegister(&initFuncDef_0, initCallFunc_0);
iocshRegister(&initFuncDef_1, initCallFunc_1);
iocshRegister(&initFuncDef_2, initCallFunc_2);
iocshRegister(&initFuncDef_3, initCallFunc_3);
iocshRegister(&initFuncDef_3, initCallFunc_4);
}
epicsExportRegistrar(ecmcDAQPlgRegister);

View File

@@ -19,16 +19,6 @@ extern "C" {
int executeDAQs();
/** \brief Link data to _all_ scope objects
*
* This tells the DAQ 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 linkDataToDAQs();
/** \brief Deletes all created scope objects\n
*
* Should be called when destructs.\n
@@ -36,7 +26,8 @@ int linkDataToDAQs();
void deleteAllDAQs();
// validate DAQs
int validateDAQs();
# ifdef __cplusplus
}

View File

@@ -71,11 +71,9 @@ int daqRealtime(int ecmcError)
return executeDAQs();
}
/** 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 daqEnterRT(){
return linkDataToDAQs();
return validateDAQs(); //linkDataToDAQs();
}
/** Optional function.