4484 lines
166 KiB
HTML
4484 lines
166 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
|
"http://www.w3.org/TR/html4/strict.dtd">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
|
|
<title>EPICS R3.15 Channel Access Reference Manual</title>
|
|
<style type="text/css">
|
|
<!--
|
|
h3 code {
|
|
background-color: #ddf;
|
|
font-size: larger;
|
|
}
|
|
-->
|
|
|
|
</style>
|
|
</head>
|
|
|
|
<body lang="en">
|
|
<hr>
|
|
|
|
<h1>EPICS R3.15 Channel Access Reference Manual</h1>
|
|
<address>
|
|
Jeffrey O. Hill
|
|
</address>
|
|
|
|
<p><span style="font-size: x-small; font-weight:lighter;">Los Alamos National
|
|
Laboratory, SNS Division</span></p>
|
|
<address>
|
|
Ralph Lange
|
|
</address>
|
|
|
|
<p><span style="font-size: x-small; font-weight:lighter;">Helmholtz-Zentrum
|
|
Berlin (BESSY II)</span></p>
|
|
|
|
<p><span style="font-size: xx-small; font-weight:lighter;">Copyright © 2009
|
|
Helmholtz-Zentrum Berlin für Materialien und Energie GmbH.<br>
|
|
Copyright © 2002 The University of Chicago, as Operator of Argonne National
|
|
Laboratory.<br>
|
|
Copyright © 2002 The Regents of the University of California, as Operator of
|
|
Los Alamos National Laboratory.<br>
|
|
Copyright © 2002 Berliner Speicherringgesellschaft für Synchrotronstrahlung
|
|
GmbH.</span></p>
|
|
|
|
<p><span style="font-size: xx-small; font-weight:lighter;">EPICS BASE is
|
|
distributed subject to a Software License Agreement found
|
|
in the file LICENSE that is included with this distribution.</span></p>
|
|
|
|
<p><a href="http://www.w3.org/Amaya/"><img
|
|
src="http://www.w3.org/Amaya/Icons/w3c-amaya.gif" alt="W3C-Amaya" height="31"
|
|
width="88"></a> <a href="http://validator.w3.org/check/referer"><img
|
|
src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" height="31"
|
|
width="88"></a></p>
|
|
|
|
<hr>
|
|
|
|
<h2>Table of Contents</h2>
|
|
|
|
<h3><a href="#Configuration">Configuration</a></h3>
|
|
<ul>
|
|
<li><a href="#EPICS">EPICS Environment Variables</a></li>
|
|
<li><a href="#CA and Wide Area Networks">CA and Wide Area Networks</a></li>
|
|
<li><a href="#Network">IP Network Administration Background
|
|
Information</a></li>
|
|
<li><a href="#port">IP port numbers</a></li>
|
|
<li><a href="#firewall">Firewalls</a></li>
|
|
<li><a href="#Environmen">WAN Environment</a></li>
|
|
<li><a href="#Disconnect">Disconnect Time Out Interval / Server Beacon
|
|
Period</a></li>
|
|
<li><a href="#Dynamic">Dynamic Changes in the CA Client Library Search
|
|
Interval</a></li>
|
|
<li><a href="#Configurin3">Configuring the Maximum Search Period</a></li>
|
|
<li><a href="#Repeater">The CA Repeater</a></li>
|
|
<li><a href="#Configurin">Configuring the Time Zone</a></li>
|
|
<li><a href="#Configurin1">Configuring the Maximum Array Size</a></li>
|
|
<li><a href="#Configurin2">Configuring a CA server</a></li>
|
|
</ul>
|
|
|
|
<h3><a href="#Building">Building an Application</a></h3>
|
|
<ul>
|
|
<li><a href="#Required1">Required Header (.h) Files</a></li>
|
|
<li><a href="#Required">Required Libraries</a></li>
|
|
<li><a href="#Compiler">Compiler and System Specific Build Options</a></li>
|
|
</ul>
|
|
|
|
<h3><a href="#CommandUtils">Command Line Utilities</a></h3>
|
|
<ul>
|
|
<li><a href="#acctst">acctst - CA client library regression test</a></li>
|
|
<li><a href="#caEventRat">caEventRate - PV event rate logging</a></li>
|
|
<li><a href="#casw">casw - CA server beacon anomaly logging</a></li>
|
|
<li><a href="#catime">catime - CA client library performance test</a></li>
|
|
<li><a href="#ca_test">ca_test - dump the value of a PV in each external data
|
|
type to the console</a></li>
|
|
<li><a href="#excas">excas - an example server</a></li>
|
|
</ul>
|
|
|
|
<h3 style=""><a href="#CommandTools">Command Line Tools</a></h3>
|
|
<ul style="">
|
|
<li><a href="#caget">caget - Get and print value for PVs</a></li>
|
|
<li><a href="#camonitor">camonitor - Set up monitor and continuously print
|
|
incoming values for PVs</a></li>
|
|
<li><a href="#caput">caput - Put value to a PV</a></li>
|
|
<li><a href="#cainfo">cainfo - Print all available channel status and
|
|
information for a PV</a></li>
|
|
</ul>
|
|
|
|
<h3><a href="#Troubleshooting">Troubleshooting</a></h3>
|
|
<ul>
|
|
<li><a href="#When">When Clients Do Not Connect to Their Server</a>
|
|
<ul>
|
|
<li><a href="#Broadcast">Client and Server Broadcast Addresses Don't
|
|
Match</a></li>
|
|
<li><a href="#Client">Client Isnt Configured to Use the Server's
|
|
Port</a></li>
|
|
<li><a href="#Unicast">Unicast Addresses in the EPICS_CA_ADDR_LIST Does
|
|
not Reliably Contact Servers Sharing the Same UDP Port on the Same
|
|
Host</a></li>
|
|
<li><a href="#Client1">Client Does not See Server's Beacons</a></li>
|
|
<li><a href="#Server1">A server's IP address was changed</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#Requests">Put Requests Just Prior to Process Termination Appear
|
|
to be Ignored</a></li>
|
|
<li><a href="#Problems">ENOBUFS Messages</a></li>
|
|
</ul>
|
|
|
|
<h3><a href="#Function">Function Call Interface Guidelines</a></h3>
|
|
<ul>
|
|
<li><a href="#Flushing">Flushing and Blocking</a></li>
|
|
<li><a href="#Status">Status Codes</a></li>
|
|
<li><a href="#Channel">Channel Access Data Types</a></li>
|
|
<li><a href="#User">User Supplied Callback Functions</a></li>
|
|
<li><a href="#Channel1">Channel Access Exceptions</a></li>
|
|
<li><a href="#Server">Server and Client Share the Same Address Space on The
|
|
Same Host</a></li>
|
|
<li><a href="#Arrays">Arrays</a></li>
|
|
<li><a href="#Connection">Connection Management</a></li>
|
|
<li><a href="#Thread">Thread Safety and Preemptive Callback to User
|
|
Code</a></li>
|
|
<li><a href="#Client2">CA Client Contexts and Application Specific Auxiliary
|
|
Threads</a></li>
|
|
<li><a href="#Polling">Polling the CA Client Library From Single Threaded
|
|
Applications</a></li>
|
|
<li><a href="#Avoid">Avoid Emulating Bad Practices that May Still be
|
|
Common</a></li>
|
|
<li><a href="#Calling">Calling CA Functions from the vxWorks Shell
|
|
Thread</a></li>
|
|
<li><a href="#Calling1">Calling CA Functions from POSIX signal
|
|
handlers</a></li>
|
|
</ul>
|
|
|
|
<h3>Functionality Index</h3>
|
|
<ul>
|
|
<li><a href="#ca_context_create">create CA client context</a></li>
|
|
<li><a href="#ca_context_destroy">terminate CA client context</a></li>
|
|
<li><a href="#ca_create_channel">create a channel</a></li>
|
|
<li><a href="#ca_clear_channel">delete a channel</a></li>
|
|
<li><a href="#ca_put">write to a channel</a></li>
|
|
<li><a href="#ca_put">write to a channel and wait for initiated activities to
|
|
complete</a></li>
|
|
<li><a href="#ca_get">read from a channel</a></li>
|
|
<li><a href="#ca_add_event">subscribe for state change updates</a></li>
|
|
<li><a href="#ca_clear_event">cancel a subscription</a></li>
|
|
<li><a href="#ca_pend_io">block for certain requests to complete</a></li>
|
|
<li><a href="#ca_test_io">test to see if certain requests have
|
|
completed</a></li>
|
|
<li><a href="#ca_pend_event">process CA client library background
|
|
activities</a></li>
|
|
<li><a href="#ca_flush_io">flush outstanding requests to the server</a></li>
|
|
<li><a href="#ca_add_exception_event">replace the default exception
|
|
handler</a></li>
|
|
<li><a href="#ca_dump_dbr">dump dbr type to standard out</a></li>
|
|
</ul>
|
|
|
|
<h3><a href="#Function Call Reference">Function Call Interface Index</a></h3>
|
|
<ul>
|
|
<li><a href="#ca_add_exception_event">ca_add_exception_event</a></li>
|
|
<li><a href="#ca_add_fd_registration">ca_add_fd_registration</a></li>
|
|
<li><a href="#ca_get">ca_array_get</a></li>
|
|
<li><a href="#ca_get">ca_array_get_callback</a></li>
|
|
<li><a href="#ca_put">ca_array_put</a></li>
|
|
<li><a href="#ca_put">ca_array_put_callback</a></li>
|
|
<li><a href="#ca_attach_context">ca_attach_context</a></li>
|
|
<li><a href="#ca_clear_channel">ca_clear_channel</a></li>
|
|
<li><a href="#ca_clear_event">ca_clear_subscription</a></li>
|
|
<li><a href="#ca_client_status">ca_client_status</a></li>
|
|
<li><a href="#ca_context_create">ca_context_create</a></li>
|
|
<li><a href="#ca_context_destroy">ca_context_destroy</a></li>
|
|
<li><a href="#ca_client_status">ca_context_status</a></li>
|
|
<li><a href="#ca_create_channel">ca_create_channel</a></li>
|
|
<li><a href="#ca_add_event">ca_create_subscription</a></li>
|
|
<li><a href="#ca_current_context">ca_current_context</a></li>
|
|
<li><a href="#ca_dump_dbr">ca_dump_dbr</a></li>
|
|
<li><a href="#ca_detach_context">ca_detach_context</a></li>
|
|
<li><a href="#ca_element_count">ca_element_count</a></li>
|
|
<li><a href="#ca_field_type">ca_field_type</a></li>
|
|
<li><a href="#ca_flush_io">ca_flush_io</a></li>
|
|
<li><a href="#ca_get">ca_get</a></li>
|
|
<li><a href="#ca_get">ca_get_callback</a></li>
|
|
<li><a href="#ca_host_name">ca_host_name</a></li>
|
|
<li><a href="#ca_message">ca_message</a></li>
|
|
<li><a href="#ca_name">ca_name</a></li>
|
|
<li><a href="#ca_read_access">ca_read_access</a></li>
|
|
<li><a href="#ca_replace">ca_replace_access_rights_event</a></li>
|
|
<li><a href="#ca_replace_printf_handler">ca_replace_printf_handler</a></li>
|
|
<li><a href="#ca_pend_event">ca_pend_event</a></li>
|
|
<li><a href="#ca_pend_io">ca_pend_io</a></li>
|
|
<li><a href="#ca_pend_event">ca_poll</a></li>
|
|
<li><a href="#ca_puser">ca_puser</a></li>
|
|
<li><a href="#ca_put">ca_put</a></li>
|
|
<li><a href="#ca_put">ca_put_callback</a></li>
|
|
<li><a href="#ca_set_puser">ca_set_puser</a></li>
|
|
<li><a href="#ca_signal">ca_signal</a></li>
|
|
<li><a href="#ca_sg_block">ca_sg_block</a></li>
|
|
<li><a href="#ca_sg_create">ca_sg_create</a></li>
|
|
<li><a href="#ca_sg_delete">ca_sg_delete</a></li>
|
|
<li><a href="#ca_sg_get">ca_sg_array_get</a></li>
|
|
<li><a href="#ca_sg_put">ca_sg_array_put</a></li>
|
|
<li><a href="#ca_sg_reset">ca_sg_reset</a></li>
|
|
<li><a href="#ca_sg_test">ca_sg_test</a></li>
|
|
<li><a href="#ca_state">ca_state</a></li>
|
|
<li><a href="#ca_test_event">ca_test_event</a></li>
|
|
<li><a href="#ca_test_io">ca_test_io</a></li>
|
|
<li><a href="#ca_write_access">ca_write_access</a></li>
|
|
<li><a href="#ca_state">channel_state</a></li>
|
|
<li><a href="#dbr_size">dbr_size[]</a></li>
|
|
<li><a href="#dbr_size_n">dbr_size_n</a></li>
|
|
<li><a href="#dbr_value_size">dbr_value_size[]</a></li>
|
|
<li><a href="#dbr_type_t">dbr_type_to_text</a></li>
|
|
<li><a href="#ca_signal">SEVCHK</a></li>
|
|
</ul>
|
|
|
|
<h3>Deprecated Function Call Interface Function Index</h3>
|
|
<ul>
|
|
<li><a href="#ca_add_event">ca_add_event</a></li>
|
|
<li><a href="#ca_clear_event">ca_clear_event</a></li>
|
|
<li><a href="#ca_create_channel">ca_search</a></li>
|
|
<li><a href="#ca_create_channel">ca_search_and_connect</a></li>
|
|
<li><a href="#ca_context_destroy">ca_task_exit</a></li>
|
|
<li><a href="#ca_context_create">ca_task_initialize</a></li>
|
|
</ul>
|
|
|
|
<h3><a href="#Return">Return Codes</a></h3>
|
|
<hr>
|
|
|
|
<h2><a name="Configuration"></a>Configuration</h2>
|
|
|
|
<h3>Why Reconfigure Channel Access</h3>
|
|
|
|
<p>Typical reasons to reconfigure EPICS Channel Access:</p>
|
|
<ul>
|
|
<li>Two independent control systems must share a network without fear of
|
|
interaction</li>
|
|
<li>A test system must not interact with an operational system</li>
|
|
<li>Use of address lists instead of broadcasts for name resolution and server
|
|
beacons</li>
|
|
<li>Control system occupies multiple IP subnets</li>
|
|
<li>Nonstandard client disconnect time outs or server beacon intervals</li>
|
|
<li>Specify the local time zone</li>
|
|
<li>Transport of large arrays</li>
|
|
</ul>
|
|
|
|
<h3><a name="EPICS">EPICS Environment Variables</a></h3>
|
|
|
|
<p>All Channel Access (CA) configuration occurs through EPICS environment
|
|
variables. When searching for an EPICS environment variable EPICS first looks
|
|
in the environment using the ANSI C getenv() call. If no matching variable
|
|
exists then the default specified in the EPICS build system configuration files
|
|
is used.</p>
|
|
|
|
<table cellspacing="1" cellpadding="1" width="75%" border="1">
|
|
<tbody>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Range</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CA_ADDR_LIST</td>
|
|
<td>{N.N.N.N N.N.N.N:P ...}</td>
|
|
<td><none></td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CA_AUTO_ADDR_LIST</td>
|
|
<td>{YES, NO}</td>
|
|
<td>YES</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CA_NAME_SERVERS</td>
|
|
<td>{N.N.N.N N.N.N.N:P ...}</td>
|
|
<td><none></td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CA_CONN_TMO</td>
|
|
<td>r > 0.1 seconds</td>
|
|
<td>30.0</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CA_BEACON_PERIOD</td>
|
|
<td>r > 0.1 seconds</td>
|
|
<td>15.0</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CA_REPEATER_PORT</td>
|
|
<td>i > 5000</td>
|
|
<td>5065</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CA_SERVER_PORT</td>
|
|
<td>i > 5000</td>
|
|
<td>5064</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CA_MAX_ARRAY_BYTES</td>
|
|
<td>i >= 16384</td>
|
|
<td>16384</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CA_MAX_SEARCH_PERIOD</td>
|
|
<td>r > 60 seconds</td>
|
|
<td>300</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_TS_MIN_WEST</td>
|
|
<td>-720 < i <720 minutes</td>
|
|
<td>360</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p>Environment variables are set differently depending on the command line
|
|
shell that is in use.</p>
|
|
|
|
<table border="1">
|
|
<tbody>
|
|
<tr>
|
|
<td>C shell</td>
|
|
<td>setenv EPICS_CA_ADDR_LIST 1.2.3.4</td>
|
|
</tr>
|
|
<tr>
|
|
<td>bash</td>
|
|
<td>export EPICS_CA_ADDR_LIST=1.2.3.4</td>
|
|
</tr>
|
|
<tr>
|
|
<td>vxWorks shell</td>
|
|
<td>putenv ( "EPICS_CA_ADDR_LIST=1.2.3.4" )</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DOS command line</td>
|
|
<td>set EPICS_CA_ADDR_LIST=1.2.3.4</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Windows NT / 2000 / XP</td>
|
|
<td>control panel / system / environment tab</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3><a name="CA and Wide Area Networks"></a>CA and Wide Area Networks</h3>
|
|
|
|
<p>Normally in a local area network (LAN) environment CA discovers the address
|
|
of the host for an EPICS process variable by broadcasting frames containing a
|
|
list of channel names (CA search messages) and waiting for responses from the
|
|
servers that host the channels identified. Likewise CA clients efficiently
|
|
discover that CA servers have recently joined the LAN or disconnected from the
|
|
LAN by monitoring periodically broadcasted beacons sent out by the servers.
|
|
Since hardware broadcasting requires special hardware capabilities, we are
|
|
required to provide additional configuration information when EPICS is extended
|
|
to operate over a wide area network (WAN).</p>
|
|
|
|
<h3><a name="Network">IP Network Administration Background Information</a></h3>
|
|
|
|
<p>Channel Access is implemented using Internet protocols (IP). IP addresses
|
|
are divided into host and network portions. The boundary between each portion
|
|
is determined by the IP netmask. Portions of the IP address corresponding to
|
|
zeros in the netmask specify the hosts address within an IP subnet. Portions of
|
|
the IP address corresponding to binary ones in the netmask specify the address
|
|
of a host's IP subnet. Normally the scope of a broadcasted frame will be
|
|
limited to one IP subnet. Addresses with the host address portion set to all
|
|
zeros or all ones are special. Modern IP kernel implementations reserve
|
|
destination addresses with the host portion set to all ones for the purpose of
|
|
addressing broadcasts to a particular subnet. In theory we can issue a
|
|
broadcast frame on any broadcast capable LAN within the interconnected Internet
|
|
by specifying the proper subnet address combined with a host portion set to all
|
|
ones. In practice these "directed broadcasts" are frequently limited by the
|
|
default router configuration. The proper directed broadcast address required to
|
|
reach a particular host can be obtained by logging into that host and typing
|
|
the command required by your local operating environment. Ignore the loop back
|
|
interface and use the broadcast address associated with an interface connected
|
|
to a path through the network to your client. Typically there will be only one
|
|
Ethernet interface.</p>
|
|
|
|
<table border="1">
|
|
<tbody>
|
|
<tr>
|
|
<td>UNIX</td>
|
|
<td>ifconfig -a</td>
|
|
</tr>
|
|
<tr>
|
|
<td>vxWorks</td>
|
|
<td>ifShow</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Windows</td>
|
|
<td>ipconfig</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p>IP ports are positive integers. The IP address, port number, and protocol
|
|
type uniquely identify the source and destination of a particular frame
|
|
transmitted between computers. Servers are typically addressed by a well known
|
|
port number. Clients are assigned a unique ephemeral port number during
|
|
initialization. IP ports below 1024 are reserved for servers that provide
|
|
standardized facilities such as mail or file transfer. Port number between 1024
|
|
and 5000 are typically reserved for ephemeral port number assignments.</p>
|
|
|
|
<h3><a name="port">IP port numbers</a></h3>
|
|
|
|
<p>The two default IP port numbers used by Channel Access may be reconfigured.
|
|
This might occur when a site decides to set up two or more completely
|
|
independent control systems that will share the same network. For instance, a
|
|
site might set up an operational control system and a test control system on
|
|
the same network. In this situation it is desirable for the test system and the
|
|
operational system to use identical PV names without fear of collision. A site
|
|
might also configure the CA port numbers because some other facility is already
|
|
using the default port numbers. The default Channel Access port numbers have
|
|
been registered with IANA.</p>
|
|
|
|
<table cellspacing="1" cellpadding="1" width="80%" border="1">
|
|
<col>
|
|
<tbody>
|
|
<tr>
|
|
<th>Purpose</th>
|
|
<th>Default</th>
|
|
<th>Environment Variable</th>
|
|
</tr>
|
|
<tr>
|
|
<td>CA Server</td>
|
|
<td>5064</td>
|
|
<td>EPICS_CA_SERVER_PORT</td>
|
|
</tr>
|
|
<tr>
|
|
<td>CA Beacons (sent to CA repeater daemon)</td>
|
|
<td>5065</td>
|
|
<td>EPICS_CA_REPEATER_PORT</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p>If a client needs to communicate with two servers that are residing at
|
|
different port numbers then an extended syntax may be used with the
|
|
EPICS_CA_ADDR_LIST environment variable. See <a href="#Environmen">WAN
|
|
Environment</a> below.</p>
|
|
|
|
<h3><a name="firewall">Firewalls</a></h3>
|
|
|
|
<p>If you want channel access clients on a machine to be able to see beacons
|
|
and replies to broadcast PV search requests, you need to permit inbound UDP
|
|
packets with source port EPICS_CA_SERVER_PORT (default is 5064) or destination
|
|
port EPICS_CA_REPEATER_PORT (default is 5065). On systems using iptables this
|
|
can be accomplished by rules like</p>
|
|
<pre> -A INPUT -s 192.168.0.0/22 -p udp --sport 5064 -j ACCEPT
|
|
-A INPUT -s 192.168.0.0/22 -p udp --dport 5065 -j ACCEPT</pre>
|
|
|
|
<p>If you want channel access servers (e.g. "soft IOCs") on a machine to be
|
|
able to be seen by clients, you need to permit inbound TCP or UDP packets with
|
|
destination port EPICS_CA_SERVER_PORT (default is 5064). On systems using
|
|
iptables this can be accomplished by rules like</p>
|
|
<pre> -A INPUT -s 192.168.0.0/22 -p udp --dport 5064 -j ACCEPT
|
|
-A INPUT -s 192.168.0.0/22 -p tcp --dport 5064 -j ACCEPT</pre>
|
|
|
|
<p>In all cases the "-s 192.168.0.0/22" specifies the range of addresses from
|
|
which you wish to accept packets.</p>
|
|
|
|
<h3><a name="Environmen">WAN Environment</a></h3>
|
|
|
|
<p>When the CA client library connects a channel it must first determine the IP
|
|
address of the server the channels Process Variable resides on. To accomplish
|
|
this the client sends name resolution (search) requests to a list of server
|
|
destination addresses. These server destination addresses can be IP unicast
|
|
addresses (individual host addresses) or IP broadcast addresses. Each name
|
|
resolution (search) request contains a list of Process Variable names.If one of
|
|
the servers reachable by this address list knows the IP address of a CA server
|
|
that can service one or more of the specified Process Variables, then it sends
|
|
back a response containing the server's IP address and port number.</p>
|
|
|
|
<p>During initialization CA builds the list of server destination addresses
|
|
used when sending CA client name resolution (search) requests. This table is
|
|
initialized by introspecting the network interfaces attached to the host. For
|
|
each interface found that is attached to a broadcast capable IP subnet, the
|
|
broadcast address of that subnet is added to the list. For each point to point
|
|
interface found, the destination address of that link is added to the list.
|
|
This automatic server address list initialization can be disabled if the EPICS
|
|
environment variable EPICS_CA_AUTO_ADDR_LIST exists and its value is either
|
|
"no" or "NO". The typical default is to enable network interface introspection
|
|
driven initialization with EPICS_CA_AUTO_ADDR_LIST set to "YES" or "yes".</p>
|
|
|
|
<p>Following network interface introspection, any IP addresses specified in the
|
|
EPICS environment variable EPICS_CA_ADDR_LIST are added to the list of
|
|
destination addresses for CA client name resolution requests. In an EPICS
|
|
system crossing multiple subnets the EPICS_CA_ADDR_LIST must be set so that CA
|
|
name resolution (search requests) frames pass from CA clients to the targeted
|
|
CA servers unless a CA proxy (gateway) is installed. The addresses in
|
|
EPICS_CA_ADDR_LIST may be dotted IP addresses or host names if the local OS has
|
|
support for host name to IP address translation. When multiple names are added
|
|
to EPICS_CA_ADDR_LIST they must be separated by white space. There is no
|
|
requirement that the addresses specified in the EPICS_CA_ADDR_LIST be broadcast
|
|
addresses, but this will often be the most convenient choice.</p>
|
|
|
|
<p>For any IP addresses specified in the EPICS environment variable
|
|
EPICS_CA_NAME_SERVERS, TCP connections are opened and used for CA client name
|
|
resolution requests. (Thus, broadcast addresses are not allowed in
|
|
EPICS_CA_NAME_SERVERS.) When used in combination with an empty
|
|
EPICS_CA_ADDR_LIST and EPICS_CA_AUTO_ADDR_LIST set to "NO", Channel Access can
|
|
be run without using UDP for name resolution. Such an TCP-only mode allows for
|
|
Channel Access to work e.g. through SSH tunnels.</p>
|
|
|
|
<table border="1">
|
|
<tbody>
|
|
<tr>
|
|
<td>C shell</td>
|
|
<td>setenv EPICS_CA_ADDR_LIST "1.2.3.255 8.9.10.255"</td>
|
|
</tr>
|
|
<tr>
|
|
<td>bash</td>
|
|
<td>export EPICS_CA_ADDR_LIST="1.2.3.255 8.9.10.255"</td>
|
|
</tr>
|
|
<tr>
|
|
<td>vxWorks</td>
|
|
<td>putenv ( "EPICS_CA_ADDR_LIST=1.2.3.255 8.9.10.255" )</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p>If a client needs to communicate with two servers that are residing at
|
|
different port numbers then an extended syntax may be used with the
|
|
EPICS_CA_ADDR_LIST environment variable. Each host name or IP address in the
|
|
EPICS_CA_ADDR_LIST may be immediately followed by a colon and an IP port number
|
|
without intervening whitespace. Entries that do not specify a port number will
|
|
default to EPICS_CA_SERVER_PORT.</p>
|
|
|
|
<table border="1">
|
|
<tbody>
|
|
<tr>
|
|
<td>C shell</td>
|
|
<td>setenv EPICS_CA_ADDR_LIST "1.2.3.255 8.9.10.255:10000"</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h4><a name="Routing">Routing Restrictions on vxWorks Systems</a></h4>
|
|
|
|
<p>Frequently vxWorks systems boot by default with routes limiting access only
|
|
to the local subnet. If a EPICS system is operating in a WAN environment it may
|
|
be necessary to configure routes into the vxWorks system which enable a vxWorks
|
|
based CA server to respond to requests originating outside its subnet. These
|
|
routing restrictions can also apply to vxWorks base CA clients communicating
|
|
with off subnet servers. An EPICS system manager can implement an rudimentary,
|
|
but robust, form of access control for a particular host by not providing
|
|
routes in that host that reach outside of a limited set of subnets. See
|
|
"routeLib" in the vxWorks reference manual.</p>
|
|
|
|
<h3><a name="Disconnect">Disconnect Time Out Interval</a></h3>
|
|
|
|
<p>If the CA client library does not see a beacon from a server that it is
|
|
connected to for EPICS_CA_CONN_TMO seconds then an state-of-health message is
|
|
sent to the server over TCP/IP. If this state-of-health message isn't promptly
|
|
replied to then the client library will conclude that channels communicating
|
|
with the server are no longer responsive and inform the CA client side
|
|
application via function callbacks. The parameter EPICS_CA_CONN_TMO is
|
|
specified in floating point seconds. The default is typically 30 seconds. For
|
|
efficient operation it is recommended that EPICS_CA_CONN_TMO be set to no less
|
|
than twice the value specified for EPICS_CA_BEACON_PERIOD.</p>
|
|
|
|
<p>Prior to EPICS R3.14.5 an unresponsive server implied an immediate TCP
|
|
circuit disconnect, immediate resumption of UDP based search requests, and
|
|
immediate attempts to reconnect. There was concern about excessive levels of
|
|
additional activity when servers are operated close to the edge of resource
|
|
limitations. Therefore with version R3.14.5 and greater the CA client library
|
|
continues to inform client side applications when channels are unresponsive,
|
|
but does not immediately disconnect the TCP circuit. Instead the CA client
|
|
library postpones circuit shutdown until receiving indication of circuit
|
|
disconnect from the IP kernel. This can occur either because a server is
|
|
restarted or because the IP kernel's internal TCP circuit inactivity keep alive
|
|
timer has expired after a typically long duration (as is appropriate for IP
|
|
based systems that need to avoid thrashing during periods of excessive load).
|
|
The net result is less search and TCP circuit setup and shutdown activity
|
|
during periods of excessive load.</p>
|
|
|
|
<h3><a name="Dynamic">Dynamic Changes in the CA Client Library Search
|
|
Interval</a></h3>
|
|
|
|
<p>The CA client library will continuously attempt to connect any CA channels
|
|
that an application has created until it is successful. The library
|
|
periodically queries the server destination address list described above with
|
|
name resolution requests for any unresolved channels. Since this address list
|
|
frequently contains broadcast addresses, and because nonexistent process
|
|
variable names are frequently configured, or servers may be temporarily
|
|
unavailable, then it is necessary for the CA client library internals to
|
|
carefully schedule these requests in time to avoid introducing excessive load
|
|
on the network and the servers.</p>
|
|
|
|
<p>When the CA client library has many channels to connect, and most of its
|
|
name resolution requests are responded to, then it sends name resolution
|
|
requests at an interval that is twice the estimated round trip interval for the
|
|
set of servers responding, or at the minimum delay quantum for the operating
|
|
system - whichever is greater. The number of UDP frames per interval is also
|
|
dynamically adjusted based on the past success rates.</p>
|
|
|
|
<p>If a name resolution request is not responded to, then the client library
|
|
doubles the delay between name resolution attempts and reduces the number of
|
|
requests per interval. The maximum delay between attempts is limited by
|
|
EPICS_CA_MAX_SEARCH_PERIOD (see <a href="#Configurin3">Configuring the Maximum
|
|
Search Period</a>). Note however that prior to R3.14.7, if the client library
|
|
did not receive any responses over a long interval it stopped sending name
|
|
resolution attempts altogether until a beacon anomaly was detected (see
|
|
below).</p>
|
|
|
|
<p>The CA client library continually estimates the beacon period of all server
|
|
beacons received. If a particular server's beacon period becomes significantly
|
|
shorter or longer then the client is said to detect a beacon anomaly. The
|
|
library boosts the search interval for unresolved channels when a beacon
|
|
anomaly is seen or when <em>any</em> successful search response is received,
|
|
but with a longer initial interval between requests than is used when the
|
|
application creates a channel. Creation of a new channel does <em>not</em>
|
|
(starting with EPICS R3.14.7) change the interval used when searching for
|
|
preexisting unresolved channels. The program "casw" prints a message on
|
|
standard out for each CA client beacon anomaly detect event.</p>
|
|
|
|
<p>See also <a href="#Client1">When a Client Does not See the Server's
|
|
Beacon</a>.</p>
|
|
|
|
<h3><a name="Configurin3">Configuring the Maximum Search
|
|
Period</a></h3>
|
|
|
|
<p>The rate at which name resolution (search) requests are sent exponentially
|
|
backs off to a plateau rate. The value of this plateau has an impact on network
|
|
traffic because it determines the rate that clients search for channel names
|
|
that are miss-spelled or otherwise don't exist in a server. Furthermore, for
|
|
clients that are unable to see the beacon from a new server, the plateau rate
|
|
may also determine the maximum interval that the client will wait until
|
|
discovering a new server.</p>
|
|
|
|
<p>Starting with EPICS R3.14.7 this maximum search rate interval plateau in
|
|
seconds is determined by the EPICS_CA_MAX_SEARCH_PERIOD environment
|
|
variable.</p>
|
|
|
|
<p>See also <a href="#Client1">When a Client Does not See the Server's
|
|
Beacon</a>.</p>
|
|
|
|
<h3><a name="Repeater">The CA Repeater</a></h3>
|
|
|
|
<p>When several client processes run on the same host it is not possible for
|
|
all of them to directly receive a copy of the server beacon messages when the
|
|
beacon messages are sent to unicast addresses, or when legacy IP kernels are
|
|
still in use. To avoid confusion over these restrictions a special UDP server,
|
|
the CA Repeater, is automatically spawned by the CA client library when it is
|
|
not found to be running. This program listens for server beacons sent to the
|
|
UDP port specified in the EPICS_CA_REPEATER_PORT parameter and fans any beacons
|
|
received out to any CA client program running on the same host that have
|
|
registered themselves with the CA Repeater. If the CA Repeater is not already
|
|
running on a workstation, then the "caRepeater" program must be in your path
|
|
before using the CA client library for the first time.</p>
|
|
|
|
<p>If a host based IOC is run on the same workstation with standalone CA client
|
|
processes, then it is probably best to start the caRepeater process when the
|
|
workstation is booted. Otherwise it is possible for the standalone CA client
|
|
processes to become dependent on a CA repeater started within the confines of
|
|
the host based IOC. As long as the host based IOC continues to run there is
|
|
nothing wrong with this situation, but problems could arise if this host based
|
|
IOC process exits before the standalone client processes which are relying on
|
|
its CA repeater for services exit.</p>
|
|
|
|
<p>Since the repeater is intended to be shared by multiple clients then it
|
|
could be argued that it makes less sense to set up a CA repeater that listens
|
|
for beacons on only a subset of available network interfaces. In the worst case
|
|
situation the client library might see beacon anomalies from servers that it is
|
|
not interested in. Modifications to the CA repeater forcing it to listen only
|
|
on a subset of network interfaces might be considered for a future release if
|
|
there appear to be situations that require it.</p>
|
|
|
|
<h3><a name="Configurin">Configuring the Time Zone</a></h3>
|
|
|
|
<p><em>Note: Starting with EPICS R3.14 all of the libraries in the EPICS base
|
|
distribution rely on facilities built into the operating system to determine
|
|
the correct time zone. Nevertheless, several programs commonly used with EPICS
|
|
still use the original "tssubr" library and therefore they still rely on proper
|
|
configuration of EPICS_TS_MIN_WEST.</em></p>
|
|
|
|
<p>While the CA client library does not translate between the local time and
|
|
the time zone independent internal storage of EPICS time stamps, many EPICS
|
|
client side applications call core EPICS libraries which provide these
|
|
services. To set the correct time zone users must compute the number of
|
|
positive minutes west of GMT (maximum 720 inclusive) or the negative number of
|
|
minutes east of GMT (minimum -720 inclusive). This integer value is then placed
|
|
in the variable EPICS_TS_MIN_WEST.</p>
|
|
|
|
<table cellspacing="1" cellpadding="1" width="75%" border="1">
|
|
<tbody>
|
|
<tr>
|
|
<th>Time Zone</th>
|
|
<th>EPICS_TS_MIN_WEST</th>
|
|
</tr>
|
|
<tr>
|
|
<td>USA Eastern</td>
|
|
<td>300</td>
|
|
</tr>
|
|
<tr>
|
|
<td>USA Central</td>
|
|
<td>360</td>
|
|
</tr>
|
|
<tr>
|
|
<td>USA Mountain</td>
|
|
<td>420</td>
|
|
</tr>
|
|
<tr>
|
|
<td>USA Pacific</td>
|
|
<td>480</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Alaska</td>
|
|
<td>540</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Hawaii</td>
|
|
<td>600</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Japan</td>
|
|
<td>-540</td>
|
|
</tr>
|
|
<tr>
|
|
<td>China</td>
|
|
<td>-420</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Germany</td>
|
|
<td>-120</td>
|
|
</tr>
|
|
<tr>
|
|
<td>United Kingdom</td>
|
|
<td>0</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3><a name="Configurin1">Configuring the Maximum Array Size</a></h3>
|
|
|
|
<p>Starting with version R3.14 the environment variable
|
|
EPICS_CA_MAX_ARRAY_BYTES determines the size of the largest array that may pass
|
|
through CA. Prior to this version only arrays smaller than 16k bytes could be
|
|
transfered. The CA libraries maintains a free list of 16384 byte network
|
|
buffers that are used for ordinary communication. If EPICS_CA_MAX_ARRAY_BYTES
|
|
is larger than 16384 then a second free list of larger data buffers is
|
|
established and used only after a client send its first large array request.</p>
|
|
|
|
<p>The CA client library uses EPICS_CA_MAX_ARRAY_BYTES to determines the
|
|
maximum array that it will send or receive. Likewise, the CA server uses
|
|
EPICS_CA_MAX_ARRAY_BYTES to determine the maximum array that it may send or
|
|
receive. The client does not influence the server's message size quotas and
|
|
visa versa. In fact the value of EPICS_CA_MAX_ARRAY_BYTES need not be the same
|
|
in the client and the server. If the server receives a request which is too
|
|
large to read or respond to in entirety then it sends an exception message to
|
|
the client. Likewise, if the CA client library receives a request to send an
|
|
array larger than EPICS_CA_MAX_ARRAY_BYTES it will return ECA_TOLARGE.</p>
|
|
|
|
<p>A common mistake is to correctly calculate the maximum datum size in bytes
|
|
by multiplying the number of elements by the size of a single element, but
|
|
neglect to add additional bytes for the compound data types (for example
|
|
DBR_GR_DOUBLE) commonly used by the more sophisticated client side
|
|
applications. <em>Based on this confusion, one could arrive at the conclusion
|
|
that EPICS_CA_MAX_ARRAY_BYTES might have been better named
|
|
EPICS_CA_MAX_DATUM_BYTES, or that the software should be changed internally to
|
|
round the users request up by the size of the maximum scalar datum (nothing has
|
|
been done to address this issue so far).</em></p>
|
|
|
|
<h3><a name="Configurin2">Configuring a CA Server</a></h3>
|
|
|
|
<table cellspacing="1" cellpadding="1" width="75%" border="1">
|
|
<tbody>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Range</th>
|
|
<th>Default</th>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CAS_SERVER_PORT</td>
|
|
<td>i > 5000</td>
|
|
<td>EPICS_CA_SERVER_PORT</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CAS_AUTO_BEACON_ADDR_LIST</td>
|
|
<td>{YES, NO}</td>
|
|
<td>EPICS_CA_AUTO_ADDR_LIST</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CAS_BEACON_ADDR_LIST</td>
|
|
<td>{N.N.N.N N.N.N.N:P ...}</td>
|
|
<td>EPICS_CA_ADDR_LIST<sup>1</sup></td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CAS_BEACON_PERIOD</td>
|
|
<td>r > 0.1 seconds</td>
|
|
<td>EPICS_CA_BEACON_PERIOD</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CAS_BEACON_PORT</td>
|
|
<td>i > 5000</td>
|
|
<td>EPICS_CA_REPEATER_PORT</td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CAS_INTF_ADDR_LIST</td>
|
|
<td>{N.N.N.N N.N.N.N:P ...}</td>
|
|
<td><none></td>
|
|
</tr>
|
|
<tr>
|
|
<td>EPICS_CAS_IGNORE_ADDR_LIST</td>
|
|
<td>{N.N.N.N N.N.N.N:P ...}</td>
|
|
<td><none></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h4>Server Port</h4>
|
|
|
|
<p>The server configures its port number from the EPICS_CAS_SERVER_PORT
|
|
environment variable if it is specified. Otherwise the EPICS_CA_SERVER_PORT
|
|
environment variable determines the server's port number. Two servers can share
|
|
the same UDP port number on the same machine, but there are restrictions - see
|
|
a <a href="#Unicast">discussion of unicast addresses and two servers sharing
|
|
the same UDP port on the same host</a>.</p>
|
|
|
|
<h4>Server Beacons</h4>
|
|
|
|
<p>The EPICS_CAS_BEACON_PERIOD parameter determines the server's beacon period
|
|
and is specified in floating point seconds. The default is typically 15
|
|
seconds. See also <a href="#Disconnect">EPICS_CA_CONN_TMO</a> and
|
|
<a href="#Dynamic">Dynamic Changes in the CA Client Library Search
|
|
Interval</a>.</p>
|
|
|
|
<p>CA servers build a list of addresses to send beacons to during
|
|
initialization. If EPICS_CAS_AUTO_BEACON_ADDR_LIST has the value "YES"
|
|
(the default) this list will be automatically populated with the broadcast
|
|
addresses of all network interfaces. However, if the user also
|
|
defines EPICS_CAS_INTF_ADDR_LIST then beacon address list automatic
|
|
configuration is constrained to the network interfaces specified therein, and
|
|
therefore only the broadcast addresses of the specified LAN interfaces, will be
|
|
automatically configured.</p>
|
|
|
|
<p>If EPICS_CAS_BEACON_ADDR_LIST is defined then its contents will be used to
|
|
augment any automatic configuration of the beacon address list. Individual
|
|
entries in EPICS_CAS_BEACON_ADDR_LIST may override the destination port number
|
|
if ":nnn" follows the host name or IP address there.</p>
|
|
|
|
<p>The EPICS_CAS_BEACON_PORT parameter specifies the destination port for
|
|
server beacons. The only exception to this occurs when ports are specified in
|
|
EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If
|
|
EPICS_CAS_BEACON_PORT is not specified then beacons are sent to the port
|
|
specified in EPICS_CA_REPEATER_PORT.</p>
|
|
|
|
<h4>Binding a Server to a Limited Set of Network Interfaces</h4>
|
|
|
|
<p>The parameter EPICS_CAS_INTF_ADDR_LIST allows a ca server to bind itself to,
|
|
and therefore accept messages received by, a limited set of the local host's
|
|
network interfaces (each specified by its IP address). On UNIX systems type
|
|
"netstat -ie" (type "ipconfig" on windows) to see a list of the local host's
|
|
network interfaces. By default,
|
|
the CA server is accessible from all network interfaces configured into its
|
|
host.</p>
|
|
|
|
<p>Until R3.15.4 the CA server employed by iocCore did not
|
|
implement the EPICS_CAS_INTF_ADDR_LIST feature.</p>
|
|
|
|
<p>Prior to R3.15.4 CA servers would build the beacon address list
|
|
using EPICS_CA_ADDR_LIST if EPICS_CAS_BEACON_ADDR_LIST was no set.</p>
|
|
|
|
<h4>Ignoring Process Variable Name Resolution Requests From Certain Hosts</h4>
|
|
|
|
<p>Name resolution requests originating from any of the IP addresses specified
|
|
in the EPICS_CAS_IGNORE_ADDR_LIST parameter are not replied to.<em>In R3.14 and
|
|
previous releases the CA server employed by iocCore does not implement this
|
|
feature.</em></p>
|
|
|
|
<h4>Client Configuration that also Applies to Servers</h4>
|
|
|
|
<p>See also <a href="#Configurin1">Configuring the Maximum Array Size</a>.</p>
|
|
|
|
<p>See also <a href="#Routing">Routing Restrictions on vxWorks Systems</a>.</p>
|
|
<hr>
|
|
|
|
<h2><a name="Building">Building an Application</a></h2>
|
|
|
|
<h3><a name="Required1">Required Header (.h) Files</a></h3>
|
|
|
|
<p>An application that uses the CA client library functions described in this
|
|
document will need to include the cadef.h header files as follows.</p>
|
|
|
|
<p><code>#include "cadef.h"</code></p>
|
|
|
|
<p>This header file is located at "<EPICS base>/include/". It includes
|
|
many other header files (operating system specific and otherwise), and
|
|
therefore the application must also specify "<EPICS
|
|
base>/include/os/<arch>" in its header file search path.</p>
|
|
|
|
<h3><a name="Required">Required Libraries</a></h3>
|
|
|
|
<p>An application that uses the Channel Access Client Library functions
|
|
described in this document will need to link with the EPICS CA Client Library
|
|
and also the EPICS Common Library. The EPICS CA Client Library calls the EPICS
|
|
Common Library. The following table shows the names of these libraries on UNIX
|
|
and Windows systems.</p>
|
|
|
|
<table border="1">
|
|
<caption></caption>
|
|
<tbody>
|
|
<tr>
|
|
<th>
|
|
<div style="text-align: left">
|
|
</div>
|
|
</th>
|
|
<th>UNIX Object</th>
|
|
<th>UNIX Shareable</th>
|
|
<th>Windows Object</th>
|
|
<th>Windows Shareable</th>
|
|
</tr>
|
|
<tr>
|
|
<th style="text-align: left">EPICS CA Client Library</th>
|
|
<td>libca.a</td>
|
|
<td>libca.so</td>
|
|
<td>ca.lib</td>
|
|
<td>ca.dll</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
<div style="text-align: left">
|
|
EPICS Common Library</div>
|
|
</th>
|
|
<td>libCom.a</td>
|
|
<td>libCom.so</td>
|
|
<td>Com.lib</td>
|
|
<td>Com.dll</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p></p>
|
|
|
|
<p>The above libraries are located in "<EPICS
|
|
base>/lib/<architecture>".</p>
|
|
|
|
<h3><a name="Compiler">Compiler and System Specific Build
|
|
Options</a></h3>
|
|
|
|
<p>If you do not use the EPICS build environment (layered make files) then it
|
|
may be helpful to run one of the EPICS make files and watch the compile/link
|
|
lines. This may be the simplest way to capture the latest system and compiler
|
|
specific options required by your build environment. Some snapshots of typical
|
|
build lines are shown below, but this information may be out of date.</p>
|
|
|
|
<h4>Typical Linux Build Options</h4>
|
|
|
|
<p><code>gcc -D_GNU_SOURCE -DOSITHREAD_USE_DEFAULT_STACK -D_X86_ -DUNIX -Dlinux
|
|
-O3 -g -Wall -I. -I.. -I../../../../include/compiler/gcc
|
|
-I../../../../include/os/Linux -I../../../../include -c ../acctst.c</code></p>
|
|
|
|
<p><code>g++ -o acctst -L/home/user/epics/base-3.15/lib/linux-x86
|
|
-Wl,-rpath,/home/user/epics/base-3.15/lib/linux-x86
|
|
acctstMain.o acctst.o -lca -lCom</code></p>
|
|
|
|
<h4>Typical Solaris Build Options</h4>
|
|
|
|
<p><code>/opt/SUNWspro/bin/cc -c -D_POSIX_C_SOURCE=199506L -D_XOPEN_SOURCE=500
|
|
-DOSITHREAD_USE_DEFAULT_STACK -DUNIX -DSOLARIS=9 -mt -D__EXTENSIONS__ -Xc -v
|
|
-xO4 -I. -I.. -I../../../../include/compiler/solStudio
|
|
-I../../../../include/os/solaris -I../../../../include ../acctst.c</code></p>
|
|
|
|
<p><code>/opt/SUNWspro/bin/CC -o acctst
|
|
-L/home/user/epics/base-3.15/lib/solaris-sparc/ -mt -z ignore -z combreloc
|
|
-z lazyload -R/home/user/epics/base-3.15/lib/solaris-sparc acctstMain.o
|
|
acctst.o -lca -lCom</code></p>
|
|
|
|
<h4>Typical Windows Build Options</h4>
|
|
|
|
<p><code>cl -c /nologo /D__STDC__=0 /Ox /GL /W3 /w44355 /MD -I. -I..
|
|
-I..\\..\\..\\..\\include\\compiler\\msvc -I..\\..\\..\\..\\include\\os\\WIN32
|
|
-I..\\..\\..\\..\\include ..\\acctst.c</code></p>
|
|
|
|
<p><code>link -nologo /LTCG /incremental:no /opt:ref /release /version:3.15
|
|
-out:acctst.exe acctstMain.obj acctst.obj
|
|
d:/user/epics/base-3.15/lib/win32-x86/ca.lib
|
|
d:/user/epics/base-3.15/lib/win32-x86/Com.lib</code></p>
|
|
|
|
<h4>Typical vxWorks Build Options</h4>
|
|
|
|
<p><code>/usr/local/vxWorks-6.9/gnu/4.3.3-vxworks-6.9/x86-linux2/bin/ccppc
|
|
-DCPU=PPC32 -DvxWorks=vxWorks -O2 -Wall -mstrict-align -mlongcall -fno-builtin
|
|
-include /usr/local/vxWorks-6.9/vxworks-6.9/target/h/vxWorks.h
|
|
-I. -I../O.Common -I.. -I../../../../include/compiler/gcc
|
|
-I../../../../include/os/vxWorks -I../../../../include
|
|
-I/usr/local/vxWorks-6.9/vxworks-6.9/target/h
|
|
-I/usr/local/vxWorks-6.9/vxworks-6.9/target/h/wrn/coreip
|
|
-c ../acctst.c</code></p>
|
|
|
|
<h4>Other Systems and Compilers</h4>
|
|
|
|
<p>Contributions gratefully accepted.</p>
|
|
<hr>
|
|
|
|
<h2><a name="CommandUtils">Command Line Utilities</a></h2>
|
|
|
|
<h3><a name="acctst">acctst</a></h3>
|
|
<pre>acctst <PV name> [progress logging level] [channel duplication count]
|
|
[test repetition count] [enable preemptive callback]</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Channel Access Client Library regression test.</p>
|
|
|
|
<p>The PV used with the test must be native type DBR_DOUBLE or DBR_FLOAT, and
|
|
modified only by acctst while the test is running. Therefore, periodically
|
|
scanned hardware attached analog input records do not work well. Test failure
|
|
is indicated if the program stops prior to printing "test complete". If
|
|
unspecified the progress logging level is zero, and no messages are printed
|
|
while the test is progressing. If unspecified, the channel duplication count is
|
|
20000. If unspecified, the test repetition count is once only. If unspecified,
|
|
preemptive callback is disabled.</p>
|
|
|
|
<h3><a name="catime">catime</a></h3>
|
|
<pre>catime <PV name> [channel count] [append number to pv name if true]</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Channel Access Client Library performance test.</p>
|
|
|
|
<p>If unspecified, the channel count is 10000. If the "append number to pv name
|
|
if true" argument is specified and it is greater than zero then the channel
|
|
names in the test are numbered as follows.</p>
|
|
|
|
<p><PV name>000000, <PV name>000001, ... <PV name>nnnnnn</p>
|
|
|
|
<h3><a name="casw">casw</a></h3>
|
|
<pre>casw [-i <interest level>]</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>CA server "beacon anomaly" logging.</p>
|
|
|
|
<p>CA server beacon anomalies occur when a new server joins the network, a
|
|
server is rebooted, network connectivity to a server is reestablished, or if a
|
|
server's CPU exits a CPU load saturated state.</p>
|
|
|
|
<p>CA clients with unresolved channels reset their search request scheduling
|
|
timers whenever they see a beacon anomaly.</p>
|
|
|
|
<p>This program can be used to detect situations where there are too many
|
|
beacon anomalies. IP routing configuration problems may result in false beacon
|
|
anomalies that might cause CA clients to use unnecessary additional network
|
|
bandwidth and server CPU load when searching for unresolved channels.</p>
|
|
|
|
<p>If there are no new CA servers appearing on the network, and network
|
|
connectivity remains constant, then casw should print no messages at all. At
|
|
higher interest levels the program prints a message for every beacon that is
|
|
received, and anomalous entries are flagged with a star.</p>
|
|
|
|
<h3><a name="caEventRat">caEventRate</a></h3>
|
|
<pre>caEventRate <PV name> [subscription count]</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Connect to the specified PV, subscribe for monitor updates the specified
|
|
number of times (default once), and periodically log the current sampled event
|
|
rate, average event rate, and the standard deviation of the event rate in Hertz
|
|
to standard out.</p>
|
|
|
|
<h3><a name="ca_test">ca_test</a></h3>
|
|
<pre>ca_test <PV name> [value to be written]</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>If a value is specified it is written to the PV. Next, the current value of
|
|
the PV is converted to each of the many external data type that can be
|
|
specified at the CA client library interface, and each of these is formated and
|
|
then output to the console.</p>
|
|
<hr>
|
|
|
|
<h2><a name="CommandTools">Command Line Tools</a></h2>
|
|
|
|
<h3><a name="caget">caget</a></h3>
|
|
<pre>caget [options] <PV name> ...</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Get and print value for PV(s).</p>
|
|
|
|
<p>The values for one or multiple PVs are read and printed to stdout. The
|
|
DBR_... format in which the data is read, the output format, and a number of
|
|
details of how integer and float values are represented can be controlled using
|
|
command line options.</p>
|
|
|
|
<p>When getting multiple PVs, their order on the command line is retained in
|
|
the output.</p>
|
|
|
|
<table border="1">
|
|
<caption></caption>
|
|
<thead>
|
|
<tr>
|
|
<th>Option</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>-h</td>
|
|
<td>Print usage information</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>CA options:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>-w <sec></td>
|
|
<td>Wait time, specifies longer CA timeout, default is 1.0 second</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-c</td>
|
|
<td>Asynchronous get (use ca_get_callback instead of ca_get)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-p <prio></td>
|
|
<td>CA priority (0-99, default 0=lowest)</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Format and data type options:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td>Default output format is "name value"</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-t</td>
|
|
<td>Terse mode - print only value, without name</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-a</td>
|
|
<td>Wide mode "name timestamp value stat sevr" (read PVs as
|
|
DBR_TIME_xxx)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-d <type></td>
|
|
<td>Request specific dbr type; use string (DBR_ prefix may be omitted)<br>
|
|
or number of one of the following types:<br>
|
|
<table border="1">
|
|
<tbody>
|
|
<tr>
|
|
<td>DBR_STRING</td>
|
|
<td>0</td>
|
|
<td>DBR_STS_FLOAT</td>
|
|
<td>9</td>
|
|
<td>DBR_TIME_LONG</td>
|
|
<td>19</td>
|
|
<td>DBR_CTRL_SHORT</td>
|
|
<td>29</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_INT</td>
|
|
<td>1</td>
|
|
<td>DBR_STS_ENUM</td>
|
|
<td>10</td>
|
|
<td>DBR_TIME_DOUBLE</td>
|
|
<td>20</td>
|
|
<td>DBR_CTRL_INT</td>
|
|
<td>29</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_SHORT</td>
|
|
<td>1</td>
|
|
<td>DBR_STS_CHAR</td>
|
|
<td>11</td>
|
|
<td>DBR_GR_STRING</td>
|
|
<td>21</td>
|
|
<td>DBR_CTRL_FLOAT</td>
|
|
<td>30</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_FLOAT</td>
|
|
<td>2</td>
|
|
<td>DBR_STS_LONG</td>
|
|
<td>12</td>
|
|
<td>DBR_GR_SHORT</td>
|
|
<td>22</td>
|
|
<td>DBR_CTRL_ENUM</td>
|
|
<td>31</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_ENUM</td>
|
|
<td>3</td>
|
|
<td>DBR_STS_DOUBLE</td>
|
|
<td>13</td>
|
|
<td>DBR_GR_INT</td>
|
|
<td>22</td>
|
|
<td>DBR_CTRL_CHAR</td>
|
|
<td>32</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_CHAR</td>
|
|
<td>4</td>
|
|
<td>DBR_TIME_STRING</td>
|
|
<td>14</td>
|
|
<td>DBR_GR_FLOAT</td>
|
|
<td>23</td>
|
|
<td>DBR_CTRL_LONG</td>
|
|
<td>33</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_LONG</td>
|
|
<td>5</td>
|
|
<td>DBR_TIME_INT</td>
|
|
<td>15</td>
|
|
<td>DBR_GR_ENUM</td>
|
|
<td>24</td>
|
|
<td>DBR_CTRL_DOUBLE</td>
|
|
<td>34</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_DOUBLE</td>
|
|
<td>6</td>
|
|
<td>DBR_TIME_SHORT</td>
|
|
<td>15</td>
|
|
<td>DBR_GR_CHAR</td>
|
|
<td>25</td>
|
|
<td>DBR_STSACK_STRING</td>
|
|
<td>37</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_STS_STRING</td>
|
|
<td>7</td>
|
|
<td>DBR_TIME_FLOAT</td>
|
|
<td>16</td>
|
|
<td>DBR_GR_LONG</td>
|
|
<td>26</td>
|
|
<td>DBR_CLASS_NAME</td>
|
|
<td>38</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_STS_SHORT</td>
|
|
<td>8</td>
|
|
<td>DBR_TIME_ENUM</td>
|
|
<td>17</td>
|
|
<td>DBR_GR_DOUBLE</td>
|
|
<td>27</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_STS_INT</td>
|
|
<td>8</td>
|
|
<td>DBR_TIME_CHAR</td>
|
|
<td>18</td>
|
|
<td>DBR_CTRL_STRING</td>
|
|
<td>28</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Enum format:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>-n</td>
|
|
<td>Print DBF_ENUM value as number (default is enum string)</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Arrays:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td>Value format: Print number of requested values, then list of
|
|
values</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Default:</td>
|
|
<td>Print all values</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-# <count></td>
|
|
<td>Print first <count> elements of an array</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-S</td>
|
|
<td>Print array of char as a string (long string)</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Floating point type format:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Default:</td>
|
|
<td>Use %g format</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-e <nr></td>
|
|
<td>Use %e format, with a precision of <nr> digits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-f <nr></td>
|
|
<td>Use %f format, with a precision of <nr> digits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-g <nr></td>
|
|
<td>Use %g format, with a precision of <nr> digits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-s</td>
|
|
<td>Get value as string (honors server-side precision)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-lx</td>
|
|
<td>Round to long integer and print as hex number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-lo</td>
|
|
<td>Round to long integer and print as octal number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-lb</td>
|
|
<td>Round to long integer and print as binary number</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Integer number format:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Default:</td>
|
|
<td>Print as decimal number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-0x</td>
|
|
<td>Print as hex number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-0o</td>
|
|
<td>Print as octal number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-0b</td>
|
|
<td>Print as binary number</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Alternate output field separator:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>-F <ofs></td>
|
|
<td>Use <ofs> as an alternate output field separator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3><a name="camonitor">camonitor</a></h3>
|
|
<pre>camonitor [options] <PV name> ...</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Subscribe to and print value updates for PV(s).</p>
|
|
|
|
<table border="1">
|
|
<caption></caption>
|
|
<thead>
|
|
<tr>
|
|
<th>Option</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>-h</td>
|
|
<td>Print usage information</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>CA options:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>-w <sec></td>
|
|
<td>Wait time, specifies longer CA timeout, default is 1.0 second</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-m <msk></td>
|
|
<td>Specify CA event mask to use. <msk> is any combination of<br>
|
|
'v' (value), 'a' (alarm), 'l' (log/archive), 'p' (property).<br>
|
|
Default event mask is 'va'</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-p <prio></td>
|
|
<td>CA priority (0-99, default 0=lowest)</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Timestamps:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Default:</td>
|
|
<td>Print absolute timestamps (as reported by CA server)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-t <key></td>
|
|
<td>Specify timestamp source(s) and type, with <key> containing<br>
|
|
's' = CA server (remote) timestamps<br>
|
|
'c' = CA client (local) timestamps (shown in '()'s)<br>
|
|
'n' = no timestamps<br>
|
|
'r' = relative timestamps (time elapsed since start of program)<br>
|
|
'i' = incremental timestamps (time elapsed since last update)<br>
|
|
'I' = incremental timestamps (time since last update, by channel)<br>
|
|
'r', 'i' or 'I' require 's' or 'c' to select the time source</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Enum Format:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>-n</td>
|
|
<td>Print DBF_ENUM values as number (default is enum string)</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Arrays:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td>Array values: Print number of elements, then list of values</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Default:</td>
|
|
<td>Default: Request and print all elements (dynamic arrays supported)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-# <num></td>
|
|
<td>Request and print up to <num> elements</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-S</td>
|
|
<td>Print array of char as a string (long string)</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Floating point format:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Default:</td>
|
|
<td>Use %g format</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-e <num></td>
|
|
<td>Use %e format, with a precision of <num> digits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-f <num></td>
|
|
<td>Use %f format, with a precision of <num> digits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-g <num></td>
|
|
<td>Use %g format, with a precision of <num> digits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-s</td>
|
|
<td>Get value as string (honors server-side precision)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-lx</td>
|
|
<td>Round to long integer and print as hex number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-lo</td>
|
|
<td>Round to long integer and print as octal number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-lb</td>
|
|
<td>Round to long integer and print as binary number</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Integer number format:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Default:</td>
|
|
<td>Print as decimal number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-0x</td>
|
|
<td>Print as hex number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-0o</td>
|
|
<td>Print as octal number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-0b</td>
|
|
<td>Print as binary number</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3><a name="caput">caput</a></h3>
|
|
<pre>caput [options] <PV name> <value> ...
|
|
caput -a [options] <PV name> <no of elements> <value> ...</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Put value to a PV.</p>
|
|
|
|
<p>The specified value is written to the PV (as a string). The PV's value is
|
|
read before and after the write operation and printed as "Old" and "New" values
|
|
on stdout.</p>
|
|
|
|
<p>There are two variants to the arguments for this command. For the scalar
|
|
variant without the <code>-a</code> flag, all the value arguments provided after
|
|
the PV name are concatenated with a single space character between them, and the
|
|
resulting string (up to 40 characters long unless the <code>-S</code> flag is
|
|
given) is written to the specified PV.</p>
|
|
|
|
<p>The array variant with the <code>-a</code> flag writes an array of string
|
|
values to the specified PV. The numeric argument giving the number of array
|
|
elements is actually ignored, the array length to be written is actually
|
|
controlled by the number of values provided on the command line.</p>
|
|
|
|
<table border="1">
|
|
<caption></caption>
|
|
<thead>
|
|
<tr>
|
|
<th>Option</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>-h</td>
|
|
<td>Print usage information</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>CA options:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>-w <sec></td>
|
|
<td>Wait time, specifies longer CA timeout, default is 1.0 second</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-c</td>
|
|
<td>Asynchronous put (use ca_put_callback and wait for completion)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-p <prio></td>
|
|
<td>CA priority (0-99, default 0=lowest)</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Format options:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>-t</td>
|
|
<td>Terse mode - print only successfully written value, without name</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-l</td>
|
|
<td>Long mode "name timestamp value stat sevr" (read PVs as DBR_TIME_xxx)</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Enum Format:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Default:</td>
|
|
<td>Auto - try value as ENUM string, then as index number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-n</td>
|
|
<td>Force interpretation of values as numbers</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-s</td>
|
|
<td>Force interpretation of values as strings</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>Arrays:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Default:</td>
|
|
<td>Put scalar</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td>Value format: all value arguments concatenated with spaces</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-S</td>
|
|
<td>Put string as an array of chars (long string)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-a</td>
|
|
<td>Put array</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td>Value format: number of values, then list of values</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3><a name="cainfo">cainfo</a></h3>
|
|
<pre>cainfo [options] <PV name> ...</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Get and print channel and connection information for PV(s).</p>
|
|
|
|
<p>All available Channel Access related information about PV(s) is printed to
|
|
stdout.</p>
|
|
|
|
<p>The -s option allows to specify an interest level for calling Channel
|
|
Access' internal report function <code>ca_client_status()</code>, that prints lots of
|
|
internal informations on stdout, including environment settings, used CA ports
|
|
etc.</p>
|
|
|
|
<table border="1">
|
|
<caption></caption>
|
|
<thead>
|
|
<tr>
|
|
<th>Option</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>-h</td>
|
|
<td>Print usage information</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
<td><strong>CA options:</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td>-w <sec></td>
|
|
<td>Wait time, specifies longer CA timeout, default is 1.0 second</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-s <level></td>
|
|
<td>Call ca_client_status with the specified interest level</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-p <prio></td>
|
|
<td>CA priority (0-99, default 0=lowest)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3><a name="excas">excas</a></h3>
|
|
|
|
<p>excas [options]</p>
|
|
|
|
<p>This is an example CA server that is sometimes used for testing purposes. An
|
|
example server can be created with the makeBaseApp Perl script, as described in
|
|
the application Developer's Guide.</p>
|
|
|
|
<table border="1">
|
|
<col>
|
|
<col>
|
|
<tbody>
|
|
<tr>
|
|
<th>Option</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
<tr>
|
|
<td>-d <uuuu></td>
|
|
<td>set level uuuu for debug messages, where uuuu is an positive integer
|
|
number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-p <aaaa></td>
|
|
<td>prefix all of the PV names below with aaaa changing, for example, the
|
|
name of "bill" to "xyz:bill"</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-t <n.n></td>
|
|
<td>set execution time where n.n is a positive real number</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-c <uuuu></td>
|
|
<td>set the numbered alias count</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-s <nnn></td>
|
|
<td>the default, nnn is one, enables periodic scanning of the PV
|
|
replacing the PV with its value added with a small random change, when
|
|
nnn is zero it turns off this type of periodic scanning </td>
|
|
</tr>
|
|
<tr>
|
|
<td>-ss <nnn></td>
|
|
<td>the default, nnn is one, enables synchronous scanning, and if nnn is
|
|
zero it turns on asynchronous scanning</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-ad <n.n></td>
|
|
<td>set the delay before asynchronous operations complete (defaults to
|
|
0.1 seconds)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-an <nnn></td>
|
|
<td>set the maximum number of simultaneous asynchronous operations
|
|
(defaults to 1000)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p>The example server has a compile time fixed set of example variables.</p>
|
|
|
|
<table border="1">
|
|
<col>
|
|
<col>
|
|
<col>
|
|
<col>
|
|
<col>
|
|
<col>
|
|
<col>
|
|
<tbody>
|
|
<tr>
|
|
<th>Process Variable Name</th>
|
|
<th>Number of Elements</th>
|
|
<th>IO Type</th>
|
|
<th>Data Type</th>
|
|
<th>High Limit</th>
|
|
<th>Low Limit</th>
|
|
<th>Scan Period</th>
|
|
</tr>
|
|
<tr>
|
|
<td>jane</td>
|
|
<td>1</td>
|
|
<td>Synchronous</td>
|
|
<td>float point, 64 bits</td>
|
|
<td>10.0</td>
|
|
<td>0.0</td>
|
|
<td>0.1 Seconds, random noise changes</td>
|
|
</tr>
|
|
<tr>
|
|
<td>fred</td>
|
|
<td>1</td>
|
|
<td>Synchronous</td>
|
|
<td>float point, 64 bits</td>
|
|
<td>10.0</td>
|
|
<td>-10.0</td>
|
|
<td>2.0 Seconds, random noise changes</td>
|
|
</tr>
|
|
<tr>
|
|
<td>janet</td>
|
|
<td>1</td>
|
|
<td>Asynchronous</td>
|
|
<td>float point, 64 bits</td>
|
|
<td>10.0</td>
|
|
<td>0.0</td>
|
|
<td>0.1 Seconds, random noise changes</td>
|
|
</tr>
|
|
<tr>
|
|
<td>freddy</td>
|
|
<td>1</td>
|
|
<td>Asynchronous</td>
|
|
<td>float point, 64 bits</td>
|
|
<td>10.0</td>
|
|
<td>-10.0</td>
|
|
<td>2.0 Seconds, random noise changes</td>
|
|
</tr>
|
|
<tr>
|
|
<td>alan</td>
|
|
<td>100</td>
|
|
<td>Synchronous</td>
|
|
<td>float point, 64 bits</td>
|
|
<td>10.0</td>
|
|
<td>-10.0</td>
|
|
<td>2.0 Seconds, random noise changes</td>
|
|
</tr>
|
|
<tr>
|
|
<td>albert</td>
|
|
<td>1000</td>
|
|
<td>Synchronous</td>
|
|
<td>float point, 64 bits</td>
|
|
<td>10.0</td>
|
|
<td>-10.0</td>
|
|
<td>20.0 Seconds, random noise changes</td>
|
|
</tr>
|
|
<tr>
|
|
<td>boot</td>
|
|
<td>1</td>
|
|
<td>Synchronous</td>
|
|
<td>enumerated, 16 bits</td>
|
|
<td>10.0</td>
|
|
<td>-10.0</td>
|
|
<td>changed only by client</td>
|
|
</tr>
|
|
<tr>
|
|
<td>booty</td>
|
|
<td>1</td>
|
|
<td>Asynchronous</td>
|
|
<td>enumerated, 16 bits</td>
|
|
<td>10.0</td>
|
|
<td>-10.0</td>
|
|
<td>1.0 Seconds, random noise changes</td>
|
|
</tr>
|
|
<tr>
|
|
<td>bill</td>
|
|
<td>1</td>
|
|
<td>Synchronous</td>
|
|
<td>float point, 64 bits</td>
|
|
<td>10.0</td>
|
|
<td>-10.0</td>
|
|
<td>changed only by client</td>
|
|
</tr>
|
|
<tr>
|
|
<td>billy</td>
|
|
<td>1</td>
|
|
<td>Asynchronous</td>
|
|
<td>float point, 64 bits</td>
|
|
<td>10.0</td>
|
|
<td>-10.0</td>
|
|
<td>changed only by client</td>
|
|
</tr>
|
|
<tr>
|
|
<td>bloaty</td>
|
|
<td>100000</td>
|
|
<td>Synchronous</td>
|
|
<td>float point, 64 bits</td>
|
|
<td>10.0</td>
|
|
<td>-10.0</td>
|
|
<td>changed only by client</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h4>Bugs</h4>
|
|
|
|
<p>Not all of the options listed above have been tested recently.</p>
|
|
<hr>
|
|
|
|
<h2><a name="Troubleshooting">Troubleshooting</a></h2>
|
|
|
|
<h3><a name="When">When Clients Do Not Connect to Their Server</a></h3>
|
|
|
|
<h4><a name="Broadcast">Client and Server Broadcast Addresses Don't
|
|
Match</a></h4>
|
|
|
|
<p>Verify that the broadcast addresses are identical on the server's host and
|
|
on the client's host. This can be checked on UNIX with "netstat -i" or
|
|
"ifconfig -a"; on vxWorks with ifShow; and on windows with ipconfig. It is
|
|
normal for the broadcast addresses to not be identical if the client and server
|
|
are not directly attached to the same IP subnet, and in this situation the
|
|
EPICS_CA_ADDR_LIST must be set. Otherwise, if the client and server are
|
|
intended to be on the same IP subnet, then the problem may be that the IP
|
|
netmask is incorrectly set in the network interface configuration. On most
|
|
operating systems, when the host's IP address is configured, the host's IP
|
|
subnet mask is also configured.</p>
|
|
|
|
<h4><a name="Client">Client Isn't Configured to Use the Server's Port</a></h4>
|
|
|
|
<p>Verify that the client and server are using the same UDP port. Check the
|
|
server's port by running "netstat -a | grep nnn" where nnn is the port number
|
|
configured in the client. If you do not set EPICS_CA_SERVER_PORT or
|
|
EPICS_CAS_SERVER_PORT then the default port will be 5064.</p>
|
|
|
|
<h4><a name="Unicast">Unicast Addresses in the EPICS_CA_ADDR_LIST Does not
|
|
Reliably Contact Servers Sharing the Same UDP Port on the Same Host</a></h4>
|
|
|
|
<p>Two servers can run on the same host with the same server port number, but
|
|
there are restrictions. If the host has a modern IP kernel it is possible to
|
|
have two or more servers share the same UDP port. It is not possible for these
|
|
servers to run on the same host using the same TCP port. If the CA server
|
|
library detects that a server is attempting to start on the same port as an
|
|
existing CA server then both servers will use the same UDP port, and the 2nd
|
|
server will be allocated an ephemeral TCP port. Clients can be configured to
|
|
use the same port number for both servers. They will locate the 2nd server via
|
|
the shared UDP port, and transparently connect to the 2nd server's ephemeral
|
|
TCP port. Be aware however that If there are two server's running on the same
|
|
host sharing the same UDP port then they will both receive UDP search requests
|
|
sent as broadcasts, but unfortunately (due to a weakness of most IP kernel
|
|
implementations) only one of the servers will typically receive UDP search
|
|
requests sent to unicast addresses (i.e. a single specific host's ip
|
|
address).</p>
|
|
|
|
<h4><a name="Client1">Client Does not See Server's Beacons</a></h4>
|
|
|
|
<p>Two conclusions deserve special emphasis. <em>First, if a client does not
|
|
see the server's beacons, then it will use additional network and server
|
|
resources sending periodic state-of-health messages.</em> <em>Second, if a
|
|
client does not see a newly introduced server's beacon, then it will take up to
|
|
EPICS_CA_MAX_SEARCH_PERIOD to find that newly introduced server.</em> Also,
|
|
starting with EPICS R3.14.7 the client library does <em>not</em> suspend
|
|
searching for a channel after 100 unsuccessful attempts until a beacon anomaly
|
|
is seen. Therefore, if the client library is from before version R3.14.7 of
|
|
EPICS and it timed out attempting to find a server whose beacon can't be seen
|
|
by the client library then the client application might need to be restarted in
|
|
order to connect to this new beacon-out-of-range server. The typical situation
|
|
where a client would not see the server's beacon might be when the client isn't
|
|
on the same IP subnet as the server, and the client's EPICS_CA_ADDR_LIST was
|
|
modified to include a destination address for the server, but the server's
|
|
beacon address list was not modified so that its beacons are received by the
|
|
client.</p>
|
|
|
|
<h4><a name="Server1">A Server's IP Address Was Changed</a></h4>
|
|
|
|
<p>When communication over a virtual circuit times out, then each channel
|
|
attached to the circuit enters a disconnected state and the disconnect callback
|
|
handler specified for the channel is called. However, the circuit is not
|
|
disconnected until TCP/IP's internal, typically long duration, keep alive timer
|
|
expires. The disconnected channels remain attached to the beleaguered circuit
|
|
and no attempt is made to search for, or to reestablish, a new circuit. If, at
|
|
some time in the future, the circuit becomes responsive again, then the
|
|
attached channels enter a connected state again and reconnect callback
|
|
handlers are called. Any monitor subscriptions that received an update message
|
|
while the channel was disconnected are also refreshed. If at any time the
|
|
library receives an indication from the operating system that a beleaguered
|
|
circuit has shutdown or was disconnected then the library will immediately
|
|
reattempt to find servers for each channel and connect circuits to them.</p>
|
|
|
|
<p>A well known negative side effect of the above behavior is that CA clients
|
|
will wait the full (typically long) duration of TCP/IP's internal keep alive
|
|
timer prior to reconnecting under the following scenario (all of the following
|
|
occur):</p>
|
|
<ul>
|
|
<li>An server's (IOC's) operating system crashes (or is abruptly turned off)
|
|
or a vxWorks system is stopped by any means</li>
|
|
<li>This operating system does not immediately reboot using the same IP
|
|
address</li>
|
|
<li>A duplicate of the server (IOC) is started appearing at a different IP
|
|
address</li>
|
|
</ul>
|
|
|
|
<p>It is unlikely that any rational organization will advocate the above
|
|
scenario in a production system. Nevertheless, there <em>are</em> opportunities
|
|
for users to become confused during control system <em>development</em>, but it
|
|
is felt that the robustness improvements justify isolated confusion during the
|
|
system integration and checkout activities where the above scenarios are most
|
|
likely to occur.</p>
|
|
|
|
<p>Contrast the above behavior with the CA client library behavior of releases
|
|
prior to R3.14.5 where the beleaguered circuit was immediately closed when
|
|
communication over it timed out. Any attached channels were immediately
|
|
searched for, and after successful search responses arrived then attempts were
|
|
made to build a new circuit. This behavior could result in undesirable resource
|
|
consumption resulting from periodic circuit setup and teardown overhead
|
|
(thrashing) during periods of CPU / network / IP kernel buffer congestion.</p>
|
|
|
|
<h3><a name="Requests">Put Requests Just Prior to Process
|
|
Termination Appear to be Ignored</a></h3>
|
|
|
|
<p>Short lived CA client applications that issue a CA put request and then
|
|
immediately exit the process (return from <code>main</code> or call
|
|
<code>exit</code>) may find that there request isn't executed. To guarantee
|
|
that the request is sent call <code>ca_flush_io()</code> followed by
|
|
<code>ca_context_destroy()</code> prior to terminating the process.</p>
|
|
|
|
<h3><a name="Problems">ENOBUFS Messages</a></h3>
|
|
|
|
<p>Many Berkley UNIX derived Internet Protocol (IP) kernels use a memory
|
|
management scheme with a fixed sized low level memory allocation quantum called
|
|
an "mbuf". Messages about "ENOBUFS" are an indication that your IP kernel is
|
|
running low on mbuf buffers. An IP kernel mbuf starvation situation may lead to
|
|
temporary IP communications stalls or reduced throughput. This issue has to
|
|
date been primarily associated with vxWorks systems where mbuf starvation on
|
|
earlier vxWorks versions is rumored to lead to permanent IP communications
|
|
stalls which are resolved only by a system reboot. IP kernels that use mbufs
|
|
frequently allow the initial and maximum number of mbufs to be configured.
|
|
Consult your OS's documentation for configuration procedures which vary between
|
|
OS and even between different versions of the same OS.</p>
|
|
|
|
<h4>Contributing Circumstances</h4>
|
|
<ul>
|
|
<li>The total number of connected clients is high. Each active socket
|
|
requires dedicated mbufs for protocol control blocks, and for any data that
|
|
might be pending in the operating system for transmission to Channel Access
|
|
or to the network at a given instant. If you increase the vxWorks limit on
|
|
the maximum number of file descriptors then it may also be necessary to
|
|
increase the size of the mbuf pool.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>The server has multiple connections where the server's sustained event
|
|
(monitor subscription update) production rate is higher than the client's
|
|
or the network's sustained event consumption rate. This ties up a per
|
|
socket quota of mbufs for data that are pending transmission to the client
|
|
via the network. In particular, if there are multiple clients that
|
|
subscribe for monitor events but do not call <code>ca_pend_event()</code>
|
|
or <code>ca_poll()</code>
|
|
to process their CA input queue, then a significant mbuf consuming backlog
|
|
can occur in the server.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>The server does not get a chance to run (because some other higher
|
|
priority thread is running) and the CA clients are sending a high volume of
|
|
data over TCP or UDP. This ties up a quota of mbufs for each socket in the
|
|
server that isn't being reduced by the server's socket read system
|
|
calls.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>The server has multiple stale connections. Stale connections occur when a
|
|
client is abruptly turned off or disconnected from the network, and an
|
|
internal "keepalive" timer has not yet expired for the virtual circuit in
|
|
the operating system, and therefore mbufs may be dedicated to unused
|
|
virtual circuits. This situation is made worse if there are active monitor
|
|
subscriptions associated with stale connections which will rapidly increase
|
|
the number of dedicated mbufs to the quota available for each circuit.</li>
|
|
<li>When sites switch to the vxWorks 5.4 IP kernel they frequently run into
|
|
network pool exhaustion problems. This may be because the original vxWorks
|
|
IP kernel expanded the network pool as needed at runtime while the new
|
|
kernel's pool is statically configured at compile time, and does
|
|
<em>not</em> expand as needed at runtime. Also, at certain sites problems
|
|
related to vxWorks network driver pool exhaustion have also been reported
|
|
(this can also result in ENOBUF diagnostic messages).</li>
|
|
</ul>
|
|
|
|
<h4>Related Diagnostics</h4>
|
|
<ul>
|
|
<li>The EPICS command "casr [interest level]" displays information about the
|
|
CA server and how many clients are connected.</li>
|
|
<li>The vxWorks command "inetstatShow" indicates how many bytes are pending
|
|
in mbufs and indirectly (based on the number of circuits listed) how many
|
|
mbuf based protocol control blocks have been consumed. The vxWorks commands
|
|
(availability depending on vxWorks version) mbufShow, netStackSysPoolShow,
|
|
and netStackDataPoolShow indicate how much space remains in the network
|
|
stack pool.</li>
|
|
<li>The RTEMS command "netstat [interest level]" displays network information
|
|
including mbuf consumption statistics.</li>
|
|
</ul>
|
|
|
|
<h3>Server Subscription Update Queuing</h3>
|
|
|
|
<p>If the subscription update producer in the server produces subscription
|
|
updates faster than the subscription update consumer in the client consumes
|
|
them, then events have to be discarded if the buffering in the server
|
|
isn't allowed to grow to an infinite size. This is a law of nature –
|
|
based on queuing theory of course.</p>
|
|
|
|
<p>What is done depends on the version of the CA server. All server versions
|
|
place quotas on the maximum number of subscription updates allowed on the
|
|
subscription update queue at any given time. If this limit is reached, an
|
|
intervening update is discarded in favor of a more recent update. Depending on
|
|
the version of the server, rapidly updating subscriptions are or are not
|
|
allowed to cannibalize the quotas of slow updating subscriptions in limited
|
|
ways. Nevertheless, there is always room on the queue for at least one update
|
|
for each subscription. This guarantees that the most recent update is always
|
|
sent.</p>
|
|
|
|
<p>Adding further complication, the CA client library also implements a
|
|
primitive type of flow control. If the client library sees that it is reading a
|
|
large number of messages one after another w/o intervening delay it knows that
|
|
it is not consuming events as fast as they are produced. In that situation it
|
|
sends a message telling the server to temporarily stop sending subscription
|
|
update messages. When the client catches up it sends another message asking the
|
|
server to resume with subscription updates. This prevents slow clients from
|
|
getting time warped, but also guarantees that intervening events are discarded
|
|
until the slow client catches up.</p>
|
|
|
|
<p>There is currently no message on the IOC's console when a particular client
|
|
is slow on the uptake. A message of this type used to exist many years ago, but
|
|
it was a source of confusion (and what we will call message noise) so it was
|
|
removed.</p>
|
|
|
|
<p>There is unfortunately no field in the protocol allowing the server to
|
|
indicate that an intervening subscription update was discarded. We should
|
|
probably add that capability in a future version. Such a feature would, for
|
|
example, be beneficial when tuning an archiver installation.</p>
|
|
<hr>
|
|
|
|
<h2><a name="Function">Function Call Interface General Guidelines</a></h2>
|
|
|
|
<h3><a name="Flushing">Flushing and Blocking</a></h3>
|
|
|
|
<p>Significant performance gains can be realized when the CA client library
|
|
doesn't wait for a response to return from the server after each request. All
|
|
requests which require interaction with a CA server are accumulated (buffered)
|
|
and not forwarded to the IOC until one of <code>ca_flush_io()</code>,
|
|
<code>ca_pend_io()</code>, <code>ca_pend_event()</code>, or
|
|
<code>ca_sg_block()</code> are called allowing several operations to be
|
|
efficiently sent over the network together. Any process variable values written
|
|
into your program's variables by <code>ca_get()</code> should not be referenced by your
|
|
program until ECA_NORMAL has been received from <code>ca_pend_io()</code>.</p>
|
|
|
|
<h3><a name="Status">Status Codes</a></h3>
|
|
|
|
<p>If successful, the routines described here return the status code
|
|
ECA_NORMAL. Unsuccessful status codes returned from the client library are
|
|
listed with each routine in this manual. Operations that appear to be valid to
|
|
the client can still fail in the server. Writing the string "off" to a floating
|
|
point field is an example of this type of error. If the server for a channel is
|
|
located in a different address space than the client then the <code>ca_xxx()</code>
|
|
operations that communicate with the server return status indicating the
|
|
validity of the request and whether it was successfully enqueued to the server,
|
|
but communication of completion status is deferred until a user callback is
|
|
called, or lacking that an exception handler is called. An error number and the
|
|
error's severity are embedded in CA status (error) constants. Applications
|
|
shouldn't test the success of a CA function call by checking to see if the
|
|
returned value is zero as is the UNIX convention. Below are several methods to
|
|
test CA function returns. See <a href="#ca_signal"><code>ca_signal()</code> and
|
|
<code>SEVCHK()</code></a> for more information on this topic.</p>
|
|
<pre>status = ca_XXXX();
|
|
SEVCHK( status, "ca_XXXX() returned failure status");
|
|
|
|
if ( status & CA_M_SUCCESS ) {
|
|
printf ( "The requested ca_XXXX() operation didn't complete successfully");
|
|
}
|
|
|
|
if ( status != ECA_NORMAL ) {
|
|
printf("The requested ca_XXXX() operation didn't complete successfully because \"%s\"\n",
|
|
ca_message ( status ) );
|
|
}</pre>
|
|
|
|
<h3><a name="Channel">Channel Access Data Types</a></h3>
|
|
|
|
<p>CA channels form a virtual circuit between a process variable (PV) and a
|
|
client side application program. It is possible to connect a wide variety of
|
|
data sources into EPICS using the CA server library. When a CA channel
|
|
communicates with an EPICS Input Output Controller (IOC) then a field is a
|
|
specialization of a PV, and an EPICS record is a plug compatible function block
|
|
that contains fields, and the meta data below frequently are mapped onto
|
|
specific fields within the EPICS records by the EPICS record support (see the
|
|
EPICS Application Developer Guide).</p>
|
|
|
|
<p>Arguments of type chtype specifying the data type you wish to transfer. They
|
|
expect one of the set of DBR_XXXX data type codes defined in db_access.h. There
|
|
are data types for all of the C primitive types, and there are also compound (C
|
|
structure) types that include various process variable properties such as
|
|
units, limits, time stamp, or alarm status. The primitive C types follow a
|
|
naming convention where the C typedef dbr_xxxx_t corresponds to the DBR_XXXX
|
|
data type code. The compound (C structure) types follow a naming convention
|
|
where the C structure tag dbr_xxxx corresponds to the DBR_XXXX data type code.
|
|
The following tables provides more details on the structure of the CA data type
|
|
space. Since data addresses are passed to the CA client library as typeless
|
|
"void *" pointers then care should be taken to ensure that you have passed the
|
|
correct C data type corresponding to the DBR_XXXX type that you have specified.
|
|
Architecture independent types are provided in db_access.h to assist
|
|
programmers in writing portable code. For example "dbr_short_t" should be used
|
|
to send or receive type DBR_SHORT. Be aware that type name DBR_INT has been
|
|
deprecated in favor of the less confusing type name DBR_SHORT. In practice,
|
|
both the DBR_INT type code and the DBR_SHORT type code refer to a 16 bit
|
|
integer type, and are functionally equivalent.</p>
|
|
|
|
<table border="1">
|
|
<caption>Channel Access Primitive Data Types</caption>
|
|
<tbody>
|
|
<tr>
|
|
<th>CA Type Code</th>
|
|
<th>Primitive C Data Type</th>
|
|
<th>Data Size</th>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_CHAR</td>
|
|
<td>dbr_char_t</td>
|
|
<td>8 bit character</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_SHORT</td>
|
|
<td>dbr_short_t</td>
|
|
<td>16 bit integer</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_ENUM</td>
|
|
<td>dbr_enum_t</td>
|
|
<td>16 bit unsigned integer</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_LONG</td>
|
|
<td>dbr_long_t</td>
|
|
<td>32 bit signed integer</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_FLOAT</td>
|
|
<td>dbr_float_t</td>
|
|
<td>32 bit IEEE floating point</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_DOUBLE</td>
|
|
<td>dbr_double_t</td>
|
|
<td>64 bit IEEE floating point</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_STRING</td>
|
|
<td>dbr_string_t</td>
|
|
<td>40 character string</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<table border="1">
|
|
<caption>Structure of the Channel Access Data Type Space</caption>
|
|
<tbody>
|
|
<tr>
|
|
<th>CA Type Code</th>
|
|
<th>Read / Write</th>
|
|
<th>Primitive C Data Type</th>
|
|
<th>Process Variable Properties</th>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_<PRIMITIVE TYPE></td>
|
|
<td>RW</td>
|
|
<td>dbr_<primitive type>_t</td>
|
|
<td>value</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_STS_<PRIMITIVE TYPE></td>
|
|
<td>R</td>
|
|
<td>struct dbr_sts_<primitive type></td>
|
|
<td>value, alarm status, and alarm severity</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_TIME_<PRIMITIVE TYPE></td>
|
|
<td>R</td>
|
|
<td>struct dbr_time_<primitive type></td>
|
|
<td>value, alarm status, alarm severity, and time stamp</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_GR_<PRIMITIVE TYPE></td>
|
|
<td>R</td>
|
|
<td>struct dbr_gr_<primitive type></td>
|
|
<td>value, alarm status, alarm severity, units, display precision, and
|
|
graphic limits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_CTRL_<PRIMITIVE TYPE></td>
|
|
<td>R</td>
|
|
<td>struct dbr_ctrl_<primitive type></td>
|
|
<td>value, alarm status, alarm severity, units, display precision,
|
|
graphic limits, and control limits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_PUT_ACKT</td>
|
|
<td>W</td>
|
|
<td>dbr_put_ackt_t</td>
|
|
<td>Used for global alarm acknowledgement. Do transient alarms have to be
|
|
acknowledged? (0,1) means (no, yes).</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_PUT_ACKS</td>
|
|
<td>W</td>
|
|
<td>dbr_put_acks_t</td>
|
|
<td>Used for global alarm acknowledgement. The highest alarm severity to
|
|
acknowledge. If the current alarm severity is less then or equal to
|
|
this value the alarm is acknowledged.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_STSACK_STRING</td>
|
|
<td>R</td>
|
|
<td>struct dbr_stsack_string</td>
|
|
<td>value, alarm status, alarm severity, ackt, acks</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DBR_CLASS_NAME</td>
|
|
<td>R</td>
|
|
<td>dbr_class_name_t</td>
|
|
<td>name of enclosing interface (name of the record if channel is
|
|
attached to EPICS run time database)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p></p>
|
|
|
|
<p>Channel value arrays can also be included within the structured CA data
|
|
types. If more than one element is requested, then the individual elements can
|
|
be accessed in an application program by indexing a pointer to the value field
|
|
in the DBR_XXX structure. For example, the following code computes the sum of
|
|
the elements in a array process variable and prints its time stamp. The
|
|
<code><a href="#dbr_size_n">dbr_size_n</a>()</code> function can be used to determine the correct
|
|
number of bytes to reserve when there are more than one value field elements in
|
|
a structured CA data type.</p>
|
|
<pre>#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "cadef.h"
|
|
|
|
int main ( int argc, char ** argv )
|
|
{
|
|
struct dbr_time_double * pTD;
|
|
const dbr_double_t * pValue;
|
|
unsigned nBytes;
|
|
unsigned elementCount;
|
|
char timeString[32];
|
|
unsigned i;
|
|
chid chan;
|
|
double sum;
|
|
int status;
|
|
|
|
if ( argc != 2 ) {
|
|
fprintf ( stderr, "usage: %s <channel name>", argv[0] );
|
|
return -1;
|
|
}
|
|
|
|
status = ca_create_channel ( argv[1], 0, 0, 0, & chan );
|
|
SEVCHK ( status, "ca_create_channel()" );
|
|
status = ca_pend_io ( 15.0 );
|
|
if ( status != ECA_NORMAL ) {
|
|
fprintf ( stderr, "\"%s\" not found.\n", argv[1] );
|
|
return -1;
|
|
}
|
|
|
|
elementCount = ca_element_count ( chan );
|
|
nBytes = dbr_size_n ( DBR_TIME_DOUBLE, elementCount );
|
|
pTD = ( struct dbr_time_double * ) malloc ( nBytes );
|
|
if ( ! pTD ) {
|
|
fprintf ( stderr, "insufficient memory to complete request\n" );
|
|
return -1;
|
|
}
|
|
|
|
status = ca_array_get ( DBR_TIME_DOUBLE, elementCount, chan, pTD );
|
|
SEVCHK ( status, "ca_array_get()" );
|
|
status = ca_pend_io ( 15.0 );
|
|
if ( status != ECA_NORMAL ) {
|
|
fprintf ( stderr, "\"%s\" didn't return a value.\n", argv[1] );
|
|
return -1;
|
|
}
|
|
|
|
pValue = & pTD->value;
|
|
sum = 0.0;
|
|
for ( i = 0; i < elementCount; i++ ) {
|
|
sum += pValue[i];
|
|
}
|
|
|
|
epicsTimeToStrftime ( timeString, sizeof ( timeString ),
|
|
"%a %b %d %Y %H:%M:%S.%f", & pTD->stamp );
|
|
|
|
printf ( "The sum of elements in %s at %s was %f\n",
|
|
argv[1], timeString, sum );
|
|
|
|
ca_clear_channel ( chan );
|
|
ca_task_exit ();
|
|
free ( pTD );
|
|
|
|
return 0;
|
|
}</pre>
|
|
|
|
<h3><a name="User">User Supplied Callback Functions</a></h3>
|
|
|
|
<p>Certain CA client initiated requests asynchronously execute an application
|
|
supplied callback in the client process when a response arrives. The functions
|
|
<code>ca_put_callback()</code>, <code>ca_get_callback()</code>, and
|
|
<code>ca_create_subscription()</code> all request notification of
|
|
asynchronous completion via this mechanism. The <code>event_handler_args</code>
|
|
structure is passed <em>by value</em> to the application supplied
|
|
callback. In this structure the <code>dbr</code> field is a void pointer to any
|
|
data that might be returned. The <code>status</code> field will be
|
|
set to one of the CA error codes in caerr.h and will indicate the status of the
|
|
operation performed in the IOC. If the status field isn't set to ECA_NORMAL or
|
|
data isn't normally returned from the operation (i.e. put callback) then you
|
|
should expect that the <code>dbr</code> field will be set to a null pointer
|
|
(zero). The fields <code>usr</code>, <code>chid</code>, and <code>type</code>
|
|
are set to the values specified when the request was made by the application.
|
|
The <code>dbr</code> pointer, and any data that it points to, are valid only when
|
|
executing within the user's callback function.</p>
|
|
<pre>typedef struct event_handler_args {
|
|
void *usr; /* user argument supplied with request */
|
|
chanId chid; /* channel id */
|
|
long type; /* the type of the item returned */
|
|
long count; /* the element count of the item returned */
|
|
const void *dbr; /* a pointer to the item returned */
|
|
int status; /* ECA_XXX status of the requested op from the server */
|
|
} evargs;
|
|
|
|
void myCallback ( struct event_handler_args args )
|
|
{
|
|
if ( args.status != ECA_NORMAL ) {
|
|
}
|
|
if ( args.type == DBR_TIME_DOUBLE ) {
|
|
const struct dbr_time_double * pTD =
|
|
( const struct dbr_time_double * ) args.dbr;
|
|
}
|
|
}</pre>
|
|
|
|
<h3><a name="Channel1">Channel Access Exceptions</a></h3>
|
|
|
|
<p>When the server detects a failure, and there is no client callback function
|
|
attached to the request, an exception handler is executed in the client. The
|
|
default exception handler prints a message on the console and exits if the
|
|
exception condition is severe. Certain internal exceptions within the CA client
|
|
library, and failures detected by the SEVCHK macro may also cause the exception
|
|
handler to be invoked. To modify this behavior see
|
|
<code><a href="#ca_add_exception_event">ca_add_exception_event</a>()</code>.</p>
|
|
|
|
<h3><a name="Server">Server and Client Share the Same Address Space on The Same
|
|
Host</a></h3>
|
|
|
|
<p>If the Process Variable's server and it's client are colocated within the
|
|
same memory address space and the same host then the <code>ca_xxx()</code> operations bypass
|
|
the server and directly interact with the server tool component (commonly the
|
|
IOC's function block database). In this situation the <code>ca_xxx()</code> routines
|
|
frequently return the completion status of the requested operation directly to
|
|
the caller with no opportunity for asynchronous notification of failure via an
|
|
exception handler. Likewise, callbacks may be directly invoked by the CA
|
|
library functions that request them.</p>
|
|
|
|
<h3><a name="Arrays">Arrays</a></h3>
|
|
|
|
<p>For routines that require an argument specifying the number of array
|
|
elements, no more than the process variable's maximum native element count may
|
|
be requested. The process variable's maximum native element count is available
|
|
from <code>ca_element_count()</code> when the channel is connected. If fewer elements than
|
|
the process variable's native element count are requested, the requested values
|
|
will be fetched beginning at element zero. By default CA limits the number of
|
|
elements in an array to be no more than approximately 16k divided by the size
|
|
of one element in the array. Starting with EPICS R3.14 the maximum array size
|
|
may be configured in the client and in the server.</p>
|
|
|
|
<h3><a name="Connection">Connection Management</a></h3>
|
|
|
|
<p>Application programs should assume that CA servers may be restarted, and
|
|
that network connectivity is transient. When you create a CA channel its
|
|
initial connection state will most commonly be disconnected. If the Process
|
|
Variable's server is available the library will immediately initiate the
|
|
necessary actions to make a connection with it. Otherwise, the client library
|
|
will monitor the state of servers on the network and connect or reconnect with
|
|
the process variable's server as it becomes available. After the channel
|
|
connects the application program can freely perform IO operations through the
|
|
channel, but should expect that the channel might disconnect at any time due to
|
|
network connectivity disruptions or server restarts.</p>
|
|
|
|
<p>Three methods can be used to determine if a channel is connected: the
|
|
application program might call <code><a href="#ca_state">ca_state</a>()</code>
|
|
to obtain the current connection state, block in
|
|
<code><a href="#ca_pend_io">ca_pend_io</a>()</code> until the channel connects,
|
|
or install a connection callback handler when it calls
|
|
<code><a href="#ca_create_channel">ca_create_channel</a>()</code>. The
|
|
<code><a href="#ca_pend_io">ca_pend_io</a>()</code> approach is best suited to
|
|
simple command line programs with short runtime duration, and the connection
|
|
callback method is best suited to toolkit components with long runtime duration.
|
|
Use of <code><a href="#ca_state">ca_state</a>()</code> is appropriate only in
|
|
programs that prefer to poll for connection state changes instead of opting for
|
|
asynchronous notification. The <code>ca_pend_io()</code> function blocks only
|
|
for channels created specifying a null connection handler callback function. The
|
|
user's connection state change function will be run immediately from within
|
|
<code><a href="#ca_create_channel">ca_create_channel</a>()</code> if the CA
|
|
client and CA server are both hosted within the same address space (within the
|
|
same process).</p>
|
|
|
|
<h3><a name="Thread">Thread Safety and Preemptive Callback to User Code</a></h3>
|
|
|
|
<p>Starting with EPICS R3.14 the CA client libraries are fully thread safe on
|
|
all OS (in past releases the library was thread safe only on vxWorks). When the
|
|
client library is initialized the programmer may specify if preemptive callback
|
|
is to be enabled. Preemptive callback is disabled by default. If preemptive
|
|
callback is enabled, then the user's callback functions might be called by CA's
|
|
auxiliary threads when the main initiating channel access thread is not inside
|
|
of a function in the channel access client library. Otherwise, the user's
|
|
callback functions will be called only when the main initiating channel access
|
|
thread is executing inside of the CA client library. When the CA client library
|
|
invokes a user's callback function, it will always wait for the current
|
|
callback to complete prior to executing another callback function. Programmers
|
|
enabling preemptive callback should be familiar with using mutex locks to
|
|
create a reliable multi-threaded program.</p>
|
|
|
|
<p>To set up a traditional single threaded client, you will need code like this
|
|
(see <code><a href="#ca_context_create">ca_context_create</a>()</code> and
|
|
<a href="#Client2">CA Client Contexts and Application Specific Auxiliary
|
|
Threads</a>) .</p>
|
|
|
|
<p><code>SEVCHK ( ca_context_create(ca_disable_preemptive_callback ),
|
|
"application pdq calling ca_context_create" );</code></p>
|
|
|
|
<p>To set up a preemptive callback enabled CA client context you will need code
|
|
like this (see <code><a href="#ca_context_create">ca_context_create</a>()</code> and
|
|
<a href="#Client2">CA Client Contexts and Application Specific Auxiliary
|
|
Threads</a>).</p>
|
|
|
|
<p><code>SEVCHK ( ca_context_create(ca_enable_preemptive_callback ),
|
|
"application pdq calling ca_context_create" );</code></p>
|
|
|
|
<h3><a name="Client2">CA Client Contexts and Application Specific Auxiliary
|
|
Threads</a></h3>
|
|
|
|
<p>It is often necessary for several CA client side tools running in the same
|
|
address space (process) to be independent of each other. For example, the
|
|
database CA links and the sequencer are designed to not use the same CA client
|
|
library threads, network circuits, and data structures. Each thread that calls
|
|
<code><a href="#ca_context_create">ca_context_create</a>()</code> for the first time either
|
|
directly or implicitly when calling any CA library function for the first time,
|
|
creates a CA client library context. A CA client library context contains all
|
|
of the threads, network circuits, and data structures required to connect and
|
|
communicate with the channels that a CA client application has created. The
|
|
priority of auxiliary threads spawned by the CA client library are at fixed
|
|
offsets from the priority of the thread that called
|
|
<code><a href="#ca_context_create">ca_context_create</a>()</code>. An application specific
|
|
auxiliary thread can join a CA context by calling
|
|
<code><a href="#ca_attach_context">ca_attach_context</a>()</code> using the CA context
|
|
identifier that was returned from
|
|
<code><a href="#ca_current_context">ca_current_context</a>()</code> when it is called by the
|
|
thread that created the context which needs to be joined. A context which is to
|
|
be joined must be preemptive - it must be created using
|
|
<a href="#ca_context_create">ca_context_create(ca_enable_preemptive_callback)</a>.
|
|
It is not possible to attach a thread to a non-preemptive CA context created
|
|
explicitly <em>or implicitly</em> with
|
|
ca_create_context(ca_disable_preemptive_callback). Once a thread has joined
|
|
with a CA context it need only make ordinary <code>ca_xxxx()</code> library calls to use the
|
|
context.</p>
|
|
|
|
|
|
<p>A CA client library context can be shut down and cleaned up, after
|
|
destroying any channels or application specific threads that are attached to
|
|
it, by calling <code><a href="#ca_context_destroy">ca_context_destroy</a>()</code>. The
|
|
context may be created and destroyed by different threads as long as they are
|
|
both part of the same context.</p>
|
|
|
|
<h3><a name="Polling">Polling the CA Client Library From Single Threaded
|
|
Applications</a></h3>
|
|
|
|
<p>If preemptive callback is not enabled, then for proper operation CA must
|
|
periodically be polled to take care of background activity. This requires that
|
|
your application must either wait in one of <code>ca_pend_event()</code>, <code>ca_pend_io()</code>, or
|
|
<code>ca_sg_block()</code> or alternatively it should call <code>ca_poll()</code> at least every 100
|
|
milliseconds. In single threaded applications a file descriptor manager like
|
|
Xt or the interface described in fdManager.h can be used to monitor both mouse
|
|
clicks and also CA's file descriptors so that <code>ca_poll()</code> can be called
|
|
immediately when CA server messages arrives over the network.</p>
|
|
|
|
<h3><a name="Avoid">Avoid Emulating Bad Practices that May Still be
|
|
Common</a></h3>
|
|
|
|
<p>With the embryonic releases of EPICS it was a common practice to examine a
|
|
channel's connection state, its native type, and its native element count by
|
|
directly accessing fields in a structure using a pointer stored in type
|
|
<code>chid</code>. Likewise, a user private pointer in the per channel
|
|
structure was also commonly set by directly accessing fields in the channel
|
|
structure. A number of difficulties arise from this practice, which has long
|
|
since been deprecated. For example, prior to release 3.13 it was recognized
|
|
that transient changes in certain private fields in the per channel structure
|
|
would make it difficult to reliably test the channels connection state using
|
|
these private fields directly. Therefore, in release 3.13 the names of certain
|
|
fields were changed to discourage this practice. Starting with release 3.14
|
|
codes written this way will not compile. Codes intending to maintain the
|
|
highest degree of portability over a wide range of EPICS versions should be
|
|
especially careful. For example you should replace all instances off
|
|
<code>channel_id->count</code> with
|
|
<code>ca_element_count(channel_id)</code>. This approach should be reliable on
|
|
all versions of EPICS in use today. The construct <code>ca_puser(chid) =
|
|
xxxx</code> is particularly problematic. The best mechanisms for setting the
|
|
per channel private pointer will be to pass the user private pointer in when
|
|
creating the channel. This approach is implemented on all versions. Otherwise,
|
|
you can also use <code>ca_set_puser(CHID,PUSER)</code>, but this function is
|
|
available only after the first official (post beta) release of EPICS 3.13.</p>
|
|
|
|
<h3><a name="Calling">Calling CA Functions from the vxWorks Shell
|
|
Thread</a></h3>
|
|
|
|
<p>Calling CA functions from the vxWorks shell thread is a somewhat
|
|
questionable practice for the following reasons.</p>
|
|
<ul>
|
|
<li>The vxWorks shell thread runs at the very highest priority in the system
|
|
and therefore socket calls are made at a priority that is above the
|
|
priority of tNetTask. This has caused problems with the WRS IP kernel in
|
|
the past. That symptom was observed some time ago, but we don't know if
|
|
WRS has fixed the problem.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>The vxWorks shell thread runs at the very highest priority in the system
|
|
and therefore certain CA auxiliary threads will not get the priorities that
|
|
are requested for them. This might cause problems only when in a CPU
|
|
saturation situations.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>If the code does not call <code>ca_context_destroy()</code> (named <code>ca_task_exit()</code> in past
|
|
releases) then resources are left dangling.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>In EPICS R3.13 the CA client library installed vxWorks task exit handlers
|
|
behaved strangely if CA functions were called from the vxWorks shell,
|
|
<code>ca_task_exit()</code> wasn't called, and the vxWorks shell restarted. In
|
|
EPICS R3.14 vxWorks task exit handlers are not installed and therefore
|
|
cleanup is solely the responsibility of the user. With EPICS R3.14 the user
|
|
must call <code>ca_context_destroy()</code> or <code>ca_task_exit()</code> to clean up on vxWorks. This
|
|
is the same behavior as on all other OS.</li>
|
|
</ul>
|
|
|
|
<h3><a name="Calling1">Calling CA Functions from POSIX signal
|
|
handlers</a></h3>
|
|
|
|
<p>As you might expect, it isn't safe to call the CA client library from a POSIX
|
|
signal handler. Likewise, it isn't safe to call the CA client library from
|
|
interrupt context.</p>
|
|
<hr>
|
|
|
|
<h2><a name="Function Call Reference"></a>Function Call Reference</h2>
|
|
|
|
<h3><code><a name="ca_context_create">ca_context_create()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
enum ca_preemptive_callback_select
|
|
{ ca_disable_preemptive_callback, ca_enable_preemptive_callback };
|
|
int ca_context_create ( enum ca_preemptive_callback_select SELECT );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>This function, or <code><a href="#ca_attach_context">ca_attach_context</a>()</code>,
|
|
should be called once from each thread prior to making any of the other Channel
|
|
Access calls. If one of the above is not called before making other CA calls
|
|
then a non-preemptive context is created by default, and future attempts to
|
|
create a preemptive context for the current threads will fail.</p>
|
|
|
|
<p>If <code>ca_disable_preemptive_callback</code> is specified then additional
|
|
threads are <em>not</em> allowed to join the CA context using
|
|
<code>ca_context_attach()</code> because allowing other threads to join implies that CA
|
|
callbacks will be called preemptively from more than one thread.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>SELECT</code></dt>
|
|
<dd>This argument specifies if preemptive invocation of callback functions
|
|
is allowed. If so your callback functions might be called when the thread
|
|
that calls this routine is not executing in the CA client library. There
|
|
are two implications to consider. </dd>
|
|
<dd><p>First, if preemptive callback mode is enabled the developer must
|
|
provide mutual exclusion protection for his data structures. In this mode
|
|
it's possible for two threads to touch the application's data structures
|
|
at once: this might be the initializing thread (the thread that called
|
|
ca_context_create) and also a private thread created by the CA client
|
|
library for the purpose of receiving network messages and calling
|
|
callbacks. It might be prudent for developers who are unfamiliar with
|
|
mutual exclusion locking in a multi-threaded environment to specify
|
|
<code>ca_disable_preemptive_callback</code>. </p>
|
|
<p>Second, if preemptive callback mode is enabled the application is no
|
|
longer burdened with the necessity of periodically polling the CA client
|
|
library in order that it might take care of its background activities. If
|
|
<code>ca_enable_preemptive_callback</code> is specified then CA client
|
|
background activities, such as connection management, will proceed even
|
|
if the thread that calls this routine is not executing in the CA client
|
|
library. Furthermore, in preemptive callback mode callbacks might be
|
|
called with less latency because the library is not required to wait
|
|
until the initializing thread (the thread that called ca_context_create)
|
|
is executing within the CA client library.</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_ALLOCMEM - Failed, unable to allocate space in pool</p>
|
|
|
|
<p>ECA_NOTTHREADED - Current thread is already a member of a non-preemptive
|
|
callback CA context (possibly created implicitly)</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_context_destroy">ca_context_destroy</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_context_destroy">ca_context_destroy()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
void ca_context_destroy();</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Shut down the calling thread's channel access client context and free any
|
|
resources allocated. Detach the calling thread from any CA client context.</p>
|
|
|
|
<p>Any user-created threads that have attached themselves to the CA context
|
|
must stop using it prior to its being destroyed. A program running in an IOC
|
|
context must delete all of its channels prior to calling <code>ca_context_destroy()</code>
|
|
to avoid a crash.</p>
|
|
|
|
<p>A CA client application that calls epicsExit() <em>must</em> install an
|
|
EPICS exit handler that calls <code>ca_context_destroy()</code> only <em>after</em> first
|
|
calling <code>ca_create_context()</code>. This will guarantee that the EPICS exit handlers
|
|
get called in the correct order.</p>
|
|
|
|
<p>On many OS that execute programs in a process based environment the
|
|
resources used by the client library such as sockets and allocated memory are
|
|
automatically released by the system when the process exits and
|
|
<code>ca_context_destroy()</code> hasn't been called, but on light weight systems such as
|
|
vxWorks or RTEMS no cleanup occurs unless the application calls
|
|
<code>ca_context_destroy()</code>.</p>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_context_create">ca_context_create</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_create_channel">ca_create_channel()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
typedef void ( caCh ) (struct connection_handler_args);
|
|
int ca_create_channel (const char *PVNAME,
|
|
caCh *USERFUNC, void *PUSER,
|
|
capri PRIORITY, chid *PCHID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>This function creates a CA channel. The CA client library will attempt to
|
|
establish and maintain a virtual circuit between the caller's application and a
|
|
named process variable in a CA server. Each call to <code>ca_create_channel()</code> allocates
|
|
resources in the CA client library and potentially also a CA server. The
|
|
function <code>ca_clear_channel()</code> is used to release these resources. If successful,
|
|
the routine writes a channel identifier into the user's variable of type
|
|
"chid". This identifier can be used with any channel access call that operates
|
|
on a channel.</p>
|
|
|
|
<p>The circuit may be initially connected or disconnected depending on the
|
|
state of the network and the location of the channel. A channel will only enter
|
|
a connected state after the server's address is determined, and only if channel
|
|
access successfully establishes a virtual circuit through the network to the
|
|
server. Channel access routines that send a request to a server will return
|
|
ECA_DISCONNCHID if the channel is currently disconnected.</p>
|
|
|
|
<p>There are two ways to obtain asynchronous notification when a channel enters
|
|
a connected state.</p>
|
|
<ul>
|
|
<li>The first and simplest method requires that you call <code>ca_pend_io()</code>, and
|
|
wait for successful completion, prior to using a channel that was created
|
|
specifying a null connection callback function pointer.</li>
|
|
<li>The second method requires that you register a connection handler by
|
|
supplying a valid connection callback function pointer. This connection
|
|
handler is called whenever the connection state of the channel changes. If
|
|
you have installed a connection handler then <code>ca_pend_io()</code> will <em>not</em>
|
|
block waiting for the channel to enter a connected state.</li>
|
|
</ul>
|
|
|
|
<p>The function ca_state(CHID) can be used to test the connection state of a
|
|
channel. Valid connections may be isolated from invalid ones with this function
|
|
if <code>ca_pend_io()</code> times out.</p>
|
|
|
|
<p>Due to the inherently transient nature of network connections the order of
|
|
connection callbacks relative to the order that <code>ca_create_channel()</code> calls are
|
|
made by the application can't be guaranteed, and application programs may need
|
|
to be prepared for a connected channel to enter a disconnected state at any
|
|
time.</p>
|
|
|
|
<h4>Example</h4>
|
|
|
|
<p>See caExample.c in the example application created by makeBaseApp.pl.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>PVNAME</code></dt>
|
|
<dd>A nil terminated process variable name string. EPICS process control
|
|
function block database variable names are of the form "<record
|
|
name>.<field name>". If the field name and the period separator
|
|
are omitted then the "VAL" field is implicit. For example "RFHV01" and
|
|
"RFHV01.VAL" reference the same EPICS process control function block
|
|
database variable.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>USERFUNC</code></dt>
|
|
<dd>Optional address of the user's callback function to be run when the
|
|
connection state changes. Casual users of channel access may decide to
|
|
set this field to null or 0 if they do not need to have a callback
|
|
function run in response to each connection state change event.
|
|
<p>The following structure is passed <em>by value </em>to the user's
|
|
connection callback function. The <code>op</code> field will
|
|
be set by the CA client library to <code>CA_OP_CONN_UP</code> when the
|
|
channel connects, and to <code>CA_OP_CONN_DOWN</code> when the channel
|
|
disconnects. See <code><a href="#ca_puser">ca_puser</a>()</code> if the
|
|
<code>PUSER</code> argument is required in your callback
|
|
handler<code>.</code></p>
|
|
<pre>struct ca_connection_handler_args {
|
|
chanId chid; /* channel id */
|
|
long op; /* one of CA_OP_CONN_UP or CA_OP_CONN_DOWN */
|
|
};</pre>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PUSER</code></dt>
|
|
<dd>The value of this void pointer argument is retained in
|
|
storage associated with the specified channel. See the MACROS manual page
|
|
for reading and writing this field. Casual users of channel access may
|
|
wish to set this field to null or 0.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PRIORITY</code></dt>
|
|
<dd>The priority level for dispatch within the server or network with 0
|
|
specifying the lowest dispatch priority and 99 the highest. This
|
|
parameter currently does not impact dispatch priorities within the
|
|
client, but this might change in the future. The abstract priority range
|
|
specified is mapped into an operating system specific range of priorities
|
|
within the server. This parameter is ignored if the server is running on
|
|
a network or operating system that does not have native support for
|
|
prioritized delivery or execution respectively. Specifying many different
|
|
priorities within the same program can increase resource consumption in
|
|
the client and the server because an independent virtual circuit, and
|
|
associated data structures, is created for each priority that is used on
|
|
a particular server.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PCHID</code></dt>
|
|
<dd>The user supplied channel identifier storage is overwritten with a
|
|
channel identifier if this routine is successful.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
|
|
|
|
<p>ECA_STRTOBIG - Unusually large string</p>
|
|
|
|
<p>ECA_ALLOCMEM - Unable to allocate memory</p>
|
|
|
|
<h3><code><a name="ca_clear_channel">ca_clear_channel()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_clear_channel (chid CHID);</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Shutdown and reclaim resources associated with a channel created by
|
|
<code>ca_create_channel()</code>.</p>
|
|
|
|
<p>All remote operation requests such as the above are accumulated (buffered)
|
|
and not forwarded to the IOC until one of <code>ca_flush_io()</code>, <code>ca_pend_io()</code>,
|
|
<code>ca_pend_event()</code>, or <code>ca_sg_block()</code> are called. This allows several requests to be
|
|
efficiently sent over the network in one message.</p>
|
|
|
|
<p>Clearing a channel does not cause its disconnect handler to be called, but
|
|
clearing a channel does shutdown and reclaim any channel state change event
|
|
subscriptions (monitors) registered with the channel.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>Identifies the channel to delete.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADCHID - Corrupted CHID</p>
|
|
|
|
<h3><code><a name="ca_put">ca_put()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_put ( chtype TYPE,
|
|
chid CHID, void *PVALUE );
|
|
int ca_array_put ( chtype TYPE, unsigned long COUNT,
|
|
chid CHID, const void *PVALUE);
|
|
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
|
|
int ca_put_callback ( chtype TYPE,
|
|
chid CHID, const void *PVALUE,
|
|
caEventCallBackFunc PFUNC, void *USERARG );
|
|
int ca_array_put_callback ( chtype TYPE, unsigned long COUNT,
|
|
chid CHID, const void *PVALUE,
|
|
caEventCallBackFunc PFUNC, void *USERARG );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Write a scalar or array value to a process variable.</p>
|
|
|
|
<p>When <code>ca_put()</code> or <code>ca_array_put()</code> are invoked the client will receive no response
|
|
unless the request can not be fulfilled in the server. If unsuccessful an
|
|
exception handler is run on the client side.</p>
|
|
|
|
<p>When <code>ca_put_callback()</code> or <code>ca_array_put_callback()</code> are invoked the user supplied
|
|
asynchronous callback is called only after the initiated write operation, and
|
|
all actions resulting from the initiating write operation, complete.</p>
|
|
|
|
<p>If unsuccessful the callback function is invoked indicating failure status.
|
|
</p>
|
|
|
|
<p>If the channel disconnects before a put callback request can be completed,
|
|
then the client's callback function is called with failure status, but this
|
|
does not guarantee that the server did not receive and process the request
|
|
before the disconnect. If a connection is lost and then resumed outstanding ca
|
|
put requests are not automatically reissued following reconnect.</p>
|
|
|
|
<p>All of these functions return ECA_DISCONN if the channel is currently
|
|
disconnected.</p>
|
|
|
|
<p>All put requests are accumulated (buffered) and not forwarded to the IOC
|
|
until one of <code>ca_flush_io()</code>, <code>ca_pend_io()</code>, <code>ca_pend_event()</code>, or <code>ca_sg_block()</code> are called.
|
|
This allows several requests to be efficiently combined into one message.</p>
|
|
|
|
<h4>Description (IOC Database Specific)</h4>
|
|
|
|
<p>A CA put request causes the record to process if the record's SCAN field is
|
|
set to passive, and the field being written has its process passive attribute
|
|
set to true. If such a record is already processing when a put request is
|
|
initiated the specified field is written immediately, and the record is
|
|
scheduled to process again as soon as it finishes processing. Earlier instances
|
|
of multiple put requests initiated while the record is being processing may be
|
|
discarded, but the last put request initiated is always written and
|
|
processed.</p>
|
|
|
|
<p>A CA put <em>callback</em> request causes the record to process if the
|
|
record's SCAN field is set to passive, and the field being written has its
|
|
process passive attribute set to true. For such a record, the user's put
|
|
callback function is not called until after the record, and any records that
|
|
the record links to, finish processing. If such a record is already processing
|
|
when a put <em>callback</em> request is initiated the put <em>callback</em>
|
|
request is postponed until the record, and any records it links to, finish
|
|
processing.</p>
|
|
|
|
<p>If the record's SCAN field is not set to passive, or the field being written
|
|
has its process passive attribute set to false then the CA put or CA put
|
|
<em>callback</em> request cause the specified field to be immediately written,
|
|
but they do not cause the record to be processed.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The external type of the supplied value to be written. Conversion will
|
|
occur if this does not match the native type. Specify one from the set of
|
|
DBR_XXXX in db_access.h</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>COUNT</code></dt>
|
|
<dd>Element count to be written to the specified channel. This must match
|
|
the array pointed to by PVALUE.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>Channel identifier</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PVALUE</code></dt>
|
|
<dd>Pointer to a value or array of values provided by the application to be
|
|
written to the channel.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PFUNC</code></dt>
|
|
<dd>address of <a href="#User">user supplied callback function</a> to be
|
|
run when the requested operation completes</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>USERARG</code></dt>
|
|
<dd>pointer sized variable retained and then passed back to user supplied
|
|
function above</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADCHID - Corrupted CHID</p>
|
|
|
|
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
|
|
|
|
<p>ECA_BADCOUNT - Requested count larger than native element count</p>
|
|
|
|
<p>ECA_STRTOBIG - Unusually large string supplied</p>
|
|
|
|
<p>ECA_NOWTACCESS - Write access denied</p>
|
|
|
|
<p>ECA_ALLOCMEM - Unable to allocate memory</p>
|
|
|
|
<p>ECA_DISCONN - Channel is disconnected</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_flush_io">ca_flush_io</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_pend_event">ca_pend_event</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_sg_put">ca_sg_array_put</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_get">ca_get()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_get ( chtype TYPE,
|
|
chid CHID, void *PVALUE );
|
|
int ca_array_get ( chtype TYPE, unsigned long COUNT,
|
|
chid CHID, void *PVALUE );
|
|
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
|
|
int ca_get_callback ( chtype TYPE,
|
|
chid CHID,
|
|
caEventCallBackFunc USERFUNC, void *USERARG);
|
|
int ca_array_get_callback ( chtype TYPE, unsigned long COUNT,
|
|
chid CHID,
|
|
caEventCallBackFunc USERFUNC, void *USERARG);</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Read a scalar or array value from a process variable.</p>
|
|
|
|
<p>When <code>ca_get()</code> or <code>ca_array_get()</code> are invoked the returned channel value can't be
|
|
assumed to be stable in the application supplied buffer until after ECA_NORMAL
|
|
is returned from <code>ca_pend_io()</code>. If a connection is lost outstanding ca get
|
|
requests are not automatically reissued following reconnect.</p>
|
|
|
|
<p>When <code>ca_get_callback()</code> or <code>ca_array_get_callback()</code> are invoked a value is read
|
|
from the channel and then the user's callback is invoked with a pointer to the
|
|
retrieved value. Note that <code>ca_pend_io()</code> will not block for the delivery of values
|
|
requested by <code>ca_get_callback()</code>. If the channel disconnects before a
|
|
<code>ca_get_callback()</code> request can be completed, then the client's callback function is
|
|
called with failure status.</p>
|
|
|
|
<p>All of these functions return ECA_DISCONN if the channel is currently
|
|
disconnected.</p>
|
|
|
|
<p>All get requests are accumulated (buffered) and not forwarded to the IOC
|
|
until one of <code>ca_flush_io()</code>, <code>ca_pend_io()</code>, <code>ca_pend_event()</code>, or <code>ca_sg_block()</code> are called.
|
|
This allows several requests to be efficiently sent over the network in one
|
|
message.</p>
|
|
|
|
<h4>Description (IOC Database Specific)</h4>
|
|
|
|
<p>A CA get or CA get callback request causes the record's field to be read
|
|
immediately independent of whether the record is currently being processed or
|
|
not. There is currently no mechanism in place to cause a record to be processed
|
|
when a CA get request is initiated.</p>
|
|
|
|
<h4>Example</h4>
|
|
|
|
<p>See caExample.c in the example application created by makeBaseApp.pl.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The external type of the user variable to return the value into.
|
|
Conversion will occur if this does not match the native type. Specify one
|
|
from the set of DBR_XXXX in db_access.h</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>COUNT</code></dt>
|
|
<dd>Element count to be read from the specified channel. Must match the
|
|
array pointed to by PVALUE. For <code>ca_array_get_callback()</code> a count of zero
|
|
means use the current element count from the server.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>Channel identifier</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PVALUE</code></dt>
|
|
<dd>Pointer to an application supplied buffer where the current value of
|
|
the channel is to be written.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>USERFUNC</code></dt>
|
|
<dd>Address of <a href="#User">user supplied callback function</a> to be
|
|
run when the requested operation completes.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>USERARG</code></dt>
|
|
<dd>Pointer sized variable retained and then passed back to user supplied
|
|
callback function above.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
|
|
|
|
<p>ECA_BADCHID - Corrupted CHID</p>
|
|
|
|
<p>ECA_BADCOUNT - Requested count larger than native element count</p>
|
|
|
|
<p>ECA_GETFAIL - A local database get failed</p>
|
|
|
|
<p>ECA_NORDACCESS - Read access denied</p>
|
|
|
|
<p>ECA_ALLOCMEM - Unable to allocate memory</p>
|
|
|
|
<p>ECA_DISCONN - Channel is disconnected</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_pend_io">ca_pend_io</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_pend_event">ca_pend_event</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_sg_get">ca_sg_array_get</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_add_event">ca_create_subscription()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
|
|
int ca_create_subscription ( chtype TYPE, unsigned long COUNT,
|
|
chid CHID, unsigned long MASK,
|
|
caEventCallBackFunc USERFUNC, void *USERARG,
|
|
evid *PEVID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Register a state change subscription and specify a callback function to be
|
|
invoked whenever the process variable undergoes significant state changes. A
|
|
significant change can be a change in the process variable's value, alarm
|
|
status, or alarm severity. In the process control function block database the
|
|
deadband field determines the magnitude of a significant change for the
|
|
process variable's value. Each call to this function consumes resources in the
|
|
client library and potentially a CA server until one of <code>ca_clear_channel()</code> or
|
|
<code>ca_clear_subscription()</code> is called.</p>
|
|
|
|
<p>Subscriptions may be installed or canceled against both connected and
|
|
disconnected channels. The specified USERFUNC is called once immediately after
|
|
the subscription is installed with the process variable's current state if the
|
|
process variable is connected. Otherwise, the specified USERFUNC is called
|
|
immediately after establishing a connection (or reconnection) with the process
|
|
variable. The specified USERFUNC is called immediately with the process
|
|
variable's current state from within <code>ca_create_subscription()</code> if the client and the
|
|
process variable share the same address space.</p>
|
|
|
|
<p>If a subscription is installed on a channel in a disconnected state then the
|
|
requested count will be set to the native maximum element count of the channel
|
|
if the requested count is larger.</p>
|
|
|
|
<p>All subscription requests such as the above are accumulated (buffered) and
|
|
not forwarded to the IOC until one of <code>ca_flush_io()</code>, <code>ca_pend_io()</code>, <code>ca_pend_event()</code>,
|
|
or <code>ca_sg_block()</code> are called. This allows several requests to be efficiently sent
|
|
over the network in one message.</p>
|
|
|
|
<p>If at any time after subscribing, read access to the specified process
|
|
variable is lost, then the callback will be invoked immediately indicating
|
|
that read access was lost via the status argument. When read access is restored
|
|
normal event processing will resume starting always with at least one update
|
|
indicating the current state of the channel.</p>
|
|
|
|
<p>A better name for this function might have been <code>ca_subscribe()</code>.</p>
|
|
|
|
<h4>Example</h4>
|
|
|
|
<p>See caMonitor.c in the example application created by makeBaseApp.pl.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The type of value presented to the callback function. Conversion will
|
|
occur if it does not match native type. Specify one from the set of
|
|
DBR_XXXX in db_access.h</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>COUNT</code></dt>
|
|
<dd>The element count to be read from the specified channel. A count of
|
|
zero means use the current element count from the server.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>channel identifier</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>USRERFUNC</code></dt>
|
|
<dd>The address of <a href="#User">user supplied callback function</a> to
|
|
be invoked with each subscription update.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>USERARG</code></dt>
|
|
<dd>pointer sized variable retained and passed back to user callback
|
|
function</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>RESERVED</code></dt>
|
|
<dd>Reserved for future use. Specify 0.0 to remain upwardly compatible.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PEVID</code></dt>
|
|
<dd>This is a pointer to user supplied event id which is overwritten if
|
|
successful. This event id can later be used to clear a specific event.
|
|
This option may be omitted by passing a null pointer.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>MASK</code></dt>
|
|
<dd>A mask with bits set for each of the event trigger types requested. The
|
|
event trigger mask must be a <em>bitwise or</em> of one or more of the
|
|
following constants.
|
|
<ul>
|
|
<li>DBE_VALUE - Trigger events when the channel value exceeds the
|
|
monitor dead band</li>
|
|
<li>DBE_ARCHIVE (or DBE_LOG) - Trigger events when the channel value
|
|
exceeds the archival dead band</li>
|
|
<li>DBE_ALARM - Trigger events when the channel alarm state changes</li>
|
|
<li>DBE_PROPERTY - Trigger events when a channel property changes.</li>
|
|
</ul>
|
|
<p>For functions above that do not include a trigger specification,
|
|
events will be triggered when there are significant changes in the
|
|
channel's value or when there are changes in the channel's alarm state.
|
|
This is the same as "DBE_VALUE | DBE_ALARM."</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADCHID - Corrupted CHID</p>
|
|
|
|
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
|
|
|
|
<p>ECA_ALLOCMEM - Unable to allocate memory</p>
|
|
|
|
<p>ECA_ADDFAIL - A local database event add failed</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_pend_event">ca_pend_event</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_flush_io">ca_flush_io</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_clear_event">ca_clear_subscription()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_clear_subscription ( evid EVID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Cancel a subscription.</p>
|
|
|
|
<p>All cancel-subscription requests such as the above are accumulated (buffered)
|
|
and not forwarded to the server until one of <code>ca_flush_io()</code>, <code>ca_pend_io()</code>,
|
|
<code>ca_pend_event()</code>, or <code>ca_sg_block()</code> are called. This allows several requests to be
|
|
efficiently sent together in one message.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt>EVID</dt>
|
|
<dd>event id returned by ca_create_subscription()</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADCHID - Corrupted CHID</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_add_event">ca_create_subscription</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_pend_io">ca_pend_io()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_pend_io ( double TIMEOUT );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>This function flushes the send buffer and then blocks until outstanding
|
|
<code><a href="#ca_get">ca_get</a>()</code> requests complete, and until channels created
|
|
specifying null connection handler function pointers connect for the first
|
|
time.</p>
|
|
<ul>
|
|
<li>If ECA_NORMAL is returned then it can be safely assumed that all
|
|
outstanding <code><a href="#ca_get">ca_get</a>()</code> requests have completed
|
|
successfully and channels created specifying null connection handler
|
|
function pointers have connected for the first time.</li>
|
|
<li>If ECA_TIMEOUT is returned then it must be assumed for all previous
|
|
<code><a href="#ca_get">ca_get</a>()</code> requests and properly qualified first time
|
|
channel connects have failed.</li>
|
|
</ul>
|
|
|
|
<p>If ECA_TIMEOUT is returned then get requests may be reissued followed by a
|
|
subsequent call to <code>ca_pend_io()</code>. Specifically, the function will block only for
|
|
outstanding <code><a href="#ca_get">ca_get</a>()</code> requests issued, and also any channels
|
|
created specifying a null connection handler function pointer, after the last
|
|
call to <code>ca_pend_io()</code> or ca client context creation whichever is later. Note
|
|
that <code><a href="#ca_create_channel">ca_create_channel</a>()</code> requests generally
|
|
should not be reissued for the same process variable unless
|
|
<code><a href="#ca_clear_channel">ca_clear_channel</a>()</code> is called first.</p>
|
|
|
|
<p>If no <code><a href="#ca_get">ca_get</a>()</code> or connection state change events are
|
|
outstanding then <code>ca_pend_io()</code> will flush the send buffer and return immediately
|
|
<em>without processing any outstanding channel access background
|
|
activities</em>.</p>
|
|
|
|
<p>The delay specified to <code>ca_pend_io()</code> should take into account worst case
|
|
network delays such as Ethernet collision exponential back off until
|
|
retransmission delays which can be quite long on overloaded networks.</p>
|
|
|
|
<p>Unlike <code><a href="#ca_pend_event">ca_pend_event</a>()</code>, this routine
|
|
will not process CA's background activities if none of the selected IO requests
|
|
are pending.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt>TIMEOUT</dt>
|
|
<dd>Specifies the time out interval. A <code>TIMEOUT</code> interval of
|
|
zero specifies forever.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_TIMEOUT - Selected IO requests didn't complete before specified
|
|
timeout</p>
|
|
|
|
<p>ECA_EVDISALLOW - Function inappropriate for use within an event handler</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_get">ca_get</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_create_channel">ca_create_channel</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_test_io">ca_test_io</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_test_io">ca_test_io()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_test_io();</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>This function tests to see if all <code><a href="#ca_get">ca_get</a>()</code> requests are
|
|
complete and channels created specifying a null connection callback function
|
|
pointer are connected. It will report the status of outstanding
|
|
<code><a href="#ca_get">ca_get</a>()</code> requests issued, and channels created specifying a
|
|
null connection callback function pointer, after the last call to <code>ca_pend_io()</code>
|
|
or CA context initialization whichever is later.</p>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_IODONE - All IO operations completed</p>
|
|
|
|
<p>ECA_IOINPROGRESS - IO operations still in progress</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_pend_io">ca_pend_io</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_pend_event">ca_pend_event()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_pend_event ( double TIMEOUT );
|
|
int ca_poll ();</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>When <code>ca_pend_event()</code> is invoked the send buffer is flushed and CA background
|
|
activity is processed for TIMEOUT seconds.</p>
|
|
|
|
<p>When <code>ca_poll()</code> is invoked the send buffer is flushed and any outstanding CA
|
|
background activity is processed.</p>
|
|
|
|
<p>The <code>ca_pend_event()</code> function will <em>not</em> return before the specified
|
|
timeout expires and all unfinished channel access labor has been processed,
|
|
and unlike <code><a href="#ca_pend_io">ca_pend_io</a>()</code> returning from the
|
|
function does <em>not </em>indicate anything about the status of pending IO
|
|
requests.</p>
|
|
|
|
<p>Both <code>ca_pend_event()</code> and <code>ca_poll()</code> return ECA_TIMEOUT
|
|
when successful. This behavior probably isn't intuitive, but it is preserved to
|
|
insure backwards compatibility.</p>
|
|
|
|
<p>See also <a href="#Thread">Thread Safety and Preemptive Callback to User
|
|
Code</a>.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>TIMEOUT</code></dt>
|
|
<dd>The duration to block in this routine in seconds. A timeout of zero
|
|
seconds blocks forever.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_TIMEOUT - The operation timed out</p>
|
|
|
|
<p>ECA_EVDISALLOW - Function inappropriate for use within a callback
|
|
handler</p>
|
|
|
|
<h3><code><a name="ca_flush_io">ca_flush_io()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_flush_io();</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Flush outstanding IO requests to the server. This routine might be useful
|
|
to users who need to flush requests prior to performing client side labor in
|
|
parallel with labor performed in the server.</p>
|
|
|
|
<p>Outstanding requests are also sent whenever the buffer which holds them
|
|
becomes full.</p>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<h3><code><a name="ca_signal">ca_signal()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_signal ( long CA_STATUS, const char * CONTEXT_STRING );
|
|
void SEVCHK( CA_STATUS, CONTEXT_STRING );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Provide the error message character string associated with the supplied
|
|
channel access error code and the supplied error context to diagnostics. If the
|
|
error code indicates an unsuccessful operation a stack dump is printed, if this
|
|
capability is available on the local operating system, and execution is
|
|
terminated.</p>
|
|
|
|
<p>SEVCHK is a macro envelope around <code>ca_signal()</code> which only calls <code>ca_signal()</code> if
|
|
the supplied error code indicates an unsuccessful operation. SEVCHK is the
|
|
recommended error handler for simple applications which do not wish to write
|
|
code testing the status returned from each channel access call.</p>
|
|
|
|
<h4>Examples</h4>
|
|
<pre>status = ca_context_create (...);
|
|
SEVCHK ( status, "Unable to create a CA client context" );</pre>
|
|
|
|
<p>If the application only wishes to print the message associated with an error
|
|
code or test the severity of an error there are also functions provided for
|
|
this purpose.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CA_STATUS</code></dt>
|
|
<dd>The status (error code) returned from a channel access function.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>CONTEXT_STRING</code></dt>
|
|
<dd>A null terminated character string to supply as error context to
|
|
diagnostics.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<h3><code><a
|
|
name="ca_add_exception_event">ca_add_exception_event()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
typedef void (*pCallback) ( struct exception_handler_args HANDLERARGS );
|
|
int ca_add_exception_event ( pCallback USERFUNC, void *USERARG );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Replace the currently installed CA context global exception handler callback.</p>
|
|
|
|
<p>When an error occurs in the server asynchronous to the clients thread then
|
|
information about this type of error is passed from the server to the client in
|
|
an exception message. When the client receives this exception message an
|
|
exception handler callback is called.The default exception handler prints a
|
|
diagnostic message on the client's standard out and terminates execution if the
|
|
error condition is severe.</p>
|
|
|
|
<p>Note that certain fields in "struct exception_handler_args" are not
|
|
applicable in the context of some error messages. For instance, a failed get
|
|
will supply the address in the client task where the returned value was
|
|
requested to be written. For other failed operations the value of the addr
|
|
field should not be used.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>USERFUNC</code></dt>
|
|
<dd>Address of user callback function to be executed when an exceptions
|
|
occur. Passing a null value causes the default exception handler to be
|
|
reinstalled. The following structure is passed by value to the user's
|
|
callback function. Currently, the <code>op</code> field can be one of
|
|
<code>CA_OP_GET, CA_OP_PUT, CA_OP_CREATE_CHANNEL, CA_OP_ADD_EVENT,
|
|
CA_OP_CLEAR_EVENT, or CA_OP_OTHER.</code>
|
|
<pre>struct exception_handler_args {
|
|
void *usr; /* user argument supplied when installed */
|
|
chanId chid; /* channel id (may be null) */
|
|
long type; /* type requested */
|
|
long count; /* count requested */
|
|
void *addr; /* user's address to write results of CA_OP_GET */
|
|
long stat; /* channel access ECA_XXXX status code */
|
|
long op; /* CA_OP_GET, CA_OP_PUT, ..., CA_OP_OTHER */
|
|
const char *ctx; /* a character string containing context info */
|
|
sonst char *pFile; /* source file name (may be NULL) */
|
|
unsigned lineNo; /* source file line number (may be zero) */
|
|
};</pre>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>USERARG</code></dt>
|
|
<dd>pointer sized variable retained and passed back to user function
|
|
above</dd>
|
|
</dl>
|
|
|
|
<h4>Example</h4>
|
|
<pre>void ca_exception_handler (
|
|
struct exception_handler_args args)
|
|
{
|
|
char buf[512];
|
|
char *pName;
|
|
|
|
if ( args.chid ) {
|
|
pName = ca_name ( args.chid );
|
|
}
|
|
else {
|
|
pName = "?";
|
|
}
|
|
sprintf ( buf,
|
|
"%s - with request chan=%s op=%d data type=%s count=%d",
|
|
args.ctx, pName, args.op, dbr_type_to_text ( args.type ), args.count );
|
|
ca_signal ( args.stat, buf );
|
|
}
|
|
ca_add_exception_event ( ca_exception_handler , 0 );</pre>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p></p>
|
|
|
|
<h3><code><a name="ca_add_fd_registration">ca_add_fd_registration()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_add_fd_registration ( void ( USERFUNC * ) ( void *USERARG, int FD, int OPENED ), void * USERARG )</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>For use with the services provided by a file descriptor manager (IO
|
|
multiplexor) such as "fdmgr.c". A file descriptor manager is often needed when
|
|
two file descriptor IO intensive libraries such as the EPICS channel access
|
|
client library and the X window system client library must coexist in the same
|
|
UNIX process. This function allows an application code to be notified whenever
|
|
the CA client library places a new file descriptor into service and whenever
|
|
the CA client library removes a file descriptor from service. Specifying
|
|
USERFUNC=NULL disables file descriptor registration (this is the default).</p>
|
|
|
|
<h4>Arguments</h4>
|
|
|
|
<p>USERFUNC</p>
|
|
|
|
<p>Pointer to a user supplied C function returning null with the above
|
|
arguments.</p>
|
|
|
|
<p>USERARG</p>
|
|
|
|
<p>User supplied pointer sized variable passed to the above function.</p>
|
|
|
|
<p>FD </p>
|
|
|
|
<p>A file descriptor.</p>
|
|
|
|
<p>OPENED </p>
|
|
|
|
<p>Boolean argument is true if the file descriptor was opened and false if the
|
|
file descriptor was closed.</p>
|
|
|
|
<h4>Example</h4>
|
|
<pre>int s;
|
|
static struct myStruct aStruct;
|
|
|
|
void fdReg ( struct myStruct *pStruct, int fd, int opened )
|
|
{
|
|
if ( opened ) printf ( "fd %d was opened\n", fd );
|
|
else printf ( "fd %d was closed\n", fd );
|
|
}
|
|
s = ca_add_fd_registration ( fdReg, & aStruct );
|
|
SEVCHK ( s, NULL );</pre>
|
|
|
|
<h4>Comments</h4>
|
|
|
|
<p>When using this function it is advisable to call it only once prior to
|
|
calling any other CA function, or once just after creating the CA context (if
|
|
you create the context explicitly). Use of this interface can improve latency
|
|
slightly in applications that use non preemptive callback mode at the expense
|
|
of some additional runtime overhead when compared to the alternative which is
|
|
just polling <code>ca_pend_event()</code> periodically. It would probably not be appropriate
|
|
to use this function with preemptive callback mode. Starting with R3.14 this
|
|
function is implemented in a special backward compatibility mode. if
|
|
<code>ca_add_fd_registration()</code> is called, a single pseudo UDP fd is
|
|
created which CA pokes whenever something significant happens. Xt and others
|
|
can watch this fd so that backwards compatibility is preserved, and so that
|
|
they will not need to use preemptive callback mode but they will nevertheless
|
|
get the lowest latency response to the arrival of CA messages.</p>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>"ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p></p>
|
|
|
|
<h3><code><a name="ca_replace_printf_handler">ca_replace_printf_handler
|
|
()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
typedef int caPrintfFunc ( const char *pFormat, va_list args );
|
|
int ca_replace_printf_handler ( caPrintfFunc *PFUNC );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Replace the default handler for formatted diagnostic message output. The
|
|
default handler uses fprintf to send messages to 'stderr'.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>PFUNC</code></dt>
|
|
<dd>The address of a user supplied callback handler to be invoked when CA
|
|
prints diagnostic messages. Installing a null pointer will cause the
|
|
default callback handler to be reinstalled.</dd>
|
|
</dl>
|
|
|
|
<h4>Examples</h4>
|
|
<pre>int my_printf ( char *pformat, va_list args ) {
|
|
int status;
|
|
status = vfprintf( stderr, pformat, args);
|
|
return status;
|
|
}
|
|
status = ca_replace_printf_handler ( my_printf );
|
|
SEVCHK ( status, "failed to install my printf handler" );</pre>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<h3><code><a name="ca_replace">ca_replace_access_rights_event()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
typedef void ( caEventCallBackFunc )(struct access_rights_handler_args);
|
|
int ca_replace_access_rights_event ( chid CHAN,
|
|
caEventCallBackFunc PFUNC );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Install or replace the access rights state change callback handler for the
|
|
specified channel.</p>
|
|
|
|
<p>The callback handler is called in the following situations.</p>
|
|
<ul>
|
|
<li>whenever CA connects the channel immediately before the channel's
|
|
connection handler is called</li>
|
|
<li>whenever CA disconnects the channel immediately after the channel's
|
|
disconnect callback is called</li>
|
|
<li>once immediately after installation if the channel is connected.</li>
|
|
<li>whenever the access rights state of a connected channel changes</li>
|
|
</ul>
|
|
|
|
<p>When a channel is created no access rights handler is installed.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHAN</code></dt>
|
|
<dd>The channel identifier.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PFUNC</code></dt>
|
|
<dd>Address of user supplied callback function. A null pointer uninstalls
|
|
the current handler. The following arguments are passed <em>by value</em>
|
|
to the supplied callback handler.
|
|
<pre>typedef struct ca_access_rights {
|
|
unsigned read_access:1;
|
|
unsigned write_access:1;
|
|
} caar;
|
|
|
|
/* arguments passed to user access rights handlers */
|
|
struct access_rights_handler_args {
|
|
chanId chid; /* channel id */
|
|
caar ar; /* new access rights state */
|
|
};</pre>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<h3><code><a name="ca_field_type">ca_field_type()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
chtype ca_field_type ( CHID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Return the native type in the server of the process variable.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>channel identifier</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The data type code will be a member of the set of DBF_XXXX in
|
|
db_access.h. The constant TYPENOTCONN is returned if the channel is
|
|
disconnected.</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_element_count">ca_element_count()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
unsigned ca_element_count ( CHID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Return the maximum array element count in the server for the specified IO
|
|
channel.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>channel identifier</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>COUNT</code></dt>
|
|
<dd>The maximum array element count in the server. An element count of
|
|
zero is returned if the channel is disconnected.</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_name">ca_name()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
char * ca_name ( CHID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Return the name provided when the supplied channel id was created.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>channel identifier</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>PNAME</code></dt>
|
|
<dd>The channel name. The string returned is valid as long as the channel
|
|
specified exists.</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_set_puser">ca_set_puser()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
void ca_set_puser ( chid CHID, void *PUSER );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Set a user private void pointer variable retained with each channel for use
|
|
at the users discretion.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt>CHID</dt>
|
|
<dd>channel identifier</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt>PUSER</dt>
|
|
<dd>user private void pointer</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_puser">ca_puser()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
void * ca_puser ( CHID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Return a user private void pointer variable retained with each channel for
|
|
use at the users discretion.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>channel identifier</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>PUSER</code></dt>
|
|
<dd>user private pointer</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_state">ca_state()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
enum channel_state {
|
|
cs_never_conn, /* valid chid, server not found or unavailable */
|
|
cs_prev_conn, /* valid chid, previously connected to server */
|
|
cs_conn, /* valid chid, connected to server */
|
|
cs_closed }; /* channel deleted by user */
|
|
enum channel_state ca_state ( CHID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Returns an enumerated type indicating the current state of the specified IO
|
|
channel.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>channel identifier</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>STATE</code></dt>
|
|
<dd>the connection state</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_message">ca_message()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
const char * ca_message ( STATUS );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>return a message character string corresponding to a user specified CA
|
|
status code.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>STATUS</code></dt>
|
|
<dd>a CA status code</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>STRING</code></dt>
|
|
<dd>the corresponding error message string</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_host_name">ca_host_name()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
char * ca_host_name ( CHID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Return a character string which contains the name of the host to which a
|
|
channel is currently connected.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>the channel identifier</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>STRING</code></dt>
|
|
<dd>The process variable server's host name. If the channel is disconnected
|
|
the string "<disconnected>" is returned.</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_read_access">ca_read_access()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_read_access ( CHID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Returns boolean true if the client currently has read access to the
|
|
specified channel and boolean false otherwise.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>the channel identifier</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>STRING</code></dt>
|
|
<dd>boolean true if the client currently has read access to the specified
|
|
channel and boolean false otherwise</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_write_access">ca_write_access()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_write_access ( CHID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Returns boolean true if the client currently has write access to the
|
|
specified channel and boolean false otherwise.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>the channel identifier</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>STRING</code></dt>
|
|
<dd>boolean true if the client currently has write access to the specified
|
|
channel and boolean false otherwise</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="dbr_size">dbr_size[]</a></code></h3>
|
|
<pre>#include <db_access.h>
|
|
extern unsigned dbr_size[/* TYPE */];</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>An array that returns the size in bytes for a DBR_XXXX type.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The data type code. A member of the set of DBF_XXXX in db_access.h.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>SIZE</code></dt>
|
|
<dd>the size in bytes of the specified type</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="dbr_size_n">dbr_size_n()</a></code></h3>
|
|
<pre>#include <db_access.h>
|
|
unsigned dbr_size_n ( TYPE, COUNT );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Returns the size in bytes for a DBR_XXXX type with COUNT elements. If the
|
|
DBR type is a structure then the value field is the last field in the
|
|
structure. If COUNT is greater than one then COUNT-1 elements are appended to
|
|
the end of the structure so that they can be addressed as an array through a
|
|
pointer to the value field.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The data type</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>COUNT</code></dt>
|
|
<dd>The element count</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>SIZE</code></dt>
|
|
<dd>the size in bytes of the specified type with the specified number of
|
|
elements</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="dbr_value_size">dbr_value_size[]</a></code></h3>
|
|
<pre>#include <db_access.h>
|
|
extern unsigned dbr_value_size[/* TYPE */];</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>The array <code>dbr_value_size[TYPE]</code> returns the size in bytes for the value
|
|
stored in a DBR_XXXX type. If the type is a structure the size of the value
|
|
field is returned otherwise the size of the type is returned.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The data type code. A member of the set of DBF_XXXX in db_access.h.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>SIZE</code></dt>
|
|
<dd>the size in bytes of the value field if the type is a structure and
|
|
otherwise the size in bytes of the type</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="dbr_type_t">dbr_type_to_text</a>()</code></h3>
|
|
<pre>#include <db_access.h>
|
|
const char * dbr_type_text ( chtype TYPE );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Returns a constant null terminated string corresponding to the specified dbr
|
|
type.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The data type code. A member of the set of DBR_XXXX in db_access.h.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
<dl>
|
|
<dt><code>STRING</code></dt>
|
|
<dt></dt>
|
|
<dd>The const string corresponding to the DBR_XXX type.</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_test_event">ca_test_event()</a></code></h3>
|
|
<pre>#include <cadef.h></pre>
|
|
|
|
<h4>Description</h4>
|
|
<pre>void ca_test_event ( struct event_handler_args );</pre>
|
|
|
|
<p>A built-in subscription update callback handler for debugging purposes that
|
|
prints diagnostics to standard out.</p>
|
|
|
|
<h4>Examples</h4>
|
|
<pre>void ca_test_event ();
|
|
status = ca_create_subscription ( type, chid, ca_test_event, NULL, NULL );
|
|
SEVCHK ( status, .... );</pre>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_add_event">ca_create_subscription</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_sg_create">ca_sg_create()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_sg_create ( CA_SYNC_GID *PGID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Create a synchronous group and return an identifier for it.</p>
|
|
|
|
<p>A synchronous group can be used to guarantee that a set of channel access
|
|
requests have completed. Once a synchronous group has been created then channel
|
|
access get and put requests may be issued within it using
|
|
<code>ca_sg_array_get()</code> and <code>ca_sg_array_put()</code> respectively.
|
|
The routines <code>ca_sg_block()</code> and <code>ca_sg_test()</code> can be
|
|
used to block for and test for completion respectively. The routine
|
|
<code>ca_sg_reset()</code> is used to discard knowledge of old requests which
|
|
have timed out and in all likelihood will never be satisfied.</p>
|
|
|
|
<p>Any number of asynchronous groups can have application requested operations
|
|
outstanding within them at any given time.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>PGID</code></dt>
|
|
<dd>Pointer to a user supplied CA_SYNC_GID.</dd>
|
|
</dl>
|
|
|
|
<h4>Examples</h4>
|
|
<pre>CA_SYNC_GID gid;
|
|
status = ca_sg_create ( &gid );
|
|
SEVCHK ( status, Sync group create failed );</pre>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_ALLOCMEM - Failed, unable to allocate memory</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_sg_delete">ca_sg_delete</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_sg_block">ca_sg_block</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_sg_test">ca_sg_test</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_sg_reset">ca_sg_reset</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_sg_put">ca_sg_array_put</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_sg_get">ca_sg_array_get</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_sg_delete">ca_sg_delete()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_sg_delete ( CA_SYNC_GID GID );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Deletes a synchronous group.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt>GID</dt>
|
|
<dd>Identifier of the synchronous group to be deleted.</dd>
|
|
</dl>
|
|
|
|
<h4>Examples</h4>
|
|
<pre>CA_SYNC_GID gid;
|
|
status = ca_sg_delete ( gid );
|
|
SEVCHK ( status, Sync group delete failed );</pre>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADSYNCGRP - Invalid synchronous group</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_sg_create">ca_sg_create</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_sg_block">ca_sg_block()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_sg_block ( CA_SYNC_GID GID, double TIMEOUT );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Flushes the send buffer and then waits until outstanding requests complete
|
|
or the specified time out expires. At this time outstanding requests include
|
|
calls to <code>ca_sg_array_get()</code> and calls to <code>ca_sg_array_put()</code>. If ECA_TIMEOUT is
|
|
returned then failure must be assumed for all outstanding queries. Operations
|
|
can be reissued followed by another <code>ca_sg_block()</code>. This routine will only block
|
|
on outstanding queries issued after the last call to <code>ca_sg_block()</code>,
|
|
<code>ca_sg_reset()</code>, or <code>ca_sg_create()</code> whichever occurs later in time. If no queries
|
|
are outstanding then <code>ca_sg_block()</code> will return immediately without processing
|
|
any pending channel access activities.</p>
|
|
|
|
<p>Values written into your program's variables by a channel access synchronous
|
|
group request should not be referenced by your program until ECA_NORMAL has
|
|
been received from <code>ca_sg_block()</code>. This routine will process pending channel
|
|
access background activity while it is waiting.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>GID</code></dt>
|
|
<dd>Identifier of the synchronous group.</dd>
|
|
<dt><code>TIMEOUT</code></dt>
|
|
<dd>The duration to block in this routine in seconds. A timeout of zero
|
|
seconds blocks forever.</dd>
|
|
</dl>
|
|
|
|
<h4>Examples</h4>
|
|
<pre>CA_SYNC_GID gid;
|
|
status = ca_sg_block(gid, 0.0);
|
|
SEVCHK(status, Sync group block failed);</pre>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_TIMEOUT - The operation timed out</p>
|
|
|
|
<p>ECA_EVDISALLOW - Function inappropriate for use within an event handler</p>
|
|
|
|
<p>ECA_BADSYNCGRP - Invalid synchronous group</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_sg_test">ca_sg_test</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_sg_reset">ca_sg_reset</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_sg_test">ca_sg_test()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_sg_test ( CA_SYNC_GID GID )</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Test to see if all requests made within a synchronous group have
|
|
completed.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>GID</code></dt>
|
|
<dd>Identifier of the synchronous group.</dd>
|
|
</dl>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Test to see if all requests made within a synchronous group have
|
|
completed.</p>
|
|
|
|
<h4>Examples</h4>
|
|
<pre>CA_SYNC_GID gid;
|
|
status = ca_sg_test ( gid );</pre>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_IODONE - IO operations completed</p>
|
|
|
|
<p>ECA_IOINPROGRESS - Some IO operations still in progress</p>
|
|
|
|
<h3><code><a name="ca_sg_reset">ca_sg_reset()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_sg_reset ( CA_SYNC_GID GID )</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Reset the number of outstanding requests within the specified synchronous
|
|
group to zero so that <code>ca_sg_test()</code> will return ECA_IODONE and <code>ca_sg_block()</code>
|
|
will not block unless additional subsequent requests are made.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>GID</code></dt>
|
|
<dd>Identifier of the synchronous group.</dd>
|
|
</dl>
|
|
|
|
<h4>Examples</h4>
|
|
<pre>CA_SYNC_GID gid;
|
|
status = ca_sg_reset(gid);</pre>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADSYNCGRP - Invalid synchronous group</p>
|
|
|
|
<h3><code><a name="ca_sg_put">ca_sg_array_put()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_sg_put ( CA_SYNC_GID GID, chtype TYPE,
|
|
chid CHID, void *PVALUE );
|
|
int ca_sg_array_put ( CA_SYNC_GID GID, chtype TYPE,
|
|
unsigned long COUNT, chid CHID, void *PVALUE );</pre>
|
|
|
|
<p>Write a value, or array of values, to a channel and increment the outstanding
|
|
request count of a synchronous group. The <code>ca_sg_put()</code> and
|
|
<code>ca_sg_array_put()</code> functionality is implemented using
|
|
<code>ca_array_put_callback()</code>.</p>
|
|
|
|
<p>All remote operation requests such as the above are accumulated (buffered)
|
|
and not forwarded to the server until one of <code>ca_flush_io()</code>,
|
|
<code>ca_pend_io()</code>, <code>ca_pend_event()</code>, or
|
|
<code>ca_sg_block()</code> are called. This allows several requests to be
|
|
efficiently sent in one message.</p>
|
|
|
|
<p>If a connection is lost and then resumed outstanding puts are not
|
|
reissued.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>GID</code></dt>
|
|
<dd>synchronous group identifier</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The type of supplied value. Conversion will occur if it does not match
|
|
the native type. Specify one from the set of DBR_XXXX in db_access.h.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>COUNT</code></dt>
|
|
<dd>element count to be written to the specified channel - must match the
|
|
array pointed to by PVALUE</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>channel identifier</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PVALUE</code></dt>
|
|
<dd>A pointer to an application supplied buffer containing the value or
|
|
array of values returned</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADSYNCGRP - Invalid synchronous group</p>
|
|
|
|
<p>ECA_BADCHID - Corrupted CHID</p>
|
|
|
|
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
|
|
|
|
<p>ECA_BADCOUNT - Requested count larger than native element count</p>
|
|
|
|
<p>ECA_STRTOBIG - Unusually large string supplied</p>
|
|
|
|
<p>ECA_PUTFAIL - A local database put failed</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_flush_io">ca_flush_io</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_sg_get">ca_sg_array_get()</a></code></h3>
|
|
<pre>#include <cadef.h>
|
|
int ca_sg_get ( CA_SYNC_GID GID, chtype TYPE,
|
|
chid CHID, void *PVALUE );
|
|
int ca_sg_array_get ( CA_SYNC_GID GID,
|
|
chtype TYPE, unsigned long COUNT,
|
|
chid CHID, void *PVALUE );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Read a value from a channel and increment the outstanding request count of a
|
|
synchronous group. The <code>ca_sg_get()</code> and
|
|
<code>ca_sg_array_get()</code> functionality is implemented using
|
|
<code>ca_array_get_callback()</code>.</p>
|
|
|
|
<p>The values written into your program's variables by <code>ca_sg_get()</code>
|
|
or <code>ca_sg_array_get()</code> should not be referenced by your program until
|
|
ECA_NORMAL has been received from <code>ca_sg_block()</code>, or until
|
|
<code>ca_sg_test()</code> returns ECA_IODONE.</p>
|
|
|
|
<p>All remote operation requests such as the above are accumulated (buffered)
|
|
and not forwarded to the server until one of <code>ca_flush_io()</code>,
|
|
<code>ca_pend_io()</code>, <code>ca_pend_event()</code>, or
|
|
<code>ca_sg_block()</code> are called. This allows several requests to be
|
|
efficiently sent in one message.</p>
|
|
|
|
<p>If a connection is lost and then resumed outstanding gets are not
|
|
reissued.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>GID</code></dt>
|
|
<dd>Identifier of the synchronous group.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>External type of returned value. Conversion will occur if this does not
|
|
match native type. Specify one from the set of DBR_XXXX in
|
|
db_access.h</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>COUNT</code></dt>
|
|
<dd>Element count to be read from the specified channel. It must match the
|
|
array pointed to by PVALUE.</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>CHID</code></dt>
|
|
<dd>channel identifier</dd>
|
|
</dl>
|
|
<dl>
|
|
<dt><code>PVALUE</code></dt>
|
|
<dd>Pointer to application supplied buffer that is to contain the value or
|
|
array of values to be returned</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_BADSYNCGRP - Invalid synchronous group</p>
|
|
|
|
<p>ECA_BADCHID - Corrupted CHID</p>
|
|
|
|
<p>ECA_BADCOUNT - Requested count larger than native element count</p>
|
|
|
|
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
|
|
|
|
<p>ECA_GETFAIL - A local database get failed</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_pend_io">ca_pend_io</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_flush_io">ca_flush_io</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_get">ca_get_callback</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_client_status">ca_client_status()</a></code></h3>
|
|
<pre>int ca_client_status ( unsigned level );
|
|
int ca_context_status ( struct ca_client_context *CONTEXT,
|
|
unsigned LEVEL );</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Prints information about the client context including, at higher interest
|
|
levels, status for each channel. Lacking a CA context pointer,
|
|
<code>ca_client_status()</code> prints information about the calling threads CA context.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CONTEXT</code></dt>
|
|
<dd>A pointer to the CA context to examine.</dd>
|
|
<dt><code>LEVEL</code></dt>
|
|
<dd>The interest level. Increasing level produces increasing detail.</dd>
|
|
</dl>
|
|
|
|
<h3><code><a name="ca_current_context">ca_current_context()</a></code></h3>
|
|
<pre>struct ca_client_context * ca_current_context ();</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Returns a pointer to the current thread's CA context. If none then null is
|
|
returned.</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_attach_context">ca_attach_context</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_detach_context">ca_detach_context</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_context_create">ca_context_create</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_context_destroy">ca_context_destroy</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_attach_context">ca_attach_context()</a></code></h3>
|
|
<pre>int ca_attach_context (struct ca_client_context *CONTEXT);</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>The calling thread becomes a member of the specified CA context. If
|
|
<code>ca_disable_preemptive_callback</code> is specified when
|
|
<code>ca_context_create()</code> is called (or if <code>ca_task_initialize()</code> is called) then
|
|
additional threads are <em>not </em>allowed to join the CA context because
|
|
allowing other threads to join implies that CA callbacks will be called
|
|
preemptively from more than one thread.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>CONTEXT</code></dt>
|
|
<dd>A pointer to the CA context to join with.</dd>
|
|
</dl>
|
|
|
|
<h4>Returns</h4>
|
|
|
|
<p>ECA_NORMAL - Normal successful completion</p>
|
|
|
|
<p>ECA_NOTTHREADED - Context is not preemptive so cannot be joined</p>
|
|
|
|
<p>ECA_ISATTACHED - Thread already attached to a CA context</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_current_context">ca_current_context</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_detach_context">ca_detach_context</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_context_create">ca_context_create</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_context_destroy">ca_context_destroy</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_detach_context">ca_detach_context()</a></code></h3>
|
|
<pre>void ca_detach_context();</pre>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Detach from any CA context currently attached to the calling thread. This
|
|
does <em>not</em> cleanup or shutdown any currently attached CA context (for
|
|
that use <code>ca_context_destroy()</code>).</p>
|
|
|
|
<h4>See Also</h4>
|
|
|
|
<p><code><a href="#ca_current_context">ca_current_context</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_attach_context">ca_attach_context</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_context_create">ca_context_create</a>()</code></p>
|
|
|
|
<p><code><a href="#ca_context_destroy">ca_context_destroy</a>()</code></p>
|
|
|
|
<h3><code><a name="ca_dump_dbr">ca_dump_dbr()</a></code></h3>
|
|
<code><pre>void ca_dump_dbr (chtype TYPE, unsigned COUNT, const void * PDBR);</pre></code>
|
|
|
|
<h4>Description</h4>
|
|
|
|
<p>Dumps the specified dbr data type to standard out.</p>
|
|
|
|
<h4>Arguments</h4>
|
|
<dl>
|
|
<dt><code>TYPE</code></dt>
|
|
<dd>The data type (from the DBR_XXX set described in db_access.h).</dd>
|
|
<dt><code>COUNT</code></dt>
|
|
<dd>The array element count</dd>
|
|
<dt><code>PDBR</code></dt>
|
|
<dd>A pointer to data of the specified count and number.</dd>
|
|
</dl>
|
|
<hr>
|
|
|
|
<h2><a name="Return">Return Codes</a></h2>
|
|
<dl>
|
|
<dt>ECA_NORMAL</dt>
|
|
<dd>Normal successful completion</dd>
|
|
<dt>ECA_ALLOCMEM</dt>
|
|
<dd>Unable to allocate additional dynamic memory</dd>
|
|
<dt>ECA_TOLARGE</dt>
|
|
<dd>The requested data transfer is greater than available memory or
|
|
EPICS_CA_MAX_ARRAY_BYTES</dd>
|
|
<dt>ECA_BADTYPE</dt>
|
|
<dd>The data type specified is invalid</dd>
|
|
<dt>ECA_BADSTR</dt>
|
|
<dd>Invalid string</dd>
|
|
<dt>ECA_BADCHID</dt>
|
|
<dd>Invalid channel identifier</dd>
|
|
<dt>ECA_BADCOUNT</dt>
|
|
<dd>Invalid element count requested</dd>
|
|
<dt>ECA_PUTFAIL</dt>
|
|
<dd>Channel write request failed</dd>
|
|
<dt>ECA_GETFAIL</dt>
|
|
<dd>Channel read request failed</dd>
|
|
<dt>ECA_ADDFAIL</dt>
|
|
<dd>unable to install subscription request</dd>
|
|
<dt>ECA_TIMEOUT</dt>
|
|
<dd>User specified timeout on IO operation expired</dd>
|
|
<dt>ECA_EVDISALLOW</dt>
|
|
<dd>function called was inappropriate for use within a callback
|
|
function</dd>
|
|
<dt>ECA_IODONE</dt>
|
|
<dd>IO operations have completed</dd>
|
|
<dt>ECA_IOINPROGRESS</dt>
|
|
<dd>IO operations are in progress</dd>
|
|
<dt>ECA_BADSYNCGRP</dt>
|
|
<dd>Invalid synchronous group identifier</dd>
|
|
<dt>ECA_NORDACCESS</dt>
|
|
<dd>Read access denied</dd>
|
|
<dt>ECA_NOWTACCESS</dt>
|
|
<dd>Write access denied</dd>
|
|
<dt>ECA_DISCONN</dt>
|
|
<dd>Virtual circuit disconnect"</dd>
|
|
<dt>ECA_DBLCHNL</dt>
|
|
<dd>Identical process variable name on multiple servers</dd>
|
|
<dt>ECA_EVDISALLOW</dt>
|
|
<dd>Request inappropriate within subscription (monitor) update callback</dd>
|
|
<dt>ECA_BADMONID</dt>
|
|
<dd>Bad event subscription (monitor) identifier</dd>
|
|
<dt>ECA_BADMASK</dt>
|
|
<dd>Invalid event selection mask</dd>
|
|
<dt>ECA_PUTCBINPROG</dt>
|
|
<dd>Put callback timed out</dd>
|
|
<dt>ECA_PUTCBINPROG</dt>
|
|
<dd>Put callback timed out</dd>
|
|
<dt>ECA_ANACHRONISM</dt>
|
|
<dd>Requested feature is no longer supported</dd>
|
|
<dt>ECA_NOSEARCHADDR</dt>
|
|
<dd>Empty PV search address list</dd>
|
|
<dt>ECA_NOCONVERT</dt>
|
|
<dd>No reasonable data conversion between client and server types</dd>
|
|
<dt>ECA_BADFUNCPTR</dt>
|
|
<dd>Invalid function pointer</dd>
|
|
<dt>ECA_ISATTACHED</dt>
|
|
<dd>Thread is already attached to a client context</dd>
|
|
<dt>ECA_UNAVAILINSERV</dt>
|
|
<dd>Not supported by attached service</dd>
|
|
<dt>ECA_CHANDESTROY</dt>
|
|
<dd>User destroyed channel</dd>
|
|
<dt>ECA_BADPRIORITY</dt>
|
|
<dd>Invalid channel priority</dd>
|
|
<dt>ECA_NOTTHREADED</dt>
|
|
<dd>Preemptive callback not enabled - additional threads may not join
|
|
context</dd>
|
|
<dt>ECA_16KARRAYCLIENT</dt>
|
|
<dd>Client's protocol revision does not support transfers exceeding 16k
|
|
bytes</dd>
|
|
</dl>
|
|
|
|
<p></p>
|
|
</body>
|
|
</html>
|