examples are moved to project exampleCPP; update doc
This commit is contained in:
+326
-101
@@ -26,25 +26,7 @@
|
||||
|
||||
<div class="head">
|
||||
<h1>EPICS pvaClientCPP</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
|
||||
02-October-2015</h2>
|
||||
<dl>
|
||||
<dt>This version:</dt>
|
||||
<dd><a
|
||||
href="pvaClientCPP.html">pvaClientCPP.html
|
||||
</a> </dd>
|
||||
<dt>Latest version:</dt>
|
||||
<dd><a
|
||||
href="pvaClientCPP_20151002.html">pvaClientCPP_20151002.html
|
||||
</a> </dd>
|
||||
<dt>Previous version:</dt>
|
||||
<dd><a
|
||||
href="pvaClientCPP_20150803.html">pvaClientCPP_20150803.html
|
||||
</a> </dd>
|
||||
<dt>Editors:</dt>
|
||||
<dd>Marty Kraimer, BNL</dd>
|
||||
</dl>
|
||||
<h2 class="nocount">Release 4.2 - 2016.01.12</h2>
|
||||
|
||||
<h2 class="nocount">Abstract</h2>
|
||||
|
||||
@@ -78,11 +60,6 @@ The data for the channels is presented via normative type NTMultiChannel.
|
||||
Control System</a>.</p>
|
||||
|
||||
|
||||
|
||||
<h2 class="nocount">Status of this Document and of the pvaClient Software</h2>
|
||||
|
||||
<p>pvaClientCPP is ready for use.</p>
|
||||
|
||||
</div> <!-- head -->
|
||||
|
||||
<div id="toc">
|
||||
@@ -95,92 +72,340 @@ The data for the channels is presented via normative type NTMultiChannel.
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
<p>pvaClient 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>PvaClient is a synchronous API for accessing PVData via PVAccess.
|
||||
It also provides a number of convenience methods.
|
||||
It allows the client to request access without checking for failure,
|
||||
but throws an exception if a request fails.
|
||||
A client can also check for failues and thus prevent exceptions.</p>
|
||||
|
||||
<p>This document describes the layout of the source files in this project.</p>
|
||||
<p>
|
||||
A user overview is available via
|
||||
<a
|
||||
href="./pvaClientOverview.html">pvaClientOverview.html
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
Doxygen documentation is available at
|
||||
<a
|
||||
href="./html/index.html">doxygenDoc
|
||||
</a>
|
||||
</p>
|
||||
<h2>Example Database</h2>
|
||||
<p>The examples require that the database provided by project pvaClientTestCPP
|
||||
is running.
|
||||
For example:</p>
|
||||
<p>Doxygen documentation is available at <a
|
||||
href="./html/index.html">doxygenDoc</a></p>
|
||||
|
||||
<p>The PvaClient 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 pva:</p>
|
||||
<pre>
|
||||
mrk> pwd
|
||||
/home/epicsv4/pvaClientTestCPP/database/iocBoot/exampleDatabase
|
||||
mrk> ../../bin/linux-x86_64/exampleDatabase st.cmd
|
||||
// pvaGet
|
||||
PvaClientPtr pva = PvaClient::create();
|
||||
double value = pva->channel("exampleDouble")->get()->getData()->getDouble();
|
||||
|
||||
// pvaPut
|
||||
PvaClientChannelPtr channel = pva->channel("exampleDouble");
|
||||
PvaClientPutPtr put = channel->put();
|
||||
PvaClientPutDataPtr putData = put->getData();
|
||||
putData->putDouble(3.0); put->put();
|
||||
|
||||
// pvaMonitor
|
||||
PvaClientMonitorPtr monitor = pva->channel("examplePowerSupply")->monitor("");
|
||||
PvaClientMonitorDataPtr pvaData = monitor->getData();
|
||||
while(true) {
|
||||
monitor->waitEvent();
|
||||
cout << "changed\n";
|
||||
pvaData->showChanged(cout);
|
||||
cout << "overrun\n";
|
||||
pvaData->showOverrun(cout);
|
||||
monitor->releaseEvent();
|
||||
}
|
||||
|
||||
// pvaProcess
|
||||
PvaClientChannelPtr channel = pva->channel("exampleDouble");
|
||||
PvaClientProcessPtr process = channel->createProcess();
|
||||
process->process();
|
||||
|
||||
</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
|
||||
/home/epicsv4/pvaClientCPP/example
|
||||
mrk> bin/linux-x86_64/examplePvaClientGet
|
||||
</pre>
|
||||
<p>The following is a brief description of each example.
|
||||
In order to understand each example it
|
||||
helps to also look at the source for the example.</p>
|
||||
<h2>examplePvaClientGet</h2>
|
||||
<p>This has a number of examples:</p>
|
||||
<p>A separate project <b>exampleCPP</b> has examples for <b>pvDatabaseCPP</b>
|
||||
and for <b>pvaClientCPP</b>.
|
||||
See it for pvaClientCPP examples.
|
||||
</p>
|
||||
<p>pvaClient does <b>not</b> provide support for:</p>
|
||||
<dl>
|
||||
<dt>exampleDouble</dt>
|
||||
<dd>
|
||||
This shows two methods for getting data from a channel that has a numeric
|
||||
scalar value field.
|
||||
</dd>
|
||||
<dt>exampleDoubleArray</dt>
|
||||
<dd>
|
||||
This shows two methods for getting data from a channel that has a
|
||||
double array value field.
|
||||
</dd>
|
||||
<dt>exampleCADouble</dt>
|
||||
<dd>
|
||||
This is like exampleDouble except it uses provider <b>ca</b>.
|
||||
</dd>
|
||||
<dt>exampleCADoubleArray</dt>
|
||||
<dd>
|
||||
This is like exampleDoubleArray except it uses provider <b>ca</b>.
|
||||
</dd>
|
||||
<dt>examplePowerSupply</dt>
|
||||
<dd>
|
||||
This is an example of getting data from a channel that does not
|
||||
have a value field.
|
||||
<dt>ChannelArray</dt>
|
||||
<dd>TBD</dd>
|
||||
<dt>ChannelRPC</dt>
|
||||
<dd>pvAccess itself already provides a synchronous interface.
|
||||
<b>exampleCPP</b> provides <b>helloRPC</b>, which is an example of using channelRPC.
|
||||
</dd>
|
||||
</dl>
|
||||
<h2>examplePvaClientMonitor</h2>
|
||||
<p>This is an example of creating a monitor on a channel.
|
||||
It monitors a scalar double field.
|
||||
It also issues puts to the same channel so that it can make the monitors occur.
|
||||
|
||||
<h2>Building pvaClientCPP</h2>
|
||||
<p>
|
||||
If a proper <b>RELEASE.local</b> is present one directory level above <b>pvaClientCPP</b>.
|
||||
</p>
|
||||
<h2>examplePvaClientPut</h2>
|
||||
<p>This example gets and puts to channels exampleDouble
|
||||
and exampleDoubleArray.</p>
|
||||
<h2>examplePvaClientProcess</h2>
|
||||
<p>This example makes a process request to channel exampleDouble.</p>
|
||||
<h2>helloWorldPutGet</h2>
|
||||
<p>This is an example of issuing a channelPutGet.</p>
|
||||
<h2>examplePvaClientMultiDouble</h2>
|
||||
<p>This is an example of using pvaClientMultiChannel,
|
||||
pvaClientMultiGetDouble, pvaClientMultiPutDouble, and pvaClientMultiMonitorDouble.
|
||||
<p>
|
||||
Just type:
|
||||
</p>
|
||||
<h2>examplePvaClientNTMulti</h2>
|
||||
<p>This is an example of using pvaClientMultiChannel,
|
||||
pvaClientNTMultiGet, pvaClientNTMultiPut, pvaClientNTMultiMonitor, and pvaClientNTMultiData.
|
||||
<pre>
|
||||
make
|
||||
</pre>
|
||||
<p>
|
||||
An example of a proper <b>RELEASE.local</b> is:
|
||||
</p>
|
||||
<h2>helloWorldRPC</h2>
|
||||
<p>This is an example of issuing a channelRPC request.
|
||||
It does <b>not</b> use pva.</p>
|
||||
<pre>
|
||||
EPICS4_DIR=/home/epicsv4/master
|
||||
EXAMPLE=${EPICS4_DIR}/exampleCPP
|
||||
PVDATABASE=${EPICS4_DIR}/pvDatabaseCPP
|
||||
PVACLIENT=${EPICS4_DIR}/pvaClientCPP
|
||||
PVASRV=${EPICS4_DIR}/pvaSrv
|
||||
PVACCESS=${EPICS4_DIR}/pvAccessCPP
|
||||
NORMATIVETYPES=${EPICS4_DIR}/normativeTypesCPP
|
||||
PVDATA=${EPICS4_DIR}/pvDataCPP
|
||||
PVCOMMON=${EPICS4_DIR}/pvCommonCPP
|
||||
|
||||
EPICS_BASE=/home/install/epics/base
|
||||
</pre>
|
||||
|
||||
<p>pvaClientCPP can also be built if a file RELEASE.local exists in directory configure.
|
||||
To create one do the following:</p>
|
||||
<pre>
|
||||
mrk> pwd
|
||||
/home/hg/pvaClientCPP/configure
|
||||
mrk> cp ExampleRELEASE.local RELEASE.local
|
||||
</pre>
|
||||
<p>Then edit <b>RELEASE.local</b> so that it has the correct location of each
|
||||
product pvaClientCPP requires.
|
||||
Than at the top level just execute <b>make</b>:</p>
|
||||
<pre>
|
||||
mrk> cd ..
|
||||
mrk> pwd
|
||||
/home/epicsv4/master/pvaClientCPP
|
||||
mrk> make
|
||||
</pre>
|
||||
|
||||
<h2>PvaClient</h2>
|
||||
<p>An instance of PvaClient is obtained via the call:</p>
|
||||
<pre>
|
||||
PvaClientPtr pva = PvaClient::create();
|
||||
</pre>
|
||||
|
||||
<p>PvaClient has methods to create instances of <b>PvaClientChannel</b>.
|
||||
The client can specify the provider name or use the default provider.
|
||||
The client can manage it's own channels or can let pvaClient cache channels.
|
||||
An example of using the cached method is:</p>
|
||||
<pre>
|
||||
PvaClientChannelPtr pvaChannel = pva->channel("exampleDouble");
|
||||
</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, pva caches the pvaChannel 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>
|
||||
PvaClientChannelPtr pvaChannel = pva->createChannel("exampleDouble");
|
||||
</pre>
|
||||
<p>This will create an PvaClientChannel 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>PvaClientChannel - Wrapper For Single Channel</h2>
|
||||
<h3>PvaClientChannel</h3>
|
||||
<p>This provides methods for connecting to a channel and for creating instances of
|
||||
PvaClientField, PvaClientProcess, ..., PvaClientPutGet.</p>
|
||||
<p>Connection must be made before any create method is called or
|
||||
an exception is raised.
|
||||
The following is a synchronous connection request:</p>
|
||||
<pre>
|
||||
pvaChannel->connect(5.0); // BLOCKS AND THROWS IF NO CONNECT
|
||||
</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>
|
||||
pvaChannel->issueConnect(); // DOES NOT BLOCK
|
||||
.....
|
||||
Status status =pvaChannel->waitConnect(5.0); // BLOCKS DOES NOT THROW
|
||||
if(!status.isOK()) {
|
||||
// failure do something
|
||||
}
|
||||
</pre>
|
||||
<p>Once the channel is connected other PvaClient objects can be created.
|
||||
For example:</p>
|
||||
<pre>
|
||||
PvaClientGetPtr pvaGet = pvaChannel->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 pvaGet 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>
|
||||
PvaClientGetPtr pvaGet = pvaChannel->createGet(); // DOES NOT BLOCK
|
||||
</pre>
|
||||
<p>The client must connect the pvaGet.</p>
|
||||
|
||||
<h3>PvaClientGetData</h3>
|
||||
<p>This provides the data returned by pvaGet and pvaPutGet.
|
||||
It is obtained via:</p>
|
||||
<pre>
|
||||
PvaClientGetDataPtr pvaData = pvaGet->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 = pvaData->getDouble();
|
||||
</pre>
|
||||
<p>It also keeps a bitSet showing which fields have changed since the last channelGet or channelPutGet.</p>
|
||||
|
||||
<h3>PvaClientMonitorData</h3>
|
||||
<p>To the client this looks identical to PvaClientGetData except that
|
||||
it provides two BitSets: changedBitSet and overrrunBitSet.
|
||||
It is used by pvaMonitor.
|
||||
</p>
|
||||
<h3>PvaClientPutData</h3>
|
||||
<p>This is used to provided data for pvaPut and pvaPutGet.
|
||||
It has many of the same methods as pvaGetData.
|
||||
It does not have a bitSet.
|
||||
It also has put methods like:</p>
|
||||
<pre>
|
||||
void pvaData->putDouble(5.0);
|
||||
</pre>
|
||||
<h3>PvaClientGet</h3>
|
||||
<p>This provides methods to connect to channelGet and to issue get request.
|
||||
To connect via a single synchronous call:</p>
|
||||
<pre>
|
||||
easyGet->connect(); // BLOCKS AND CAN THROW
|
||||
</pre>
|
||||
<p>This can also be done in two steps:</p>
|
||||
<pre>
|
||||
pvaGet->issueConnect(); // DOES NOT BLOCK
|
||||
...
|
||||
Status status = pvaGet->waitConnect(); // BLOCKS AND DOES NOT THROW
|
||||
</pre>
|
||||
<p>Once connected gets are issued via either:</p>
|
||||
<pre>
|
||||
void pvaGet->get(); // BLOCKS AND CAN THROW
|
||||
</pre>
|
||||
or
|
||||
<pre>
|
||||
pvaGet->issueGet(); // DOES NOT BLOCK
|
||||
...
|
||||
Status status = pvaGet->waitGet(); // BLOCKS AND DOES NOT THROW
|
||||
</pre>
|
||||
<h3>PvaClientPut</h3>
|
||||
<p>This is similar to pvaGet except that it wraps channelPut instead of channelGet.
|
||||
</p>
|
||||
<p>Once connected puts are issued via either:</p>
|
||||
<pre>
|
||||
void pvaPut->put(); // BLOCKS AND CAN THROW
|
||||
</pre>
|
||||
or
|
||||
<pre>
|
||||
pvaPut->issuePut(); // DOES NOT BLOCK
|
||||
...
|
||||
Status status = pvaPut->waitPut(); // BLOCKS AND DOES NOT THROW
|
||||
</pre>
|
||||
<h3>PvaClientMonitor</h3>
|
||||
<p>Connecting is similar to pvaGet and pvaPut.
|
||||
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 pvaMonitorData.
|
||||
</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>PvaClientProcess</h3>
|
||||
<p>Connecting is similar to pvaGet.
|
||||
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>PvaClientPutGet</h3>
|
||||
<p>Connecting is similar to pvaGet.
|
||||
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 PvaClientData for the put part of channelPutGet.
|
||||
</dd>
|
||||
<dt>getGetData</dt>
|
||||
<dd>
|
||||
Returns the PvaClientData for the get part of channelPutGet.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>Look at javaDoc for details.</p>
|
||||
|
||||
<h2>PvaClientMultiChannel - Wrapper For Multiple Channels</h2>
|
||||
<h3>PvaClientMultiChannel</h3>
|
||||
<p>This provides methods for connecting to multiple channels.
|
||||
</p>
|
||||
<h3>PvaClientMultiGetDouble</h3>
|
||||
<p>This provides support for channelGet to multiple channels where each channel has a value field that is a numeric scalar.
|
||||
</p>
|
||||
<h3>PvaClientMultiPutDouble</h3>
|
||||
<p>This provides support for channelPut to multiple channels where each channel has a value field that is a numeric scalar.
|
||||
</p>
|
||||
<h3>PvaClientMultiMonitorDouble</h3>
|
||||
<p>This provides support for monitoring changes to multiple channels where each channel has a value field that is a numeric scalar.
|
||||
</p>
|
||||
<h3>PvaClientNTMultiGet</h3>
|
||||
<p>This provides support for channelGet to multiple channels where each channel has a value field that has any valid type.
|
||||
</p>
|
||||
<h3>PvaClientNTMultiPut</h3>
|
||||
<p>This provides support for channelPut to multiple channels where each channel has a value
|
||||
field that has any valid type.
|
||||
</p>
|
||||
<h3>PvaClientNTMultiMonitor</h3>
|
||||
<p>This provides support for monitoring changes to multiple channels where each channel has a
|
||||
value field that has any valid type.
|
||||
</p>
|
||||
<h3>PvaClientNTMultiData</h3>
|
||||
<p>This provides support for monitoring changes to multiple channels where each channel has a value field that has any valid type.
|
||||
The client can get the data as normative type NTMultiChannel.
|
||||
</p>
|
||||
|
||||
</div> <!-- class="contents" -->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user