1969 lines
72 KiB
HTML
Executable File
1969 lines
72 KiB
HTML
Executable File
<! This document generated using mif2html Version 1.0 - Walt Akers - 1996 !>
|
|
<head>
|
|
<title>CDEV Documentation</title>
|
|
</head>
|
|
|
|
<body bgcolor="#E0E0FF">
|
|
|
|
<body>
|
|
<! ************************ FILE : cdevIntroductionTITLE.mif *****************************!>
|
|
<br><hr><br>
|
|
<table width=100%>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start ADDRESS ***!><font size=+12 color=Black><strong><em>
|
|
Introduction to CDEV
|
|
<!*** Finish ADDRESS ***!></p></strong></em></font>
|
|
<!*** Start ADDRESS-SUBHEAD ***!><font size=+2 color=Black><strong>
|
|
Overview of the Control Device Interface
|
|
</p>
|
|
|
|
<!*** Finish ADDRESS-SUBHEAD ***!></p></strong></font>
|
|
<!*** Start ADDRESS-VERSION ***!><font size=+2 color=Black>
|
|
Chip Watson, Jie Chen, Danjin Wu, Walt Akers
|
|
</p>
|
|
|
|
</p>
|
|
Version 1.5 December 9, 1996
|
|
</p>
|
|
|
|
</p>
|
|
TJNAF - Thomas Jefferson National Accelerator Facility
|
|
</p>
|
|
|
|
<!*** Finish ADDRESS-VERSION ***!></p></font>
|
|
</td></tr>
|
|
</table>
|
|
<! *************************** TABLE OF CONTENTS ****************************!>
|
|
<br><hr><br>
|
|
<table width=100%>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top align=center>
|
|
<!*** Start CLASS-TOC-TITLE ***!><font size=+3><strong>
|
|
Table of Contents
|
|
<!*** Finish CLASS-TOC-TITLE ***!></p></strong></font>
|
|
</td></tr>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<table>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
1.
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF1">Introduction</a>
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF2">What is CDEV</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF3">Layering and Abstraction</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF4">Information Hiding</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF5">Device Object</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF6">Standard Messages</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF7">Data Object</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
2.
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF8">Basic Operations on Devices and Data</a>
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
3.
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF9">Asychronous Operations</a>
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF10">Callback Object</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF11">System Object</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF12">Group Object</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF13">Request Object</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF14">File Descriptors and "select"</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
4.
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF15">Error Handling</a>
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
5.
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF16">Name Resolution</a>
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF17">cdevDirectory Object</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF18">Service Definition</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF19">Device Class Definition</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF20">Instance Definition</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF21">Aliases</a>
|
|
<!*** Finish UHEADING2TOC ***!><br></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
6.
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
|
<a href="cdevIntroduction.html#TOCREF22">Channel Access Service</a>
|
|
<!*** Finish HEADING1TOC ***!><br></font>
|
|
</td></tr>
|
|
</table>
|
|
</td></tr>
|
|
</table>
|
|
<! **************************** LIST OF FIGURES *****************************!>
|
|
<br><hr><br>
|
|
<table width=100%>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top align=center>
|
|
<!*** Start CLASS-LOF-TITLE ***!><font size=+3><strong>
|
|
List of Figures
|
|
<!*** Finish CLASS-LOF-TITLE ***!></p></strong></font>
|
|
</td></tr>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 1:
|
|
<a href="cdevIntroduction.html#LOFREF1">Sample usage of the send method of a cdevDevice</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 2:
|
|
<a href="cdevIntroduction.html#LOFREF2">Overview of cdevData operations</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 3:
|
|
<a href="cdevIntroduction.html#LOFREF3">Three forms of the send command</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 4:
|
|
<a href="cdevIntroduction.html#LOFREF4">Overview of the cdevCallback object and the cdevCallbackFunction</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 5:
|
|
<a href="cdevIntroduction.html#LOFREF5">Structure of the cdevCallback object</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 6:
|
|
<a href="cdevIntroduction.html#LOFREF6">Usage of the pend method in the cdevSystem object</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 7:
|
|
<a href="cdevIntroduction.html#LOFREF7">Synchronization methods in the cdevSystem object</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 8:
|
|
<a href="cdevIntroduction.html#LOFREF8">Sample usage of the cdevGroup object</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 9:
|
|
<a href="cdevIntroduction.html#LOFREF9">Sample usage of the cdevRequestObject object</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 10:
|
|
<a href="cdevIntroduction.html#LOFREF10">Structure of the cdevRequestObject object</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 11:
|
|
<a href="cdevIntroduction.html#LOFREF11">File descriptor routines of the cdevSystem object</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 12:
|
|
<a href="cdevIntroduction.html#LOFREF12">Using CDEV file descriptors with the UNIX select function</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 13:
|
|
<a href="cdevIntroduction.html#LOFREF13">Error handling mechanisms provided by the cdevSystem object</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 14:
|
|
<a href="cdevIntroduction.html#LOFREF14">Enumerated severity codes generated by CDEV</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 15:
|
|
<a href="cdevIntroduction.html#LOFREF15">Enumerated error codes generated by CDEV</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 16:
|
|
<a href="cdevIntroduction.html#LOFREF16">Obtaining a reference to the cdevDirectory device</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 17:
|
|
<a href="cdevIntroduction.html#LOFREF17">Virtual form of the data in a cdevDirectory</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 18:
|
|
<a href="cdevIntroduction.html#LOFREF18">Syntax of the #include directive</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 19:
|
|
<a href="cdevIntroduction.html#LOFREF19">Sample service definition</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 20:
|
|
<a href="cdevIntroduction.html#LOFREF20">Sample service definition</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 21:
|
|
<a href="cdevIntroduction.html#LOFREF21">Sample inherited class definition </a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 22:
|
|
<a href="cdevIntroduction.html#LOFREF22">Multiple instances of the magnet class</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
|
Figure 23:
|
|
<a href="cdevIntroduction.html#LOFREF23">Alias device name</a>
|
|
<!*** Finish FIGURELOF ***!><br></font>
|
|
</td></tr>
|
|
</table>
|
|
<! ************************ FILE : ./cdevIntroduction.mif *****************************!>
|
|
<br><hr><br>
|
|
<table width=100%>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
1.
|
|
<!*** Finish HEADING1 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
<a name="TOCREF1">
|
|
Introduction
|
|
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF2">
|
|
What is CDEV
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The CDEV (common device) C++ class library is an object-oriented framework that
|
|
provides a standard interface between an application and one or more underlying
|
|
control packages or systems. Each underlying package (called a service) is
|
|
dynamically loaded at run-time, allowing an application to access a new service by
|
|
name without re-compilation or re-linking. A major feature of CDEV is its ability to hide
|
|
the implementation details of a particular device from the high level application
|
|
developer. This allows server implementation choices to be changed without breaking
|
|
high level client applications. Additionally, because the application is unaware of the
|
|
underlying service's specific implementation, CDEV is a powerful vehicle for
|
|
developing portable applications.
|
|
</p>
|
|
The basic CDEV interface can be described through a <em>device</em>/<em>message</em> paradigm. The
|
|
<em>device</em> is not necessarily a physical object, rather, it is a cdevDevice object that
|
|
provides a standard interface to CDEV. The application uses this interface to send
|
|
messages to the device. When the cdevDevice receives this message it will
|
|
dynamically load the appropriate service (as defined in the CDEV device definition
|
|
file), and forward the message to it. The service may then perform any action
|
|
necessary to satisfy the application's request.
|
|
</p>
|
|
The CDEV API is optimized for repetitive operations, in particular for monitoring value
|
|
changes within a server. Asychronous operations with callbacks are supported,
|
|
including asychronous error notification. Specifically, CDEV supports most features of
|
|
channel access (the EPICS communications protocol).
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF3">
|
|
Layering and
|
|
Abstraction
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The CDEV library provides a standard interface to one or more underlying control
|
|
packages or systems. Currently CDEV provides support for EPICS channel access,
|
|
tcl scripts, the ACE communications package (a C++ class library over TCP/IP). The
|
|
ACE package is used to communicate with an on-line accelerator modeling package
|
|
and with CODA, the CEBAF On-line Data Acquisition system. Access to the EPICS
|
|
archive data will be added in a later release. All data will be available through a single
|
|
API (application programming interface).
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF4">
|
|
Information Hiding
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The ability to hide the implementation details of a particular device (such as the choice
|
|
of records in EPICS) from the high level application developer, allows server
|
|
implementation choices to be changed without breaking all high level client
|
|
applications. For example, several records may be merged into a new custom record
|
|
without changing applications which access those records through the CDEV API.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF5">
|
|
Device Object
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The basic idea behind CDEV is that all I/O is performed by sending messages to
|
|
devices. A device is a named entity in the control system which can respond to a set
|
|
of messages such as <em>on</em> or <em>off</em> or <em>get current</em>. Further, a device is a virtual entity
|
|
potentially spanning multiple servers and services such as channel access, an
|
|
archiver, and a static database.
|
|
</p>
|
|
Each device and message pair is mapped to a unique service (such as channel
|
|
access) and service dependent data (such as the process variable name in EPICS).
|
|
This mapping is kept in a name service, and is ultimately initialized from an ASCII file.
|
|
The designer/maintainer of the server would typically be the person responsible for
|
|
keeping the mapping current.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF6">
|
|
Standard
|
|
Messages
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Most devices will implement a number of attributes which may be read or written. In
|
|
order to facilitate developing generic applications, the following standard messages
|
|
are recommended for devices, where <em>attrib</em> is some attribute of the device:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
set <em>attrib</em> => Set the value of the attribute
|
|
get <em>attrib</em> => Get the value of the attribute
|
|
monitorOn <em>attrib</em> => Start monitoring the value of the attribute
|
|
monitorOff <em>attrib</em> => Stop monitoring the value of the attribute
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF7">
|
|
Data Object
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The message sent to the device may have an associated data object. For example,
|
|
the message <em>set current</em> will have an associated <em>value</em> for the new current setting. This
|
|
value is passed as an additional argument on the send call.
|
|
</p>
|
|
Data returned from the server to the client may contain multiple tagged values,
|
|
including <em>value</em>, <em>status</em>, and<em> timestamp</em>. Each of these items is extracted from the
|
|
returned data object by specifying a name or an integer tag. Any data object may
|
|
contain an arbitrary number of tagged entries, allowing considerable flexibility in
|
|
defining future clients and servers.
|
|
</p>
|
|
Acknowledgment: This work derives some of its ideas about devices and messages
|
|
from work done at Argonne by Claude Saunders on a device oriented layer above
|
|
channel access. Much additional analysis & design work has been done by members
|
|
of the EPICS collaboration.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
2.
|
|
<!*** Finish HEADING1 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
<a name="TOCREF8">
|
|
Basic Operations on Devices and Data
|
|
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The basic user deals only with the device and data objects. The device is created by
|
|
name, and I/O consists of sending messages to this device. The device object is the
|
|
simplest I/O object to use: a single device (magnet, viewer, etc.) may be completely
|
|
controlled from a single device object, with data being passed by 2 data objects (one
|
|
for output, another for returned results; dataless commands would not require either).
|
|
The following sample code reads the magnet current from one magnet, and sets the
|
|
magnet current for a second magnet to that value:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 1:
|
|
<a name="LOFREF1">
|
|
Sample usage of the send method of a cdevDevice
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
void main ()
|
|
{
|
|
// *************************************************************
|
|
// * Get references to the 2 devices
|
|
// *************************************************************
|
|
cdevDevice& mag1 = cdevDevice::attachRef ("Magnet1");
|
|
cdevDevice& mag2 = cdevDevice::attachRef ("Magnet2");
|
|
cdevData result;
|
|
|
|
// *************************************************************
|
|
// * Get the current from the first magnet and use it to set
|
|
// * the current on the second.
|
|
// *************************************************************
|
|
mag1.send("get current", NULL, result);
|
|
mag2.send("set current", result, NULL);
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 1>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
The send call, which is synchronous, takes 3 arguments, and returns an integer
|
|
status:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
int send(char* msg, cdevData& out, cdevData& result);
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Like all CDEV calls, a return code of 0 means success (error handling is described in
|
|
a later section). The first argument to <em>send</em> is a character string message. The device
|
|
name and this string uniquely determine the underlying service to use, and whatever
|
|
addressing data that service needs to locate the server. The first <em>send</em> operation
|
|
automatically connects to the requested service, initializing any underlying packages
|
|
as needed.
|
|
</p>
|
|
The second and third arguments are outbound and result data of type cdevData. This
|
|
is a composite data object which may contain an arbitrary number of data values
|
|
tagged with an integer tag. The data is self-describing to the extent that cdevData
|
|
keeps track of the data type, and can automatically convert between data types
|
|
through C++ function overloading or by explicit direction from the caller. The integer
|
|
tags are not known to the user at compile time (i.e., no header files required), and can
|
|
be referred to by character string equivalents. The cdevData class keeps track of all
|
|
integer tags and their character string equivalents. Character string tags may be
|
|
converted to integer tags at run time to improve performance. The following code
|
|
demonstrates how to insert values into and extract values from a cdevData object:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 2:
|
|
<a name="LOFREF2">
|
|
Overview of cdevData operations
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
cdevData d1, d2;
|
|
int valtag;
|
|
float x, x2;
|
|
int status;
|
|
...
|
|
d1.tagC2I("value",&valtag); // get the integer tag for "value"
|
|
...
|
|
d1.insert("value",37.9); // insert using a character tag
|
|
device.send("message",d1,d2); // send d1, get back d2
|
|
d2.get(valtag,&x); // get "value" from d2 into x
|
|
d2.get("status",&status); // extract the "status"
|
|
x2 = d2; // get "value" into x2 (= overload)
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 3>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
The last line above demonstrates using operator overloading to extract the "value"
|
|
item from the data object; i.e., the character tag "value" is the default tag to use in
|
|
extracting a data item for the "=" function overload. This form is available for all scalar
|
|
types supported by cdevData.
|
|
</p>
|
|
Most I/O operations use the "value" tag to transmit a single value (scalar or array).
|
|
Other commonly used tags are "status" and "time" (a POSIX time struct). These
|
|
tagged data items are optionally returned by some servers under the control of the I/O
|
|
context (see below for changing the default context).
|
|
</p>
|
|
In this release, cdevData supports the following data types: <em>unsigned char, short,
|
|
unsigned short, int, unsigned int, long, unsigned long, float, double</em>, <em>character strings</em>
|
|
and <em>time stamp. </em>All data types may be either scalar or multi-dimensional arrays.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
3.
|
|
<!*** Finish HEADING1 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
<a name="TOCREF9">
|
|
Asychronous Operations
|
|
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
In addition to the synchronous send, there are 2 asynchronous forms for sending
|
|
messages. The class definition for all three forms is given below.
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 3:
|
|
<a name="LOFREF3">
|
|
Three forms of the send command
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
class cdevDevice:
|
|
{
|
|
public:
|
|
int send (char* msg, cdevData& out, cdevData& result);
|
|
int sendNoBlock (char* msg, cdevData& out, cdevData& result);
|
|
int sendCallback (char* msg, cdevData& out, cdevCallback cb);
|
|
};
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 5>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
The second form, sendNoBlock, takes the same arguments as send but completes
|
|
asynchronously. That is, the result will be invalid until some synchronizing action is
|
|
taken (discussed below). The third form returns the result to a callback function
|
|
specified as part of the callback argument. For each of these asychronous calls, the
|
|
message may be buffered by the underlying service, so that upon return from the call
|
|
there is no guarantee that the message has even been sent yet. Transmission may be
|
|
forced with a flush call using the cdevSystem object described below. A flush is
|
|
automatically performed if pend is called.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF10">
|
|
Callback Object
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The callback object is a simple object containing 2 items: a function pointer, and an
|
|
arbitrary user argument. As an example, the following code fragment demonstrates
|
|
monitoring the magnet current asynchronously (the third argument to the callback
|
|
function is discussed later):
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 4:
|
|
<a name="LOFREF4">
|
|
Overview of the cdevCallback object and the cdevCallbackFunction
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
// declare the callback func
|
|
cdevCallbackFunction gotit;
|
|
|
|
// create callback object
|
|
cdevCallback callbk(gotit, myarg);
|
|
...
|
|
mag1.sendCallback("monitorOn current",NULL,callbk);
|
|
...
|
|
|
|
void gotit(int status, void* userarg, cdevRequestObject& reqobj,
|
|
cdevData& result)
|
|
{
|
|
float f = result;
|
|
printf("new value is %f\\n",f);
|
|
}
|
|
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 7>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
The following code defines the callback (the cdevRequestObject is described below):
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 5:
|
|
<a name="LOFREF5">
|
|
Structure of the cdevCallback object
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
typedef void (*cdevCallbackFunction)(int status, void* userarg,
|
|
cdevRequestObject& reqobj,
|
|
cdevData& result);
|
|
class cdevCallback
|
|
{
|
|
public:
|
|
cdevCallback (cdevCallbackFunction func, void* userarg);
|
|
cdevCallbackFunction function;
|
|
void* userarg;
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 9>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF11">
|
|
System Object
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Waiting for completion of asychronous operations may be accomplished in one of two
|
|
ways: (1) using groups, and (2) using the system object. The system object keeps
|
|
track of all devices, and contains methods for flushing, polling, and pending for
|
|
asychronous operations.
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 6:
|
|
<a name="LOFREF6">
|
|
Usage of the pend method in the cdevSystem object
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
// get default system
|
|
cdevSystem& sys = cdevSystem::defaultSystem();
|
|
...
|
|
mag1.sendNoBlock("on",...); // async op(s)
|
|
mag2.sendNoBlock("on",...); // async op(s)
|
|
...
|
|
sys.pend(); // wait for all I/O to complete
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 13>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
The following class interface shows the forms for each synchronization method:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 7:
|
|
<a name="LOFREF7">
|
|
Synchronization methods in the cdevSystem object
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
class cdevSystem
|
|
{
|
|
public:
|
|
intflush();
|
|
int poll();
|
|
intpend();
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 15>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
<em>flush</em>: Flush all pending output to the network for those services that perform send
|
|
buffering.
|
|
</p>
|
|
<em>poll:</em> Flush all pending output, and process all received replies (including dispatching
|
|
callbacks, if any). Any received monitor callbacks will be delivered as well.
|
|
</p>
|
|
<em>pend</em>: Flush all pending output, and process all replies for the specified number of
|
|
seconds. If the time argument is omitted, wait until all replies have been received. If a
|
|
monitor operation was started, this waits for the connection (first callback) only.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF12">
|
|
Group Object
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
An alternative mechanism for waiting for asychronous calls is through the use of
|
|
groups. A group keeps track off all I/O operations started from the time the group is
|
|
started until the group is ended. Groups may be nested or overlapped, and support
|
|
the same flush/poll/pend operations as the system object. For example:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 8:
|
|
<a name="LOFREF8">
|
|
Sample usage of the cdevGroup object
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
cdevGroup g1, g2;
|
|
...
|
|
g1.start();
|
|
mag1.sendCallback(...);
|
|
mag2.sendCallback(...);
|
|
g2.start();
|
|
bpm1.sendNoBlock(...);
|
|
bpm2.sendNoBlock(...);
|
|
g1.end();
|
|
mag3.sendCallback(...);
|
|
bpm3.sendNoBlock(...);
|
|
g2.end();
|
|
g1.pend(4.0);
|
|
// at this point operations on mag1, mag2, bpm1, & bpm2 are done
|
|
// or have timed out (error handling discussed later).
|
|
...
|
|
// mag3 and bpm3 may not be finished yet, pend on the second
|
|
// group to wait for their completion
|
|
g2.pend();
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 17>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
Note: Allowing nested or overlapped groups allows library calls to start or stop groups
|
|
without needing to know if another group is already active.
|
|
</p>
|
|
Groups may be operated in one of two modes. Immediate mode (default) causes
|
|
grouped operations to be immediately executed, and the group is just used for
|
|
completion synchronization. Deferred mode causes messages to be held back until
|
|
the group is ended and the operations are flushed. After the operations are complete,
|
|
he group of operations may be flushed again (without re-posting), allowing the group
|
|
to function as a list manager/executor.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF13">
|
|
Request Object
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Occasionally, an I/O operation may need to be repeated may times. In this case, it is
|
|
not efficient to parse the message each time to determine which server to use. It is
|
|
possible to bypass this parsing by creating a request object. The request object is like
|
|
the device object, except that the message string is specified at creation time, and the
|
|
request object is therefore specific to the particular underlying service to which that
|
|
message must be directed.
|
|
</p>
|
|
In the case of EPICS channel access, the request object opens and maintains the
|
|
channel to the EPICS process variable. The request object is NOT the same as an
|
|
EPICS channel, in that the request object binds a device and a message, and the
|
|
message implies a direction. If the message is considered to be of the form <em>verb</em> +
|
|
<em>attribute </em>then the EPICS channel essentially binds device and attribute but not verb. In
|
|
some future release of CDEV, a more channel like object may be included if there is a
|
|
demand for it. If two cdevRequestObjects reference the same EPICS channel, only a
|
|
single channel access connection is established.
|
|
</p>
|
|
The following code demonstrates sending a set of data values to a single magnet
|
|
using a request object. Note that the send call omits the message argument:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 9:
|
|
<a name="LOFREF9">
|
|
Sample usage of the cdevRequestObject object
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
cdevRequestObject& mag1BDL =
|
|
cdevRequestObject::attachRef("mag1","set BDL");
|
|
cdevData mydata;
|
|
...
|
|
{
|
|
mydata = i*10; // 10 amp steps
|
|
mag1BDL.send(mydata,NULL); // ignore errors for now
|
|
sleep(1);
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 19>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
In most cases, the device object will create the request object to perform a requested
|
|
I/O operation. All 3 forms of send are supported by the request object, with a calling
|
|
syntax identical to the device calls without the message argument. The interface to the
|
|
request object is given below:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 10:
|
|
<a name="LOFREF10">
|
|
Structure of the cdevRequestObject object
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
class cdevRequestObject
|
|
{
|
|
public:
|
|
char* message(); // returns the message string
|
|
cdevDevice& device(); // returns the device object
|
|
int state(); // connected/disconnected/
|
|
int access(); // read/write/none
|
|
int send(cdevData& out, cdevData& result);
|
|
int sendNoBlock(cdevData& out, cdevData& result);
|
|
int sendCallback(cdevData& out, cdevCallback callback);
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 21>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
When an asynchronous operation completes, the relevant request object is passed to
|
|
the user's callback routine. This allows the user to extract the message string and
|
|
device name from the request object if necessary or desired.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF14">
|
|
File Descriptors
|
|
and "select"
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
An alternative mechanism for dealing with asynchronous operations is to directly test
|
|
the file descriptors being used. This interface is currently implemented in the
|
|
cdevSystem class. The pertinent methods have the following form:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 11:
|
|
<a name="LOFREF11">
|
|
File descriptor routines of the cdevSystem object
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
typedef void (*cdevFdChangedCallback)(int fd, int opened,
|
|
void* userarg)
|
|
class cdevSystem
|
|
{
|
|
public:
|
|
...
|
|
int getFd(int fd[], int &numFD);
|
|
int addFdChangedCallback(cdevFdChangedCallback cbk, void* arg);
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 23>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The getFd method will populate a user allocated array of integers (fd) with the file
|
|
descriptors currently in use by the cdevSystem object. The number of file descriptors
|
|
that were allocated by the user is specified in the numFD variable. Upon completion,
|
|
the numFD variable will be set to the number of file descriptors actually copied into the
|
|
fd array. An error is returned if the buffer is not sufficient to store the complete set of
|
|
file descriptors.
|
|
</p>
|
|
The addFdChangedCallback method allows the user to specify a function to be called
|
|
each time a file descriptor is added (opened=1) or closed (opened=0).
|
|
</p>
|
|
The following code illustrates the usage of the UNIX select call:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 12:
|
|
<a name="LOFREF12">
|
|
Using CDEV file descriptors with the UNIX select function
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
int myFD[5];
|
|
|
|
void mySelectLoop ( cdevSystem & system )
|
|
{
|
|
int fd[20];
|
|
int numFD = 15, nfds;
|
|
fd_set rfds; // Ready file descriptors
|
|
fd_set afds; // Active file descriptors
|
|
|
|
// Copy the file descriptors I am already using to the list
|
|
memcpy(fd, myFD, sizeof(myFD));
|
|
|
|
// Get the file descriptors in use by the cdevSystem object
|
|
system.getFd(&fd[5], numFD);
|
|
|
|
// Add in the 5 previously defined file descriptors
|
|
numFD += 5;
|
|
|
|
// Zero the active file descriptors
|
|
FD_ZERO(&afds);
|
|
|
|
// Setup the active file descriptors
|
|
|
|
// Get the maximum number of file descriptors
|
|
nfds = FD_SETSIZE;
|
|
|
|
while(1) {
|
|
// Copy the active descriptors to the ready descriptors
|
|
memcpy((void *)&rfds, (void *)&afds, sizeof(rfds));
|
|
|
|
// Use select to detect activity on the file descriptors
|
|
|
|
// Iterate through the list of file descriptors
|
|
{
|
|
if (FD_ISSET(fd[i], &rfds)
|
|
{
|
|
// Respond to active file descriptor here
|
|
}
|
|
}
|
|
}
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 25>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
4.
|
|
<!*** Finish HEADING1 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
<a name="TOCREF15">
|
|
Error Handling
|
|
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Most CDEV routines return an integer status, with 0=success. Errors may also be
|
|
automatically printed or routed to a user supplied error handler. Control over this
|
|
behavior is through the system object:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 13:
|
|
<a name="LOFREF13">
|
|
Error handling mechanisms provided by the cdevSystem object
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
typedef void (*cdevErrorHandler)(int severity, char* text,
|
|
cdevRequestObject& request);
|
|
class cdevSystem
|
|
{
|
|
public:
|
|
...
|
|
int autoErrorOn();
|
|
int autoErrorOff();
|
|
cdevErrorHandler setErrorHandler(cdevErrorHandler handler = 0);
|
|
int reportError(int severity, char *name,
|
|
cdevRequestObject* request, char* format, ...);
|
|
void setThreshold ( int errorThreshold );
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 27>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
<em></em>
|
|
</p>
|
|
<em>The </em><em>severity </em><em>parameter indicates the </em>level of the error. Severity levels are informative,
|
|
warning, error, and severe error. The following values are defined in cdevErrCode.h to
|
|
describe the severity of an error message:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 14:
|
|
<a name="LOFREF14">
|
|
Enumerated severity codes generated by CDEV
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
CDEV_SEVERITY_INFO Informative message
|
|
|
|
CDEV_SEVERITY_WARN Warning message - operation encountered a
|
|
problem during processing.
|
|
|
|
CDEV_SEVERITY_ERROR Error message - operation cannot be completed
|
|
|
|
CDEV_SEVERITY_SEVERE Severe/Fatal Error - cdev cannot continue
|
|
execution
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 29>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
<em>autoErrorOn</em> Turn on default error handling, which prints error to stdout.
|
|
</p>
|
|
<em>autoErrorOff</em> Turn off default error handling.
|
|
</p>
|
|
<em>setErrorHandler</em> Set a new function to be the system error handler. Return the old
|
|
function pointer. Omitting the argument resets the handler to the default handler which
|
|
simply prints error messages to stderr.
|
|
</p>
|
|
<em>reportError</em> Routine which behaves like printf with 3 additional arguments (severity,
|
|
caller's name, and request object if available).
|
|
</p>
|
|
Note: For simplicity of use, a very compact set of error codes is implemented in CDEV.
|
|
The following error codes are defined in the header file cdevErrCode.h.
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 15:
|
|
<a name="LOFREF15">
|
|
Enumerated error codes generated by CDEV
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
CDEV_WARNING = -2 Failure of function is non-consequential
|
|
CDEV_ERROR = -1 Errors that are not in any categories
|
|
CDEV_SUCCESS = 0 Success
|
|
CDEV_INVALIDOBJ = 1 Invalid cdev objects
|
|
CDEV_INVALIDARG = 2 Invalid argument passed to cdev calls
|
|
CDEV_INVALIDSVC = 3 Wrong service during dynamic loading
|
|
CDEV_INVALIDOP = 4 Operation is unsupported (collection)
|
|
CDEV_NOTCONNECTED = 5 Not connected to low network service
|
|
CDEV_IOFAILED = 6 Low level network service IO failed
|
|
CDEV_CONFLICT = 7 Conflicts of data types or tags
|
|
CDEV_NOTFOUND = 8 Cannot find user request (cdevData)
|
|
CDEV_TIMEOUT = 9 Time out
|
|
CDEV_CONVERT = 10 cdevData Conversion error
|
|
CDEV_OUTOFRANGE = 11 Value out of range for device attribute
|
|
CDEV_NOACCESS = 12 Insufficient access to perform request
|
|
CDEV_ACCESSCHANGED = 13 Change in access permission of device
|
|
CDEV_DISCONNECTED = 60 Application has lost server connection
|
|
CDEV_RECONNECTED = 61 Application has regained server connection
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 31>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
5.
|
|
<!*** Finish HEADING1 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
<a name="TOCREF16">
|
|
Name Resolution
|
|
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Some type of name resolution system is needed to (1) locate which package (called a
|
|
service) underneath CDEV will support the specified message for the specified device
|
|
and (2) provide parameters needed by the service to contact the server and perform
|
|
the desired operation. For example, the message "get current" sent to a magnet
|
|
"mag1" might use the service "ca" (channel access), with parameter "mag1cur.val"
|
|
(record and field). This parameter is referred to as service data, i.e. data used by the
|
|
service to perform the operation. The user is typically unaware of this data, which
|
|
should be supplied by the device implementer.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF17">
|
|
cdevDirectory
|
|
Object
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Name resolution in CDEV is implemented by the <em>cdevDirectory</em> device. The
|
|
cdevDirectory device supports a <em>query</em> message allowing the user to search the
|
|
Device Directory List (DDL) for devices which are (1) members of a user specified
|
|
class or (2) match a user specified regular expression.
|
|
</p>
|
|
As with any cdevDevice object, the user instantiates a cdevDirectory device by using
|
|
the <em>cdevDevice::attachPtr() </em>or <em>cdevDevice::attachRef()</em> method. The following code
|
|
fragment illustrates the correct method for attaching to a cdevDirectory device.
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 16:
|
|
<a name="LOFREF16">
|
|
Obtaining a reference to the cdevDirectory device
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
cdevDevice & device = cdevDevice::attachRef("cdevDirectory");
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 11>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
Like all other devices, the cdevDirectory response to messages. The following
|
|
messages may be submitted to this device:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<table>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
query: Identify the devices that match the selection criteria.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
queryClass: Identify the DDL class from which a device is instantiated.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
queryAttributes: Identify all attributes supported by a device or a DDL class.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
queryMessages: Identify all messages supported by a device or DDL class.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
queryVerbs: Identify all verbs supported by a device or DDL class.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
service: Identify the service that is used by a device/message pair.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
serviceData: Identify service data specified for a device/message pair.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
update: Add information to the cdevDirectory data structure.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
validate: Verify that a device or DDL class contains certain definitions.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
</table>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
By default, there is a single directory device. To allow for arbitrary expansion CDEV
|
|
will allow each service to register additional directory devices with the system object.
|
|
A search list of directories may be specified to the system directory device (planned
|
|
feature).
|
|
</p>
|
|
Each directory acts as if it has a table of information in the following form:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 17:
|
|
<a name="LOFREF17">
|
|
Virtual form of the data in a cdevDirectory
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
dev-class dev-namemessageserviceservice-data
|
|
magnet mag1 on ca {pv=M1CSR.VAL default=1}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 33>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
This table is loaded from a device definition file which describes the mapping from
|
|
(device,message) to (service,serviceData), where "service" is one of the dynamically
|
|
loaded CDEV services, and "serviceData" is whatever information that service needs
|
|
to send the message to the device. In this example the service data contains an
|
|
EPICS process variable name and a default value to write to that channel.
|
|
</p>
|
|
It is NOT the purpose of the device definition file to completely specify the datatypes of
|
|
all data passed between device and user. CDEV does considerable data type
|
|
conversion as needed, and services do reasonable run-time validation. The goal is to
|
|
make the file as small as is reasonably possible and still maintain readability.
|
|
</p>
|
|
General:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<table>
|
|
<tr><td width=5% valign=top>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
leading whitespace is not significant
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
any amount of whitespace may separate language elements, including
|
|
space, tab, and newline, with the exception that at least one whitespace
|
|
character is needed before the colon separating a class name and its
|
|
inherited classes.
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
keywords are case sensitive
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
NOTE: This specification is preliminary, and will be expanded to support additional
|
|
features as time allows.
|
|
</p>
|
|
The interface definition consists of three parts: service definitions, device class
|
|
definitions, and device instantiation (in that order). Standard definitions may be
|
|
specified via include files using a cpp syntax:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 18:
|
|
<a name="LOFREF18">
|
|
Syntax of the #include directive
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
#include "filename"
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 35>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
</td></tr>
|
|
</table>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF18">
|
|
Service Definition
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The service definition declares a service name, and lists all tags which the service will
|
|
accept for its "serviceData". The following 3 lines define a service named "myservice"
|
|
which supports serviceData that specifies values for any of the tags "abc", "def", and
|
|
"ghi":
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 19:
|
|
<a name="LOFREF19">
|
|
Sample service definition
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
service myservice
|
|
{
|
|
tags {abc, def, ghi}
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 37>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
As a more concrete example, the following is the specification for thechannel access
|
|
service:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 20:
|
|
<a name="LOFREF20">
|
|
Sample service definition
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
service ca
|
|
{
|
|
tags {pv, default}
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 39>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
The "pv" tag is used to specify the process variable name, and the "default" tag is used
|
|
to specify a default value for a "set" operation (examples are below).
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF19">
|
|
Device Class
|
|
Definition
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Device classes are used to define a collection of similar devices; that is, devices which
|
|
will respond to the same set of messages. In order to simplify class definition, the
|
|
following design choices are made:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<table>
|
|
<tr><td width=5% valign=top>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
multiple inheritance is supported, and
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
messages may be defined as verb + attribute, where the list of verbs is
|
|
defined separately from the list of attributes.
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
The second item reduces the amount of text needed to define a device, since all
|
|
operations on a single attribute (get, set, monitor, etc.) may be defined in a single line
|
|
as long as they all use the same serviceData.
|
|
</p>
|
|
For this initial specification, the class definition contains 4 parts:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
inheritance specification
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
verbs
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
attributes
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
messages
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
For each attribute or message there are 3 parts:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
attribute or message text
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
service name
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start LISTBULLET2 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
service data
|
|
<!*** Finish LISTBULLET2 ***!></p></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Service data is zero or more (name=value) pairs, where the allowed set of names are
|
|
defined by the "tags" clause in the service specification. The value may contain a pair
|
|
of angle brackets "<>" into which the device name will be substituted.
|
|
</p>
|
|
Example: Suppose there are a set of magnets for which it is possible to read and write
|
|
bdl (integral field), and current (amps). That is, the messages "get bdl", "get current",
|
|
"set bdl", etc. are valid. Also, each magnet responds to the commands "on" and "off".
|
|
Further suppose that the beamline position and length of the magnet are available in a
|
|
static database (assume read/write).
|
|
</p>
|
|
Here is a complete class definition:
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 21:
|
|
<a name="LOFREF21">
|
|
Sample inherited class definition
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
class stdio
|
|
{
|
|
verbs {get, set, monitorOn, monitorOff}
|
|
}
|
|
|
|
class magnet : stdio
|
|
{
|
|
attributes
|
|
{
|
|
bdl ca {pv=<>.bdl};
|
|
current ca {pv=<>.val};
|
|
zpos os {path=<>/phy/z};
|
|
length os {path=<>/phy/len}
|
|
}
|
|
messages
|
|
{
|
|
on ca {pv=<>CSR.val, default=1};
|
|
off ca {pv=<>CSR.val, default=0};
|
|
}
|
|
}
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 41>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
Note the semicolon at the end of each line of attributes or messages (except for the
|
|
last line). Note also that the process variable name has a place holder into which the
|
|
device name will be substituted. More sophisticated name mangling is envisaged, but
|
|
not for this release. Syntax is still open to revision.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
</table>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF20">
|
|
Instance Definition
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Instances of a class are given by following the class name with a list of instance
|
|
names. Device names may be separated by whitespace characters (including
|
|
newline) or by commas.
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 22:
|
|
<a name="LOFREF22">
|
|
Multiple instances of the magnet class
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
magnet : m1 m2 m3;
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 43>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
Combined with the previous definition, the message "on" sent to magnet m2 would
|
|
select the process variable "m2CSR.val" with "1" as the value to write.
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
|
<a name="TOCREF21">
|
|
Aliases
|
|
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Sometimes it is convenient to refer to a device by more than one name. The DDL
|
|
syntax supports simple aliases, one per line.
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
|
Figure 23:
|
|
<a name="LOFREF23">
|
|
Alias device name
|
|
<table border=1><tr><td>
|
|
<table>
|
|
<tr><td>
|
|
<! ***** Empty Column ***** !>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black>
|
|
alias myname m1
|
|
<!*** Finish PROGRAM ***!></font></pre>
|
|
</td></tr>
|
|
</table>
|
|
</tr></td></table>
|
|
<AFrame 45>
|
|
</a> <!*** Finish FIGURE ***!></p></em></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top align=right>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
6.
|
|
<!*** Finish HEADING1 ***!></p></strong></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
|
<a name="TOCREF22">
|
|
Channel Access Service
|
|
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
EPICS / Channel Access version 3.12 is recommended.
|
|
</p>
|
|
Features:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<table>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
Supports synchronous and asynchronous send's.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
Tracks file descriptor registration.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
Fetches data in native type (type conversion done on client and not server).
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
Provides a default name service so that if a device is not defined, then an
|
|
EPICS channel access connection is attempted with the record name set equal
|
|
to the device name, and the field name set equal to the attribute name.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
</table>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Restrictions:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<table>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
Only supports set/get/monitorOn/monitorOff verbs and the pv and readonly
|
|
tags. Support for arbitrary messages with default data will be in the next release.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
Discards all exception callbacks from channel access in this version.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
Channel access security is not supported in this release.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
</table>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
Compilation options:
|
|
<!*** Finish BODY ***!></p></font>
|
|
<table>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
_CA_SYNC_CONN = perform connections synchronously, waiting up to 4
|
|
seconds.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
_CDEV_DEBUG = print verbose messages
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
<tr><td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
<img src="bullet.jpg">
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td>
|
|
<td valign=top>
|
|
<!*** Start LISTBULLET1 ***!><font size=+1 color=Black>
|
|
_EPICS_3_12 = if not defined, use 3.11 calls instead.
|
|
<!*** Finish LISTBULLET1 ***!></p></font>
|
|
</td></tr>
|
|
</table>
|
|
<!*** Start BODY ***!><font size=+1 color=Black>
|
|
|
|
</p>
|
|
|
|
<!*** Finish BODY ***!></p></font>
|
|
</td></tr>
|
|
</table>
|
|
</body>
|