Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70ee857782 | ||
|
|
07f09e0759 | ||
|
|
ba832ddfd0 | ||
|
|
93c2284091 | ||
|
|
cc5b6f6351 | ||
|
|
a26a625e49 | ||
|
|
93b4892528 | ||
|
|
e57348a4c5 | ||
|
|
7059cb0354 | ||
|
|
f2d6e05816 | ||
|
|
e949493722 | ||
|
|
6969bbd571 | ||
|
|
9edea59ab9 | ||
|
|
1928b87634 | ||
|
|
d9ed321298 | ||
|
|
935f915e5d | ||
|
|
6263f4c335 | ||
|
|
62134efd19 | ||
|
|
8a06b9ee8e | ||
|
|
bc6fd2b9ff | ||
|
|
3b6f23515f | ||
|
|
3c5f419ce7 | ||
|
|
3418c22cde | ||
|
|
22806c5301 | ||
|
|
62fb27fdf8 | ||
|
|
6250625036 | ||
|
|
d77ec8a978 | ||
|
|
322bb4800b | ||
|
|
0437602236 | ||
|
|
bd37756ba3 | ||
|
|
fb4e7f0fc1 | ||
|
|
5279e4e739 | ||
|
|
ffef21e58c | ||
|
|
e901ae3ea0 | ||
|
|
8a050e0f81 | ||
|
|
a72112f928 | ||
|
|
be701cc98a | ||
|
|
9b000ffe6c | ||
|
|
6c91249340 | ||
|
|
b052e28788 | ||
|
|
247839b94d | ||
|
|
ecdf70d858 | ||
|
|
a004f7ea08 | ||
|
|
898868d5f4 | ||
|
|
eb4dab73e9 | ||
|
|
e1adfe30df | ||
|
|
2715f585e0 | ||
|
|
c2e3315f54 | ||
|
|
d0ddcead24 | ||
|
|
5f42eec15a | ||
|
|
20e55d5bca | ||
|
|
6d2d63621e | ||
|
|
b3f96f730f | ||
|
|
02930b78a0 | ||
|
|
68cc5e3b28 | ||
|
|
0c0a77def5 | ||
|
|
79b05db5e2 | ||
|
|
cd653a809f |
3
configure/CONFIG_PVDATABASE_VERSION
Normal file
3
configure/CONFIG_PVDATABASE_VERSION
Normal file
@@ -0,0 +1,3 @@
|
||||
EPICS_PVDATABASE_MAJOR_VERSION = 4
|
||||
EPICS_PVDATABASE_MINOR_VERSION = 5
|
||||
EPICS_PVDATABASE_MAINTENANCE_VERSION = 0
|
||||
@@ -2,6 +2,8 @@ TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
CFG += CONFIG_PVDATABASE_VERSION
|
||||
|
||||
TARGETS = $(CONFIG_TARGETS)
|
||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||
|
||||
|
||||
@@ -2,6 +2,31 @@
|
||||
|
||||
This document summarizes the changes to the module between releases.
|
||||
|
||||
## Release 4.5.0 (EPICS 7.0.3, Jul 2019)
|
||||
|
||||
1) support is a new feature.
|
||||
2) processRecord is new
|
||||
|
||||
|
||||
## Release 4.4.2 (EPICS 7.0.2.2, Apr 2019)
|
||||
|
||||
Formerly if a client makes a request for a subfield of a non structure field
|
||||
it resulted in a crash.
|
||||
|
||||
Now if a request is made for a subfield of a non structure field
|
||||
|
||||
1) if the field is not a union an exception is thrown which is passed to the client.
|
||||
2) if the field is a union
|
||||
a) if more than one subfield is requested an exception is thrown
|
||||
b) if the subfield is the type for the current union the request succeeds
|
||||
c) if type is not the same an exception is thrown
|
||||
|
||||
|
||||
## Release 4.4.1 (EPICS 7.0.2.1, Mar 2019)
|
||||
|
||||
* Cleaned up some build warnings.
|
||||
* RTEMS test harness simplified.
|
||||
|
||||
|
||||
## Release 4.4 (EPICS 7.0.2, Dec 2018)
|
||||
|
||||
@@ -30,5 +55,3 @@ The test is now a regression test which can be run using:
|
||||
This is the first release of pvDatabaseCPP.
|
||||
|
||||
It provides functionality equivalent to pvDatabaseJava.
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
TODO
|
||||
===========
|
||||
|
||||
monitorPlugin
|
||||
-------------
|
||||
|
||||
A debate is on-going about what semantics should be.
|
||||
|
||||
Must test record delete.
|
||||
-------------------
|
||||
|
||||
Must test removing a record from the PVDatabase while a pvAccess client
|
||||
is attached. Also why do both unlisten and detach exists?
|
||||
|
||||
|
||||
create more regression tests
|
||||
----------------
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
|
||||
<div class="head">
|
||||
<h1>pvDatabaseCPP</h1>
|
||||
<h2 class="nocount">Release 4.4 - December 2018</h2>
|
||||
<h2 class="nocount">Release ? - TBD</h2>
|
||||
Latest update 2019.06.19.
|
||||
|
||||
|
||||
<h2 class="nocount">Abstract</h2>
|
||||
@@ -69,8 +70,6 @@ pvDatabaseCPP is one of the components of
|
||||
EPICS Version 7
|
||||
</p>
|
||||
<p>This document is only a guide to help locate code and documentation related to pvDatabaseCPP
|
||||
</p>
|
||||
<p>
|
||||
It is intended for developers that want to use pvDatabaseCPP.
|
||||
</p>
|
||||
<h2>Developer Guide</h2>
|
||||
@@ -87,7 +86,7 @@ In particular read everything related to pvDatabase.
|
||||
</p>
|
||||
<p>pvDatabase has plugin support, which is implemented in <b>pvCopy</b>.
|
||||
<b>pvCopy</b> was originally implemented in <b>pvDataCPP</b>,
|
||||
but pvDatabaseCPP now implemnents its own version and adds plugin support.
|
||||
but pvDatabaseCPP now implements its own version and adds plugin support.
|
||||
</p>
|
||||
<p>
|
||||
See
|
||||
@@ -98,7 +97,7 @@ pvRequest
|
||||
for details.
|
||||
</p>
|
||||
<p>The developerGuide discusses code in a way that applies to both CPP and C++.
|
||||
For the descriptions of the CPP specific code consult the next section.
|
||||
For the descriptions of the CPP specific code consult the following sections.
|
||||
</p>
|
||||
|
||||
<h2>doxygen</h2>
|
||||
@@ -108,22 +107,82 @@ href="./html/index.html">doxgen</a>
|
||||
</p>
|
||||
|
||||
<h2>pvDatabaseCPP</h2>
|
||||
<p>pvDatabaseCPP itself has the following implementations of a <b>PVRecord</b></p>
|
||||
<h3>include/pv</h3>
|
||||
<p>The header files that describe the various components implemented by pvDatabase.
|
||||
</p>
|
||||
<dl>
|
||||
<dt>RemoveRecord.cpp</dt>
|
||||
<dd>
|
||||
This is the code that is used to delete another record in the same <b>IOC</b>.
|
||||
</dd>
|
||||
<dt>TraceRecord.cpp</dt>
|
||||
<dd>
|
||||
This is the code that is used to set the trace level
|
||||
in another record in the same <b>IOC</b>.
|
||||
</dd>
|
||||
<dt>pvDatabase.h</dt>
|
||||
<dd>
|
||||
This describes PVRecord and PVDatabase.
|
||||
</dd>
|
||||
<dt>channelProviderLocal.h </dt>
|
||||
<dd>
|
||||
This describes a channel provider for PVDatabase
|
||||
</dd>
|
||||
<dt>pvSupport.h</dt>
|
||||
<dd>
|
||||
This is the base class for support attached to a field of a record.
|
||||
</dd>
|
||||
<dt>controlSupport.h</dt>
|
||||
<dd>
|
||||
This is support that implements control limits.
|
||||
</dd>
|
||||
<dt>scalarAlarmSupport.h</dt>
|
||||
<dd>
|
||||
This is support for a alarm limits for a scalar numeric field.
|
||||
</dd>
|
||||
<dt>processRecord.h</dt>
|
||||
<dd>
|
||||
This is a PVRecord that periodical processes a set of PVRecords in the local PVDatabase.
|
||||
</dd>
|
||||
<dt>removeRecord.h</dt>
|
||||
<dd>
|
||||
This is a PVRecord that removes a PVRecord in the local PVDatabase.
|
||||
</dd>
|
||||
<dt>traceRecord.h</dt>
|
||||
<dd>
|
||||
This is a PVRecord that sets the trace value for another PVRecord in the local PVDatabase.
|
||||
</dd>
|
||||
<dt>pvStructureCopy.h</dt>
|
||||
<dd>
|
||||
This is a facility that allows a client to access a subfield of the fields in a PVRecord.
|
||||
It also provides record and field options an plugin support.
|
||||
</dd>
|
||||
<dt>pvPlugin.h</dt>
|
||||
<dd>
|
||||
This is the base class for a plugin attached to a record or field of PVRecord.
|
||||
</dd>
|
||||
<dt>pvArrayPlugin.h</dt>
|
||||
<dd>
|
||||
A plugin for accessing a subset of the elements in an array field.
|
||||
</dd>
|
||||
<dt>pvDeadbandPlugin.h</dt>
|
||||
<dd>
|
||||
A deadband plugin for monitors.
|
||||
</dd>
|
||||
<dt>pvTimestampPlugin.h</dt>
|
||||
<dd>
|
||||
A plugin for timeStamp.
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>src/database</h3>
|
||||
<p>This has the code that implements pvDatabase and pvRecord.</p>
|
||||
<h3>src/pvAccess</h3>
|
||||
<p>This has the code for the channel provider for pvDatabase.
|
||||
</p>
|
||||
<h3>src/support</h3>
|
||||
<p>This has the pvSupport code.</p>
|
||||
<h3>src/special</h3>
|
||||
<p>
|
||||
This has the code for processRecord, removeRecord, and traceRecord.
|
||||
</p>
|
||||
<h3>src/copy</h3>
|
||||
<p>This has the code for pvStructureCopy and all the plugin support.
|
||||
</p>
|
||||
<h2>exampleCPP</h2>
|
||||
<p>Example code is available as part of this release.
|
||||
<a
|
||||
href="http://epics-pvdata.sourceforge.net/docbuild/exampleCPP/tip/documentation/exampleCPP.html">
|
||||
href="https://github.com/epics-base/exampleCPP">
|
||||
exampleCPP
|
||||
</a>
|
||||
</p>
|
||||
@@ -173,6 +232,24 @@ other functionality.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3>support</h3>
|
||||
<p>This creates records that have the following features:</p>
|
||||
<dl>
|
||||
<dt>value</dt>
|
||||
<dd>
|
||||
Each record has a value field the is a numeric scalar field.
|
||||
In addition each has the following fields:
|
||||
alarm,timeStamp,control,scalarAlarm, and display.
|
||||
</dd>
|
||||
<dt>support</dt>
|
||||
<dd>
|
||||
Each record uses the control and scalarAlarm support provided by pvDatabaseCPP.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
It also creates records that can be used by clients to show example of the plugin support.
|
||||
</p>
|
||||
|
||||
<h2>iocshell commands</h2>
|
||||
<p>Shell commands are made available via the standard DBD include mechanism
|
||||
provided by iocCore.
|
||||
@@ -194,7 +271,7 @@ pvDatabaseCPP
|
||||
</dd>
|
||||
</dl>
|
||||
<p>In addition any code that implements a PVRecord must implement an ioc command.
|
||||
Look at any of the examples in <b>exampleCPP</b> to see how to implement shell commands.</p>
|
||||
Look at the examples in <b>exampleCPP/support</b> to see how to implement shell commands.</p>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
22
src/Makefile
22
src/Makefile
@@ -3,22 +3,40 @@
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
# needed for Windows
|
||||
LIB_SYS_LIBS_WIN32 += netapi32 ws2_32
|
||||
|
||||
PVDATABASE_SRC = $(TOP)/src
|
||||
|
||||
LIBRARY += pvDatabase
|
||||
|
||||
# shared library ABI version.
|
||||
SHRLIB_VERSION ?= 4.4.0
|
||||
SHRLIB_VERSION ?= $(EPICS_PVDATABASE_MAJOR_VERSION).$(EPICS_PVDATABASE_MINOR_VERSION).$(EPICS_PVDATABASE_MAINTENANCE_VERSION)
|
||||
|
||||
INC += pv/pvPlugin.h
|
||||
INC += pv/pvStructureCopy.h
|
||||
INC += pv/pvArrayPlugin.h
|
||||
INC += pv/pvDeadbandPlugin.h
|
||||
INC += pv/pvTimestampPlugin.h
|
||||
|
||||
INC += pv/pvDatabase.h
|
||||
|
||||
INC += pv/channelProviderLocal.h
|
||||
INC += pv/pvDatabase.h
|
||||
|
||||
INC += pv/traceRecord.h
|
||||
INC += pv/removeRecord.h
|
||||
INC += pv/processRecord.h
|
||||
|
||||
INC += pv/pvSupport.h
|
||||
INC += pv/controlSupport.h
|
||||
INC += pv/scalarAlarmSupport.h
|
||||
|
||||
|
||||
include $(PVDATABASE_SRC)/copy/Makefile
|
||||
include $(PVDATABASE_SRC)/database/Makefile
|
||||
include $(PVDATABASE_SRC)/pvAccess/Makefile
|
||||
include $(PVDATABASE_SRC)/special/Makefile
|
||||
include $(PVDATABASE_SRC)/support/Makefile
|
||||
|
||||
pvDatabase_LIBS += $(EPICS_BASE_PVA_CORE_LIBS)
|
||||
pvDatabase_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
SRC_DIRS += $(PVDATABASE_SRC)/copy
|
||||
|
||||
INC += pv/pvStructureCopy.h
|
||||
INC += pv/pvPlugin.h
|
||||
INC += pv/pvArrayPlugin.h
|
||||
INC += pv/pvDeadbandPlugin.h
|
||||
INC += pv/pvTimestampPlugin.h
|
||||
|
||||
LIBSRCS += pvCopy.cpp
|
||||
LIBSRCS += pvPlugin.cpp
|
||||
LIBSRCS += pvCopy.cpp
|
||||
LIBSRCS += pvArrayPlugin.cpp
|
||||
LIBSRCS += pvDeadbandPlugin.cpp
|
||||
LIBSRCS += pvTimestampPlugin.cpp
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <pv/convert.h>
|
||||
#include <pv/pvSubArrayCopy.h>
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvArrayPlugin.h>
|
||||
#include "pv/pvArrayPlugin.h"
|
||||
|
||||
using std::string;
|
||||
using std::size_t;
|
||||
@@ -177,8 +177,8 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bo
|
||||
} else {
|
||||
for(long i=0; i<len; ++i) {
|
||||
copy(*copyArray,indfrom,1,*masterArray,indto,1,1);
|
||||
indfrom += increment;
|
||||
indto += 1;
|
||||
indfrom += 1;
|
||||
indto += increment;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
#include <pv/thread.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvPlugin.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
#include "pv/pvPlugin.h"
|
||||
#include "pv/pvStructureCopy.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
@@ -168,7 +168,7 @@ PVFieldPtr PVCopy::getMasterPVField(size_t structureOffset)
|
||||
node = getMasterNode(snode,structureOffset);
|
||||
}
|
||||
if(!node) {
|
||||
throw std::invalid_argument(
|
||||
throw std::logic_error(
|
||||
"PVCopy::getMasterPVField: structureOffset not valid");
|
||||
}
|
||||
size_t diff = structureOffset - node->structureOffset;
|
||||
@@ -212,19 +212,91 @@ bool PVCopy::updateCopyFromBitSet(
|
||||
return checkIgnore(copyPVStructure,bitSet);
|
||||
}
|
||||
|
||||
void PVCopy::updateMasterField(
|
||||
CopyNodePtr const & node,
|
||||
PVFieldPtr const & pvCopy,
|
||||
PVFieldPtr const &pvMaster,
|
||||
BitSetPtr const &bitSet)
|
||||
{
|
||||
bool result = false;
|
||||
for(size_t i=0; i< node->pvFilters.size(); ++i) {
|
||||
PVFilterPtr pvFilter = node->pvFilters[i];
|
||||
if(pvFilter->filter(pvCopy,bitSet,false)) result = true;
|
||||
}
|
||||
if(result) return;
|
||||
pvMaster->copyUnchecked(*pvCopy);
|
||||
}
|
||||
|
||||
void PVCopy::updateMasterCheckBitSet(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
BitSetPtr const &bitSet,
|
||||
size_t nextSet)
|
||||
{
|
||||
if(!bitSet->get(nextSet)) {
|
||||
size_t next = bitSet->nextSetBit(nextSet);
|
||||
if(next==string::npos) return;
|
||||
updateMasterCheckBitSet(copyPVStructure,bitSet,next);
|
||||
return;
|
||||
}
|
||||
PVFieldPtr pvField = copyPVStructure;
|
||||
if(nextSet!=0) pvField = copyPVStructure->getSubField(nextSet);
|
||||
if(pvField->getField()->getType()==epics::pvData::structure) {
|
||||
bitSet->clear(nextSet);
|
||||
PVStructurePtr pv = static_pointer_cast<PVStructure>(pvField);
|
||||
PVFieldPtrArray pvFieldArray = pv->getPVFields();
|
||||
for(size_t i=0; i>pvFieldArray.size(); ++i) {
|
||||
PVFieldPtr pvField = pvFieldArray[i];
|
||||
bitSet->set(pvField->getFieldOffset());
|
||||
}
|
||||
}
|
||||
size_t next = bitSet->nextSetBit(nextSet+1);
|
||||
if(next==string::npos) return;
|
||||
updateMasterCheckBitSet(copyPVStructure,bitSet,next);
|
||||
}
|
||||
|
||||
CopyNodePtr PVCopy::getCopyNode(std::size_t fieldOffset)
|
||||
{
|
||||
if(fieldOffset==0) return headNode;
|
||||
CopyNodePtr node = headNode;
|
||||
while(true) {
|
||||
if(!node->isStructure) return node;
|
||||
CopyStructureNodePtr structNode = static_pointer_cast<CopyStructureNode>(node);
|
||||
CopyNodePtrArrayPtr nodes = structNode->nodes;
|
||||
bool okToContinue = false;
|
||||
for(size_t i=0; i< nodes->size(); i++) {
|
||||
node = (*nodes)[i];
|
||||
size_t soff = node->structureOffset;
|
||||
if(fieldOffset>=soff && fieldOffset<soff+node->nfields) {
|
||||
okToContinue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(okToContinue) continue;
|
||||
}
|
||||
throw std::logic_error("PVCopy::getCopyNode fieldOffset not valid");
|
||||
}
|
||||
|
||||
|
||||
void PVCopy::updateMaster(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
BitSetPtr const &bitSet)
|
||||
{
|
||||
if(bitSet->get(0)) {
|
||||
for(size_t i=0; i< copyPVStructure->getNumberFields(); ++i) {
|
||||
bitSet->set(i,true);
|
||||
updateMasterCheckBitSet(copyPVStructure,bitSet,0);
|
||||
size_t nextSet =0;
|
||||
while(true) {
|
||||
nextSet = bitSet->nextSetBit(nextSet);
|
||||
if(nextSet==string::npos) return;
|
||||
PVFieldPtr pvCopy = copyPVStructure->getSubField(nextSet);
|
||||
PVFieldPtr pvMaster = headNode->masterPVField;
|
||||
if(pvMaster->getField()->getType()==epics::pvData::structure) {
|
||||
PVStructurePtr pv = static_pointer_cast<PVStructure>(pvMaster);
|
||||
pvMaster = pv->getSubField(pvCopy->getFullName());
|
||||
}
|
||||
updateMasterField(getCopyNode(nextSet),pvCopy,pvMaster,bitSet);
|
||||
bitSet->clear(nextSet);
|
||||
}
|
||||
updateMaster(copyPVStructure,headNode,bitSet);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset)
|
||||
{
|
||||
if(fieldOffset==0) return headNode->options;
|
||||
@@ -248,7 +320,7 @@ PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset)
|
||||
}
|
||||
}
|
||||
if(okToContinue) continue;
|
||||
throw std::invalid_argument("fieldOffset not valid");
|
||||
throw std::logic_error("PVCopy::getOptions logic error: fieldOffset not valid");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,36 +421,6 @@ void PVCopy::updateCopyFromBitSet(
|
||||
updateCopyFromBitSet(pvCopyFields[i],(*structureNode->nodes)[i],bitSet);
|
||||
}
|
||||
}
|
||||
void PVCopy::updateMaster(
|
||||
PVFieldPtr const & pvCopy,
|
||||
CopyNodePtr const & node,
|
||||
BitSetPtr const & bitSet)
|
||||
{
|
||||
bool result = false;
|
||||
bool update = bitSet->get(pvCopy->getFieldOffset());
|
||||
if(update) {
|
||||
for(size_t i=0; i< node->pvFilters.size(); ++i) {
|
||||
PVFilterPtr pvFilter = node->pvFilters[i];
|
||||
if(pvFilter->filter(pvCopy,bitSet,false)) result = true;
|
||||
}
|
||||
}
|
||||
if(!node->isStructure) {
|
||||
if(result) return;
|
||||
PVFieldPtr pvMaster = node->masterPVField;
|
||||
pvMaster->copy(*pvCopy);
|
||||
return;
|
||||
}
|
||||
CopyStructureNodePtr structureNode = static_pointer_cast<CopyStructureNode>(node);
|
||||
size_t offset = structureNode->structureOffset;
|
||||
size_t nextSet = bitSet->nextSetBit(offset);
|
||||
if(nextSet==string::npos) return;
|
||||
if(offset>=pvCopy->getNextFieldOffset()) return;
|
||||
PVStructurePtr pvCopyStructure = static_pointer_cast<PVStructure>(pvCopy);
|
||||
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
|
||||
for(size_t i=0; i<pvCopyFields.size(); ++i) {
|
||||
updateMaster(pvCopyFields[i],(*structureNode->nodes)[i],bitSet);
|
||||
}
|
||||
}
|
||||
|
||||
PVCopy::PVCopy(
|
||||
PVStructurePtr const &pvMaster)
|
||||
@@ -464,7 +506,13 @@ StructureConstPtr PVCopy::createStructure(
|
||||
fields.push_back(field);
|
||||
}
|
||||
size_t numsubfields = fields.size();
|
||||
if(numsubfields==0) return NULLStructure;
|
||||
if(numsubfields==0) {
|
||||
std::stringstream ss;
|
||||
ss << pvFromRequest << "\n";
|
||||
string val("no fields from the following request were found\n");
|
||||
val += ss.str();
|
||||
throw std::invalid_argument(val);
|
||||
}
|
||||
return getFieldCreate()->createStructure(fieldNames, fields);
|
||||
}
|
||||
|
||||
@@ -487,16 +535,65 @@ CopyNodePtr PVCopy::createStructureNodes(
|
||||
requestPVStructure->getSubField<PVStructure>("_options");
|
||||
PVFieldPtr pvMasterField = pvMasterStructure->getSubField(fieldName);
|
||||
if(!pvMasterField) {
|
||||
throw std::logic_error("did not find field in master");
|
||||
throw std::logic_error("PVCopy::createStructureNodes did not find field in master");
|
||||
}
|
||||
size_t numberRequest = requestPVStructure->getPVFields().size();
|
||||
if(pvSubFieldOptions) numberRequest--;
|
||||
bool haveOptions = false;
|
||||
if(pvSubFieldOptions) {
|
||||
numberRequest--;
|
||||
haveOptions = true;
|
||||
}
|
||||
if(numberRequest>0) {
|
||||
nodes->push_back(createStructureNodes(
|
||||
static_pointer_cast<PVStructure>(pvMasterField),
|
||||
requestPVStructure,
|
||||
static_pointer_cast<PVStructure>(copyPVField)));
|
||||
continue;
|
||||
Type copyType = copyPVField->getField()->getType();
|
||||
if(copyType==epics::pvData::structure) {
|
||||
nodes->push_back(createStructureNodes(
|
||||
static_pointer_cast<PVStructure>(pvMasterField),
|
||||
requestPVStructure,
|
||||
static_pointer_cast<PVStructure>(copyPVField)));
|
||||
continue;
|
||||
}
|
||||
if(copyType==epics::pvData::union_) {
|
||||
if(numberRequest!=1) {
|
||||
std::stringstream ss;
|
||||
ss << pvFromRequest << "\n";
|
||||
string val("In the following request a union field has more than one subfield in\n");
|
||||
val += ss.str();
|
||||
throw std::invalid_argument(val);
|
||||
}
|
||||
PVUnionPtr pvUnion = static_pointer_cast<PVUnion>(pvMasterField);
|
||||
std::string selectedName = pvUnion->getSelectedFieldName();
|
||||
PVFieldPtrArray const & pvFields = requestPVStructure->getPVFields();
|
||||
size_t len = pvFields.size();
|
||||
if(len>2 || (haveOptions && len!=2)) {
|
||||
std::stringstream ss;
|
||||
ss << pvFromRequest << "\n";
|
||||
string val("PVCopy logic error: pvRequest is\n");
|
||||
val += ss.str();
|
||||
throw std::logic_error(val);
|
||||
}
|
||||
size_t indRequestValue = 0;
|
||||
if((pvFields[0]->getFieldName().compare("_options"))==0) indRequestValue = 1;
|
||||
PVFieldPtr pvRequestValue = pvFields[indRequestValue];
|
||||
if(pvRequestValue) {
|
||||
string requestName = pvRequestValue->getFieldName();
|
||||
if(requestName.compare(selectedName)!=0) {
|
||||
std::stringstream ss;
|
||||
ss << pvFromCopy << "\n";
|
||||
string requestName = pvRequestValue->getFieldName();
|
||||
string val("field ");
|
||||
val += requestName + " does not match union type in\n";
|
||||
val += ss.str();
|
||||
throw std::invalid_argument(val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << pvFromCopy << "\n";
|
||||
string val("requested a subfield of field ");
|
||||
val += fieldName + " which does not have type structure in\n";
|
||||
val += ss.str();
|
||||
throw std::invalid_argument(val);
|
||||
}
|
||||
}
|
||||
CopyNodePtr node(new CopyNode());
|
||||
node->options = pvSubFieldOptions;
|
||||
|
||||
@@ -4,12 +4,15 @@
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/pvSubArrayCopy.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvDeadbandPlugin.h>
|
||||
#include "pv/pvDeadbandPlugin.h"
|
||||
|
||||
using std::string;
|
||||
using std::size_t;
|
||||
@@ -64,9 +67,9 @@ PVDeadbandFilterPtr PVDeadbandFilter::create(
|
||||
ScalarConstPtr scalar = static_pointer_cast<const Scalar>(field);
|
||||
if(!ScalarTypeFunc::isNumeric(scalar->getScalarType())) return PVDeadbandFilterPtr();
|
||||
bool absolute = false;
|
||||
if(requestValue.find("abs")>=0) {
|
||||
if(requestValue.find("abs")==0) {
|
||||
absolute = true;
|
||||
} else if(requestValue.find("rel")>=0) {
|
||||
} else if(requestValue.find("rel")==0) {
|
||||
absolute = false;
|
||||
} else {
|
||||
return PVDeadbandFilterPtr();
|
||||
|
||||
@@ -4,9 +4,13 @@
|
||||
*/
|
||||
|
||||
#include <pv/pvData.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvStructureCopy.h>
|
||||
#include <pv/pvPlugin.h>
|
||||
#include "pv/pvPlugin.h"
|
||||
|
||||
using namespace epics::pvData;
|
||||
|
||||
|
||||
@@ -3,14 +3,17 @@
|
||||
* The License for this software can be found in the file LICENSE that is included with the distribution.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvTimestampPlugin.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
#include "pv/pvPlugin.h"
|
||||
#include "pv/pvTimestampPlugin.h"
|
||||
|
||||
|
||||
using std::string;
|
||||
using std::size_t;
|
||||
|
||||
@@ -10,13 +10,19 @@
|
||||
*/
|
||||
|
||||
#include <epicsGuard.h>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
#include <pv/pvPlugin.h>
|
||||
#include <pv/pvArrayPlugin.h>
|
||||
#include <pv/pvTimestampPlugin.h>
|
||||
#include <pv/pvDeadbandPlugin.h>
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/pvPlugin.h"
|
||||
#include "pv/pvArrayPlugin.h"
|
||||
#include "pv/pvTimestampPlugin.h"
|
||||
#include "pv/pvDeadbandPlugin.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
|
||||
@@ -8,13 +8,25 @@
|
||||
* @author mrk
|
||||
* @date 2012.11.21
|
||||
*/
|
||||
#include <list>
|
||||
#include <epicsGuard.h>
|
||||
#include <epicsThread.h>
|
||||
#include <pv/status.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/createRequest.h>
|
||||
#include <pv/pvaVersion.h>
|
||||
#include <pv/pvaVersionNum.h>
|
||||
#include <pv/monitor.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
@@ -42,7 +54,6 @@ PVRecord::PVRecord(
|
||||
pvStructure(pvStructure),
|
||||
depthGroupPut(0),
|
||||
traceLevel(0),
|
||||
isDestroyed(false),
|
||||
isAddListener(false)
|
||||
{
|
||||
}
|
||||
@@ -53,13 +64,8 @@ void PVRecord::notifyClients()
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
if(traceLevel>0) {
|
||||
cout << "PVRecord::notifyClients() " << recordName
|
||||
<< " isDestroyed " << (isDestroyed ? "true" : "false")
|
||||
<< endl;
|
||||
}
|
||||
if(isDestroyed) {
|
||||
return;
|
||||
}
|
||||
isDestroyed = true;
|
||||
}
|
||||
pvTimeStamp.detach();
|
||||
for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin();
|
||||
@@ -105,6 +111,37 @@ PVRecord::~PVRecord()
|
||||
notifyClients();
|
||||
}
|
||||
|
||||
void PVRecord::remove()
|
||||
{
|
||||
PVDatabasePtr pvDatabase(PVDatabase::getMaster());
|
||||
if(pvDatabase) pvDatabase->removeRecord(shared_from_this());
|
||||
pvTimeStamp.detach();
|
||||
for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin();
|
||||
iter!=pvListenerList.end();
|
||||
iter++ )
|
||||
{
|
||||
PVListenerPtr listener = iter->lock();
|
||||
if(!listener) continue;
|
||||
if(traceLevel>0) {
|
||||
cout << "PVRecord::remove() calling listener->unlisten " << recordName << endl;
|
||||
}
|
||||
listener->unlisten(shared_from_this());
|
||||
}
|
||||
pvListenerList.clear();
|
||||
for (std::list<PVRecordClientWPtr>::iterator iter = clientList.begin();
|
||||
iter!=clientList.end();
|
||||
iter++ )
|
||||
{
|
||||
PVRecordClientPtr client = iter->lock();
|
||||
if(!client) continue;
|
||||
if(traceLevel>0) {
|
||||
cout << "PVRecord::remove() calling client->detach " << recordName << endl;
|
||||
}
|
||||
client->detach(shared_from_this());
|
||||
}
|
||||
clientList.clear();
|
||||
}
|
||||
|
||||
void PVRecord::initPVRecord()
|
||||
{
|
||||
PVRecordStructurePtr parent;
|
||||
@@ -115,13 +152,6 @@ void PVRecord::initPVRecord()
|
||||
if(pvField) pvTimeStamp.attach(pvField);
|
||||
}
|
||||
|
||||
void PVRecord::destroy()
|
||||
{
|
||||
PVDatabasePtr pvDatabase(PVDatabase::getMaster());
|
||||
if(pvDatabase) pvDatabase->removeRecord(shared_from_this());
|
||||
notifyClients();
|
||||
}
|
||||
|
||||
void PVRecord::process()
|
||||
{
|
||||
if(traceLevel>2) {
|
||||
@@ -207,9 +237,6 @@ bool PVRecord::addPVRecordClient(PVRecordClientPtr const & pvRecordClient)
|
||||
cout << "PVRecord::addPVRecordClient() " << recordName << endl;
|
||||
}
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
if(isDestroyed) {
|
||||
return false;
|
||||
}
|
||||
// clean clientList
|
||||
bool clientListClean = false;
|
||||
while(!clientListClean) {
|
||||
@@ -243,9 +270,6 @@ bool PVRecord::addListener(
|
||||
cout << "PVRecord::addListener() " << recordName << endl;
|
||||
}
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
if(isDestroyed) {
|
||||
return false;
|
||||
}
|
||||
pvListenerList.push_back(pvListener);
|
||||
this->pvListener = pvListener;
|
||||
isAddListener = true;
|
||||
@@ -274,9 +298,6 @@ bool PVRecord::removeListener(
|
||||
cout << "PVRecord::removeListener() " << recordName << endl;
|
||||
}
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
if(isDestroyed) {
|
||||
return false;
|
||||
}
|
||||
std::list<PVListenerWPtr>::iterator iter;
|
||||
for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ )
|
||||
{
|
||||
|
||||
@@ -11,11 +11,6 @@
|
||||
#ifndef CHANNELPROVIDERLOCAL_H
|
||||
#define CHANNELPROVIDERLOCAL_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define channelProviderLocalEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
@@ -28,16 +23,10 @@
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/status.h>
|
||||
#include <pv/serverContext.h>
|
||||
|
||||
|
||||
#ifdef channelProviderLocalEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef channelProviderLocalEpicsExportSharedSymbols
|
||||
#endif
|
||||
#include <pv/pvStructureCopy.h>
|
||||
#include <pv/pvDatabase.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
@@ -78,10 +67,10 @@ public:
|
||||
*/
|
||||
virtual ~ChannelProviderLocal();
|
||||
/**
|
||||
* @brief Destroy the channel provider.
|
||||
* @brief DEPRECATED
|
||||
*
|
||||
*/
|
||||
virtual void destroy() EPICS_DEPRECATED {};
|
||||
virtual void destroy(){};
|
||||
/**
|
||||
* @brief Returns the channel provider name.
|
||||
*
|
||||
@@ -202,10 +191,10 @@ public:
|
||||
*/
|
||||
virtual ~ChannelLocal();
|
||||
/**
|
||||
* @brief Destroy the channel.
|
||||
* @brief DEPRECATED
|
||||
*
|
||||
*/
|
||||
virtual void destroy() EPICS_DEPRECATED {};
|
||||
virtual void destroy() {};
|
||||
/**
|
||||
* @brief Detach from the record.
|
||||
*
|
||||
|
||||
90
src/pv/controlSupport.h
Normal file
90
src/pv/controlSupport.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2019.06.01
|
||||
*/
|
||||
#ifndef CONTROLSUPPORT_H
|
||||
#define CONTROLSUPPORT_H
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/pvSupport.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
class ControlSupport;
|
||||
typedef std::tr1::shared_ptr<ControlSupport> ControlSupportPtr;
|
||||
|
||||
/**
|
||||
* @brief Base interface for a ControlSupport.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass ControlSupport :
|
||||
PVSupport
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ControlSupport);
|
||||
/**
|
||||
* The Destructor.
|
||||
*/
|
||||
virtual ~ControlSupport();
|
||||
/**
|
||||
* @brief Connects to contol fields.
|
||||
*
|
||||
* @param pvValue The field to support.
|
||||
* @param pvSupport Support specific fields.
|
||||
* @return <b>true</b> for success and <b>false</b> for failure.
|
||||
*/
|
||||
virtual bool init(
|
||||
epics::pvData::PVFieldPtr const & pvValue,
|
||||
epics::pvData::PVFieldPtr const & pvSupport);
|
||||
/**
|
||||
* @brief Honors control fields.
|
||||
*
|
||||
*
|
||||
* @return Returns true is any fields were modified; otherwise false.
|
||||
*/
|
||||
virtual bool process();
|
||||
/**
|
||||
* @brief If implementing minSteps it sets isMinStep to false.
|
||||
*
|
||||
* @return Returns true is any fields were modified; otherwise false.
|
||||
*/
|
||||
virtual void reset();
|
||||
/**
|
||||
* @brief create a ControlSupport
|
||||
*
|
||||
* @param pvRecord - The pvRecord to which the support is attached.
|
||||
* @return The new ControlSupport
|
||||
*/
|
||||
static ControlSupportPtr create(PVRecordPtr const & pvRecord);
|
||||
/**
|
||||
* @brief create a controlSupport required by ControlSupport
|
||||
*
|
||||
* @param scalarType The type for outputValue.
|
||||
* @return The controlField introspection structure.
|
||||
*/
|
||||
static epics::pvData::StructureConstPtr controlField(epics::pvData::ScalarType scalarType);
|
||||
private:
|
||||
ControlSupport(PVRecordPtr const & pvRecord);
|
||||
PVRecordPtr pvRecord;
|
||||
epics::pvData::PVScalarPtr pvValue;
|
||||
epics::pvData::PVStructurePtr pvControl;
|
||||
epics::pvData::PVDoublePtr pvLimitLow;
|
||||
epics::pvData::PVDoublePtr pvLimitHigh;
|
||||
epics::pvData::PVDoublePtr pvMinStep;
|
||||
epics::pvData::PVScalarPtr pvOutputValue;
|
||||
double currentValue;
|
||||
bool isMinStep;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* CONTROLSUPPORT_H */
|
||||
|
||||
89
src/pv/processRecord.h
Normal file
89
src/pv/processRecord.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* processRecord.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2019.06.07
|
||||
*/
|
||||
#ifndef PROCESSRECORD_H
|
||||
#define PROCESSRECORD_H
|
||||
|
||||
#include <map>
|
||||
#include <epicsThread.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/channelProviderLocal.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
typedef std::tr1::shared_ptr<epicsThread> EpicsThreadPtr;
|
||||
|
||||
class ProcessRecord;
|
||||
typedef std::tr1::shared_ptr<ProcessRecord> ProcessRecordPtr;
|
||||
|
||||
/**
|
||||
* @brief Process another record in the same database.
|
||||
*
|
||||
* A record to process another record
|
||||
* It is meant to be used via a channelPutGet request.
|
||||
* The argument has one field: recordName.
|
||||
* The result has a field named status.
|
||||
*/
|
||||
class epicsShareClass ProcessRecord :
|
||||
public PVRecord,
|
||||
public epicsThreadRunable
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ProcessRecord);
|
||||
/**
|
||||
* Factory methods to create ProcessRecord.
|
||||
* @param recordName The name for the ProcessRecord.
|
||||
* @param delay Delay time to wait between process requests.
|
||||
* @return A shared pointer to ProcessRecord.
|
||||
*/
|
||||
static ProcessRecordPtr create(
|
||||
std::string const & recordName,double delay);
|
||||
/**
|
||||
* standard init method required by PVRecord
|
||||
* @return true unless record name already exists.
|
||||
*/
|
||||
virtual bool init();
|
||||
/**
|
||||
* @brief Process the record specified by recordName.
|
||||
*/
|
||||
virtual void process();
|
||||
/**
|
||||
* @brief The run method for the thread.
|
||||
*/
|
||||
virtual void run();
|
||||
/**
|
||||
* @brief Start the thread
|
||||
*/
|
||||
void startThread();
|
||||
/**
|
||||
* @brief Stop the thread
|
||||
*/
|
||||
void stop();
|
||||
private:
|
||||
ProcessRecord(
|
||||
std::string const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure,double delay);
|
||||
double delay;
|
||||
EpicsThreadPtr thread;
|
||||
epics::pvData::Event runStop;
|
||||
epics::pvData::Event runReturn;
|
||||
PVDatabasePtr pvDatabase;
|
||||
PVRecordMap pvRecordMap;
|
||||
epics::pvData::PVStringPtr pvCommand;
|
||||
epics::pvData::PVStringPtr pvRecordName;
|
||||
epics::pvData::PVStringPtr pvResult;
|
||||
epics::pvData::Mutex mutex;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* PROCESSRECORD_H */
|
||||
@@ -6,10 +6,6 @@
|
||||
#ifndef PVARRAYPLUGIN_H
|
||||
#define PVARRAYPLUGIN_H
|
||||
|
||||
#if defined(_WIN32) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <pv/lock.h>
|
||||
@@ -6,26 +6,15 @@
|
||||
#ifndef PVDATABASE_H
|
||||
#define PVDATABASE_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define pvdatabaseEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
|
||||
|
||||
#ifdef pvdatabaseEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef pvdatabaseEpicsExportSharedSymbols
|
||||
#endif
|
||||
#include <pv/pvStructureCopy.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
@@ -98,18 +87,18 @@ public:
|
||||
*/
|
||||
virtual void process();
|
||||
/**
|
||||
* @brief Destroy the record.
|
||||
*
|
||||
* Destroy the PVRecord. Release any resources used and
|
||||
* get rid of listeners and requesters.
|
||||
* If derived class overrides this then it must call PVRecord::destroy()
|
||||
* after it has destroyed any resorces it uses.
|
||||
*
|
||||
* Note: for most classes destroy no longer exists or has been deprecated.
|
||||
* This method makes it possible to remove a record from a database
|
||||
* while the database is still running.
|
||||
* @brief DEPRECATED
|
||||
*/
|
||||
virtual void destroy();
|
||||
virtual void destroy() {}
|
||||
/**
|
||||
* @brief remove record from database.
|
||||
*
|
||||
* Remove the PVRecord. Release any resources used and
|
||||
* get rid of listeners and requesters.
|
||||
* If derived class overrides this then it must call PVRecord::remove()
|
||||
* after it has destroyed any resorces it uses.
|
||||
*/
|
||||
virtual void remove();
|
||||
/**
|
||||
* @brief Optional method for derived class.
|
||||
*
|
||||
@@ -276,7 +265,6 @@ private:
|
||||
epics::pvData::Mutex mutex;
|
||||
std::size_t depthGroupPut;
|
||||
int traceLevel;
|
||||
bool isDestroyed;
|
||||
// following only valid while addListener or removeListener is active.
|
||||
bool isAddListener;
|
||||
PVListenerWPtr pvListener;
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
#ifndef PVDEADBANDPLUGIN_H
|
||||
#define PVDEADBANDPLUGIN_H
|
||||
|
||||
#if defined(_WIN32) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
@@ -9,14 +9,10 @@
|
||||
#ifndef PVPLUGIN_H
|
||||
#define PVPLUGIN_H
|
||||
|
||||
#if defined(_WIN32) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
@@ -26,6 +22,9 @@ class PVPlugin;
|
||||
class PVFilter;
|
||||
class PVPluginRegistry;
|
||||
|
||||
class PVCopy;
|
||||
typedef std::tr1::shared_ptr<PVCopy> PVCopyPtr;
|
||||
|
||||
typedef std::tr1::shared_ptr<PVPlugin> PVPluginPtr;
|
||||
typedef std::tr1::shared_ptr<PVFilter> PVFilterPtr;
|
||||
typedef std::map<std::string,PVPluginPtr> PVPluginMap;
|
||||
@@ -10,10 +10,6 @@
|
||||
#ifndef PVSTRUCTURECOPY_H
|
||||
#define PVSTRUCTURECOPY_H
|
||||
|
||||
#if defined(_WIN32) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
@@ -204,10 +200,16 @@ private:
|
||||
epics::pvData::PVFieldPtr const &pvCopy,
|
||||
CopyNodePtr const &node,
|
||||
epics::pvData::BitSetPtr const &bitSet);
|
||||
void updateMaster(
|
||||
epics::pvData::PVFieldPtr const &pvCopy,
|
||||
CopyNodePtr const &node,
|
||||
void updateMasterField(
|
||||
CopyNodePtr const & node,
|
||||
epics::pvData::PVFieldPtr const & pvCopy,
|
||||
epics::pvData::PVFieldPtr const &pvMaster,
|
||||
epics::pvData::BitSetPtr const &bitSet);
|
||||
void updateMasterCheckBitSet(
|
||||
epics::pvData::PVStructurePtr const ©PVStructure,
|
||||
epics::pvData::BitSetPtr const &bitSet,
|
||||
size_t nextSet);
|
||||
CopyNodePtr getCopyNode(std::size_t fieldOffset);
|
||||
|
||||
PVCopy(epics::pvData::PVStructurePtr const &pvMaster);
|
||||
bool init(epics::pvData::PVStructurePtr const &pvRequest);
|
||||
@@ -239,7 +241,6 @@ private:
|
||||
std::string *builder,
|
||||
CopyNodePtr const &node,
|
||||
int indentLevel);
|
||||
friend class PVCopyMonitor;
|
||||
};
|
||||
|
||||
}}
|
||||
78
src/pv/pvSupport.h
Normal file
78
src/pv/pvSupport.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2019.06.01
|
||||
*/
|
||||
#ifndef PVSUPPORT_H
|
||||
#define PVSUPPORT_H
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
class PVSupport;
|
||||
typedef std::tr1::shared_ptr<PVSupport> PVSupportPtr;
|
||||
|
||||
/**
|
||||
* @brief Base interface for a PVSupport.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PVSupport
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVSupport);
|
||||
/**
|
||||
* The Destructor.
|
||||
*/
|
||||
virtual ~PVSupport(){}
|
||||
/**
|
||||
* @brief Optional initialization method.
|
||||
*
|
||||
* Called after PVRecord is created but before record is installed into PVDatabase.
|
||||
*
|
||||
* @param pvValue The field to support.
|
||||
* @param pvSupport Support specific fields.
|
||||
* @return <b>true</b> for success and <b>false</b> for failure.
|
||||
*/
|
||||
virtual bool init(
|
||||
epics::pvData::PVFieldPtr const & pvValue,
|
||||
epics::pvData::PVFieldPtr const & pvSupport) {return true;}
|
||||
/**
|
||||
* @brief Optional method for derived class.
|
||||
*
|
||||
* It is called before record is added to database.
|
||||
*/
|
||||
virtual void start() {}
|
||||
/**
|
||||
* @brief Virtual method for derived class.
|
||||
*
|
||||
* Called when record is processed.
|
||||
* It is the method that implements support.
|
||||
* It is called each time the record is processed.
|
||||
*
|
||||
* @return Returns true is any fields were modified; otherwise false.
|
||||
*/
|
||||
virtual bool process() = 0;
|
||||
/**
|
||||
* @brief Optional method for derived class.
|
||||
*
|
||||
*/
|
||||
virtual void reset() {};
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* PVSUPPORT_H */
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
#ifndef PVTIMESTAMPPLUGIN_H
|
||||
#define PVTIMESTAMPPLUGIN_H
|
||||
|
||||
#if defined(_WIN32) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <pv/lock.h>
|
||||
@@ -60,7 +56,7 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A filter that sets a timeStamp to the current time.
|
||||
* @brief A filter that sets a timeStamp to/from the current field or pvCopy.
|
||||
*/
|
||||
class epicsShareClass PVTimestampFilter : public PVFilter
|
||||
{
|
||||
@@ -11,10 +11,10 @@
|
||||
#ifndef REMOVERECORD_H
|
||||
#define REMOVERECORD_H
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
|
||||
|
||||
111
src/pv/scalarAlarmSupport.h
Normal file
111
src/pv/scalarAlarmSupport.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2019.06.01
|
||||
*/
|
||||
#ifndef SCALARALARMSUPPORT_H
|
||||
#define SCALARALARMSUPPORT_H
|
||||
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/pvSupport.h>
|
||||
#include <pv/alarm.h>
|
||||
#include <pv/pvAlarm.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
class ScalarAlarmSupport;
|
||||
typedef std::tr1::shared_ptr<ScalarAlarmSupport> ScalarAlarmSupportPtr;
|
||||
|
||||
/**
|
||||
* @brief Base interface for a ScalarAlarmSupport.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass ScalarAlarmSupport :
|
||||
PVSupport
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ScalarAlarmSupport);
|
||||
/**
|
||||
* The Destructor.
|
||||
*/
|
||||
virtual ~ScalarAlarmSupport();
|
||||
/**
|
||||
* @brief Connects to contol fields.
|
||||
*
|
||||
* @param pvValue The field to support.
|
||||
* @param pvAlarm The alarm field.
|
||||
* @param pvSupport Support specific fields.
|
||||
* @return <b>true</b> for success and <b>false</b> for failure.
|
||||
*/
|
||||
virtual bool init(
|
||||
epics::pvData::PVFieldPtr const & pvValue,
|
||||
epics::pvData::PVStructurePtr const & pvAlarm,
|
||||
epics::pvData::PVFieldPtr const & pvSupport);
|
||||
/**
|
||||
* @brief Honors scalarAlarm fields.
|
||||
*
|
||||
*
|
||||
* @return Returns true is any fields were modified; otherwise false.
|
||||
*/
|
||||
virtual bool process();
|
||||
/**
|
||||
* @brief If implementing minSteps it sets isMinStep to false.
|
||||
*
|
||||
*/
|
||||
virtual void reset();
|
||||
/**
|
||||
* @brief create a ScalarAlarm
|
||||
*
|
||||
* @param pvRecord - The pvRecord to which the support is attached.
|
||||
* @return The new ScalarAlarm
|
||||
*/
|
||||
static ScalarAlarmSupportPtr create(PVRecordPtr const & pvRecord);
|
||||
/**
|
||||
* @brief create a scalarAlarm required by ScalarAlarm
|
||||
*
|
||||
* @return The scalarAlarmField introspection structure.
|
||||
*/
|
||||
static epics::pvData::StructureConstPtr scalarAlarmField();
|
||||
private:
|
||||
|
||||
ScalarAlarmSupport(PVRecordPtr const & pvRecord);
|
||||
enum {
|
||||
range_Lolo = 0,
|
||||
range_Low,
|
||||
range_Normal,
|
||||
range_High,
|
||||
range_Hihi,
|
||||
range_Invalid,
|
||||
range_Undefined
|
||||
} AlarmRange;
|
||||
void setAlarm(
|
||||
epics::pvData::PVStructurePtr const & pvAlarm,
|
||||
int alarmRange);
|
||||
PVRecordPtr pvRecord;
|
||||
int prevAlarmRange;
|
||||
epics::pvData::PVScalarPtr pvValue;
|
||||
epics::pvData::PVStructurePtr pvAlarm;
|
||||
epics::pvData::PVStructurePtr pvScalarAlarm;
|
||||
epics::pvData::PVBooleanPtr pvActive;
|
||||
epics::pvData::PVDoublePtr pvLowAlarmLimit;
|
||||
epics::pvData::PVDoublePtr pvLowWarningLimit;
|
||||
epics::pvData::PVDoublePtr pvHighWarningLimit;
|
||||
epics::pvData::PVDoublePtr pvHighAlarmLimit;
|
||||
epics::pvData::PVDoublePtr pvHysteresis;
|
||||
double requestedValue;
|
||||
double currentValue;
|
||||
bool isHystersis;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* SCALARALARMSUPPORT_H */
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
#ifndef TRACERECORD_H
|
||||
#define TRACERECORD_H
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
|
||||
@@ -13,12 +13,21 @@
|
||||
|
||||
#include <epicsGuard.h>
|
||||
#include <epicsThread.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/createRequest.h>
|
||||
#include <pv/pvaVersion.h>
|
||||
#include <pv/pvaVersionNum.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/pvSubArrayCopy.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/channelProviderLocal.h"
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
@@ -71,13 +80,13 @@ class ChannelProcessLocal :
|
||||
public:
|
||||
POINTER_DEFINITIONS(ChannelProcessLocal);
|
||||
virtual ~ChannelProcessLocal();
|
||||
virtual void destroy() {} // DEPRECATED
|
||||
static ChannelProcessLocalPtr create(
|
||||
ChannelLocalPtr const &channelLocal,
|
||||
ChannelProcessRequester::shared_pointer const & channelProcessRequester,
|
||||
PVStructurePtr const & pvRequest,
|
||||
PVRecordPtr const &pvRecord);
|
||||
virtual void process();
|
||||
virtual void destroy() EPICS_DEPRECATED {};
|
||||
virtual std::tr1::shared_ptr<Channel> getChannel();
|
||||
virtual void cancel(){}
|
||||
virtual void lock();
|
||||
@@ -204,13 +213,13 @@ class ChannelGetLocal :
|
||||
public:
|
||||
POINTER_DEFINITIONS(ChannelGetLocal);
|
||||
virtual ~ChannelGetLocal();
|
||||
virtual void destroy() {} // DEPRECATED
|
||||
static ChannelGetLocalPtr create(
|
||||
ChannelLocalPtr const &channelLocal,
|
||||
ChannelGetRequester::shared_pointer const & channelGetRequester,
|
||||
PVStructurePtr const & pvRequest,
|
||||
PVRecordPtr const &pvRecord);
|
||||
virtual void get();
|
||||
virtual void destroy() EPICS_DEPRECATED {};
|
||||
virtual std::tr1::shared_ptr<Channel> getChannel();
|
||||
virtual void cancel(){}
|
||||
virtual void lock();
|
||||
@@ -378,6 +387,7 @@ class ChannelPutLocal :
|
||||
public:
|
||||
POINTER_DEFINITIONS(ChannelPutLocal);
|
||||
virtual ~ChannelPutLocal();
|
||||
virtual void destroy() {} // DEPRECATED
|
||||
static ChannelPutLocalPtr create(
|
||||
ChannelLocalPtr const &channelLocal,
|
||||
ChannelPutRequester::shared_pointer const & channelPutRequester,
|
||||
@@ -385,7 +395,6 @@ public:
|
||||
PVRecordPtr const &pvRecord);
|
||||
virtual void put(PVStructurePtr const &pvStructure,BitSetPtr const &bitSet);
|
||||
virtual void get();
|
||||
virtual void destroy() EPICS_DEPRECATED {};
|
||||
virtual std::tr1::shared_ptr<Channel> getChannel();
|
||||
virtual void cancel(){}
|
||||
virtual void lock();
|
||||
@@ -551,6 +560,7 @@ class ChannelPutGetLocal :
|
||||
public:
|
||||
POINTER_DEFINITIONS(ChannelPutGetLocal);
|
||||
virtual ~ChannelPutGetLocal();
|
||||
virtual void destroy() {} // DEPRECATED
|
||||
static ChannelPutGetLocalPtr create(
|
||||
ChannelLocalPtr const &channelLocal,
|
||||
ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
|
||||
@@ -561,7 +571,6 @@ public:
|
||||
BitSetPtr const &putBitSet);
|
||||
virtual void getPut();
|
||||
virtual void getGet();
|
||||
virtual void destroy() EPICS_DEPRECATED {};
|
||||
virtual std::tr1::shared_ptr<Channel> getChannel();
|
||||
virtual void cancel(){}
|
||||
virtual void lock();
|
||||
@@ -769,6 +778,7 @@ class ChannelRPCLocal :
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ChannelRPCLocal);
|
||||
virtual void destroy() {} // DEPRECATED
|
||||
static ChannelRPCLocalPtr create(
|
||||
ChannelLocalPtr const & channelLocal,
|
||||
ChannelRPCRequester::shared_pointer const & channelRPCRequester,
|
||||
@@ -805,7 +815,6 @@ public:
|
||||
virtual void request(PVStructurePtr const & pvArgument);
|
||||
virtual Channel::shared_pointer getChannel();
|
||||
virtual void cancel() {}
|
||||
virtual void destroy() EPICS_DEPRECATED {};
|
||||
virtual void lock() {}
|
||||
virtual void unlock() {}
|
||||
virtual void lastRequest() {}
|
||||
@@ -964,6 +973,7 @@ class ChannelArrayLocal :
|
||||
public:
|
||||
POINTER_DEFINITIONS(ChannelArrayLocal);
|
||||
virtual ~ChannelArrayLocal();
|
||||
virtual void destroy() {} // DEPRECATED
|
||||
static ChannelArrayLocalPtr create(
|
||||
ChannelLocalPtr const &channelLocal,
|
||||
ChannelArrayRequester::shared_pointer const & channelArrayRequester,
|
||||
@@ -975,7 +985,6 @@ public:
|
||||
size_t offset, size_t count, size_t stride);
|
||||
virtual void getLength();
|
||||
virtual void setLength(size_t length);
|
||||
virtual void destroy() EPICS_DEPRECATED {};
|
||||
virtual std::tr1::shared_ptr<Channel> getChannel();
|
||||
virtual void cancel(){}
|
||||
virtual void lock();
|
||||
@@ -1151,7 +1160,7 @@ void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride)
|
||||
pvCopy->setLength(count);
|
||||
copy(pvArray,offset,stride,pvCopy,0,1,count);
|
||||
}
|
||||
} catch(std::exception e) {
|
||||
} catch(std::exception& e) {
|
||||
exceptionMessage = e.what();
|
||||
}
|
||||
Status status = Status::Ok;
|
||||
@@ -1178,7 +1187,7 @@ void ChannelArrayLocal::putArray(
|
||||
try {
|
||||
epicsGuard <PVRecord> guard(*pvr);
|
||||
copy(pvArray,0,1,this->pvArray,offset,stride,count);
|
||||
} catch(std::exception e) {
|
||||
} catch(std::exception& e) {
|
||||
exceptionMessage = e.what();
|
||||
}
|
||||
Status status = Status::Ok;
|
||||
@@ -1199,7 +1208,7 @@ void ChannelArrayLocal::getLength()
|
||||
try {
|
||||
epicsGuard <PVRecord> guard(*pvr);
|
||||
length = pvArray->getLength();
|
||||
} catch(std::exception e) {
|
||||
} catch(std::exception& e) {
|
||||
exceptionMessage = e.what();
|
||||
}
|
||||
Status status = Status::Ok;
|
||||
@@ -1225,7 +1234,7 @@ void ChannelArrayLocal::setLength(size_t length)
|
||||
if(pvArray->getLength()!=length) pvArray->setLength(length);
|
||||
}
|
||||
requester->setLengthDone(Status::Ok,getPtrSelf());
|
||||
} catch(std::exception e) {
|
||||
} catch(std::exception& e) {
|
||||
string exceptionMessage = e.what();
|
||||
Status status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
|
||||
requester->setLengthDone(status,getPtrSelf());
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* channelChannelProviderLocal.cpp */
|
||||
/* channelProviderLocal.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
@@ -10,13 +10,16 @@
|
||||
*/
|
||||
|
||||
#include <epicsThread.h>
|
||||
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/syncChannelFind.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/timeStamp.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/channelProviderLocal.h"
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
|
||||
@@ -14,11 +14,17 @@
|
||||
#include <epicsGuard.h>
|
||||
#include <pv/thread.h>
|
||||
#include <pv/bitSetUtil.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/timeStamp.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/channelProviderLocal.h"
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
@@ -135,10 +141,10 @@ class MonitorLocal :
|
||||
public:
|
||||
POINTER_DEFINITIONS(MonitorLocal);
|
||||
virtual ~MonitorLocal();
|
||||
virtual void destroy() {} // DEPRECATED
|
||||
virtual Status start();
|
||||
virtual Status stop();
|
||||
virtual MonitorElementPtr poll();
|
||||
virtual void destroy() EPICS_DEPRECATED {};
|
||||
virtual void detach(PVRecordPtr const & pvRecord){}
|
||||
virtual void release(MonitorElementPtr const & monitorElement);
|
||||
virtual void dataPut(PVRecordFieldPtr const & pvRecordField);
|
||||
|
||||
@@ -11,30 +11,19 @@
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include <cantProceed.h>
|
||||
#include <epicsStdio.h>
|
||||
#include <epicsMutex.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsThread.h>
|
||||
#include <iocsh.h>
|
||||
#include <shareLib.h>
|
||||
#include <epicsExit.h>
|
||||
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/syncChannelFind.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/timeStamp.h>
|
||||
|
||||
// this declared epicsExportSharedSymbols
|
||||
// The following must be the last include for code pvDatabase uses
|
||||
#include <epicsExport.h>
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#define epicsExportSharedSymbols
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/channelProviderLocal.h"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
@@ -4,3 +4,12 @@ SRC_DIRS += $(PVDATABASE_SRC)/special
|
||||
|
||||
LIBSRCS += traceRecord.cpp
|
||||
LIBSRCS += removeRecord.cpp
|
||||
LIBSRCS += processRecord.cpp
|
||||
|
||||
DBD += traceRecordRegister.dbd
|
||||
DBD += removeRecordRegister.dbd
|
||||
DBD += processRecordRegister.dbd
|
||||
|
||||
LIBSRCS += traceRecordRegister.cpp
|
||||
LIBSRCS += removeRecordRegister.cpp
|
||||
LIBSRCS += processRecordRegister.cpp
|
||||
|
||||
167
src/special/processRecord.cpp
Normal file
167
src/special/processRecord.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/* processRecord.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.04.18
|
||||
*/
|
||||
#include <map>
|
||||
#include <epicsThread.h>
|
||||
#include <pv/event.h>
|
||||
#include <shareLib.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/status.h>
|
||||
#include <pv/serverContext.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/processRecord.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
ProcessRecordPtr ProcessRecord::create(
|
||||
std::string const & recordName,double delay)
|
||||
{
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
|
||||
addNestedStructure("argument")->
|
||||
add("command",pvString)->
|
||||
add("recordName",pvString)->
|
||||
endNested()->
|
||||
addNestedStructure("result") ->
|
||||
add("status",pvString) ->
|
||||
endNested()->
|
||||
createStructure();
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
|
||||
ProcessRecordPtr pvRecord(
|
||||
new ProcessRecord(recordName,pvStructure,delay));
|
||||
if(!pvRecord->init()) pvRecord.reset();
|
||||
return pvRecord;
|
||||
}
|
||||
|
||||
void ProcessRecord::startThread()
|
||||
{
|
||||
thread = EpicsThreadPtr(new epicsThread(
|
||||
*this,
|
||||
"processRecord",
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
epicsThreadPriorityLow));
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void ProcessRecord::stop()
|
||||
{
|
||||
runStop.signal();
|
||||
runReturn.wait();
|
||||
}
|
||||
|
||||
|
||||
ProcessRecord::ProcessRecord(
|
||||
std::string const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure,double delay)
|
||||
: PVRecord(recordName,pvStructure),
|
||||
delay(delay),
|
||||
pvDatabase(PVDatabase::getMaster())
|
||||
{
|
||||
}
|
||||
|
||||
bool ProcessRecord::init()
|
||||
{
|
||||
initPVRecord();
|
||||
PVStructurePtr pvStructure = getPVStructure();
|
||||
pvCommand = pvStructure->getSubField<PVString>("argument.command");
|
||||
pvRecordName = pvStructure->getSubField<PVString>("argument.recordName");
|
||||
if(!pvRecordName) return false;
|
||||
pvResult = pvStructure->getSubField<PVString>("result.status");
|
||||
if(!pvResult) return false;
|
||||
startThread();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProcessRecord::process()
|
||||
{
|
||||
string recordName = pvRecordName->get();
|
||||
string command = pvCommand->get();
|
||||
if(command.compare("add")==0) {
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
std::map<std::string,PVRecordPtr>::iterator iter = pvRecordMap.find(recordName);
|
||||
if(iter!=pvRecordMap.end()) {
|
||||
pvResult->put(recordName + " already present");
|
||||
return;
|
||||
}
|
||||
PVRecordPtr pvRecord = pvDatabase->findRecord(recordName);
|
||||
if(!pvRecord) {
|
||||
pvResult->put(recordName + " not in pvDatabase");
|
||||
return;
|
||||
}
|
||||
pvRecordMap.insert(PVRecordMap::value_type(recordName,pvRecord));
|
||||
pvResult->put("success");
|
||||
return;
|
||||
} else if(command.compare("remove")==0) {
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
std::map<std::string,PVRecordPtr>::iterator iter = pvRecordMap.find(recordName);
|
||||
if(iter==pvRecordMap.end()) {
|
||||
pvResult->put(recordName + " not found");
|
||||
return;
|
||||
}
|
||||
pvRecordMap.erase(iter);
|
||||
pvResult->put("success");
|
||||
return;
|
||||
} else {
|
||||
pvResult->put(command + " not a valid command: only add and remove are valid");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessRecord::run()
|
||||
{
|
||||
while(true) {
|
||||
if(runStop.tryWait()) {
|
||||
runReturn.signal();
|
||||
return;
|
||||
}
|
||||
if(delay>0.0) epicsThreadSleep(delay);
|
||||
epicsGuard<epics::pvData::Mutex> guard(mutex);
|
||||
PVRecordMap::iterator iter;
|
||||
for(iter = pvRecordMap.begin(); iter!=pvRecordMap.end(); ++iter) {
|
||||
PVRecordPtr pvRecord = (*iter).second;
|
||||
pvRecord->lock();
|
||||
pvRecord->beginGroupPut();
|
||||
try {
|
||||
pvRecord->process();
|
||||
} catch (std::exception& ex) {
|
||||
std::cout << "record " << pvRecord->getRecordName() << "exception " << ex.what() << "\n";
|
||||
} catch (...) {
|
||||
std::cout<< "record " << pvRecord->getRecordName() << " process exception\n";
|
||||
}
|
||||
pvRecord->endGroupPut();
|
||||
pvRecord->unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
67
src/special/processRecordRegister.cpp
Normal file
67
src/special/processRecordRegister.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright information and license terms for this software can be
|
||||
* found in the file LICENSE that is included with the distribution
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.07.24
|
||||
*/
|
||||
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <iocsh.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
|
||||
// The following must be the last include for code pvDatabase uses
|
||||
#include <epicsExport.h>
|
||||
#define epicsExportSharedSymbols
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/processRecord.h"
|
||||
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
using namespace std;
|
||||
|
||||
static const iocshArg testArg0 = { "recordName", iocshArgString };
|
||||
static const iocshArg testArg1 = { "delay", iocshArgDouble };
|
||||
static const iocshArg *testArgs[] = {
|
||||
&testArg0,&testArg1};
|
||||
|
||||
static const iocshFuncDef processRecordFuncDef = {"processRecordCreate", 2,testArgs};
|
||||
|
||||
static void processRecordCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
char *recordName = args[0].sval;
|
||||
if(!recordName) {
|
||||
throw std::runtime_error("processRecordCreate invalid number of arguments");
|
||||
}
|
||||
double delay = args[1].dval;
|
||||
if(delay<0.0) delay = 1.0;
|
||||
ProcessRecordPtr record = ProcessRecord::create(recordName,delay);
|
||||
bool result = PVDatabase::getMaster()->addRecord(record);
|
||||
if(!result) cout << "recordname" << " not added" << endl;
|
||||
}
|
||||
|
||||
static void processRecordRegister(void)
|
||||
{
|
||||
static int firstTime = 1;
|
||||
if (firstTime) {
|
||||
firstTime = 0;
|
||||
iocshRegister(&processRecordFuncDef, processRecordCallFunc);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
epicsExportRegistrar(processRecordRegister);
|
||||
}
|
||||
1
src/special/processRecordRegister.dbd
Normal file
1
src/special/processRecordRegister.dbd
Normal file
@@ -0,0 +1 @@
|
||||
registrar("processRecordRegister")
|
||||
@@ -8,9 +8,28 @@
|
||||
* @author mrk
|
||||
* @date 2013.04.18
|
||||
*/
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/removeRecord.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/status.h>
|
||||
#include <pv/serverContext.h>
|
||||
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/removeRecord.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
@@ -65,7 +84,7 @@ void RemoveRecord::process()
|
||||
pvResult->put(name + " not found");
|
||||
return;
|
||||
}
|
||||
pvRecord->destroy();
|
||||
pvRecord->remove();
|
||||
pvResult->put("success");
|
||||
}
|
||||
|
||||
|
||||
62
src/special/removeRecordRegister.cpp
Normal file
62
src/special/removeRecordRegister.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright information and license terms for this software can be
|
||||
* found in the file LICENSE that is included with the distribution
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.07.24
|
||||
*/
|
||||
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
#include <epicsThread.h>
|
||||
#include <iocsh.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
|
||||
// The following must be the last include for code pvDatabase uses
|
||||
#include <epicsExport.h>
|
||||
#define epicsExportSharedSymbols
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/removeRecord.h"
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
using namespace std;
|
||||
|
||||
static const iocshArg testArg0 = { "recordName", iocshArgString };
|
||||
static const iocshArg *testArgs[] = {
|
||||
&testArg0};
|
||||
|
||||
static const iocshFuncDef removeRecordFuncDef = {"removeRecordCreate", 1,testArgs};
|
||||
|
||||
static void removeRecordCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
char *recordName = args[0].sval;
|
||||
if(!recordName) {
|
||||
throw std::runtime_error("removeRecordCreate invalid number of arguments");
|
||||
}
|
||||
RemoveRecordPtr record = RemoveRecord::create(recordName);
|
||||
bool result = PVDatabase::getMaster()->addRecord(record);
|
||||
if(!result) cout << "recordname" << " not added" << endl;
|
||||
}
|
||||
|
||||
static void removeRecordRegister(void)
|
||||
{
|
||||
static int firstTime = 1;
|
||||
if (firstTime) {
|
||||
firstTime = 0;
|
||||
iocshRegister(&removeRecordFuncDef, removeRecordCallFunc);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
epicsExportRegistrar(removeRecordRegister);
|
||||
}
|
||||
1
src/special/removeRecordRegister.dbd
Normal file
1
src/special/removeRecordRegister.dbd
Normal file
@@ -0,0 +1 @@
|
||||
registrar("removeRecordRegister")
|
||||
@@ -8,9 +8,27 @@
|
||||
* @author mrk
|
||||
* @date 2013.04.18
|
||||
*/
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/traceRecord.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/status.h>
|
||||
#include <pv/serverContext.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/channelProviderLocal.h"
|
||||
#include "pv/traceRecord.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
|
||||
63
src/special/traceRecordRegister.cpp
Normal file
63
src/special/traceRecordRegister.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright information and license terms for this software can be
|
||||
* found in the file LICENSE that is included with the distribution
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.07.24
|
||||
*/
|
||||
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <iocsh.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
|
||||
// The following must be the last include for code pvDatabase uses
|
||||
#include <epicsExport.h>
|
||||
#define epicsExportSharedSymbols
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/traceRecord.h"
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
using namespace std;
|
||||
|
||||
static const iocshArg testArg0 = { "recordName", iocshArgString };
|
||||
static const iocshArg *testArgs[] = {
|
||||
&testArg0};
|
||||
|
||||
static const iocshFuncDef traceRecordFuncDef = {"traceRecordCreate", 1,testArgs};
|
||||
|
||||
static void traceRecordCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
char *recordName = args[0].sval;
|
||||
if(!recordName) {
|
||||
throw std::runtime_error("traceRecordCreate invalid number of arguments");
|
||||
}
|
||||
TraceRecordPtr record = TraceRecord::create(recordName);
|
||||
bool result = PVDatabase::getMaster()->addRecord(record);
|
||||
if(!result) cout << "recordname" << " not added" << endl;
|
||||
}
|
||||
|
||||
static void traceRecordRegister(void)
|
||||
{
|
||||
static int firstTime = 1;
|
||||
if (firstTime) {
|
||||
firstTime = 0;
|
||||
iocshRegister(&traceRecordFuncDef, traceRecordCallFunc);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
epicsExportRegistrar(traceRecordRegister);
|
||||
}
|
||||
1
src/special/traceRecordRegister.dbd
Normal file
1
src/special/traceRecordRegister.dbd
Normal file
@@ -0,0 +1 @@
|
||||
registrar("traceRecordRegister")
|
||||
6
src/support/Makefile
Normal file
6
src/support/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
SRC_DIRS += $(PVDATABASE_SRC)/support
|
||||
|
||||
LIBSRCS += controlSupport.cpp
|
||||
LIBSRCS += scalarAlarmSupport.cpp
|
||||
138
src/support/controlSupport.cpp
Normal file
138
src/support/controlSupport.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/* controlSupport.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2019.06.01
|
||||
*/
|
||||
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#define epicsExportSharedSymbols
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include <pv/pvSupport.h>
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/controlSupport.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
ControlSupport::~ControlSupport()
|
||||
{
|
||||
cout << "ControlSupport::~ControlSupport()\n";
|
||||
}
|
||||
|
||||
epics::pvData::StructureConstPtr ControlSupport::controlField(ScalarType scalarType)
|
||||
{
|
||||
return FieldBuilder::begin()
|
||||
->setId("control_t")
|
||||
->add("limitLow", pvDouble)
|
||||
->add("limitHigh", pvDouble)
|
||||
->add("minStep", pvDouble)
|
||||
->add("outputValue", scalarType)
|
||||
->createStructure();
|
||||
}
|
||||
|
||||
|
||||
ControlSupportPtr ControlSupport::create(PVRecordPtr const & pvRecord)
|
||||
{
|
||||
ControlSupportPtr support(new ControlSupport(pvRecord));
|
||||
return support;
|
||||
}
|
||||
|
||||
ControlSupport::ControlSupport(PVRecordPtr const & pvRecord)
|
||||
: pvRecord(pvRecord)
|
||||
{}
|
||||
|
||||
bool ControlSupport::init(PVFieldPtr const & pv,PVFieldPtr const & pvsup)
|
||||
{
|
||||
if(pv) {
|
||||
if(pv->getField()->getType()==epics::pvData::scalar) {
|
||||
ScalarConstPtr s = static_pointer_cast<const Scalar>(pv->getField());
|
||||
if(ScalarTypeFunc::isNumeric(s->getScalarType())) {
|
||||
pvValue = static_pointer_cast<PVScalar>(pv);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!pvValue) {
|
||||
cout << "ControlSupport for record " << pvRecord->getRecordName()
|
||||
<< " failed because not numeric scalar\n";
|
||||
return false;
|
||||
}
|
||||
pvControl = static_pointer_cast<PVStructure>(pvsup);
|
||||
if(pvControl) {
|
||||
pvLimitLow = pvControl->getSubField<PVDouble>("limitLow");
|
||||
pvLimitHigh = pvControl->getSubField<PVDouble>("limitHigh");
|
||||
pvMinStep = pvControl->getSubField<PVDouble>("minStep");
|
||||
pvOutputValue = pvControl->getSubField<PVScalar>("outputValue");
|
||||
}
|
||||
if(!pvControl || !pvLimitLow || !pvLimitHigh || !pvMinStep || !pvOutputValue) {
|
||||
cout << "ControlSupport for record " << pvRecord->getRecordName()
|
||||
<< " failed because pvSupport not a valid control structure\n";
|
||||
return false;
|
||||
}
|
||||
ConvertPtr convert = getConvert();
|
||||
currentValue = convert->toDouble(pvValue);
|
||||
isMinStep = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ControlSupport::process()
|
||||
{
|
||||
ConvertPtr convert = getConvert();
|
||||
double value = convert->toDouble(pvValue);
|
||||
if(!isMinStep && value==currentValue) return false;
|
||||
double limitLow = pvLimitLow->get();
|
||||
double limitHigh = pvLimitHigh->get();
|
||||
double minStep = pvMinStep->get();
|
||||
bool setValue = false;
|
||||
if(limitHigh>limitLow) {
|
||||
if(value>limitHigh) {value = limitHigh;setValue=true;}
|
||||
if(value<limitLow) {value = limitLow;setValue=true;}
|
||||
}
|
||||
if(setValue) convert->fromDouble(pvValue,value);
|
||||
double diff = value - currentValue;
|
||||
double outputValue = value;
|
||||
if(minStep>0.0) {
|
||||
if(diff<0.0) {
|
||||
outputValue = currentValue - minStep;
|
||||
if(limitHigh>limitLow && outputValue<=limitLow) outputValue = limitLow;
|
||||
isMinStep = true;
|
||||
if(outputValue<value) {
|
||||
outputValue = value;
|
||||
isMinStep = false;
|
||||
}
|
||||
} else {
|
||||
outputValue = currentValue + minStep;
|
||||
if(limitHigh>limitLow && outputValue>=limitHigh) outputValue = limitHigh;
|
||||
isMinStep = true;
|
||||
if(outputValue>value) {
|
||||
outputValue = value;
|
||||
isMinStep = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(outputValue==currentValue) return false;
|
||||
currentValue = outputValue;
|
||||
convert->fromDouble(pvOutputValue,outputValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ControlSupport::reset()
|
||||
{
|
||||
isMinStep = false;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
219
src/support/scalarAlarmSupport.cpp
Normal file
219
src/support/scalarAlarmSupport.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
/* scalarAlarmSupport.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2019.06.01
|
||||
*/
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/alarm.h>
|
||||
#include <pv/pvAlarm.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "pv/pvStructureCopy.h"
|
||||
#include "pv/pvSupport.h"
|
||||
#include "pv/pvDatabase.h"
|
||||
#include "pv/scalarAlarmSupport.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
ScalarAlarmSupport::~ScalarAlarmSupport()
|
||||
{
|
||||
cout << "ScalarAlarmSupport::~ScalarAlarmSupport()\n";
|
||||
}
|
||||
|
||||
|
||||
epics::pvData::StructureConstPtr ScalarAlarmSupport::scalarAlarmField()
|
||||
{
|
||||
return FieldBuilder::begin()
|
||||
->setId("scalarAlarm_t")
|
||||
->add("lowAlarmLimit", pvDouble)
|
||||
->add("lowWarningLimit", pvDouble)
|
||||
->add("highWarningLimit", pvDouble)
|
||||
->add("highAlarmLimit", pvDouble)
|
||||
->add("hysteresis", pvDouble)
|
||||
->createStructure();
|
||||
}
|
||||
|
||||
ScalarAlarmSupportPtr ScalarAlarmSupport::create(PVRecordPtr const & pvRecord)
|
||||
{
|
||||
ScalarAlarmSupportPtr support(new ScalarAlarmSupport(pvRecord));
|
||||
return support;
|
||||
}
|
||||
|
||||
ScalarAlarmSupport::ScalarAlarmSupport(PVRecordPtr const & pvRecord)
|
||||
: pvRecord(pvRecord),
|
||||
prevAlarmRange(range_Undefined)
|
||||
{}
|
||||
|
||||
|
||||
bool ScalarAlarmSupport::init(
|
||||
PVFieldPtr const & pvval,
|
||||
PVStructurePtr const & pvalarm,
|
||||
PVFieldPtr const & pvsup)
|
||||
{
|
||||
if(pvval->getField()->getType()==epics::pvData::scalar) {
|
||||
ScalarConstPtr s = static_pointer_cast<const Scalar>(pvval->getField());
|
||||
if(ScalarTypeFunc::isNumeric(s->getScalarType())) {
|
||||
pvValue = static_pointer_cast<PVScalar>(pvval);
|
||||
}
|
||||
}
|
||||
if(!pvValue) {
|
||||
cout << "ScalarAlarmSupport for record " << pvRecord->getRecordName()
|
||||
<< " failed because not numeric scalar\n";
|
||||
return false;
|
||||
}
|
||||
pvScalarAlarm = static_pointer_cast<PVStructure>(pvsup);
|
||||
if(pvScalarAlarm) {
|
||||
pvLowAlarmLimit = pvScalarAlarm->getSubField<PVDouble>("lowAlarmLimit");
|
||||
pvLowWarningLimit = pvScalarAlarm->getSubField<PVDouble>("lowWarningLimit");
|
||||
pvHighWarningLimit = pvScalarAlarm->getSubField<PVDouble>("highWarningLimit");
|
||||
pvHighAlarmLimit = pvScalarAlarm->getSubField<PVDouble>("highAlarmLimit");
|
||||
pvHysteresis = pvScalarAlarm->getSubField<PVDouble>("hysteresis");
|
||||
}
|
||||
if(!pvScalarAlarm
|
||||
|| !pvLowAlarmLimit || !pvLowWarningLimit
|
||||
|| !pvLowWarningLimit || !pvHighAlarmLimit
|
||||
|| !pvHysteresis)
|
||||
{
|
||||
cout << "ScalarAlarmSupport for record " << pvRecord->getRecordName()
|
||||
<< " failed because pvSupport not a valid scalarAlarm structure\n";
|
||||
return false;
|
||||
}
|
||||
pvAlarm = pvalarm;
|
||||
ConvertPtr convert = getConvert();
|
||||
requestedValue = convert->toDouble(pvValue);
|
||||
currentValue = requestedValue;
|
||||
isHystersis = false;
|
||||
setAlarm(pvAlarm,range_Undefined);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScalarAlarmSupport::process()
|
||||
{
|
||||
ConvertPtr convert = getConvert();
|
||||
double value = convert->toDouble(pvValue);
|
||||
double lowAlarmLimit = pvLowAlarmLimit->get();
|
||||
double lowWarningLimit = pvLowWarningLimit->get();
|
||||
double highWarningLimit = pvHighWarningLimit->get();
|
||||
double highAlarmLimit = pvHighAlarmLimit->get();
|
||||
double hysteresis = pvHysteresis->get();
|
||||
int alarmRange = range_Normal;
|
||||
if(highAlarmLimit>lowAlarmLimit) {
|
||||
if(value>=highAlarmLimit
|
||||
||(prevAlarmRange==range_Hihi && value>=highAlarmLimit-hysteresis)) {
|
||||
alarmRange = range_Hihi;
|
||||
} else if(value<=lowAlarmLimit
|
||||
||(prevAlarmRange==range_Lolo && value<=lowAlarmLimit+hysteresis)) {
|
||||
alarmRange = range_Lolo;
|
||||
}
|
||||
}
|
||||
if(alarmRange==range_Normal && (highWarningLimit>lowWarningLimit)) {
|
||||
if(value>=highWarningLimit
|
||||
||(prevAlarmRange==range_High && value>=highWarningLimit-hysteresis)) {
|
||||
alarmRange = range_High;
|
||||
} else if(value<=lowWarningLimit
|
||||
||(prevAlarmRange==range_Low && value<=lowWarningLimit+hysteresis)) {
|
||||
alarmRange = range_Low;
|
||||
}
|
||||
}
|
||||
bool retValue = false;
|
||||
if(alarmRange!=prevAlarmRange) {
|
||||
setAlarm(pvAlarm,alarmRange);
|
||||
retValue = true;
|
||||
}
|
||||
prevAlarmRange = alarmRange;
|
||||
currentValue = value;
|
||||
return retValue;
|
||||
}
|
||||
|
||||
void ScalarAlarmSupport::reset()
|
||||
{
|
||||
isHystersis = false;
|
||||
}
|
||||
|
||||
void ScalarAlarmSupport::setAlarm(
|
||||
epics::pvData::PVStructurePtr const & pva,
|
||||
int alarmRange)
|
||||
{
|
||||
Alarm alarm;
|
||||
PVAlarm pvAlarm;
|
||||
if(!pvAlarm.attach(pva)) throw std::logic_error("bad alarm field");
|
||||
epics::pvData::AlarmStatus status(epics::pvData::noStatus);
|
||||
epics::pvData::AlarmSeverity severity(epics::pvData::noAlarm);
|
||||
string message;
|
||||
switch (alarmRange) {
|
||||
case range_Lolo :
|
||||
{
|
||||
severity = epics::pvData::majorAlarm;
|
||||
status = epics::pvData::recordStatus;
|
||||
message = "major low alarm";
|
||||
break;
|
||||
}
|
||||
case range_Low :
|
||||
{
|
||||
severity = epics::pvData::minorAlarm;
|
||||
status = epics::pvData::recordStatus;
|
||||
message = "minor low alarm";
|
||||
break;
|
||||
}
|
||||
case range_Normal :
|
||||
{
|
||||
break;
|
||||
}
|
||||
case range_High :
|
||||
{
|
||||
severity = epics::pvData::minorAlarm;
|
||||
status = epics::pvData::recordStatus;
|
||||
message = "minor high alarm";
|
||||
break;
|
||||
}
|
||||
case range_Hihi :
|
||||
{
|
||||
severity = epics::pvData::majorAlarm;
|
||||
status = epics::pvData::recordStatus;
|
||||
message = "major high alarm";
|
||||
break;
|
||||
}
|
||||
case range_Invalid :
|
||||
{
|
||||
severity = epics::pvData::invalidAlarm;
|
||||
status = epics::pvData::recordStatus;
|
||||
message = "invalid alarm";
|
||||
break;
|
||||
}
|
||||
case range_Undefined :
|
||||
{
|
||||
severity = epics::pvData::undefinedAlarm;
|
||||
status = epics::pvData::recordStatus;
|
||||
message = "undefined alarm";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
severity = epics::pvData::undefinedAlarm;
|
||||
status = epics::pvData::recordStatus;
|
||||
message = "bad alarm definition";
|
||||
break;
|
||||
}
|
||||
}
|
||||
alarm.setStatus(status);
|
||||
alarm.setSeverity(severity);
|
||||
alarm.setMessage(message);
|
||||
pvAlarm.set(alarm);
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -23,7 +23,7 @@ TESTSPEC_vxWorks = pvDbTestHarness.$(MUNCH_SUFFIX); pvDatabaseAllTests
|
||||
|
||||
# Build for RTEMS, with harness code & configuration
|
||||
PROD_RTEMS += pvDbTestHarness
|
||||
pvDbTestHarness_SRCS_RTEMS += rtemsTestHarness.c rtemsConfig.c
|
||||
pvDbTestHarness_SRCS_RTEMS += rtemsTestHarness.c
|
||||
TESTSPEC_RTEMS = pvDbTestHarness.$(MUNCH_SUFFIX); pvDatabaseAllTests
|
||||
|
||||
# Build test scripts for hosts
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* RTEMS configuration for EPICS
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Author: W. Eric Norum
|
||||
* norume@aps.anl.gov
|
||||
* (630) 252-4793
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* RTEMS CONFIGURATION *
|
||||
***********************************************************************
|
||||
*/
|
||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||
|
||||
#if __RTEMS_MAJOR__>4 || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99)
|
||||
# define CONFIGURE_UNIFIED_WORK_AREAS
|
||||
#else
|
||||
# define CONFIGURE_EXECUTIVE_RAM_SIZE (2000*1024)
|
||||
#endif
|
||||
|
||||
#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(30)
|
||||
#define CONFIGURE_MAXIMUM_SEMAPHORES rtems_resource_unlimited(500)
|
||||
#define CONFIGURE_MAXIMUM_TIMERS rtems_resource_unlimited(20)
|
||||
#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES rtems_resource_unlimited(5)
|
||||
#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
|
||||
|
||||
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 150
|
||||
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
|
||||
#define CONFIGURE_MAXIMUM_DRIVERS 8
|
||||
|
||||
#define CONFIGURE_MICROSECONDS_PER_TICK 20000
|
||||
|
||||
#define CONFIGURE_INIT_TASK_PRIORITY 80
|
||||
|
||||
#define CONFIGURE_MALLOC_STATISTICS 1
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \
|
||||
RTEMS_NO_TIMESLICE | \
|
||||
RTEMS_NO_ASR | \
|
||||
RTEMS_INTERRUPT_LEVEL(0))
|
||||
#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_FLOATING_POINT | RTEMS_LOCAL)
|
||||
#define CONFIGURE_INIT_TASK_STACK_SIZE (16*1024)
|
||||
rtems_task Init (rtems_task_argument argument);
|
||||
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||
|
||||
#define CONFIGURE_FILESYSTEM_NFS
|
||||
#define CONFIGURE_FILESYSTEM_IMFS
|
||||
|
||||
/*
|
||||
* This should be made BSP dependent, not CPU dependent but I know of no
|
||||
* appropriate conditionals to use.
|
||||
* The new general time support makes including the RTC driver less important.
|
||||
*/
|
||||
#if !defined(mpc604) && !defined(__mc68040__) && !defined(__mcf5200__) && !defined(mpc7455) && !defined(__arm__) /* don't have RTC code */
|
||||
#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER
|
||||
#endif
|
||||
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/confdefs.h>
|
||||
@@ -1,294 +0,0 @@
|
||||
/*
|
||||
* Network configuration -- QEMU NOT using DHCP
|
||||
*
|
||||
************************************************************
|
||||
* EDIT THIS FILE TO REFLECT YOUR NETWORK CONFIGURATION *
|
||||
* BEFORE RUNNING ANY RTEMS PROGRAMS WHICH USE THE NETWORK! *
|
||||
************************************************************
|
||||
*
|
||||
* The dynamic probing is based upon the EPICS network
|
||||
* configuration file written by:
|
||||
* W. Eric Norum
|
||||
* eric.norum@usask.ca
|
||||
* (306) 966-5394
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_NETWORKCONFIG_H_
|
||||
#define _RTEMS_NETWORKCONFIG_H_
|
||||
|
||||
/* #define USE_LIBBSDPORT */
|
||||
|
||||
#if defined(USE_LIBBSDPORT)
|
||||
#include <bsp/libbsdport_api.h>
|
||||
#define CONFIGURE_MAXIMUM_TIMERS 10
|
||||
#endif
|
||||
/*
|
||||
* For TFTP test application
|
||||
*/
|
||||
#if (defined (RTEMS_USE_BOOTP))
|
||||
#define RTEMS_TFTP_TEST_HOST_NAME "BOOTP_HOST"
|
||||
#define RTEMS_TFTP_TEST_FILE_NAME "BOOTP_FILE"
|
||||
#else
|
||||
#define RTEMS_TFTP_TEST_HOST_NAME "XXX.YYY.ZZZ.XYZ"
|
||||
#define RTEMS_TFTP_TEST_FILE_NAME "tftptest"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For NFS test application
|
||||
*
|
||||
* NFS mount and a directory to ls once mounted
|
||||
*/
|
||||
#define RTEMS_NFS_SERVER "192.168.1.210"
|
||||
#define RTEMS_NFS_SERVER_PATH "/home"
|
||||
#define RTEMS_NFS_LS_PATH "/mnt/nfstest"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This file can be copied to an application source directory
|
||||
* and modified to override the values shown below.
|
||||
*
|
||||
* The following CPP symbols may be passed from the Makefile:
|
||||
*
|
||||
* symbol default description
|
||||
*
|
||||
* NETWORK_TASK_PRIORITY 150 can be read by app from public
|
||||
* var 'gesysNetworkTaskPriority'
|
||||
* FIXED_IP_ADDR <undefined> hardcoded IP address (e.g.,
|
||||
* "192.168.0.10"); disables BOOTP;
|
||||
* must also define FIXED_NETMASK
|
||||
* FIXED_NETMASK <undefined> IP netmask string
|
||||
* (e.g. "255.255.255.0")
|
||||
* MULTI_NETDRIVER <undefined> ugly hack; if defined try to probe
|
||||
* a variety of PCI and ISA drivers
|
||||
* (i386 ONLY) use is discouraged!
|
||||
* NIC_NAME <undefined> Ethernet driver name (e.g. "pcn1");
|
||||
* must also define NIC_ATTACH
|
||||
* NIC_ATTACH <undefined> Ethernet driver attach function
|
||||
* (e.g., rtems_fxp_attach).
|
||||
* If these are undefined then
|
||||
* a) MULTI_NETDRIVER is used
|
||||
* (if defined)
|
||||
* b) RTEMS_BSP_NETWORK_DRIVER_NAME/
|
||||
* RTEMS_BSP_NETWORK_DRIVER_ATTACH
|
||||
* are tried
|
||||
* MEMORY_CUSTOM <undefined> Allocate the defined amount of
|
||||
* memory for mbufs and mbuf clusters,
|
||||
* respectively. Define to a comma ','
|
||||
* separated pair of two numerical
|
||||
* values, e.g: 100*1024,200*1024
|
||||
* MEMORY_SCARCE <undefined> Allocate few memory for mbufs
|
||||
* (hint for how much memory the
|
||||
* board has)
|
||||
* MEMORY_HUGE <undefined> Allocate a lot of memory for mbufs
|
||||
* (hint for how much memory the
|
||||
* board has)
|
||||
* If none of MEMORY_CUSTOM/
|
||||
* MEMORY_SCARCE/MEMORY_HUGE are
|
||||
* defined then a medium amount of
|
||||
* memory is allocated for mbufs.
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/rtems_bsdnet.h>
|
||||
|
||||
#if 0
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#else
|
||||
#include "verscheck.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//#define MULTI_NETDRIVER
|
||||
//#define RTEMS_BSP_NETWORK_DRIVER_NAME 1
|
||||
|
||||
#define FIXED_IP_ADDR "192.168.1.249"
|
||||
#define FIXED_NETMASK "255.255.255.0"
|
||||
|
||||
#ifndef NETWORK_TASK_PRIORITY
|
||||
#define NETWORK_TASK_PRIORITY 150 /* within EPICS' range */
|
||||
#endif
|
||||
|
||||
/* make publicly available for startup scripts... */
|
||||
const int gesysNetworkTaskPriority = NETWORK_TASK_PRIORITY;
|
||||
|
||||
#ifdef FIXED_IP_ADDR
|
||||
#define RTEMS_DO_BOOTP 0
|
||||
#else
|
||||
#define RTEMS_DO_BOOTP rtems_bsdnet_do_bootp
|
||||
#define FIXED_IP_ADDR 0
|
||||
#undef FIXED_NETMASK
|
||||
#define FIXED_NETMASK 0
|
||||
#endif
|
||||
|
||||
#if !defined(NIC_NAME)
|
||||
|
||||
#ifdef MULTI_NETDRIVER
|
||||
|
||||
#if 0
|
||||
#if RTEMS_VERSION_ATLEAST(4,6,99)
|
||||
#define pcib_init pci_initialize
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
extern int rtems_elnk_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
extern int rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
|
||||
/* these don't probe and will be used even if there's no device :-( */
|
||||
extern int rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
extern int rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *, int);
|
||||
|
||||
static struct rtems_bsdnet_ifconfig isa_netdriver_config[] = {
|
||||
{
|
||||
"ep0", rtems_3c509_driver_attach, isa_netdriver_config + 1,
|
||||
},
|
||||
{
|
||||
"ne1", rtems_ne_driver_attach, 0, irno: 9 /* qemu cannot configure irq-no :-(; has it hardwired to 9 */
|
||||
},
|
||||
};
|
||||
|
||||
static struct rtems_bsdnet_ifconfig pci_netdriver_config[]={
|
||||
{
|
||||
"dc1", rtems_dec21140_driver_attach, pci_netdriver_config+1,
|
||||
},
|
||||
#if !defined(USE_LIBBSDPORT)
|
||||
{
|
||||
"fxp1", rtems_fxp_attach, pci_netdriver_config+2,
|
||||
},
|
||||
#else
|
||||
{
|
||||
"", libbsdport_netdriver_attach, pci_netdriver_config+2,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"elnk1", rtems_elnk_driver_attach, isa_netdriver_config,
|
||||
},
|
||||
};
|
||||
|
||||
static int pci_check(struct rtems_bsdnet_ifconfig *ocfg, int attaching)
|
||||
{
|
||||
struct rtems_bsdnet_ifconfig *cfg;
|
||||
int if_index_pre;
|
||||
extern int if_index;
|
||||
if ( attaching ) {
|
||||
cfg = pci_initialize() ?
|
||||
isa_netdriver_config : pci_netdriver_config;
|
||||
}
|
||||
while ( cfg ) {
|
||||
printk("Probing '%s'", cfg->name);
|
||||
/* unfortunately, the return value is unreliable - some drivers report
|
||||
* success even if they fail.
|
||||
* Check if they chained an interface (ifnet) structure instead
|
||||
*/
|
||||
if_index_pre = if_index;
|
||||
cfg->attach(cfg, attaching);
|
||||
if ( if_index > if_index_pre ) {
|
||||
/* assume success */
|
||||
printk(" .. seemed to work\n");
|
||||
ocfg->name = cfg->name;
|
||||
ocfg->attach = cfg->attach;
|
||||
return 0;
|
||||
}
|
||||
printk(" .. failed\n");
|
||||
cfg = cfg->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#define NIC_NAME "dummy"
|
||||
#define NIC_ATTACH pci_check
|
||||
|
||||
#else
|
||||
|
||||
#if defined(RTEMS_BSP_NETWORK_DRIVER_NAME) /* Use NIC provided by BSP */
|
||||
|
||||
/* force ne2k_isa on i386 for qemu */
|
||||
#if defined(__i386__)
|
||||
# define NIC_NAME BSP_NE2000_NETWORK_DRIVER_NAME
|
||||
# define NIC_ATTACH BSP_NE2000_NETWORK_DRIVER_ATTACH
|
||||
|
||||
#else
|
||||
|
||||
# define NIC_NAME RTEMS_BSP_NETWORK_DRIVER_NAME
|
||||
# define NIC_ATTACH RTEMS_BSP_NETWORK_DRIVER_ATTACH
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ifdef MULTI_NETDRIVER */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef NIC_NAME
|
||||
|
||||
extern int NIC_ATTACH();
|
||||
|
||||
#if RTEMS_BSP_NETWORK_DRIVER_ATTACH == BSP_NE2000_NETWORK_DRIVER_ATTACH
|
||||
static char ethernet_address[6] = { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x34 };
|
||||
#endif
|
||||
|
||||
static struct rtems_bsdnet_ifconfig netdriver_config[1] = {{
|
||||
NIC_NAME, /* name */
|
||||
(int (*)(struct rtems_bsdnet_ifconfig*,int))NIC_ATTACH, /* attach function */
|
||||
0, /* link to next interface */
|
||||
FIXED_IP_ADDR,
|
||||
FIXED_NETMASK
|
||||
#if RTEMS_BSP_NETWORK_DRIVER_ATTACH == BSP_NE2000_NETWORK_DRIVER_ATTACH
|
||||
,
|
||||
ethernet_address,
|
||||
irno:9,
|
||||
port:0xc100
|
||||
#endif
|
||||
}};
|
||||
#else
|
||||
#warning "NO KNOWN NETWORK DRIVER FOR THIS BSP -- YOU MAY HAVE TO EDIT networkconfig.h"
|
||||
#endif
|
||||
|
||||
struct rtems_bsdnet_config rtems_bsdnet_config = {
|
||||
#ifdef NIC_NAME
|
||||
netdriver_config, /* link to next interface */
|
||||
RTEMS_DO_BOOTP, /* Use BOOTP to get network configuration */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif
|
||||
NETWORK_TASK_PRIORITY, /* Network task priority */
|
||||
#if defined(MEMORY_CUSTOM)
|
||||
MEMORY_CUSTOM,
|
||||
#elif defined(MEMORY_SCARCE)
|
||||
100*1024, /* MBUF space */
|
||||
200*1024, /* MBUF cluster space */
|
||||
#elif defined(MEMORY_HUGE)
|
||||
2*1024*1024, /* MBUF space */
|
||||
5*1024*1024, /* MBUF cluster space */
|
||||
#else
|
||||
180*1024, /* MBUF space */
|
||||
350*1024, /* MBUF cluster space */
|
||||
#endif
|
||||
#if (!defined (RTEMS_USE_BOOTP)) && defined(ON_RTEMS_LAB_WINSYSTEMS)
|
||||
"rtems", /* Host name */
|
||||
"nodomain.com", /* Domain name */
|
||||
"192.168.1.14", /* Gateway */
|
||||
"192.168.1.1", /* Log host */
|
||||
{"89.212.75.6" }, /* Name server(s) */
|
||||
{"192.168.1.1" }, /* NTP server(s) */
|
||||
#else
|
||||
NULL, /* Host name */
|
||||
NULL, /* Domain name */
|
||||
NULL, /* Gateway */
|
||||
NULL, /* Log host */
|
||||
{ NULL }, /* Name server(s) */
|
||||
{ NULL }, /* NTP server(s) */
|
||||
#endif /* !RTEMS_USE_BOOTP */
|
||||
0, /* efficiency */
|
||||
0, /* udp TX buffer */
|
||||
0, /* udp RX buffer */
|
||||
0, /* tcp TX buffer */
|
||||
0, /* tcp RX buffer */
|
||||
};
|
||||
#endif /* _RTEMS_NETWORKCONFIG_H_ */
|
||||
@@ -1,36 +1,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <rtems/rtems_bsdnet.h>
|
||||
#include <rtems/error.h>
|
||||
|
||||
#include "rtemsNetworking.h"
|
||||
|
||||
#include <osdTime.h>
|
||||
/*
|
||||
* Copyright information and license terms for this software can be
|
||||
* found in the file LICENSE that is included with the distribution
|
||||
*/
|
||||
|
||||
extern void pvDatabaseAllTests(void);
|
||||
|
||||
rtems_task
|
||||
Init (rtems_task_argument ignored)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
rtems_bsdnet_initialize_network ();
|
||||
//rtems_bsdnet_show_if_stats ();
|
||||
|
||||
rtems_time_of_day timeOfDay;
|
||||
if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&timeOfDay) != RTEMS_SUCCESSFUL) {
|
||||
timeOfDay.year = 2014;
|
||||
timeOfDay.month = 1;
|
||||
timeOfDay.day = 1;
|
||||
timeOfDay.hour = 0;
|
||||
timeOfDay.minute = 0;
|
||||
timeOfDay.second = 0;
|
||||
timeOfDay.ticks = 0;
|
||||
|
||||
rtems_status_code ret = rtems_clock_set(&timeOfDay);
|
||||
if (ret != RTEMS_SUCCESSFUL) {
|
||||
printf("**** Can't set time %s\n", rtems_status_text(ret));
|
||||
}
|
||||
}
|
||||
osdTimeRegister();
|
||||
|
||||
pvDatabaseAllTests();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user