all EasyChannel methods are implemented except channelArray; EasyMultiChannel not started.
This commit is contained in:
+35
-157
@@ -28,7 +28,7 @@
|
||||
<h1>EPICS easyPVA</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
|
||||
02-Mar-2015</h2>
|
||||
13-Mar-2015</h2>
|
||||
<dl>
|
||||
<dt>This version:</dt>
|
||||
<dd><a
|
||||
@@ -68,8 +68,6 @@ The first is as an NTMultiChannel. The second is as a double array.
|
||||
The double array can be used if the value field of every channel is a numeric scalar.
|
||||
There is code for NTMultiChannel that helps with access to more complicated data types.
|
||||
</p>
|
||||
<p>EasyPVA will become part of pvAccess when it is ready. </p>
|
||||
|
||||
<!-- last para of Abstract is boilerplate reference to EPICS -->
|
||||
<p>For more information about EPICS generally, please refer to the home page of the <a
|
||||
href="http://www.aps.anl.gov/epics/">Experimental Physics and Industrial
|
||||
@@ -96,159 +94,35 @@ There is code for NTMultiChannel that helps with access to more complicated data
|
||||
<p>EasyPVA is a synchronous API for accessing PVData via PVAccess. It provides
|
||||
an interface to many of the features provided by pvData and pvAccess.</p>
|
||||
|
||||
<p>The EasyPVA API has the following features:</p>
|
||||
<ol>
|
||||
<li>Makes common requests easy to program</li>
|
||||
<li>Provides full access to the pvAccess API for more demanding
|
||||
applications</li>
|
||||
<li>Allows efficient client side programs.</li>
|
||||
</ol>
|
||||
|
||||
<p>This document briefly describes the CPP version of EasyPVA.
|
||||
Doxygen documentation is available at <a
|
||||
href="./html/index.html">doxygenDoc</a></p>
|
||||
<h3>EasyPVA Interfaces</h3>
|
||||
<h4>Simple</h4>
|
||||
<p>The following</p>
|
||||
<pre>
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
double value = easyPVA->channel("exampleDouble")->get()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
</pre>
|
||||
produces:
|
||||
<pre>
|
||||
as double 5
|
||||
</pre>
|
||||
<p>This is an example of the simplest way to use EasyPVA.
|
||||
An important feature is that,
|
||||
when the simple interface is used,
|
||||
EasyPva caches Channels, ChannelGets, etc.
|
||||
This if the above code is replaced by:</p>
|
||||
<pre>
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
double value = easyPVA->channel("exampleDouble")->get()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
value = easyPVA->channel("exampleDouble")->get()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
</pre>
|
||||
The second call will reuse the channel and channelGet created by the first call.
|
||||
<p>But if any problems occur using the simple interface an exception is thrown.</p>
|
||||
|
||||
<h4>More Complex But No Exceptions.</h4>
|
||||
<p>The following</p>
|
||||
<pre>
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDouble");
|
||||
easyChannel->issueConnect();
|
||||
Status status = easyChannel->waitConnect(2.0);
|
||||
if(!status.isOK()) {cout << " connect failed\n"; return;}
|
||||
EasyGetPtr easyGet = easyChannel->createGet();
|
||||
easyGet->issueConnect();
|
||||
status = easyGet->waitConnect();
|
||||
if(!status.isOK()) {cout << " createGet failed\n"; return;}
|
||||
value = easyGet->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
</pre>
|
||||
also produces:
|
||||
<pre>
|
||||
as double 5
|
||||
</pre>
|
||||
<p>The main feature of this over the simple way is that no exceptions will be thrown.</p>
|
||||
|
||||
<h3>Initialization</h3>
|
||||
|
||||
<p>A client obtains the interface to EasyPVA via the call:</p>
|
||||
<pre>EasyPVAPtr easyPVA = EasyPVAFactorys->create();</pre>
|
||||
|
||||
<p>The client can call this an arbitrary number of times.
|
||||
On the first call the PVAccess client factory is started.
|
||||
When the last EasyPVA is destroyed the PVAccess client factory is stopped.
|
||||
</p>This document describes the layout of the source files in this project.</p>
|
||||
<p>
|
||||
A user overview is available via
|
||||
<a
|
||||
href="./overiew.html">overview.html
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h3>EasyPVA Overview</h3>
|
||||
|
||||
<p>EasyPVA creates interfaces to one of the following:</p>
|
||||
<dl>
|
||||
<dt>EasyChannel</dt>
|
||||
<dd>This creates an interface for accessing a single channel.<br />
|
||||
There are two methods for creating an EasyChannel,
|
||||
with the difference being that the second
|
||||
specifiers the name of the provider.
|
||||
The other assumes that the provider is "pva" (pvAccess).
|
||||
</dd>
|
||||
<dt>EasyMultiChannel</dt>
|
||||
<dd>This creates an interface for accessing a set of channels.<br />
|
||||
There are multiple methods for creating an EasyMultiChannel.
|
||||
The provider can be supplied or use a default of "pva".
|
||||
A union for the UnionArray for accessing the value fields of each channel
|
||||
can be provided or a default of variant union will be used.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3>EasyChannel Overview</h3>
|
||||
|
||||
<p>This interface creates Easy support for each PVAccess::Channel create
|
||||
method:</p>
|
||||
<dl>
|
||||
<dt>EasyField</dt>
|
||||
<dd>This gets the introspection interface from a channel. The
|
||||
implementation provides full access to the features of
|
||||
Channel::getField.</dd>
|
||||
<dt>EasyProcess</dt>
|
||||
<dd>This is used to process a channel. The implementation provides full
|
||||
access to the features of ChannelProcess.</dd>
|
||||
<dt>EasyGet</dt>
|
||||
<dd>This is used to get values from a channel. The implementation allows
|
||||
full access to all the features of ChannelGet. By default it asks for the
|
||||
fields value, alarm, and timeStamp. If the channel has a value field then
|
||||
EasyGet provides convenience methods for a scalar value and for an array
|
||||
value. </dd>
|
||||
<dt>EasyPut</dt>
|
||||
<dd>This is used to get the current value of a channel and to put values to
|
||||
a channel. The implementation allows full access to all the features of
|
||||
ChannelPut. By default it asks for the field value, alarm, and timeStamp.
|
||||
If the channel has a value field then EasyPut provides convenience
|
||||
methods for a scalar value and for an array value. </dd>
|
||||
<dt>EasyRPC</dt>
|
||||
<dd>This is an interface to ChannelRPC.
|
||||
The implementation allows full access to all the features of ChannelRPC.
|
||||
</dd>
|
||||
<dt>EasyPutGet</dt>
|
||||
<dd>This is an interface to ChannelPutGet. Details TBD.</dd>
|
||||
<dt>EasyMonitor</dt>
|
||||
<dd>This is an interface to Monitor.
|
||||
The implementation allows full access to all the features of pvAccess Monitor.
|
||||
</dd>
|
||||
<dt>EasyArray</dt>
|
||||
<dd>This is an interface to ChannelArray. Details TBD.</dd>
|
||||
<dt>EasyProcess</dt>
|
||||
<dd>This is an interface to ChannelProcess. Details TBD.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>EasyMultiChannel Overview</h3>
|
||||
<p>This interface creates Easy support for accessing a set of channels.
|
||||
The only requirement of the channels is that each must have a top level field named value.
|
||||
<p>
|
||||
Doxygen documentation is available at
|
||||
<a
|
||||
href="./html/index.html">doxygenDoc
|
||||
</a>
|
||||
</p>
|
||||
<dl>
|
||||
<dt>EasyMultiGet</dt>
|
||||
<dd>This is used to get values from a a set of channels.
|
||||
The result can either be an NTMultiChannel structure or a <b>double[]</b> array.
|
||||
The createGet method determines the result type.
|
||||
</dd>
|
||||
<dt>EasyMultiPut</dt>
|
||||
<dd>This is used to get and put values from/to a set of channels.
|
||||
The data supplied can either be an NTMultiChannel structure or a <b>double[]</b> array.
|
||||
The createPut method determines the type.
|
||||
</dd>
|
||||
<dt>EasyMonitor</dt>
|
||||
<dd>This is used to monitor values from a set of channels.
|
||||
Each event can either be an NTMultiChannel structure or a <b>double[]</b> array.
|
||||
The createMonitor method determines the data type.
|
||||
</dd>
|
||||
</dl>
|
||||
<h2>Building</h2>
|
||||
<p>After obtaining the source:</p>
|
||||
<pre>
|
||||
cd configure
|
||||
cp ExampleRELEASE.local RELEASE.local
|
||||
</pre>
|
||||
<p>Edit <b>RELEASE.local</b> so that all path names are correct for you environment.
|
||||
</p>
|
||||
<p>
|
||||
Then:</p>
|
||||
<pre>
|
||||
cd ..
|
||||
make
|
||||
</pre>
|
||||
|
||||
<h2>example source code</h2>
|
||||
<h3>Example Database</h3>
|
||||
<h2>Example and Test Database</h2>
|
||||
<p>The examples require that an example pvAccess server is runnimg.
|
||||
This distribution has a file <b>exampleDatabaseEasyPVA.zip</b>.
|
||||
When unzipped this is used to create an example IOC database.
|
||||
@@ -267,8 +141,14 @@ make
|
||||
cd iocBoot/exampleDatabase
|
||||
../../bin/<arch:>/exampleDatabase st.cmd
|
||||
</pre>
|
||||
<h3>Examples</h3>
|
||||
<p>These are examples in directory <b>example/src</b>.
|
||||
<h2>Testing</h2>
|
||||
<p>The tests will fail unless the example database is running.</p>
|
||||
<p>Once it is running:</p>
|
||||
<pre>
|
||||
make runtests
|
||||
</pre>
|
||||
<h2>Examples</h2>
|
||||
<p>Examples are in directory <b>example/src</b>.
|
||||
An example of how to run them is:</p>
|
||||
<pre>
|
||||
mrk> pwd
|
||||
@@ -279,8 +159,6 @@ mrk> bin/linux-x86_64/exampleEasyGet
|
||||
See the source code for each example.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div> <!-- class="contents" -->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||
<title>easyPVA C++ Overview</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||
table { margin-left: auto; margin-right: auto }
|
||||
.diagram { text-align: center; margin: 2.5em 0 }
|
||||
body { margin-right: 10% }
|
||||
/*]]>*/</style>
|
||||
|
||||
<!-- Script that generates the Table of Contents -->
|
||||
<script type="text/javascript" src="http://epics-pvdata.sourceforge.net/script/tocgen.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="head">
|
||||
<h1>easyPVA C++ Overview</h1>
|
||||
|
||||
</div> <!-- head -->
|
||||
|
||||
<div id="toc">
|
||||
<h2 class="nocount">Table of Contents</h2>
|
||||
</div>
|
||||
|
||||
<!-- Place what you would like in the Table of Contents, inside the contents div -->
|
||||
<div id="contents" class="contents">
|
||||
<hr />
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
<p>EasyPVA is a synchronous API for accessing PVData via PVAccess.
|
||||
It also provides a number of convience methods.
|
||||
It allows the client to request access without checking for failure,
|
||||
but throws an exception when a reuest fails.
|
||||
A client can also check for failues and thus prevent failures.</p>
|
||||
|
||||
<p>The EasyPVA API has the following features:</p>
|
||||
<ol>
|
||||
<li>Provides a synchronous API rather than the callback API provided by pvAccess.</li>
|
||||
<li>Makes common requests easy.</li>
|
||||
<li>Provides full access to the pvAccess API for more demanding
|
||||
applications</li>
|
||||
<li>Allows efficient client side programs.</li>
|
||||
<li>Takes care of most object resource management problems.</li>
|
||||
</ol>
|
||||
<p>Simple examples of using easyPVA:</p>
|
||||
<pre>
|
||||
// easyGet
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
double value = easyPVA->channel("exampleDouble")->get()->getData()->getDouble();
|
||||
|
||||
// easyPut
|
||||
EasyChannelPtr channel = easyPVA->channel("exampleDouble");
|
||||
EasyPutPtr put = channel->put();
|
||||
EasyPutDataPtr putData = put->getData();
|
||||
putData->putDouble(3.0); put->put();
|
||||
|
||||
// easyMonitor
|
||||
EasyMonitorPtr monitor = easyPVA->channel("examplePowerSupply")->monitor("");
|
||||
EasyMonitorDataPtr easyData = monitor->getData();
|
||||
while(true) {
|
||||
monitor->waitEvent();
|
||||
cout << "changed\n";
|
||||
easyData->showChanged(cout);
|
||||
cout << "overrun\n";
|
||||
easyData->showOverrun(cout);
|
||||
monitor->releaseEvent();
|
||||
}
|
||||
|
||||
// easyProcess
|
||||
EasyChannelPtr channel = easyPVA->channel("exampleDouble");
|
||||
EasyProcessPtr process = channel->createProcess();
|
||||
process->process();
|
||||
|
||||
</pre>
|
||||
|
||||
<h2>EasyPVA</h2>
|
||||
<p>An instance of EasyPVA is obtained via the call:</p>
|
||||
<pre>
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
</pre>
|
||||
|
||||
<p>EasyPVA has methods to create instances of <b>EasyChannel</b>.
|
||||
The client can specify the provider name or use the default provider.
|
||||
The client can manage it's own channels or can let easyPVA cache channels.
|
||||
An example of using the cache method is:</p>
|
||||
<pre>
|
||||
string channelName("exampleDouble");
|
||||
EasyChannelPtr easyChannel = easyPVA->channel(channelName);
|
||||
</pre>
|
||||
<p>This will attempt to connect to channel exampleDouble.
|
||||
Since the client did not specify a timeout an exception wll be thrown if
|
||||
the connection request fails.
|
||||
The client will block until the connection is made or an exception is thrown.
|
||||
If the request succeeds, easyPVA caches the easyChannel so that if the
|
||||
client makes another request for the same channel the cached object is
|
||||
returned to the client.
|
||||
</p>
|
||||
<p>An example of using a non cached method is:</p>
|
||||
<pre>
|
||||
string channelName("exampleDouble");
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel(channelName);
|
||||
</pre>
|
||||
<p>This will create an EasyChannel and return it to the client.
|
||||
The client must itself connect.
|
||||
This is useful if the client wants to connect to multiple channels in parallel.
|
||||
</p>
|
||||
|
||||
<h2>EasyChannel - Wrapper For Single Channel</h2>
|
||||
<h3>EasyChannel</h3>
|
||||
<p>This provides methods for connecting to a channel and for creating instances of
|
||||
EasyField, EasyProcess, ..., EasyRPC.</p>
|
||||
<p>Connection must be made before any crete method is called or
|
||||
an exception is raised.
|
||||
The following is a synchronous connection request:</p>
|
||||
<pre>
|
||||
easyChannel->connect(5.0); // BLOCKS
|
||||
</pre>
|
||||
<p>This blocks until then connection is made or until timout occurs.
|
||||
An exception is raised if the connection request fails.
|
||||
</p>
|
||||
<p>The same request can be made without blocking and without exceptions.</p>
|
||||
<pre>
|
||||
easyChannel->issueConnect(); // DOES NOT BLOCK
|
||||
.....
|
||||
Status status =easyChannel->waitConnect(5.0); // BLOCKS
|
||||
if(!status.isOK()) {
|
||||
// failure do something
|
||||
}
|
||||
</pre>
|
||||
<p>Once the channel is connected other Easy objects can be created.
|
||||
For example:</p>
|
||||
<pre>
|
||||
EasyGetPtr easyGet = easyChannel->get(); // DOES BLOCK
|
||||
</pre>
|
||||
<p>This is a caching request.
|
||||
If the client already has made an identical request the client will receive the
|
||||
cached object.
|
||||
If a new easyGet is created than it is connected before it is returned to the client.
|
||||
</p>
|
||||
<p>The client can also managed it's own objects:</p>
|
||||
<pre>
|
||||
EasyGetPtr easyGet = easyChannel->createGet(); // DOES NOT BLOCK
|
||||
</pre>
|
||||
<p>The client must connect the easyGet.</p>
|
||||
|
||||
<h3>EasyGetData</h3>
|
||||
<p>This provides the data returned by easyGet and easyPutGet.
|
||||
It is obtained via:</p>
|
||||
<pre>
|
||||
EasyGetDataPtr easyData = easyGet->getData();
|
||||
</pre>
|
||||
<p>It provides methods to get everything returned by channelGet.
|
||||
In addition there are methods that make it easier to handle a value
|
||||
field that is a scalar or a scalarArray.
|
||||
Also for a scalar that is a double or a scalarArray with element type double.
|
||||
</p>
|
||||
<p>An example is:</p>
|
||||
<pre>
|
||||
double value = easyData->getDouble();
|
||||
</pre>
|
||||
<p>It also keeps a bitSet showing which fields have changed since the last channelGet or channelPutGet.</p>
|
||||
|
||||
<h3>EasyMonitorData</h3>
|
||||
<p>To the client this looks identical to EasyGetData except that
|
||||
it provides two BitSets: changedBitSet and overrrunBitSet.
|
||||
It is used by easyMonitor.
|
||||
</p>
|
||||
<h3>EasyPutData</h3>
|
||||
<p>This is used to provided data for easyPut and easyPutGet.
|
||||
It has many of the same methods as easyGetData.
|
||||
It does not have a bitSet.
|
||||
It also has put methods like:</p>
|
||||
<pre>
|
||||
void easyData->putDouble(5.0);
|
||||
</pre>
|
||||
<h3>EasyGet</h3>
|
||||
<p>This provides methods to connect to channelGet and to issue get request.
|
||||
To connect via a single synchronous call:</p>
|
||||
<pre>
|
||||
eastGet->connect(); // BLOCKS
|
||||
</pre>
|
||||
<p>This can also be done in two steps:</p>
|
||||
<pre>
|
||||
easyGet->issueConnect(); // DOES NOT BLOCK
|
||||
...
|
||||
Status status = easyGet->waitConnect(); // BLOCKS
|
||||
</pre>
|
||||
<p>Once connected gets are issued via either:</p>
|
||||
<pre>
|
||||
void easyGet->get();
|
||||
</pre>
|
||||
or
|
||||
<pre>
|
||||
easyGet->issueGet(); // DOES NOT BLOCK
|
||||
...
|
||||
Status status = easyGet->waitGet(); // BLOCKS
|
||||
</pre>
|
||||
<h3>EasyPut</h3>
|
||||
<p>This is similar to easyGet except that it wraps channelPut instead of channelGet.
|
||||
</p>
|
||||
<p>Once connected puts are issued via either:</p>
|
||||
<pre>
|
||||
void easyPut->put();
|
||||
</pre>
|
||||
or
|
||||
<pre>
|
||||
easyPut->issuePut(); // DOES NOT BLOCK
|
||||
...
|
||||
Status status = easyPut->waitPut(); // BLOCKS
|
||||
</pre>
|
||||
<h3>EasyMonitor</h3>
|
||||
<p>Connecting is similar to easyGet and easyPut.
|
||||
The other methods are:</p>
|
||||
<dl>
|
||||
<dt>start</dt>
|
||||
<dd>Starts monitoring</dd>
|
||||
<dt>stop</dt>
|
||||
<dd>Stops monitoring</dd>
|
||||
<dt>poll</dt>
|
||||
<dd>polls for a monitorEvent.
|
||||
The data is avalable via easyMonitorData.
|
||||
</dd>
|
||||
<dt>releaseEvent</dt>
|
||||
<dd>Release the data from the last poll.
|
||||
Note that this must be called before another poll is requested.
|
||||
</dd>
|
||||
<dt>waitEvent</dt>
|
||||
<dd>Block until a monitorEvent is available.
|
||||
If true is returned a poll has already been issued.
|
||||
</dd>
|
||||
<dt>setRequester</dt>
|
||||
<dd>A client callback is registered to receive notice of monitorEvents.</dd>
|
||||
</dl>
|
||||
<h3>EasyProcess</h3>
|
||||
<p>Connecting is similar to easyGet.
|
||||
It has methods:</p>
|
||||
<dl>
|
||||
<dt>process</dt>
|
||||
<dd>call issueProcess and waitProcess.</dd>
|
||||
<dt>issueProcess</dt>
|
||||
<dd>call channelProcess->process() and return immediately.
|
||||
</dd>
|
||||
<dt>waitProcess</dt>
|
||||
<dd>Wait for process to complete.</dd>
|
||||
</dl>
|
||||
<h3>EasyPutGet</h3>
|
||||
<p>Connecting is similar to easyGet.
|
||||
It has methods:</p>
|
||||
<dl>
|
||||
<dt>putGet</dt>
|
||||
<dd>calls issuePutGet and waitPutGet.
|
||||
throws an exception if not successfull.
|
||||
</dd>
|
||||
<dt>issuePutGet</dt>
|
||||
<dd>
|
||||
Calls channel->putGet() and returns.
|
||||
</dd>
|
||||
<dt>waitPutGet</dt>
|
||||
<dd>
|
||||
Waits until putGet completes and returns status.
|
||||
</dd>
|
||||
<dt>getGet,issueGetGet, and waitGetGet</dt>
|
||||
<dd>Gets the data for the get part of channelPutGet.</dd>
|
||||
<dt>getPut,issueGetPut,and waitGetPut</dt>
|
||||
<dd>Gets the data for the put part of channelPutGet.</dd>
|
||||
<dt>getPutData</dt>
|
||||
<dd>
|
||||
Returns the EasyData for the put part of channelPutGet.
|
||||
</dd>
|
||||
<dt>getGetData</dt>
|
||||
<dd>
|
||||
Returns the EasyData for the get part of channelPutGet.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>Look at javaDoc for details.</p>
|
||||
|
||||
<h2>EasyMultiChannel - Wrapper For Multiple Channels</h2>
|
||||
<p>TBD</p>
|
||||
|
||||
</div> <!-- class="contents" -->
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user