Compare commits
100 Commits
R3.12.2.1
...
R3.13.0-al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97dc3b8899 | ||
|
|
13a5f820c6 | ||
|
|
da20e059f7 | ||
|
|
2c5958f022 | ||
|
|
a9cad7df54 | ||
|
|
42f6f3c9ce | ||
|
|
87a9b22a15 | ||
|
|
012180ab65 | ||
|
|
ad2128b691 | ||
|
|
7e8bdc7e43 | ||
|
|
e1042ca5ee | ||
|
|
2390c0ace5 | ||
|
|
17989d29fe | ||
|
|
92b1b34e02 | ||
|
|
427ea50c50 | ||
|
|
cdd3e932fb | ||
|
|
3e0445f2ad | ||
|
|
bbbc3b6329 | ||
|
|
14d712b57c | ||
|
|
a6d0a677ee | ||
|
|
b258b2fc14 | ||
|
|
535ef14cf8 | ||
|
|
5a983c11cb | ||
|
|
8bd797aa5b | ||
|
|
28797e7a1a | ||
|
|
2a3fc15e9e | ||
|
|
9fae1fa33c | ||
|
|
13ff432956 | ||
|
|
461584c4d1 | ||
|
|
59e1ef1d77 | ||
|
|
359225dd34 | ||
|
|
6dceef4956 | ||
|
|
81eac9ddec | ||
|
|
3e1e1ae6aa | ||
|
|
3ed241a857 | ||
|
|
6e37e4a8b7 | ||
|
|
45910c7eae | ||
|
|
ab72202752 | ||
|
|
b728e45751 | ||
|
|
8b4249b582 | ||
|
|
bf260930ea | ||
|
|
e460c225da | ||
|
|
4a07ca3a11 | ||
|
|
2aeca30e8f | ||
|
|
6ad8e0f575 | ||
|
|
18822cda96 | ||
|
|
acaa1b6fbf | ||
|
|
38875dd8a7 | ||
|
|
af39a62adc | ||
|
|
fc981f3f7b | ||
|
|
f726540476 | ||
|
|
759d10c50e | ||
|
|
27d9d4d708 | ||
|
|
8643ae7413 | ||
|
|
f04b9fd8d3 | ||
|
|
574eb184cf | ||
|
|
ff33b704aa | ||
|
|
b23500efe6 | ||
|
|
14f0ea61dd | ||
|
|
6dc0835a7d | ||
|
|
ade952f351 | ||
|
|
dd34fb320b | ||
|
|
86e4be2f04 | ||
|
|
06626adbb8 | ||
|
|
5a32f7143d | ||
|
|
717ace8079 | ||
|
|
95294e2f3e | ||
|
|
341ec908c2 | ||
|
|
f91c3356ab | ||
|
|
6b6ef88793 | ||
|
|
adea6a0894 | ||
|
|
866e676a7a | ||
|
|
a8da2b9da4 | ||
|
|
ff6d6cb70a | ||
|
|
d205dc9b10 | ||
|
|
777e2d093d | ||
|
|
dbfab6b29e | ||
|
|
ecaaeb439a | ||
|
|
a635590f31 | ||
|
|
795b9645c9 | ||
|
|
fcf601fbf1 | ||
|
|
b95596f602 | ||
|
|
d0766a4f38 | ||
|
|
a650cd3ca2 | ||
|
|
96bd0f11c9 | ||
|
|
aaa2580224 | ||
|
|
84f32df855 | ||
|
|
79baa59608 | ||
|
|
853031bc90 | ||
|
|
c3734dcfee | ||
|
|
f2a8150e2d | ||
|
|
5b8ef5a985 | ||
|
|
3aff8d6754 | ||
|
|
c12944df48 | ||
|
|
a09ab523bb | ||
|
|
c02903d397 | ||
|
|
33608d5c23 | ||
|
|
293294cb48 | ||
|
|
03104dd373 | ||
|
|
6a922b6515 |
21
COPYRIGHT_Combined
Normal file
21
COPYRIGHT_Combined
Normal file
@@ -0,0 +1,21 @@
|
||||
/* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
***********************************************************************/
|
||||
28
MakeRelease
28
MakeRelease
@@ -10,6 +10,12 @@
|
||||
# [-b] - For fully built release
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.4 1996/02/20 21:03:53 jba
|
||||
# Updated README files to reflect directory changes and new installEpics.
|
||||
#
|
||||
# Revision 1.3 1995/10/03 15:42:26 jba
|
||||
# Added *COPYRIGHT* files to release tar file.
|
||||
#
|
||||
# Revision 1.2 1995/08/28 15:49:54 jba
|
||||
# Added startup directory to release tar file
|
||||
#
|
||||
@@ -54,8 +60,8 @@
|
||||
|
||||
EPICS=${1};
|
||||
|
||||
if [ ! -d include -o ! -d src ]; then
|
||||
echo "Cannot find src or include, are you at the top of EPICS base ?"
|
||||
if [ ! -d src ]; then
|
||||
echo "Cannot find src directory, are you at the top of EPICS base ?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -67,8 +73,8 @@ if [ "${2}" = "-b" ]; then
|
||||
shift
|
||||
fi
|
||||
|
||||
# Retrieve EPICS release string from include/epicsVersion.h
|
||||
grep EPICS_VERSION_STRING include/epicsVersion.h > /dev/null 2>&1 || ERR=1;
|
||||
# Retrieve EPICS release string from src/include/epicsVersion.h
|
||||
grep EPICS_VERSION_STRING src/include/epicsVersion.h > /dev/null 2>&1 || ERR=1;
|
||||
|
||||
if [ "$ERR" = "1" ];
|
||||
then
|
||||
@@ -76,7 +82,7 @@ if [ "$ERR" = "1" ];
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
RELS=`grep "EPICS_VERSION_STRING" include/epicsVersion.h \
|
||||
RELS=`grep "EPICS_VERSION_STRING" src/include/epicsVersion.h \
|
||||
| sed -e 's-.*Version--' \
|
||||
-e 's-[ ][ ]*--g' \
|
||||
-e 's-".*--' \
|
||||
@@ -84,7 +90,7 @@ RELS=`grep "EPICS_VERSION_STRING" include/epicsVersion.h \
|
||||
|
||||
if [ -z "${RELS}" ];
|
||||
then
|
||||
echo "TOP: Cannot retrieve release number from include/epicsVersion.h";
|
||||
echo "TOP: Cannot retrieve release number from src/include/epicsVersion.h";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
@@ -95,7 +101,7 @@ echo TOP: Creating ../${RELS}.Tar;
|
||||
if [ -f ${RELS}.Tar* ];
|
||||
then
|
||||
echo "TOP: This release has already been created.";
|
||||
echo "TOP: Remove Tar file or edit include/epicsVersion.h.";
|
||||
echo "TOP: Remove Tar file or edit src/include/epicsVersion.h.";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
@@ -115,12 +121,18 @@ if [ -d startup ];
|
||||
>> /tmp/make_release.out.$$;
|
||||
fi
|
||||
|
||||
find config base/include base/man base/tools -name CVS -prune -o \
|
||||
find config -name CVS -prune -o \
|
||||
! -type d -print >> /tmp/make_release.out.$$;
|
||||
|
||||
# binary / library / default.dctsdr / <rec>Record.h / etc.
|
||||
if [ $FULLY_BUILT = "YES" ];
|
||||
then
|
||||
find base/include -name CVS -prune -o ! -type d -print \
|
||||
>> /tmp/make_release.out.$$;
|
||||
|
||||
find base/man -name CVS -prune -o ! -type d -print \
|
||||
>> /tmp/make_release.out.$$;
|
||||
|
||||
find base/bin -name CVS -prune -o ! -type d -print \
|
||||
>> /tmp/make_release.out.$$;
|
||||
|
||||
|
||||
55
Makefile
55
Makefile
@@ -12,6 +12,16 @@
|
||||
# install because the release.% syntax is illegal.
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.26 1996/01/25 21:37:09 mrk
|
||||
# uninstall base/man
|
||||
#
|
||||
# Revision 1.25 1996/01/25 21:29:42 mrk
|
||||
# base/rec=>base/db base/include now installed
|
||||
#
|
||||
# Revision 1.24 1995/08/17 20:14:59 jba
|
||||
# Added base/tools scripts functionality to base/Makefile, removed scripts
|
||||
# Moved base/tools/MakeRelease to base dir.
|
||||
#
|
||||
# Revision 1.23 1995/02/13 15:00:09 jba
|
||||
# Changed include file from CONFIG_SITE to CONFIG
|
||||
#
|
||||
@@ -57,39 +67,29 @@ include $(EPICS)/config/CONFIG
|
||||
all: install
|
||||
|
||||
build:
|
||||
@(for ARCH in ${BUILD_ARCHS}; \
|
||||
do \
|
||||
ARCH_TYPE=$$ARCH \
|
||||
${MAKE} ${MFLAGS} $@.$$ARCH; \
|
||||
done)
|
||||
@(for ARCH in ${BUILD_ARCHS}; do \
|
||||
${MAKE} $@.$${ARCH}; \
|
||||
done)
|
||||
|
||||
install:
|
||||
@(for ARCH in ${BUILD_ARCHS}; \
|
||||
do \
|
||||
ARCH_TYPE=$$ARCH \
|
||||
${MAKE} ${MFLAGS} $@.$$ARCH; \
|
||||
done)
|
||||
@(for ARCH in ${BUILD_ARCHS}; do \
|
||||
${MAKE} $@.$${ARCH}; \
|
||||
done)
|
||||
|
||||
depends:
|
||||
@(for ARCH in ${BUILD_ARCHS}; \
|
||||
do \
|
||||
ARCH_TYPE=$$ARCH \
|
||||
${MAKE} ${MFLAGS} $@.$$ARCH; \
|
||||
done)
|
||||
@(for ARCH in ${BUILD_ARCHS}; do \
|
||||
${MAKE} $@.$${ARCH}; \
|
||||
done)
|
||||
|
||||
clean:
|
||||
@(for ARCH in ${BUILD_ARCHS}; \
|
||||
do \
|
||||
ARCH_TYPE=$$ARCH \
|
||||
${MAKE} ${MFLAGS} $@.$$ARCH; \
|
||||
done)
|
||||
@(for ARCH in ${BUILD_ARCHS}; do \
|
||||
${MAKE} $@.$${ARCH}; \
|
||||
done)
|
||||
|
||||
uninstall:
|
||||
@(for ARCH in ${BUILD_ARCHS}; \
|
||||
do \
|
||||
ARCH_TYPE=$$ARCH \
|
||||
${MAKE} ${MFLAGS} $@.$$ARCH; \
|
||||
done)
|
||||
@(for ARCH in ${BUILD_ARCHS}; do \
|
||||
${MAKE} $@.$${ARCH}; \
|
||||
done)
|
||||
|
||||
release:
|
||||
@echo TOP: Creating Release...
|
||||
@@ -138,9 +138,12 @@ release.%:
|
||||
|
||||
uninstall.%:
|
||||
@echo "TOP: Uninstalling $* "
|
||||
@rm -rf ./bin/$* ./lib/$* rec.bak rec
|
||||
@rm -rf ./bin/$* ./lib/$* db include man
|
||||
@rm -rf rec.bak rec
|
||||
|
||||
clean.%:
|
||||
@echo "TOP: Cleaning $* "
|
||||
@find src -type d -name "O.$*" -prune -exec rm -rf {} \;
|
||||
|
||||
|
||||
|
||||
|
||||
14
README
14
README
@@ -13,7 +13,7 @@ Notes:
|
||||
|
||||
2. You must use GNU make (which is now THE supported make utility) for
|
||||
the build, gnumake. Set your path so that a recent version (e.g.
|
||||
V3.70) of gnumake is available (as make) before any system supplied makes.
|
||||
V3.70) of gnumake is available.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Part 1 - Configuring and Building EPICS Base
|
||||
@@ -42,8 +42,8 @@ Notes:
|
||||
|
||||
cd epics/base
|
||||
gnumake - To build and install EPICS.
|
||||
gnumake clean - To clean temporary object files. Clean will
|
||||
remove files from ALL O.ARCH dirs, not
|
||||
gnumake clean - To clean temporary object files. Top level
|
||||
clean will remove all the O.ARCH dirs, not
|
||||
only those specified in BUILD_ARCHS.
|
||||
|
||||
1.4 To create an EPICS release:
|
||||
@@ -68,8 +68,8 @@ NOTES:
|
||||
base. These tar files are then meant to be untarred at that level.
|
||||
This release will include the "epics/config" directory.
|
||||
|
||||
2. EPICS binaries are kept in the bin/ARCH and lib/ARCH directories.
|
||||
EPICS shellscripts are kept in the tools directory.
|
||||
2. EPICS binaries and shellscripts are installed into the bin/ARCH and
|
||||
lib/ARCH directories.
|
||||
|
||||
3. During a normal build (a "make" or "make install"), the "depends"
|
||||
dependency will NOT be invoked. Only if "make depends" is run
|
||||
@@ -99,7 +99,9 @@ CONFIG_SITE - This file is meant to be changed only by the EPICS system
|
||||
manager. It specifies:
|
||||
|
||||
HOST_ARCH: The system's host architecture (sun4/hp700/etc).
|
||||
BUILD_ARCHS: List of architectures to be built.
|
||||
This now come from an environment variable.
|
||||
CROSS_COMPILER_HOST_ARCHS: List of unix architectures with cross_compilers.
|
||||
CROSS_COMPILER_TARGET_ARCHS: List of architectures to build epics for.
|
||||
VX_DIR: Location of vxWorks.
|
||||
STATIC_BUILD: Whether or not to build clients statically.
|
||||
etc.
|
||||
|
||||
13
README.Linux
13
README.Linux
@@ -8,18 +8,7 @@
|
||||
|
||||
2) At this point, support for Linux only involves channel access
|
||||
clients. Since Vxworks is not available for Linux, you must
|
||||
use other platforms for developing server side code. As for
|
||||
building databases with dct and gdct, this requires that the
|
||||
$EPICS/base/tools/makesdr script works properly. Since makesdr
|
||||
is slated to be removed from the EPICS distribution in a future
|
||||
release, we didn't feel it was important to include this capability
|
||||
now. Consequently, when you run make you will receive the error
|
||||
|
||||
gnumake[4]: *** [bldDefaultSdr] Error 127
|
||||
|
||||
and
|
||||
|
||||
gnumake[3]: *** [comsubs.o] Error 1
|
||||
use other platforms for developing server side code.
|
||||
|
||||
3) You MUST start caRepeater by hand before running a client.
|
||||
Prior to running a client, you must run:
|
||||
|
||||
@@ -10,5 +10,3 @@
|
||||
|
||||
might be necessary.
|
||||
|
||||
- epics/base/tools/bsdinstall was written to replace install for hp.
|
||||
|
||||
|
||||
@@ -11,9 +11,8 @@ solaris directory /usr/ccs/bin is in your search path.
|
||||
2. It is not possible to compile EPICS under Solaris 2 using only the
|
||||
GNU gcc compiler -- you must have the Sun SPARCworks ANSI C compiler.
|
||||
|
||||
3. EPICS under Solaris 2 no longer uses the UCB compatability
|
||||
libraries. It does require the /usr/ucb/install program however. In
|
||||
order to ensure that the /usr/ucblib files are not inherited, you
|
||||
3. EPICS under Solaris 2 no longer uses the UCB compatability libraries.
|
||||
In order to ensure that the /usr/ucblib files are not inherited, you
|
||||
should ensure that your LD_LIBRARY_PATH environment variable does not
|
||||
include /usr/ucblib when you build any of the host tools.
|
||||
|
||||
|
||||
11
SkeletonCOPYRIGHT_Combined
Normal file
11
SkeletonCOPYRIGHT_Combined
Normal file
@@ -0,0 +1,11 @@
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1991 Regents of the University of California,
|
||||
and the University of Chicago Board of Governors.
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_Combined file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
@@ -11,6 +11,9 @@ DEPLIBS = ./libAs.a\
|
||||
$(DEPLIBS_BASE)/libCom.a\
|
||||
$(DEPLIBS_BASE)/libDb.a
|
||||
|
||||
INC += asDbLib.h
|
||||
INC += asLib.h
|
||||
|
||||
SRCS.c = ../ascheck.c asLib.c
|
||||
OBJS = ascheck.o
|
||||
LIBOBJS = asLib.o
|
||||
|
||||
@@ -131,7 +131,6 @@ LOCAL void eventCallback(struct event_handler_args eha)
|
||||
struct dbr_sts_double *pdata = eha.dbr;
|
||||
int Ilocked=FALSE;
|
||||
|
||||
|
||||
if(!caInitializing) {
|
||||
FASTLOCK(&asLock);
|
||||
Ilocked = TRUE;
|
||||
|
||||
@@ -184,8 +184,9 @@ static long asInitCommon(void)
|
||||
int asInit(void)
|
||||
{
|
||||
|
||||
asInitCommon();
|
||||
return(0);
|
||||
/*If no access configuration file defined return success*/
|
||||
if(!pacf) return(0);
|
||||
return(asInitCommon());
|
||||
}
|
||||
|
||||
static void wdCallback(ASDBCALLBACK *pcallback)
|
||||
@@ -300,7 +301,10 @@ ASMEMBERPVT asDbGetMemberPvt(void *paddress)
|
||||
|
||||
static void astacCallback(ASCLIENTPVT clientPvt,asClientStatus status)
|
||||
{
|
||||
printf("astac callback: status=%d",status);
|
||||
char *recordname;
|
||||
|
||||
recordname = (char *)asGetClientPvt(clientPvt);
|
||||
printf("astac callback %s: status=%d",recordname,status);
|
||||
printf(" get %s put %s\n",(asCheckGet(clientPvt) ? "Yes" : "No"),
|
||||
(asCheckPut(clientPvt) ? "Yes" : "No"));
|
||||
}
|
||||
@@ -328,6 +332,7 @@ int astac(char *pname,char *user,char *location)
|
||||
errMessage(status,"asAddClient error");
|
||||
return(1);
|
||||
} else {
|
||||
asPutClientPvt(*pasclientpvt,(void *)precord->name);
|
||||
asRegisterClientCallback(*pasclientpvt,astacCallback);
|
||||
}
|
||||
return(0);
|
||||
|
||||
78
src/as/asDbLib.h
Normal file
78
src/as/asDbLib.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* share/epicsH/dbAsLib.h */
|
||||
/* $Id$ */
|
||||
/* Author: Marty Kraimer Date: 02-23-94*/
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE,
|
||||
AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE
|
||||
AND IN ALL SOURCE LISTINGS OF THE CODE.
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
Argonne National Laboratory (ANL), with facilities in the States of
|
||||
Illinois and Idaho, is owned by the United States Government, and
|
||||
operated by the University of Chicago under provision of a contract
|
||||
with the Department of Energy.
|
||||
|
||||
Portions of this material resulted from work developed under a U.S.
|
||||
Government contract and are subject to the following license: For
|
||||
a period of five years from March 30, 1993, the Government is
|
||||
granted for itself and others acting on its behalf a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, and perform
|
||||
publicly and display publicly. With the approval of DOE, this
|
||||
period may be renewed for two additional five year periods.
|
||||
Following the expiration of this period or periods, the Government
|
||||
is granted for itself and others acting on its behalf, a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, distribute copies
|
||||
to the public, perform publicly and display publicly, and to permit
|
||||
others to do so.
|
||||
|
||||
*****************************************************************
|
||||
DISCLAIMER
|
||||
*****************************************************************
|
||||
|
||||
NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR
|
||||
THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS,
|
||||
MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
|
||||
LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
|
||||
USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS
|
||||
DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
|
||||
OWNED RIGHTS.
|
||||
|
||||
*****************************************************************
|
||||
LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
|
||||
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 02-23-94 mrk Initial Implementation
|
||||
*/
|
||||
|
||||
#ifndef INCdbAsLibh
|
||||
#define INCdbAsLibh
|
||||
#include <asLib.h>
|
||||
#include <callback.h>
|
||||
|
||||
typedef struct {
|
||||
CALLBACK callback;
|
||||
long status;
|
||||
} ASDBCALLBACK;
|
||||
|
||||
int asSetFilename(char *acf);
|
||||
int asInit(void);
|
||||
int asInitAsyn(ASDBCALLBACK *pcallback);
|
||||
int asDbGetAsl( void *paddr);
|
||||
ASMEMBERPVT asDbGetMemberPvt( void *paddr);
|
||||
int asdbdump( void);
|
||||
int aspuag(char *uagname);
|
||||
int asphag(char *hagname);
|
||||
int asprules(char *asgname);
|
||||
int aspmem(char *asgname,int clients);
|
||||
void asCaStart(void);
|
||||
void asCaStop(void);
|
||||
|
||||
#endif /*INCdbAsLibh*/
|
||||
223
src/as/asLib.h
Normal file
223
src/as/asLib.h
Normal file
@@ -0,0 +1,223 @@
|
||||
/* $Id$ */
|
||||
/* Author: Marty Kraimer Date: 09-27-93*/
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE,
|
||||
AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE
|
||||
AND IN ALL SOURCE LISTINGS OF THE CODE.
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
Argonne National Laboratory (ANL), with facilities in the States of
|
||||
Illinois and Idaho, is owned by the United States Government, and
|
||||
operated by the University of Chicago under provision of a contract
|
||||
with the Department of Energy.
|
||||
|
||||
Portions of this material resulted from work developed under a U.S.
|
||||
Government contract and are subject to the following license: For
|
||||
a period of five years from March 30, 1993, the Government is
|
||||
granted for itself and others acting on its behalf a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, and perform
|
||||
publicly and display publicly. With the approval of DOE, this
|
||||
period may be renewed for two additional five year periods.
|
||||
Following the expiration of this period or periods, the Government
|
||||
is granted for itself and others acting on its behalf, a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, distribute copies
|
||||
to the public, perform publicly and display publicly, and to permit
|
||||
others to do so.
|
||||
|
||||
*****************************************************************
|
||||
DISCLAIMER
|
||||
*****************************************************************
|
||||
|
||||
NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR
|
||||
THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS,
|
||||
MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
|
||||
LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
|
||||
USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS
|
||||
DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
|
||||
OWNED RIGHTS.
|
||||
|
||||
*****************************************************************
|
||||
LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
|
||||
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 09-27-93 mrk Initial Implementation
|
||||
*/
|
||||
#ifndef INCasLibh
|
||||
#define INCasLibh
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <errMdef.h>
|
||||
#include <ellLib.h>
|
||||
|
||||
typedef struct asgMember *ASMEMBERPVT;
|
||||
typedef struct asgClient *ASCLIENTPVT;
|
||||
typedef int (*ASINPUTFUNCPTR)(char *buf,int max_size);
|
||||
typedef enum{
|
||||
asClientCOAR /*Change of access rights*/
|
||||
/*For now this is all*/
|
||||
} asClientStatus;
|
||||
typedef void (*ASCLIENTCALLBACK) (ASCLIENTPVT,asClientStatus);
|
||||
/* The following routines are macros with the following syntax
|
||||
long asCheckGet(ASCLIENTPVT asClientPvt);
|
||||
long asCheckPut(ASCLIENTPVT asClientPvt);
|
||||
end of macros
|
||||
*/
|
||||
int asInit(void);
|
||||
long asInitialize(ASINPUTFUNCPTR inputfunction);
|
||||
/*caller must provide permanent storage for asgName*/
|
||||
long asAddMember(ASMEMBERPVT *asMemberPvt,char *asgName);
|
||||
long asRemoveMember(ASMEMBERPVT *asMemberPvt);
|
||||
/*caller must provide permanent storage for newAsgName*/
|
||||
long asChangeGroup(ASMEMBERPVT *asMemberPvt,char *newAsgName);
|
||||
void *asGetMemberPvt(ASMEMBERPVT asMemberPvt);
|
||||
void asPutMemberPvt(ASMEMBERPVT asMemberPvt,void *userPvt);
|
||||
/*client must provide permanent storage for user and host*/
|
||||
long asAddClient(ASCLIENTPVT *asClientPvt,ASMEMBERPVT asMemberPvt,
|
||||
int asl,char *user,char *host);
|
||||
/*client must provide permanent storage for user and host*/
|
||||
long asChangeClient(ASCLIENTPVT asClientPvt,int asl,char *user,char *host);
|
||||
long asRemoveClient(ASCLIENTPVT *asClientPvt);
|
||||
void *asGetClientPvt(ASCLIENTPVT asClientPvt);
|
||||
void asPutClientPvt(ASCLIENTPVT asClientPvt,void *userPvt);
|
||||
long asRegisterClientCallback(ASCLIENTPVT asClientPvt,
|
||||
ASCLIENTCALLBACK pcallback);
|
||||
long asComputeAllAsg(void);
|
||||
/*asComputeAsg is defined after ASG is defined*/
|
||||
long asCompute(ASCLIENTPVT asClientPvt);
|
||||
int asDump(void (*memcallback)(ASMEMBERPVT),void (*clientcallback)(ASCLIENTPVT),int verbose);
|
||||
int asDumpUag(char *uagname);
|
||||
int asDumpHag(char *hagname);
|
||||
int asDumpRules(char *asgname);
|
||||
int asDumpMem(char *asgname,void (*memcallback)(ASMEMBERPVT),int clients);
|
||||
int asDumpHash(void);
|
||||
|
||||
#define S_asLib_clientsExist (M_asLib| 1) /*Client Exists*/
|
||||
#define S_asLib_noUag (M_asLib| 2) /*User Access Group does not exist*/
|
||||
#define S_asLib_noHag (M_asLib| 3) /*Host Access Group does not exist*/
|
||||
#define S_asLib_noAccess (M_asLib| 4) /*access security: no access allowed*/
|
||||
#define S_asLib_noModify (M_asLib| 5) /*access security: no modification allowed*/
|
||||
#define S_asLib_badConfig (M_asLib| 6) /*access security: bad configuration file*/
|
||||
#define S_asLib_badCalc (M_asLib| 7) /*access security: bad calculation espression*/
|
||||
#define S_asLib_dupAsg (M_asLib| 8) /*Duplicate Access Security Group */
|
||||
#define S_asLib_InitFailed (M_asLib| 9) /*access security: Init failed*/
|
||||
#define S_asLib_asNotActive (M_asLib|10) /*access security is not active*/
|
||||
#define S_asLib_badMember (M_asLib|11) /*access security: bad ASMEMBERPVT*/
|
||||
#define S_asLib_badClient (M_asLib|12) /*access security: bad ASCLIENTPVT*/
|
||||
#define S_asLib_badAsg (M_asLib|13) /*access security: bad ASG*/
|
||||
#define S_asLib_noMemory (M_asLib|14) /*access security: no Memory */
|
||||
|
||||
/*Private declarations */
|
||||
#define ASMAXINP 12
|
||||
#ifdef vxWorks
|
||||
#include <fast_lock.h>
|
||||
extern FAST_LOCK asLock;
|
||||
extern int asLockInit;
|
||||
#endif
|
||||
extern int asActive;
|
||||
/* definition of access rights*/
|
||||
typedef enum{asNOACCESS,asREAD,asWRITE} asAccessRights;
|
||||
|
||||
/*Base pointers for access security*/
|
||||
typedef struct asBase{
|
||||
ELLLIST uagList;
|
||||
ELLLIST hagList;
|
||||
ELLLIST asgList;
|
||||
void *phash;
|
||||
} ASBASE;
|
||||
/*Defs for User Access Groups*/
|
||||
typedef struct{
|
||||
ELLNODE node;
|
||||
char *user;
|
||||
} UAGNAME;
|
||||
typedef struct uag{
|
||||
ELLNODE node;
|
||||
char *name;
|
||||
ELLLIST list; /*list of UAGNAME*/
|
||||
} UAG;
|
||||
/*Defs for Host Access Groups*/
|
||||
typedef struct{
|
||||
ELLNODE node;
|
||||
char *host;
|
||||
} HAGNAME;
|
||||
typedef struct hag{
|
||||
ELLNODE node;
|
||||
char *name;
|
||||
ELLLIST list; /*list of HAGNAME*/
|
||||
} HAG;
|
||||
/*Defs for Access SecurityGroups*/
|
||||
typedef struct {
|
||||
ELLNODE node;
|
||||
UAG *puag;
|
||||
}ASGUAG;
|
||||
typedef struct {
|
||||
ELLNODE node;
|
||||
HAG *phag;
|
||||
}ASGHAG;
|
||||
typedef struct{
|
||||
ELLNODE node;
|
||||
asAccessRights access;
|
||||
int level;
|
||||
int inpUsed; /*mask for which inputs are used*/
|
||||
int result; /*Result of calc converted to TRUE/FALSE*/
|
||||
char *calc;
|
||||
void *rpcl;
|
||||
ELLLIST uagList; /*List of ASGUAG*/
|
||||
ELLLIST hagList; /*List of ASGHAG*/
|
||||
} ASGRULE;
|
||||
typedef struct{
|
||||
ELLNODE node;
|
||||
char *inp;
|
||||
void *capvt;
|
||||
struct asg *pasg;
|
||||
int inpIndex;
|
||||
}ASGINP;
|
||||
typedef struct asg{
|
||||
ELLNODE node;
|
||||
char *name;
|
||||
ELLLIST inpList;
|
||||
ELLLIST ruleList;
|
||||
ELLLIST memberList;
|
||||
double *pavalue; /*pointer to array of input values*/
|
||||
int inpBad; /*mask for which inputs are bad*/
|
||||
int inpChanged; /*mask showing inputs that have changed*/
|
||||
} ASG;
|
||||
typedef struct asgMember {
|
||||
ELLNODE node;
|
||||
ASG *pasg;
|
||||
ELLLIST clientList;
|
||||
char *asgName;
|
||||
void *userPvt;
|
||||
} ASGMEMBER;
|
||||
typedef struct asgClient {
|
||||
ELLNODE node;
|
||||
ASGMEMBER *pasgMember;
|
||||
char *user;
|
||||
char *host;
|
||||
void *userPvt;
|
||||
ASCLIENTCALLBACK pcallback;
|
||||
int level;
|
||||
asAccessRights access;
|
||||
} ASGCLIENT;
|
||||
/* function prototypes*/
|
||||
void *asCalloc(size_t nobj,size_t size);
|
||||
long asComputeAsg(ASG *pasg);
|
||||
/*macros*/
|
||||
#define asCheckGet(asClientPvt)\
|
||||
(asActive ?\
|
||||
((asClientPvt)->access>=asREAD ? TRUE : FALSE)\
|
||||
: TRUE)
|
||||
#define asCheckPut(asClientPvt)\
|
||||
(asActive ?\
|
||||
((asClientPvt)->access>=asWRITE ? TRUE : FALSE)\
|
||||
: TRUE)
|
||||
|
||||
#endif /*INCasLibh*/
|
||||
@@ -2,6 +2,7 @@ EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
INC += bdt.h
|
||||
|
||||
LIBOBJS += bdt.o
|
||||
|
||||
|
||||
304
src/bdt/bdt.h
Normal file
304
src/bdt/bdt.h
Normal file
@@ -0,0 +1,304 @@
|
||||
#ifndef __BDT_H
|
||||
#define __BDT_H
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.4 1995/07/27 14:21:58 winans
|
||||
* General mods for first release.
|
||||
*
|
||||
* Revision 1.3 1995/05/30 14:47:17 winans
|
||||
* Added BDT_Ping and a port parm to BdtIpOpen.
|
||||
*
|
||||
* Revision 1.2 1995/05/16 15:38:00 winans
|
||||
* Added BdtEof to BdtState enum list.
|
||||
* Added WriteLock and DeltaFlagLock to vxWorks-side BDTs.
|
||||
* Added port number args to BdtOpenListenerTCP() and BdtOpenListenerUDP().
|
||||
*
|
||||
* Revision 1.1 1995/05/11 02:08:44 jbk
|
||||
* new file for the bulk data transfer stuff
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Author: Jim Kowalkowski
|
||||
Date: 5/1/95
|
||||
*/
|
||||
|
||||
/* got from protocols(5) (cheated) or /etc/protocols */
|
||||
#define BDT_UDP 17
|
||||
#define BDT_TCP 6
|
||||
|
||||
/* server ports - in the user reserved area */
|
||||
#define BDT_UDP_PORT 50296
|
||||
#define BDT_TCP_PORT 50297
|
||||
|
||||
/* Well known service names */
|
||||
#define BDT_SERVICE_PV "pv"
|
||||
#define BDT_SERVICE_NAME "name"
|
||||
#define BDT_SERVICE_DRV "drv"
|
||||
|
||||
#define PV_TRANSFER_SIZE 512
|
||||
|
||||
/* How often some type of message is expected to arrive at each end-point */
|
||||
#define BDT_PING_INTERVAL 10 /* Specified in seconds */
|
||||
#define BDT_CONENCTION_TIMEOUT 25 /* Specified in seconds */
|
||||
|
||||
/* message types */
|
||||
#define BDT_Ok 0
|
||||
#define BDT_Connect 1
|
||||
#define BDT_Error 2
|
||||
#define BDT_Get 3
|
||||
#define BDT_Put 4
|
||||
#define BDT_Close 5
|
||||
#define BDT_Monitor 6
|
||||
#define BDT_Value 7
|
||||
#define BDT_Delta 8
|
||||
#define BDT_Add 9
|
||||
#define BDT_Delete 10
|
||||
#define BDT_Ping 11
|
||||
|
||||
#define BDT_LAST_VERB 11
|
||||
|
||||
/* protocol states */
|
||||
typedef enum
|
||||
{ BdtIdle,BdtUnbound,BdtSData,BdtRData,BdtBad,BdtEof } BdtState;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* The format of a BDT_Connect message is:
|
||||
*
|
||||
* BdtMsgHead.verb (unsigned 16 binary = BDT_Connect)
|
||||
* BdtMsgHead.size (unsigned 32 bit binary)
|
||||
* service name length (unsigned 8 bit binary)
|
||||
* service name string (service name length characters)
|
||||
* arg1 string length (unsigned 8 bit binary)
|
||||
* arg1 string (arg1 string length characters)
|
||||
* ...
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NOTICE!!!!!!!! MONITORS ARE NOT CURRENTLY SUPPORTED!!!!!!!
|
||||
*
|
||||
* The BdtMonitor structure is created on the server-side when ever a client
|
||||
* registers a monitor. It contains a tag string that is given by the client
|
||||
* when the monitor is established. This tag string is an arbitrary binary
|
||||
* string of bytes... presumably used by the client as a pointer or index
|
||||
* to a status structure that represents the resource being monitored.
|
||||
*
|
||||
* The Message portion of the BdtMonitor represents the body of the message
|
||||
* that is to be sent to the client to indicate the status of the event that
|
||||
* happened. (It may not be present in the message.)
|
||||
*
|
||||
* The BdtMonitor structures are only hooked into the bdt.pMonitor list if they
|
||||
* are waiting to be sent to the client.
|
||||
*
|
||||
* The format of a BDT_Monitor message is:
|
||||
*
|
||||
* BdtMsgHead.verb (unsigned 16 binary = BDT_Monitor)
|
||||
* BdtMsgHead.size (unsigned 32 bit binary)
|
||||
* TagLength (unsigned 32 bit binary)
|
||||
* Tag (TagLength characters)
|
||||
* service name string (BdtMsgHead.size-TagLength-4 characters)
|
||||
*
|
||||
* The <service name string> for a monitor message should include the object
|
||||
* name(s) that are to be monitored.
|
||||
*
|
||||
*
|
||||
* The format of a BDT_Delta message is:
|
||||
*
|
||||
* BdtMsgHead.verb (unsigned 16 binary = BDT_Delta)
|
||||
* BdtMsgHead.size (unsigned 32 bit binary)
|
||||
* BdtMonitor.TagLength (unsigned 32 bit binary)
|
||||
* BdtMonitor.Tag (BdtMonitor.TagLength characters)
|
||||
* BdtMonitor.MessageLength (unsigned 32 bit binary)
|
||||
* BdtMonitor.Message (BdtMonitor.MessageLength characters)
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
struct bdt;
|
||||
typedef struct BdtMonitor
|
||||
{
|
||||
struct bdt *pBdt; /* Connection to send notices back to */
|
||||
char *Tag; /* Client-generated tag */
|
||||
int TagLength; /* Length of tag */
|
||||
char *Message; /* Server-gen'd status change message */
|
||||
int MessageLength; /* Length of Message */
|
||||
struct BdtMonitor *pNext; /* Allow queue of N outbound on BDT */
|
||||
} BdtMonitor;
|
||||
|
||||
typedef int (*BdthandlerFunc)(struct bdt *Bdt);
|
||||
typedef struct BdtHandlers
|
||||
{
|
||||
BdthandlerFunc Ok;
|
||||
BdthandlerFunc Connect;
|
||||
BdthandlerFunc Error;
|
||||
BdthandlerFunc Get;
|
||||
BdthandlerFunc Put;
|
||||
BdthandlerFunc Close;
|
||||
BdthandlerFunc Monitor;
|
||||
BdthandlerFunc Value;
|
||||
BdthandlerFunc Delta;
|
||||
BdthandlerFunc Add;
|
||||
BdthandlerFunc Delete;
|
||||
BdthandlerFunc Ping;
|
||||
} BdtHandlers;
|
||||
|
||||
struct bdt
|
||||
{
|
||||
int soc;
|
||||
int remaining_send;
|
||||
int remaining_recv;
|
||||
BdtState state;
|
||||
|
||||
#ifdef vxWorks
|
||||
char *Name; /* Service name (used for messages) */
|
||||
SEM_ID WriteLock;
|
||||
SEM_ID MonitorLock;
|
||||
BdtMonitor *pMonitor; /* List of pending monitor events */
|
||||
BdthandlerFunc *pHandlers; /* Support routines for messages */
|
||||
void *pService; /* Provate pointer for service */
|
||||
#endif
|
||||
};
|
||||
typedef struct bdt BDT;
|
||||
|
||||
struct BdtMsgHead
|
||||
{
|
||||
unsigned short verb;
|
||||
unsigned long size;
|
||||
};
|
||||
typedef struct BdtMsgHead BdtMsgHead;
|
||||
|
||||
#define BdtGetSocket(BDT) (BDT->soc)
|
||||
#define BdtGetResidualWrite(BDT) (BDT->remaining_send)
|
||||
#define BdtGetResidualRead(BDT) (BDT->remaining_recv)
|
||||
#define BdtGetProtoState(BDT) (BDT->state)
|
||||
#ifdef vxWorks
|
||||
#define BdtGetServiceName(BDT) (BDT->Name)
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Server functions:
|
||||
|
||||
BdtOpenListenerTCP:
|
||||
Open a socket locally bound to the bulk data transfer TCP server port.
|
||||
Set the socket up as a listener. Return the open socket.
|
||||
|
||||
BdtOpenListenerUDP:
|
||||
Open a socket locally bound to the bulk data transfer UDP server port.
|
||||
Return the open socket.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
int BdtOpenListenerTCP(int Port);
|
||||
int BdtOpenListenerUDP(int Port);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Utilities functions:
|
||||
|
||||
BdtMakeServer:
|
||||
Available under unix only. Put process in the background, disassociate
|
||||
process from controlling terminal and parent process, and prepare
|
||||
signals for reaping children spawned by the process.
|
||||
|
||||
BdtServerClearSignals:
|
||||
Clear the signal handlers for a process, set them to default.
|
||||
|
||||
BdtMakeBDT:
|
||||
Allocate and initialize a BDT from a socket.
|
||||
|
||||
BdtFreeBDT:
|
||||
Close the open socket and free the memory for the BDT.
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
#ifndef vxWorks
|
||||
int BdtMakeServer(char** argv);
|
||||
int BdtServerClearSignals();
|
||||
#endif
|
||||
|
||||
BDT* BdtMakeBDT(int socket); /* make a BDT from a socket */
|
||||
int BdtFreeBDT(BDT* bdt); /* free a BDT */
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Client functions:
|
||||
|
||||
BdtIpOpen:
|
||||
Open a connection to an bulk data transfer given the IP address of the
|
||||
machine where the server exists. The returned BDT is returned unbound,
|
||||
a connect must be issued before data transactions can take place.
|
||||
|
||||
BdtPvOpen:
|
||||
Open and connect (bind) to a process variable. Data transfers can
|
||||
take place after this call.
|
||||
|
||||
BdtServiceConnect:
|
||||
Used in conjunction with BdtIpOpen(). Bind an unbound BDT to a
|
||||
generic service provided by the server at the other end of the open
|
||||
connection.
|
||||
|
||||
BdtPvConnect:
|
||||
Used in conjunction with BdtIpOpen(). Bind an unbound BDT to a
|
||||
process variable on the server at the other end of the open
|
||||
connection.
|
||||
|
||||
BdtClose:
|
||||
Completely close a connection to a server and free the BDT.
|
||||
|
||||
BdtDeltaPending:
|
||||
Check if a delta message arrived at an unexpected time. This function
|
||||
clears the pending condition.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
BDT* BdtIpOpen(char* address, int port);
|
||||
BDT* BdtPvOpen(char *IocName, char* PvName);
|
||||
int BdtServiceConnect(BDT* bdt, char* service_name, char *args);
|
||||
int BdtPvConnect(BDT* bdt, char* pv_name);
|
||||
int BdtClose(BDT* bdt);
|
||||
int BdtPvDeltaPending(BDT* bdt);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Client and Server shared functions:
|
||||
|
||||
BdtSendHeader:
|
||||
Send a message header out to a connect BDT with command and message body
|
||||
size information.
|
||||
|
||||
BdtSendData:
|
||||
Send a portion or all the message body out a connected BDT. A header
|
||||
must have previously been sent with length information. The interface
|
||||
will only allow the amount of data specified in the header to be sent.
|
||||
|
||||
BdtWrite:
|
||||
This call will block until all the data specified in the size parameter
|
||||
are sent down the socket.
|
||||
|
||||
BdtRead:
|
||||
This call will block until all the data specified in the size parameter
|
||||
is read from the socket.
|
||||
|
||||
BdtReceiveHeader:
|
||||
Wait until a message header appears at the BDT, return the action and
|
||||
remaining message body size.
|
||||
|
||||
BdtReceiveData:
|
||||
Wait for a chunk or the entire body of a message to appear at the BDT.
|
||||
Put the data into the buffer for a maximum size. Return the amount of
|
||||
data actually received, or zero if there is no data remaining for the
|
||||
current message.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
int BdtSendHeader(BDT* bdt, unsigned short verb, int size);
|
||||
int BdtSendData(BDT* bdt, void* buffer, int size);
|
||||
int BdtReceiveHeader(BDT* bdt, int* verb, int* size);
|
||||
int BdtReceiveData(BDT* bdt, void* buffer, int size);
|
||||
int BdtRead(int socket, void* buffer, int size);
|
||||
int BdtWrite(int socket, void* buffer, int size);
|
||||
int BdtFlushOutput(BDT* bdt);
|
||||
int BdtPvPutArray(BDT *bdt, short DbrType, void *Buf, unsigned long NumElements, unsigned long ElementSize);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@ include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
|
||||
INC += cvtTable.h
|
||||
|
||||
SRCS.c = ../makeBpt
|
||||
OBJS = makeBpt
|
||||
|
||||
@@ -7,10 +7,10 @@ VX_WARN_YES = -Wall -pedantic
|
||||
|
||||
MENUS += menuConvert.h
|
||||
|
||||
BPTS += bptTypeJdegC.ascii
|
||||
BPTS += bptTypeJdegF.ascii
|
||||
BPTS += bptTypeKdegC.ascii
|
||||
BPTS += bptTypeKdegF.ascii
|
||||
BPTS += bptTypeJdegC.db
|
||||
BPTS += bptTypeJdegF.db
|
||||
BPTS += bptTypeKdegC.db
|
||||
BPTS += bptTypeKdegF.db
|
||||
|
||||
|
||||
SRCS.c = \
|
||||
|
||||
45
src/bpt/cvtTable.h
Normal file
45
src/bpt/cvtTable.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* $Id$
|
||||
* Breakpoint Tables
|
||||
*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 11-7-90
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 05-18-92 rcz removed extern
|
||||
* .02 05-18-92 rcz new database access
|
||||
* .03 08-19-92 jba add prototypes for cvtRawToEngBpt,cvtEngToRawBpt
|
||||
*/
|
||||
|
||||
#ifndef INCcvtTableh
|
||||
#define INCcvtTableh 1
|
||||
|
||||
/* Global Routines*/
|
||||
long cvtEngToRawBpt(double *pval,short linr,short init,
|
||||
void **ppbrk,short *plbrk);
|
||||
|
||||
long cvtRawToEngBpt(double *pval,short linr,short init,
|
||||
void **ppbrk, short *plbrk);
|
||||
|
||||
#endif
|
||||
@@ -118,7 +118,7 @@ int main(argc, argv)
|
||||
fprintf(stderr,"Input file MUST have .data extension\n");
|
||||
exit(-1);
|
||||
}
|
||||
strcpy(pext,".ascii");
|
||||
strcpy(pext,".db");
|
||||
inFile = fopen(argv[1],"r");
|
||||
if(!inFile) {
|
||||
fprintf(stderr,"Error opening %s\n",argv[1]);
|
||||
|
||||
@@ -10,6 +10,12 @@ DEPLIBS = ./libca.a\
|
||||
$(DEPLIBS_BASE)/libCom.a
|
||||
|
||||
|
||||
INC += cadef.h
|
||||
INC += caerr.h
|
||||
INC += caeventmask.h
|
||||
INC += calink.h
|
||||
INC += bsdProto.h
|
||||
|
||||
SRCS.c = \
|
||||
../iocinf.c ../access.c ../test_event.c ../service.c \
|
||||
../flow_control.c ../repeater.c ../conn.c \
|
||||
|
||||
@@ -99,6 +99,9 @@
|
||||
/************************************************************************/
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.80 1995/10/18 16:49:23 jhill
|
||||
* recv task is now running at a lower priority than the send task under vxWorks
|
||||
*
|
||||
* Revision 1.79 1995/10/12 01:30:10 jhill
|
||||
* new ca_flush_io() mechanism prevents deadlock when they call
|
||||
* ca_flush_io() from within an event routine. Also forces early
|
||||
@@ -2094,14 +2097,18 @@ long mask
|
||||
|
||||
/*
|
||||
* Check for huge waveform
|
||||
*
|
||||
* (the count is not checked here against the native count
|
||||
* when connected because this introduces a race condition
|
||||
* for the client tool - the requested count is clipped to
|
||||
* the actual count when the monitor request is sent so
|
||||
* verifying that the requested count is valid here isnt
|
||||
* required)
|
||||
*/
|
||||
if(dbr_size_n(type,count)>MAX_MSG_SIZE-sizeof(caHdr)){
|
||||
return ECA_TOLARGE;
|
||||
}
|
||||
|
||||
if(count > chix->count && chix->type != TYPENOTCONN)
|
||||
return ECA_BADCOUNT;
|
||||
|
||||
if(!mask)
|
||||
return ECA_BADMASK;
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@ static char *sccsId = "@(#) $Id$";
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.32 1995/11/29 19:17:25 jhill
|
||||
* more tests
|
||||
*
|
||||
* Revision 1.31 1995/10/12 01:30:28 jhill
|
||||
* improved the test
|
||||
*
|
||||
@@ -682,8 +685,14 @@ void null_event(struct event_handler_args args)
|
||||
int status;
|
||||
|
||||
#if 0
|
||||
status = ca_put (DBR_DOUBLE, args.chid, &fval);
|
||||
SEVCHK (status, NULL);
|
||||
if (ca_state(args.chid)==cs_conn) {
|
||||
status = ca_put(DBR_FLOAT, args.chid, &fval);
|
||||
SEVCHK(status, "put failed in null_event()");
|
||||
}
|
||||
else {
|
||||
printf("null_event() called for disconnected %s\n",
|
||||
ca_name(args.chid));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (i++ > 1000) {
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include <envDefs.h>
|
||||
|
||||
void caSetupAddrList(
|
||||
ELLLIST *pList,
|
||||
SOCKET socket);
|
||||
|
||||
void caPrintAddrList();
|
||||
void caPrintAddrList(ELLLIST *pList);
|
||||
|
||||
void caDiscoverInterfaces(
|
||||
ELLLIST *pList,
|
||||
@@ -21,15 +26,18 @@ void caAddConfiguredAddr(
|
||||
int local_addr(SOCKET socket, struct sockaddr_in *plcladdr);
|
||||
unsigned short caFetchPortConfig(ENV_PARAM *pEnv, unsigned short defaultPort);
|
||||
|
||||
union caAddr{
|
||||
struct sockaddr_in inetAddr;
|
||||
struct sockaddr sockAddr;
|
||||
};
|
||||
typedef union ca_addr {
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr sa;
|
||||
}caAddr;
|
||||
|
||||
typedef struct {
|
||||
ELLNODE node;
|
||||
union caAddr srcAddr;
|
||||
union caAddr destAddr;
|
||||
ELLNODE node;
|
||||
caAddr srcAddr;
|
||||
caAddr destAddr;
|
||||
}caAddrNode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
994
src/ca/cadef.h
Normal file
994
src/ca/cadef.h
Normal file
@@ -0,0 +1,994 @@
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* L O S A L A M O S */
|
||||
/* Los Alamos National Laboratory */
|
||||
/* Los Alamos, New Mexico 87545 */
|
||||
/* */
|
||||
/* Copyright, 1986, The Regents of the University of California. */
|
||||
/* Author Jeffrey O. Hill */
|
||||
/* hill@atdiv.lanl.gov */
|
||||
/* 505 665 1831 */
|
||||
/* */
|
||||
/* */
|
||||
/* History */
|
||||
/* ------- */
|
||||
/* */
|
||||
/* Date Person Comments */
|
||||
/* ---- ------ -------- */
|
||||
/* 08xx87 joh Init Release */
|
||||
/* 031290 joh Added db_access auto include */
|
||||
/* 031991 joh fixed SEVCHK dbl function call when status */
|
||||
/* returned indicates unsuccessful completion */
|
||||
/* 060591 joh delinting */
|
||||
/* 091691 joh exported channel state */
|
||||
/* 060392 joh added ca host name MACRO */
|
||||
/* 072792 joh added ca_test_io() decl */
|
||||
/* 072792 joh changed compile time flag from VAXC to STDC */
|
||||
/* so the function prototypes can be used by */
|
||||
/* other compilers */
|
||||
/* 072892 joh added function prototype for host name function */
|
||||
/* 101692 joh use unique name for var in SEVCHK to avoid */
|
||||
/* clashing with application */
|
||||
/* 120492 joh turn off VAXC ca_real reduction from double to */
|
||||
/* float. This was originally provided to ease */
|
||||
/* integration of the VAX FORTRAN based pt_shell */
|
||||
/* code which will in all likelyhood no longer */
|
||||
/* be used. */
|
||||
/* 120992 joh converted to dll list routines */
|
||||
/* 061193 joh added missing prototype for ca_clear_channel() */
|
||||
/* and others */
|
||||
/* 080593 rcz converted to ell list routines */
|
||||
/* 090893 joh added client id to channel in use block */
|
||||
/* 010694 joh added put callback rtn and synch group rtns */
|
||||
/* 090194 joh support C++ */
|
||||
/* 101194 joh merged NT changes */
|
||||
/* */
|
||||
/*_begin */
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Title: GTA high level channel access routines C */
|
||||
/* function prototypes */
|
||||
/* File: cadef.h */
|
||||
/* Environment: Architecture independent */
|
||||
/* ( Current ports ) */
|
||||
/* VAXC, VMS V4.6 */
|
||||
/* SUNC, BSD UNIX V4.3 */
|
||||
/* SUNC, vxWorks */
|
||||
/* */
|
||||
/* */
|
||||
/* Purpose */
|
||||
/* ------- */
|
||||
/* */
|
||||
/* GTACS universal remote access library function prototypes. */
|
||||
/* ( C default argument passing mechanisms ) */
|
||||
/* */
|
||||
/* Special comments */
|
||||
/* ------- -------- */
|
||||
/* "ca_" is the standard prefix for the "channel access" library */
|
||||
/* function names. */
|
||||
/* */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
/*_end */
|
||||
|
||||
#ifndef INCLcadefh
|
||||
#define INCLcadefh
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#define CAC_FUNC_PROTO
|
||||
#endif
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
#ifdef __STDC__
|
||||
#define CAC_FUNC_PROTO
|
||||
#endif
|
||||
|
||||
#ifndef HDRVERSIONID
|
||||
# define HDRVERSIONID(NAME,VERS)
|
||||
#endif /*HDRVERSIONID*/
|
||||
|
||||
HDRVERSIONID(cadefh, "@(#) $Id$")
|
||||
|
||||
/* auto include of all stuff that cadef.h uses */
|
||||
#if defined(CAC_FUNC_PROTO) && !defined(CA_DONT_INCLUDE_STDARGH)
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifndef INCLdb_accessh
|
||||
#include <db_access.h>
|
||||
#endif /* INCLdb_accessh */
|
||||
|
||||
#ifndef INCLcaerrh
|
||||
#include <caerr.h>
|
||||
#endif /* INCLcaerrh */
|
||||
|
||||
#ifndef INCLcaeventmaskh
|
||||
#include <caeventmask.h>
|
||||
#endif /* INCLcaeventmaskh */
|
||||
|
||||
#ifndef INCLellLibh
|
||||
#include <ellLib.h>
|
||||
#endif /* INCLellLibh */
|
||||
|
||||
/*
|
||||
*
|
||||
* NOTE: the channel in use fields type, count, name, and
|
||||
* host name are available to applications. However it is
|
||||
* recommended that the following MACROS be used to access them.
|
||||
*
|
||||
*/
|
||||
#define ca_field_type(CHID) ((CHID)->type)
|
||||
#define ca_element_count(CHID) ((CHID)->count)
|
||||
#define ca_name(CHID) ((char *)((CHID)+1))
|
||||
#define ca_puser(CHID) ((CHID)->puser)
|
||||
#define ca_host_name(CHID) ca_host_name_function(CHID)
|
||||
#define ca_read_access(CHID) ((CHID)->ar.read_access)
|
||||
#define ca_write_access(CHID) ((CHID)->ar.write_access)
|
||||
|
||||
/*
|
||||
* cs_ - `channel state'
|
||||
*
|
||||
* cs_never_conn valid chid, IOC not found
|
||||
* cs_prev_conn valid chid, IOC was found, but unavailable
|
||||
* cs_conn valid chid, IOC was found, still available
|
||||
* cs_closed invalid chid
|
||||
*/
|
||||
enum channel_state{cs_never_conn, cs_prev_conn, cs_conn, cs_closed};
|
||||
#define ca_state(CHID) ((CHID)->state)
|
||||
|
||||
typedef struct ca_access_rights{
|
||||
unsigned read_access:1;
|
||||
unsigned write_access:1;
|
||||
}caar;
|
||||
|
||||
|
||||
/* Format for the arguments to user connection handlers */
|
||||
struct connection_handler_args{
|
||||
struct channel_in_use *chid; /* Channel id */
|
||||
long op; /* External codes for CA op */
|
||||
};
|
||||
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
typedef void caCh(struct connection_handler_args args);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
typedef void caCh();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
|
||||
/* Format for the arguments to user access rights handlers */
|
||||
struct access_rights_handler_args{
|
||||
struct channel_in_use *chid; /* Channel id */
|
||||
caar ar; /* New access rights state */
|
||||
};
|
||||
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
typedef void caArh(struct access_rights_handler_args args);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
typedef void caArh();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
|
||||
struct channel_in_use{
|
||||
ELLNODE node; /* list ptrs */
|
||||
short type; /* database field type */
|
||||
#define TYPENOTCONN (-1) /* the type when disconnected */
|
||||
unsigned short count; /* array element count */
|
||||
union{
|
||||
unsigned sid; /* server id */
|
||||
struct db_addr *paddr; /* database address */
|
||||
} id;
|
||||
void *puser; /* user available area */
|
||||
enum channel_state state; /* connected/ disconnected etc */
|
||||
caar ar; /* access rights */
|
||||
|
||||
/*
|
||||
* The following fields may change or even vanish in the future
|
||||
*/
|
||||
caCh *pConnFunc;
|
||||
caArh *pAccessRightsFunc;
|
||||
ELLLIST eventq;
|
||||
unsigned cid; /* client id */
|
||||
unsigned retry; /* search retry number */
|
||||
void *piiu; /* private ioc in use block */
|
||||
#ifdef vxWorks
|
||||
void *ppn; /* ptr to optional put notify blk */
|
||||
#endif /* vxWorks */
|
||||
/*
|
||||
* channel name stored directly after this structure in a
|
||||
* null terminated string.
|
||||
*/
|
||||
};
|
||||
|
||||
typedef struct channel_in_use *chid;
|
||||
typedef long chtype;
|
||||
typedef struct pending_event *evid;
|
||||
typedef double ca_real;
|
||||
|
||||
/* The conversion routine to call for each type */
|
||||
#define VALID_TYPE(TYPE) (((unsigned short)TYPE)<=LAST_BUFFER_TYPE)
|
||||
|
||||
|
||||
/* argument passed to event handlers and callback handlers */
|
||||
struct event_handler_args{
|
||||
void *usr; /* User argument supplied when event added */
|
||||
struct channel_in_use *chid; /* Channel id */
|
||||
long type; /* the type of the value returned */
|
||||
long count; /* the element count of the item returned */
|
||||
void *dbr; /* Pointer to the value returned */
|
||||
int status; /* CA Status of the op from server - CA V4.1 */
|
||||
};
|
||||
|
||||
struct pending_event{
|
||||
ELLNODE node; /* list ptrs */
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
void (*usr_func)(struct event_handler_args args);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
void (*usr_func)();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
void *usr_arg;
|
||||
struct channel_in_use *chan;
|
||||
chtype type; /* requested type for local CA */
|
||||
unsigned long count; /* requested count for local CA */
|
||||
/*
|
||||
* the following provide for reissuing a
|
||||
* disconnected monitor
|
||||
*/
|
||||
ca_real p_delta;
|
||||
ca_real n_delta;
|
||||
ca_real timeout;
|
||||
unsigned id;
|
||||
unsigned short mask;
|
||||
};
|
||||
|
||||
void epicsShareAPI ca_test_event
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
struct event_handler_args
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/* Format for the arguments to user exception handlers */
|
||||
struct exception_handler_args{
|
||||
void *usr; /* User argument supplied when event added */
|
||||
struct channel_in_use *chid; /* Channel id */
|
||||
long type; /* Requested type for the operation */
|
||||
long count; /* Requested count for the operation */
|
||||
void *addr; /* User's address to write results of CA_OP_GET */
|
||||
long stat; /* Channel access std status code */
|
||||
long op; /* External codes for channel access operations */
|
||||
char *ctx; /* A character string containing context info */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* External OP codes for CA operations
|
||||
*
|
||||
*/
|
||||
#define CA_OP_GET 0
|
||||
#define CA_OP_PUT 1
|
||||
#define CA_OP_SEARCH 2
|
||||
#define CA_OP_ADD_EVENT 3
|
||||
#define CA_OP_CLEAR_EVENT 4
|
||||
#define CA_OP_OTHER 5
|
||||
#define CA_OP_CONN_UP 6
|
||||
#define CA_OP_CONN_DOWN 7
|
||||
|
||||
/************************************************************************/
|
||||
/* Perform Library Initialization */
|
||||
/* */
|
||||
/* Must be called once before calling any of the other routines */
|
||||
/************************************************************************/
|
||||
int epicsShareAPI ca_task_initialize
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
void
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/************************************************************************/
|
||||
/* Remove CA facility from your task */
|
||||
/* */
|
||||
/* Normally called automatically at task exit */
|
||||
/************************************************************************/
|
||||
int epicsShareAPI ca_task_exit
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
void
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Return a channel identification for the supplied channel name */
|
||||
/* (and attempt to create a virtual circuit) */
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
* preferred search mechanism
|
||||
*/
|
||||
#define ca_search(NAME,CHIDPTR)\
|
||||
ca_search_and_connect(NAME, CHIDPTR, 0, 0)
|
||||
/* ca_search
|
||||
(
|
||||
Name IO Value
|
||||
---- -- -----
|
||||
char *, NAME R NULL term ASCII channel name string
|
||||
chid * CHIDPTR RW channel index written here
|
||||
);
|
||||
*/
|
||||
|
||||
/************************************************************************
|
||||
* anachronistic entry points *
|
||||
* **** Fetching a value while searching nolonger supported**** *
|
||||
************************************************************************/
|
||||
#define ca_build_channel(NAME,XXXXX,CHIDPTR,YYYYY)\
|
||||
ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0)
|
||||
|
||||
#define ca_array_build(NAME,XXXXX, ZZZZZZ, CHIDPTR,YYYYY)\
|
||||
ca_build_and_connect(NAME, XXXXX, ZZZZZZ, CHIDPTR, YYYYY, 0, 0)
|
||||
|
||||
|
||||
/*
|
||||
* preferred search mechanism
|
||||
*/
|
||||
int epicsShareAPI ca_search_and_connect
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
char *,/* NAME R NULL term ASCII channel name string */
|
||||
chid *,/* CHIDPTR RW channel index written here */
|
||||
void (*)(struct connection_handler_args),
|
||||
/* PFUNC R the address of user's connection handler*/
|
||||
void * /* PUSER R placed in the channel's puser field */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/************************************************************************
|
||||
* anachronistic entry point *
|
||||
* **** Fetching a value while searching nolonger supported**** *
|
||||
************************************************************************/
|
||||
int epicsShareAPI ca_build_and_connect
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
char *, /* NAME R NULL term ASCII channel name string */
|
||||
chtype, /* GET_TYPE R external channel type to get */
|
||||
unsigned/* (no get if invalid type) */
|
||||
long, /* GET_COUNT R array count to get */
|
||||
chid *, /* CHIDPTR RW channel index written here */
|
||||
void *, /* PVALUE W A pointer to a user supplied buffer */
|
||||
void (*)(struct connection_handler_args),
|
||||
/* PFUNC R the address of user's connection handler*/
|
||||
void * /* PUSER R placed in the channel's puser field */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
int epicsShareAPI ca_change_connection_event
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
chid chix,
|
||||
void (*pfunc)(struct connection_handler_args)
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
int epicsShareAPI ca_replace_access_rights_event(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
chid chix,
|
||||
void (*pfunc)(struct access_rights_handler_args)
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
*
|
||||
* replace the default exception handler
|
||||
*
|
||||
*/
|
||||
int epicsShareAPI ca_add_exception_event
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
void (*pfunc)(struct exception_handler_args),
|
||||
void *arg
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/************************************************************************/
|
||||
/* deallocate resources reserved for a channel */
|
||||
/************************************************************************/
|
||||
int epicsShareAPI ca_clear_channel
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
chid /* CHAN, R channel identifier */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/************************************************************************/
|
||||
/* Write a value to a channel */
|
||||
/************************************************************************/
|
||||
#define ca_bput(CHID,PVALUE) ca_array_put(DBR_STRING, 1, CHID, (PVALUE))
|
||||
/*
|
||||
C Type Name IO Value
|
||||
------ ----- -- -----
|
||||
chid CHID R channel id
|
||||
char * PVALUE R pointer to a binary value string
|
||||
*/
|
||||
|
||||
#define ca_rput(CHID,PVALUE)\
|
||||
ca_array_put(DBR_FLOAT, 1, CHID, (PVALUE))
|
||||
/*
|
||||
C Type Name IO Value
|
||||
------ ----- -- -----
|
||||
chid CHID R channel id
|
||||
dbr_float_t * PVALUE R pointer to a real value
|
||||
*/
|
||||
|
||||
#define ca_put(CHTYPE, CHID, PVALUE) ca_array_put(CHTYPE, 1, CHID, PVALUE)
|
||||
/*
|
||||
Name IO Value
|
||||
---- -- -----
|
||||
chtype, TYPE R channel type
|
||||
chid, CHID R channel index
|
||||
void * PVALUE R pointer to new channel value of type specified
|
||||
i.e. status = ca_put(DBF_INT,chid,&value)
|
||||
*/
|
||||
|
||||
int epicsShareAPI ca_array_put
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
chtype, /* TYPE R channel type */
|
||||
unsigned long,
|
||||
/* COUNT R array element count */
|
||||
chid, /* CHID R channel index */
|
||||
void * /* PVALUE R pointer to new channel value of type */
|
||||
/* specified. */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* This routine functions identically to the original ca put request
|
||||
* with the addition of a callback to the user supplied function
|
||||
* after recod processing completes in the IOC. The arguments
|
||||
* to the user supplied callback function are declared in
|
||||
* the structure event_handler_args and include the pointer
|
||||
* sized user argument supplied when ca_array_get_callback() is called.
|
||||
*/
|
||||
int epicsShareAPI ca_array_put_callback
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
chtype, /* TYPE R channel type */
|
||||
unsigned long,
|
||||
/* COUNT R array element count */
|
||||
chid, /* CHID R channel index */
|
||||
void *, /* PVALUE R pointer to new channel value of type */
|
||||
void (*)(struct event_handler_args),
|
||||
/* USRFUNC R the address of a user supplied function */
|
||||
void * /* USRARG R An argument copied to the above function*/
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Read a value from a channel */
|
||||
/* */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#define ca_bget(CHID,PVALUE) ca_array_get(DBR_STRING, 1, CHID, PVALUE)
|
||||
/*
|
||||
C Type Name IO Value
|
||||
------ ----- -- -----
|
||||
chid CHID R channel id
|
||||
char * PVALUE W string value pointer
|
||||
*/
|
||||
|
||||
#define ca_rget(CHID,PVALUE) ca_array_get(DBR_FLOAT, 1, CHID, PVALUE)
|
||||
/*
|
||||
C Type Name IO Value
|
||||
------ ----- -- -----
|
||||
chid CHID R channel id
|
||||
dbr_float_t * PVALUE W real value pointer
|
||||
*/
|
||||
|
||||
#define ca_get(CHTYPE, CHID, PVALUE) ca_array_get(CHTYPE, 1, CHID, PVALUE)
|
||||
/*
|
||||
C Type Name IO Value
|
||||
------ ----- -- -----
|
||||
chtype, TYPE R channel type
|
||||
chid, CHID R channel index
|
||||
void * PVALUE W ptr to where channel value written
|
||||
*/
|
||||
|
||||
int epicsShareAPI ca_array_get
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
chtype, /* TYPE R channel type */
|
||||
unsigned long,
|
||||
/* COUNT R array element count */
|
||||
chid, /* CHID R channel index */
|
||||
void * /* PVALUE W ptr to where channel value written */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
/************************************************************************/
|
||||
/* Read a value from a channel and run a callback when the value */
|
||||
/* returns */
|
||||
/* */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
#define ca_bget_callback(CHID,PFUNC,ARG)\
|
||||
ca_array_get_callback(DBR_STRING, 1, CHID, PFUNC, ARG)
|
||||
/*
|
||||
C Type Name IO Value
|
||||
------ ----- -- -----
|
||||
chid CHID R channel id
|
||||
void (*)(), PFUNC R the address of a user supplied function
|
||||
void *, ARG R An argument copied to the above function
|
||||
*/
|
||||
|
||||
#define ca_rget_callback(CHID,PFUNC,ARG)\
|
||||
ca_array_get_callback(DBR_FLOAT, 1, CHID, PFUNC, ARG)
|
||||
|
||||
/*
|
||||
C Type Name IO Value
|
||||
------ ----- -- -----
|
||||
chid CHID R channel id
|
||||
void (*)(), PFUNC R the address of a user supplied function
|
||||
void *, ARG R An argument copied to the above function
|
||||
*/
|
||||
|
||||
#define ca_get_callback(CHTYPE, CHID,PFUNC,ARG)\
|
||||
ca_array_get_callback(CHTYPE, 1, CHID, PFUNC, ARG)
|
||||
/*
|
||||
C Type Name IO Value
|
||||
------ ----- -- -----
|
||||
chtype, TYPE R channel type
|
||||
chid, CHID R channel index
|
||||
void (*)(), PFUNC R the address of a user supplied function
|
||||
void *, ARG R An argument copied to the above function
|
||||
*/
|
||||
|
||||
int epicsShareAPI ca_array_get_callback
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
chtype, /* TYPE R channel type */
|
||||
unsigned long,
|
||||
/* COUNT R array element count */
|
||||
chid, /* CHID R channel index */
|
||||
void (*)(struct event_handler_args),
|
||||
/* USRFUNC R the address of a user supplied function */
|
||||
void * /* USRARG R An argument copied to the above function */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Specify a function to be executed whenever significant changes */
|
||||
/* occur to a channel. */
|
||||
/* NOTES: */
|
||||
/* 1) Evid may be omited by passing a NULL pointer */
|
||||
/* */
|
||||
/* 2) AN array count of zero specifies the native db count */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
typedef struct event_handler_args evargs;
|
||||
|
||||
/* Assumes DELTA info comes from the database or defaults */
|
||||
#define ca_add_event(TYPE,CHID,ENTRY,ARG,EVID)\
|
||||
ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,0.0,0.0,0.0,EVID)
|
||||
|
||||
/* Name IO Value
|
||||
---- -- -----
|
||||
chid, CHID R channel index
|
||||
void
|
||||
(*)(), USRFUNC R the address of a user supplied function
|
||||
void *, USRARG R An argument copied to the above function
|
||||
evid * EVIDPTR W An id to refer to this event by
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Sets both P_DELTA and M_DELTA below to argument DELTA */
|
||||
#define ca_add_delta_event(TYPE,CHID,ENTRY,ARG,DELTA,EVID)\
|
||||
ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,DELTA,DELTA,0.0,EVID)
|
||||
/* Name IO Value
|
||||
---- -- -----
|
||||
chid, CHID R channel index
|
||||
void
|
||||
(*)(), USRFUNC R the address of a user supplied function
|
||||
void *, USRARG R An argument copied to the above function
|
||||
ca_real, DELTA R Generate events after +-delta excursions
|
||||
evid * EVIDPTR W An id to refer to this event by
|
||||
*/
|
||||
|
||||
|
||||
#define ca_add_general_event(TYPE,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\
|
||||
ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)
|
||||
|
||||
#define ca_add_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\
|
||||
ca_add_masked_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID, DBE_VALUE | DBE_ALARM)
|
||||
|
||||
|
||||
|
||||
int epicsShareAPI ca_add_masked_array_event
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
chtype, /* TYPE R requested external channel type */
|
||||
unsigned long,
|
||||
/* COUNT R array element count */
|
||||
chid, /* CHID R channel index */
|
||||
void (*)(struct event_handler_args),
|
||||
/* USRFUNC R the address of a user supplied function */
|
||||
void *, /* USRARG R An argument copied to the above function*/
|
||||
ca_real,/* P_DELTA R Generate events after +delta excursions */
|
||||
ca_real,/* N_DELTA R Generate events after -delta excursions */
|
||||
ca_real,/* TIMEOUT R Generate events after timeout sec */
|
||||
evid *, /* EVIDPTR W An id to refer to this event by */
|
||||
long /* MASK R event trigger type */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Remove a function from a list of those specified to run */
|
||||
/* whenever significant changes occur to a channel */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
int epicsShareAPI ca_clear_event
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
evid /* EVID R Event id returned by add event */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Requested data is not necessarily stable prior to */
|
||||
/* return from called subroutine. Call ca_pend_io() */
|
||||
/* to guarantee that requested data is stable. Call the routine */
|
||||
/* ca_flush_io() to force all outstanding subroutine calls to be */
|
||||
/* sent out over the network. Significant increases in */
|
||||
/* performance have been measured when batching several remote */
|
||||
/* subroutine calls together into one message. Additional */
|
||||
/* improvements can be obtained by performing local processing */
|
||||
/* in parallel with outstanding remote processing. */
|
||||
/* */
|
||||
/* FLOW OF TYPICAL APPLICATION */
|
||||
/* */
|
||||
/* search() ! Obtain Channel ids */
|
||||
/* . ! " */
|
||||
/* */
|
||||
/* get() ! several requests for remote info */
|
||||
/* get() ! " */
|
||||
/* add_event() ! " */
|
||||
/* get() ! " */
|
||||
/* . */
|
||||
/* . */
|
||||
/* . */
|
||||
/* flush_io() ! send get requests */
|
||||
/* ! optional parallel processing */
|
||||
/* . ! " */
|
||||
/* . ! " */
|
||||
/* pend_io() ! wait for replies from get requests */
|
||||
/* . ! access to requested data */
|
||||
/* . ! " */
|
||||
/* pend_event() ! wait for requested events */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
/************************************************************************/
|
||||
/* This routine pends waiting for channel events and calls the */
|
||||
/* functions specified with add_event when events occur. If the */
|
||||
/* timeout is specified as 0 an infinite timeout is assumed. */
|
||||
/* if the argument early is specified TRUE then CA_NORMAL is */
|
||||
/* returned when outstanding queries complete. Otherwise if the */
|
||||
/* argument early is FALSE the routine does not return until the */
|
||||
/* entire delay specified by the timeout argument has expired. */
|
||||
/* ca_flush_io() is called by this routine. If the argument */
|
||||
/* early is TRUE then ca_pend() will return immediately without */
|
||||
/* processing outstanding CA labor if no queries are outstanding */
|
||||
/************************************************************************/
|
||||
#define ca_pend_event(TIMEOUT) ca_pend((TIMEOUT), 0/*FALSE*/)
|
||||
#define ca_pend_io(TIMEOUT) ca_pend((TIMEOUT), 1/*TRUE*/)
|
||||
|
||||
int epicsShareAPI ca_pend
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
ca_real,/* TIMEOUT R timeout in seconds */
|
||||
int /* EARLY R return early if IO completes */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* returns TRUE when queries are outstanding
|
||||
*/
|
||||
int epicsShareAPI ca_test_io
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
void
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/************************************************************************/
|
||||
/* Send out all outstanding messages in the send queue */
|
||||
/************************************************************************/
|
||||
int epicsShareAPI ca_flush_io
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
void
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
|
||||
void epicsShareAPI ca_signal
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
long, /* CODE R status returned from channel access function */
|
||||
char * /* MSG R null term string printed on error */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
void epicsShareAPI ca_signal_with_file_and_lineno
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
long, /* CODE R status returned from channel access function */
|
||||
char *, /* MSG R null term string printed on error */
|
||||
char *, /* FILE R pointer to null terminated file name string */
|
||||
int /* LINENO R line number */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Provided for efficient test and display of channel access errors
|
||||
*/
|
||||
#define SEVCHK(CA_ERROR_CODE, MESSAGE_STRING) \
|
||||
{ \
|
||||
int ca_unique_status_name = (CA_ERROR_CODE); \
|
||||
if(!(ca_unique_status_name & CA_M_SUCCESS)) \
|
||||
ca_signal_with_file_and_lineno( \
|
||||
ca_unique_status_name, \
|
||||
(MESSAGE_STRING), \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
}
|
||||
|
||||
char * epicsShareAPI ca_host_name_function
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
chid /* CHID R Channel ID */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* CA_ADD_FD_REGISTRATION
|
||||
*
|
||||
* call their function with their argument whenever
|
||||
* a new fd is added or removed
|
||||
* (for use with a manager of the select system call under UNIX)
|
||||
*
|
||||
*/
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
typedef void CAFDHANDLER(void *parg, int fd, int opened);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
typedef void CAFDHANDLER();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
|
||||
int epicsShareAPI ca_add_fd_registration(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
CAFDHANDLER *pHandler,
|
||||
void *pArg
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
#ifdef vxWorks
|
||||
int epicsShareAPI ca_channel_status(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
int tid
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef vxWorks
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
int ca_import(int tid);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
int ca_import();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
#endif /* vxWorks */
|
||||
|
||||
#ifdef vxWorks
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
int ca_import_cancel(int tid);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
int ca_import_cancel();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
#endif /* vxWorks */
|
||||
|
||||
/*
|
||||
* CA synch groups
|
||||
*
|
||||
* This facility will allow the programmer to create
|
||||
* any number of synchronization groups. The programmer might then
|
||||
* interleave IO requests within any of the groups. Once The
|
||||
* IO operations are initiated then the programmer is free to
|
||||
* block for IO completion within any one of the groups as needed.
|
||||
*/
|
||||
typedef unsigned WRITEABLE_CA_SYNC_GID;
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
typedef const unsigned CA_SYNC_GID;
|
||||
#else
|
||||
typedef unsigned CA_SYNC_GID;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* create a sync group
|
||||
*/
|
||||
int epicsShareAPI ca_sg_create(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
CA_SYNC_GID *pgid
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* delete a sync group
|
||||
*/
|
||||
int epicsShareAPI ca_sg_delete(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
CA_SYNC_GID gid
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* block for IO performed within a sync group to complete
|
||||
*/
|
||||
int epicsShareAPI ca_sg_block(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
CA_SYNC_GID gid,
|
||||
ca_real timeout
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* test for sync group IO operations in progress
|
||||
*/
|
||||
int epicsShareAPI ca_sg_test(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
CA_SYNC_GID gid
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* ca_sg_reset
|
||||
*/
|
||||
int epicsShareAPI ca_sg_reset(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
CA_SYNC_GID gid
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* initiate a get within a sync group
|
||||
* (essentially a ca_array_get() with a sync group specified)
|
||||
*/
|
||||
int epicsShareAPI ca_sg_array_get
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
CA_SYNC_GID,/* GID R synch group id */
|
||||
chtype, /* TYPE R channel type */
|
||||
unsigned long,
|
||||
/* COUNT R array element count */
|
||||
chid, /* CHID R channel index */
|
||||
void * /* PVALUE W ptr to where channel value written */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* initiate a put within a sync group
|
||||
* (essentially a ca_array_put() with a sync group specified)
|
||||
*/
|
||||
int epicsShareAPI ca_sg_array_put
|
||||
(
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
/* Name IO Value */
|
||||
/* ---- -- ----- */
|
||||
CA_SYNC_GID,/* GID R synch group id */
|
||||
chtype, /* TYPE R channel type */
|
||||
unsigned long,
|
||||
/* COUNT R array element count */
|
||||
chid, /* CHID R channel index */
|
||||
void * /* PVALUE R pointer to new channel value of type */
|
||||
/* specified. */
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
);
|
||||
|
||||
/*
|
||||
* CA_MODIFY_USER_NAME()
|
||||
*
|
||||
* Modify or override the default
|
||||
* client user name.
|
||||
*/
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
int epicsShareAPI ca_modify_user_name(char *pUserName);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
int epicsShareAPI ca_modify_user_name();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
|
||||
/*
|
||||
* CA_MODIFY_HOST_NAME()
|
||||
*
|
||||
* Modify or override the default
|
||||
* client host name.
|
||||
*/
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
int epicsShareAPI ca_modify_host_name(char *pHostName);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
int epicsShareAPI ca_modify_host_name();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
|
||||
/*
|
||||
* Put call back is available if the CA server is on version is 4.2
|
||||
* or higher.
|
||||
*
|
||||
* (return true or false)
|
||||
*/
|
||||
#ifdef CAC_FUNC_PROTO
|
||||
int epicsShareAPI ca_v42_ok(chid chan);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
int epicsShareAPI ca_v42_ok();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
|
||||
/*
|
||||
* ca_replace_printf_handler ()
|
||||
*
|
||||
* for apps that want to change where ca formatted
|
||||
* text output goes
|
||||
*/
|
||||
#if defined(CAC_FUNC_PROTO) && !defined(CA_DONT_INCLUDE_STDARGH)
|
||||
int epicsShareAPI ca_replace_printf_handler (
|
||||
int (*ca_printf_func)(const char *pformat, va_list args)
|
||||
);
|
||||
#else /*CAC_FUNC_PROTO*/
|
||||
int epicsShareAPI ca_replace_printf_handler ();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* no additions below this endif
|
||||
*/
|
||||
#endif /* INCLcadefh */
|
||||
216
src/ca/caerr.h
Normal file
216
src/ca/caerr.h
Normal file
@@ -0,0 +1,216 @@
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* L O S A L A M O S */
|
||||
/* Los Alamos National Laboratory */
|
||||
/* Los Alamos, New Mexico 87545 */
|
||||
/* */
|
||||
/* Copyright, 1986, The Regents of the University of California. */
|
||||
/* */
|
||||
/* Author: Jeffrey O. Hill */
|
||||
/* */
|
||||
/* History */
|
||||
/* ------- */
|
||||
/* */
|
||||
/* Date Programmer Comments */
|
||||
/* ---- ---------- -------- */
|
||||
/* 08--87 joh Init Release */
|
||||
/* 031290 joh Changed __CAERR__ to INCLcaerrh */
|
||||
/* 102990 joh added readonly for VAXC share image */
|
||||
/* 032092 joh added ECA_BADMASK */
|
||||
/* 072792 joh added ECA_IODONE & ECA_IOINPROGESS */
|
||||
/* 102992 joh changed wording on the no vx fp message */
|
||||
/* 011494 joh Added ECA_BADSYNCGRP */
|
||||
/* 021194 joh Added ECA_PUTCBINPROG */
|
||||
/* */
|
||||
/*_begin */
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Name: */
|
||||
/* Title: */
|
||||
/* File: */
|
||||
/* Environment: VMS, UNIX, VRTX */
|
||||
/* Equipment: VAX, SUN, VME */
|
||||
/* */
|
||||
/* */
|
||||
/* Purpose */
|
||||
/* ------- */
|
||||
/* */
|
||||
/* CA error message declaration include file */
|
||||
/* */
|
||||
/* */
|
||||
/* Special comments */
|
||||
/* ------- -------- */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
/*_end */
|
||||
|
||||
#ifndef INCLcaerrh
|
||||
#define INCLcaerrh
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
#ifndef HDRVERSIONID
|
||||
# define HDRVERSIONID(NAME,VERS)
|
||||
#endif /*HDRVERSIONID*/
|
||||
|
||||
HDRVERSIONID(caerrh, "@(#) $Id$")
|
||||
|
||||
/* CA Status Code Definitions */
|
||||
|
||||
#define CA_K_INFO 3 /* successful */
|
||||
#define CA_K_ERROR 2 /* failed- continue */
|
||||
#define CA_K_SUCCESS 1 /* successful */
|
||||
#define CA_K_WARNING 0 /* unsuccessful */
|
||||
#define CA_K_SEVERE 4 /* failed- quit */
|
||||
#define CA_K_FATAL CA_K_ERROR | CA_K_SEVERE
|
||||
|
||||
#define CA_M_MSG_NO 0x0000FFF8
|
||||
#define CA_M_SEVERITY 0x00000007
|
||||
#define CA_M_LEVEL 0x00000003
|
||||
#define CA_M_SUCCESS 0x00000001
|
||||
#define CA_M_ERROR 0x00000002
|
||||
#define CA_M_SEVERE 0x00000004
|
||||
|
||||
#define CA_S_MSG_NO 0x0D
|
||||
#define CA_S_SEVERITY 0x03
|
||||
|
||||
#define CA_V_MSG_NO 0x03
|
||||
#define CA_V_SEVERITY 0x00
|
||||
#define CA_V_SUCCESS 0x00
|
||||
|
||||
/* Define MACROS to extract/insert individual fields from a status value */
|
||||
|
||||
#define CA_EXTRACT_MSG_NO(code)\
|
||||
( ( (code) & CA_M_MSG_NO ) >> CA_V_MSG_NO )
|
||||
#define CA_EXTRACT_SEVERITY(code)\
|
||||
( ( (code) & CA_M_SEVERITY ) >> CA_V_SEVERITY )
|
||||
#define CA_EXTRACT_SUCCESS(code)\
|
||||
( ( (code) & CA_M_SUCCESS ) >> CA_V_SUCCESS )
|
||||
|
||||
#define CA_INSERT_MSG_NO(code)\
|
||||
( ((code)<< CA_V_MSG_NO) & CA_M_MSG_NO )
|
||||
#define CA_INSERT_SEVERITY(code)\
|
||||
( ((code)<< CA_V_SEVERITY)& CA_M_SEVERITY )
|
||||
#define CA_INSERT_SUCCESS(code)\
|
||||
( ((code)<< CA_V_SUCCESS) & CA_M_SUCCESS )
|
||||
|
||||
|
||||
#define DEFMSG(SEVERITY,NUMBER)\
|
||||
(CA_INSERT_MSG_NO(NUMBER) | CA_INSERT_SEVERITY(SEVERITY))
|
||||
|
||||
|
||||
#define ECA_NORMAL DEFMSG(CA_K_SUCCESS, 0)
|
||||
#define ECA_MAXIOC DEFMSG(CA_K_ERROR, 1)
|
||||
#define ECA_UKNHOST DEFMSG(CA_K_ERROR, 2)
|
||||
#define ECA_UKNSERV DEFMSG(CA_K_ERROR, 3)
|
||||
#define ECA_SOCK DEFMSG(CA_K_ERROR, 4)
|
||||
#define ECA_CONN DEFMSG(CA_K_WARNING, 5)
|
||||
#define ECA_ALLOCMEM DEFMSG(CA_K_WARNING, 6)
|
||||
#define ECA_UKNCHAN DEFMSG(CA_K_WARNING, 7)
|
||||
#define ECA_UKNFIELD DEFMSG(CA_K_WARNING, 8)
|
||||
#define ECA_TOLARGE DEFMSG(CA_K_ERROR, 9)
|
||||
#define ECA_TIMEOUT DEFMSG(CA_K_WARNING, 10)
|
||||
#define ECA_NOSUPPORT DEFMSG(CA_K_WARNING, 11)
|
||||
#define ECA_STRTOBIG DEFMSG(CA_K_WARNING, 12)
|
||||
#define ECA_BADCHID DEFMSG(CA_K_ERROR, 13)
|
||||
#define ECA_BADTYPE DEFMSG(CA_K_ERROR, 14)
|
||||
#define ECA_CHIDNOTFND DEFMSG(CA_K_INFO, 15)
|
||||
#define ECA_CHIDRETRY DEFMSG(CA_K_INFO, 16)
|
||||
#define ECA_INTERNAL DEFMSG(CA_K_FATAL, 17)
|
||||
#define ECA_DBLCLFAIL DEFMSG(CA_K_WARNING, 18)
|
||||
#define ECA_GETFAIL DEFMSG(CA_K_WARNING, 19)
|
||||
#define ECA_PUTFAIL DEFMSG(CA_K_WARNING, 20)
|
||||
#define ECA_ADDFAIL DEFMSG(CA_K_WARNING, 21)
|
||||
#define ECA_BADCOUNT DEFMSG(CA_K_WARNING, 22)
|
||||
#define ECA_BADSTR DEFMSG(CA_K_ERROR, 23)
|
||||
#define ECA_DISCONN DEFMSG(CA_K_INFO, 24)
|
||||
#define ECA_DBLCHNL DEFMSG(CA_K_INFO, 25)
|
||||
#define ECA_EVDISALLOW DEFMSG(CA_K_ERROR, 26)
|
||||
#define ECA_BUILDGET DEFMSG(CA_K_WARNING, 27)
|
||||
#define ECA_NEEDSFP DEFMSG(CA_K_INFO, 28)
|
||||
#define ECA_OVEVFAIL DEFMSG(CA_K_WARNING, 29)
|
||||
#define ECA_BADMONID DEFMSG(CA_K_ERROR, 30)
|
||||
#define ECA_NEWADDR DEFMSG(CA_K_INFO, 31)
|
||||
#define ECA_NEWCONN DEFMSG(CA_K_INFO, 32)
|
||||
#define ECA_NOCACTX DEFMSG(CA_K_WARNING, 33)
|
||||
#define ECA_DEFUNCT DEFMSG(CA_K_FATAL, 34)
|
||||
#define ECA_EMPTYSTR DEFMSG(CA_K_WARNING, 35)
|
||||
#define ECA_NOREPEATER DEFMSG(CA_K_INFO, 36)
|
||||
#define ECA_NOCHANMSG DEFMSG(CA_K_INFO, 37)
|
||||
#define ECA_DLCKREST DEFMSG(CA_K_INFO, 38)
|
||||
#define ECA_SERVBEHIND DEFMSG(CA_K_INFO, 39)
|
||||
#define ECA_NOCAST DEFMSG(CA_K_WARNING, 40)
|
||||
#define ECA_BADMASK DEFMSG(CA_K_ERROR, 41)
|
||||
#define ECA_IODONE DEFMSG(CA_K_INFO, 42)
|
||||
#define ECA_IOINPROGRESS DEFMSG(CA_K_INFO, 43)
|
||||
#define ECA_BADSYNCGRP DEFMSG(CA_K_ERROR, 44)
|
||||
#define ECA_PUTCBINPROG DEFMSG(CA_K_ERROR, 45)
|
||||
#define ECA_NORDACCESS DEFMSG(CA_K_WARNING, 46)
|
||||
#define ECA_NOWTACCESS DEFMSG(CA_K_WARNING, 47)
|
||||
#define ECA_ANACHRONISM DEFMSG(CA_K_ERROR, 48)
|
||||
#define ECA_NOSEARCHADDR DEFMSG(CA_K_WARNING, 49)
|
||||
|
||||
|
||||
#ifndef CA_ERROR_GLBLSOURCE
|
||||
epicsShareExtern char *ca_message_text[];
|
||||
#else
|
||||
char *ca_message_text[]
|
||||
=
|
||||
{
|
||||
"Normal successful completion",
|
||||
"Maximum simultaneous IOC connections exceeded",
|
||||
"Unknown internet host",
|
||||
"Unknown internet service",
|
||||
"Unable to allocate a new socket",
|
||||
"Unable to connect to internet host or service",
|
||||
"Unable to allocate additional dynamic memory",
|
||||
"Unknown IO channel",
|
||||
"Record field specified inappropriate for channel specified",
|
||||
"The array or data structure specified will not fit in CA message buffer",
|
||||
"User specified timeout on IO operation expired",
|
||||
"Sorry, that feature is planned but not supported at this time",
|
||||
"The supplied string is unusually large",
|
||||
"The request was ignored because the specified channel is disconnected",
|
||||
"The type you have requested from this channel is unknown",
|
||||
"Remote Channel not found",
|
||||
"Unable to locate all user specified channels",
|
||||
"Channel Access Internal Failure",
|
||||
"The requested local DB operation failed",
|
||||
"Could not perform a database value get for that channel",
|
||||
"Could not perform a database value put for that channel",
|
||||
"Could not perform a database event add for that channel",
|
||||
"Count requested inappropriate for that channel",
|
||||
"The supplied string has improper format",
|
||||
"Network connection lost",
|
||||
"Ambiguous channel host (multiple IOC's have a channel by that name)",
|
||||
"The CA routine called is inappropriate for use within an event handler",
|
||||
"Database value get for that channel failed during channel search",
|
||||
"Unable to initialize without the vxWorks VX_FP_TASK task option set",
|
||||
"Event queue overflow has prevented first pass event after event add",
|
||||
"A monitor by that id cant be found",
|
||||
"Remote channel has new network address",
|
||||
"New or resumed network connection",
|
||||
"Attempt to import from a task without a CA context failed",
|
||||
"Attempt to use defunct CA feature failed",
|
||||
"The supplied string is empty",
|
||||
"Unable to spawn the CA repeater thread- auto reconnect will fail",
|
||||
"No channel id match for search reply- search reply ignored",
|
||||
"Reseting dead connection- will try to reconnect",
|
||||
"Server (IOC) has fallen behind or is not responding- still waiting",
|
||||
"No internet interface with broadcast available",
|
||||
"The event selection mask supplied is empty or inappropriate",
|
||||
"IO operations have completed",
|
||||
"IO operations are in progress",
|
||||
"Invalid synchronous group identifier",
|
||||
"Put call back operation collision with put call back operation in progress",
|
||||
"Read access denied",
|
||||
"Write access denied",
|
||||
"Sorry, that anachronistic feature of CA is no longer supported",
|
||||
"The search request/beacon address list was empty after initialization"
|
||||
};
|
||||
#endif
|
||||
|
||||
#define ca_message(STATUS)\
|
||||
(ca_message_text[CA_EXTRACT_MSG_NO((STATUS))])
|
||||
|
||||
#endif
|
||||
36
src/ca/caeventmask.h
Normal file
36
src/ca/caeventmask.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
$Id$
|
||||
caeventmask.h
|
||||
|
||||
Modification History
|
||||
joh 04-16-90 Created
|
||||
|
||||
*/
|
||||
|
||||
#ifndef INCLcaeventmaskh
|
||||
#define INCLcaeventmaskh
|
||||
|
||||
/*
|
||||
event selections
|
||||
(If any more than 8 of these are needed then update the
|
||||
select field in the event_block struct in db_event.c from
|
||||
unsigned char to unsigned short)
|
||||
|
||||
|
||||
DBE_VALUE
|
||||
Trigger an event when a significant change in the channel's value
|
||||
occurs. Relies on the monitor deadband field under DCT.
|
||||
|
||||
DBE_LOG
|
||||
Trigger an event when an archive significant change in the channel's
|
||||
valuue occurs. Relies on the archiver monitor deadband field under DCT.
|
||||
|
||||
DBE_ALARM
|
||||
Trigger an event when the alarm state changes
|
||||
|
||||
*/
|
||||
#define DBE_VALUE (1<<0)
|
||||
#define DBE_LOG (1<<1)
|
||||
#define DBE_ALARM (1<<2)
|
||||
|
||||
#endif
|
||||
25
src/ca/calink.h
Normal file
25
src/ca/calink.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
#ifndef INCcalinkh
|
||||
#define INCcalinkh
|
||||
|
||||
#ifndef INCerrMdefh
|
||||
#include <errMdef.h>
|
||||
#endif
|
||||
#define S_dbCa_nullarg (M_dbCa | 1) /*dbCa_nullarg*/
|
||||
#define S_dbCa_failedmalloc (M_dbCa | 3) /*dbCa_failedmalloc*/
|
||||
#define S_dbCa_foundnull (M_dbCa | 5) /*dbCa_foundnull*/
|
||||
#define S_dbCa_ECA_EVDISALLOW (M_dbCa | 7) /*dbCa_ECA_EVDISALLOW*/
|
||||
#define S_dbCa_ECA_BADCHID (M_dbCa | 9) /*dbCa_ECA_BADCHID*/
|
||||
#define S_dbCa_ECA_BADTYPE (M_dbCa | 11) /*dbCa_ECA_BADTYPE*/
|
||||
#define S_dbCa_ECA_ALLOCMEM (M_dbCa | 13) /*dbCa_ECA_ALLOCMEM*/
|
||||
#define S_dbCa_ECA_ADDFAIL (M_dbCa | 15) /*dbCa_ECA_ADDFAIL*/
|
||||
#define S_dbCa_ECA_STRTOBIG (M_dbCa | 17) /*dbCa_ECA_STRTOBIG*/
|
||||
#define S_dbCa_ECA_GETFAIL (M_dbCa | 19) /*dbCa_ECA_GETFAIL*/
|
||||
#define S_dbCa_ECA_BADCOUNT (M_dbCa | 21) /*dbCa_ECA_BADCOUNT*/
|
||||
#define S_dbCa_ECA_PUTFAIL (M_dbCa | 23) /*dbCa_ECA_PUTFAIL*/
|
||||
#define S_dbCa_unknownECA (M_dbCa | 25) /*dbCa_unknownECA*/
|
||||
#define S_dbCa_dbfailure (M_dbCa | 27) /*dbCa_dbfailure*/
|
||||
#define S_dbCa_cafailure (M_dbCa | 29) /*dbCa_cafailure*/
|
||||
#endif /* INCcalinkh */
|
||||
@@ -141,7 +141,7 @@ int catime (char *channelName)
|
||||
itemList[i].val.intval = 0;
|
||||
itemList[i].type = DBR_INT;
|
||||
}
|
||||
printf ("interger test\n");
|
||||
printf ("integer test\n");
|
||||
test (itemList, NELEMENTS(itemList));
|
||||
|
||||
printf ("free test\n");
|
||||
|
||||
@@ -51,7 +51,6 @@ void flow_control(struct ioc_in_use *piiu)
|
||||
{
|
||||
unsigned nbytes;
|
||||
int status;
|
||||
int busy = piiu->client_busy;
|
||||
|
||||
LOCK;
|
||||
|
||||
@@ -74,19 +73,19 @@ void flow_control(struct ioc_in_use *piiu)
|
||||
*/
|
||||
if (nbytes) {
|
||||
piiu->contiguous_msg_count++;
|
||||
if (!busy)
|
||||
if (!piiu->client_busy)
|
||||
if (piiu->contiguous_msg_count >
|
||||
MAX_CONTIGUOUS_MSG_COUNT) {
|
||||
piiu->client_busy = TRUE;
|
||||
ca_busy_message(piiu);
|
||||
# ifdef DEBUG
|
||||
# if defined(DEBUG)
|
||||
printf("fc on\n");
|
||||
# endif
|
||||
}
|
||||
} else {
|
||||
piiu->contiguous_msg_count = 0;
|
||||
if (busy) {
|
||||
# ifdef DEBUG
|
||||
if (piiu->client_busy) {
|
||||
# if defined(DEBUG)
|
||||
printf("fc off\n");
|
||||
# endif
|
||||
ca_ready_message(piiu);
|
||||
|
||||
@@ -45,8 +45,6 @@ static char *sccsId = "@(#) $Id$";
|
||||
* also called by the server. All locks required are applied at
|
||||
* a higher level.
|
||||
*/
|
||||
#undef LOCK
|
||||
#undef UNLOCK
|
||||
|
||||
|
||||
/*
|
||||
@@ -295,9 +293,9 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port)
|
||||
continue;
|
||||
}
|
||||
|
||||
pNode->destAddr.inetAddr = *pInetAddr;
|
||||
pNode->destAddr.inetAddr.sin_port = htons(port);
|
||||
pNode->srcAddr.inetAddr = localAddr;
|
||||
pNode->destAddr.in = *pInetAddr;
|
||||
pNode->destAddr.in.sin_port = htons(port);
|
||||
pNode->srcAddr.in = localAddr;
|
||||
|
||||
/*
|
||||
* LOCK applied externally
|
||||
|
||||
@@ -46,7 +46,10 @@
|
||||
/* 021794 joh turn on SO_REUSEADDR only after the test for */
|
||||
/* address in use so that test works on UNIX */
|
||||
/* kernels that support multicast */
|
||||
/* $Log$ */
|
||||
/* $Log$
|
||||
* Revision 1.60 1995/11/29 19:26:01 jhill
|
||||
* cleaned up interface to recv() and send()
|
||||
* */
|
||||
/* */
|
||||
/*_begin */
|
||||
/************************************************************************/
|
||||
@@ -84,6 +87,7 @@ LOCAL void ca_process_tcp(struct ioc_in_use *piiu);
|
||||
LOCAL void ca_process_udp(struct ioc_in_use *piiu);
|
||||
LOCAL void cacRingBufferInit(struct ca_buffer *pBuf, unsigned long size);
|
||||
LOCAL char *getToken(char **ppString);
|
||||
LOCAL void close_ioc (IIU *piiu);
|
||||
|
||||
|
||||
|
||||
@@ -158,7 +162,9 @@ int net_proto
|
||||
int status;
|
||||
SOCKET sock;
|
||||
int true = TRUE;
|
||||
#if 0
|
||||
struct sockaddr_in saddr;
|
||||
#endif
|
||||
caAddrNode *pNode;
|
||||
|
||||
LOCK;
|
||||
@@ -193,9 +199,9 @@ int net_proto
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
memset((char *)&pNode->destAddr,0,sizeof(pNode->destAddr));
|
||||
pNode->destAddr.inetAddr.sin_family = AF_INET;
|
||||
pNode->destAddr.inetAddr.sin_addr = *pnet_addr;
|
||||
pNode->destAddr.inetAddr.sin_port = htons (port);
|
||||
pNode->destAddr.in.sin_family = AF_INET;
|
||||
pNode->destAddr.in.sin_addr = *pnet_addr;
|
||||
pNode->destAddr.in.sin_port = htons (port);
|
||||
ellAdd(&piiu->destAddr, &pNode->node);
|
||||
piiu->recvBytes = tcp_recv_msg;
|
||||
piiu->sendBytes = cac_tcp_send_msg_piiu;
|
||||
@@ -326,8 +332,8 @@ int net_proto
|
||||
/* connect */
|
||||
status = connect(
|
||||
sock,
|
||||
&pNode->destAddr.sockAddr,
|
||||
sizeof(pNode->destAddr.sockAddr));
|
||||
&pNode->destAddr.sa,
|
||||
sizeof(pNode->destAddr.sa));
|
||||
if(status < 0){
|
||||
ca_printf("CAC: no conn err=\"%s\"\n", strerror(MYERRNO));
|
||||
status = socket_close(sock);
|
||||
@@ -396,6 +402,7 @@ int net_proto
|
||||
return ECA_CONN;
|
||||
}
|
||||
|
||||
#if 0
|
||||
memset((char *)&saddr,0,sizeof(saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
/*
|
||||
@@ -411,6 +418,7 @@ int net_proto
|
||||
ca_printf("CAC: bind (err=%s)\n",strerror(MYERRNO));
|
||||
ca_signal(ECA_INTERNAL,"bind failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* load user and auto configured
|
||||
@@ -672,8 +680,8 @@ LOCAL void cac_udp_send_msg_piiu(struct ioc_in_use *piiu)
|
||||
&piiu->send.buf[piiu->send.rdix],
|
||||
(int) sendCnt,
|
||||
0,
|
||||
&pNode->destAddr.sockAddr,
|
||||
sizeof(pNode->destAddr.sockAddr));
|
||||
&pNode->destAddr.sa,
|
||||
sizeof(pNode->destAddr.sa));
|
||||
if(status>=0){
|
||||
actualSendCnt = (unsigned long) status;
|
||||
assert (actualSendCnt == sendCnt);
|
||||
@@ -985,7 +993,7 @@ LOCAL void ca_process_tcp(struct ioc_in_use *piiu)
|
||||
/* post message to the user */
|
||||
status = post_msg(
|
||||
piiu,
|
||||
&pNode->destAddr.inetAddr.sin_addr,
|
||||
&pNode->destAddr.in.sin_addr,
|
||||
&piiu->recv.buf[piiu->recv.rdix],
|
||||
bytesToProcess);
|
||||
if(status != OK){
|
||||
@@ -1184,7 +1192,7 @@ LOCAL void ca_process_udp(struct ioc_in_use *piiu)
|
||||
*
|
||||
*
|
||||
*/
|
||||
void close_ioc (struct ioc_in_use *piiu)
|
||||
LOCAL void close_ioc (IIU *piiu)
|
||||
{
|
||||
caAddrNode *pNode;
|
||||
chid chix;
|
||||
@@ -1216,7 +1224,7 @@ void close_ioc (struct ioc_in_use *piiu)
|
||||
*/
|
||||
pNode = (caAddrNode *) piiu->destAddr.node.next;
|
||||
assert (pNode);
|
||||
removeBeaconInetAddr (&pNode->destAddr.inetAddr.sin_addr);
|
||||
removeBeaconInetAddr (&pNode->destAddr.in.sin_addr);
|
||||
|
||||
/*
|
||||
* Mark all of their channels disconnected
|
||||
@@ -1618,13 +1626,13 @@ char *localHostName()
|
||||
void caAddConfiguredAddr(ELLLIST *pList, ENV_PARAM *pEnv,
|
||||
SOCKET socket, int port)
|
||||
{
|
||||
caAddrNode *pNode;
|
||||
ENV_PARAM list;
|
||||
char *pStr;
|
||||
char *pToken;
|
||||
union caAddr addr;
|
||||
union caAddr localAddr;
|
||||
int status;
|
||||
caAddrNode *pNode;
|
||||
ENV_PARAM list;
|
||||
char *pStr;
|
||||
char *pToken;
|
||||
caAddr addr;
|
||||
caAddr localAddr;
|
||||
int status;
|
||||
|
||||
pStr = envGetConfigParam(
|
||||
pEnv,
|
||||
@@ -1637,17 +1645,17 @@ void caAddConfiguredAddr(ELLLIST *pList, ENV_PARAM *pEnv,
|
||||
/*
|
||||
* obtain a local address
|
||||
*/
|
||||
status = local_addr(socket, &localAddr.inetAddr);
|
||||
status = local_addr(socket, &localAddr.in);
|
||||
if(status){
|
||||
return;
|
||||
}
|
||||
|
||||
while(pToken = getToken(&pStr)){
|
||||
memset((char *)&addr,0,sizeof(addr));
|
||||
addr.inetAddr.sin_family = AF_INET;
|
||||
addr.inetAddr.sin_port = htons(port);
|
||||
addr.inetAddr.sin_addr.s_addr = inet_addr(pToken);
|
||||
if(addr.inetAddr.sin_addr.s_addr == -1){
|
||||
addr.in.sin_family = AF_INET;
|
||||
addr.in.sin_port = htons(port);
|
||||
addr.in.sin_addr.s_addr = inet_addr(pToken);
|
||||
if(addr.in.sin_addr.s_addr == -1){
|
||||
ca_printf(
|
||||
"%s: Parsing '%s'\n",
|
||||
__FILE__,
|
||||
@@ -1660,11 +1668,9 @@ void caAddConfiguredAddr(ELLLIST *pList, ENV_PARAM *pEnv,
|
||||
|
||||
pNode = (caAddrNode *) calloc(1,sizeof(*pNode));
|
||||
if(pNode){
|
||||
pNode->destAddr.inetAddr = addr.inetAddr;
|
||||
pNode->srcAddr.inetAddr = localAddr.inetAddr;
|
||||
LOCK;
|
||||
pNode->destAddr.in = addr.in;
|
||||
pNode->srcAddr.in = localAddr.in;
|
||||
ellAdd(pList, &pNode->node);
|
||||
UNLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1719,12 +1725,12 @@ void caPrintAddrList(ELLLIST *pList)
|
||||
printf("Channel Access Address List\n");
|
||||
pNode = (caAddrNode *) ellFirst(pList);
|
||||
while(pNode){
|
||||
if(pNode->destAddr.sockAddr.sa_family != AF_INET){
|
||||
if(pNode->destAddr.sa.sa_family != AF_INET){
|
||||
printf("<addr entry not in internet format>");
|
||||
continue;
|
||||
}
|
||||
printf( "%s\n",
|
||||
inet_ntoa(pNode->destAddr.inetAddr.sin_addr));
|
||||
inet_ntoa(pNode->destAddr.in.sin_addr));
|
||||
|
||||
pNode = (caAddrNode *) ellNext(&pNode->node);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
/************************************************************************/
|
||||
|
||||
/* $Log$
|
||||
* Revision 1.50 1995/10/18 16:45:40 jhill
|
||||
* Use recast delay greater than one vxWorks tick
|
||||
*
|
||||
* Revision 1.49 1995/10/12 01:33:12 jhill
|
||||
* Initial delay between search frames went from .1 to .01 sec,
|
||||
* Added flush pending flag, Make all usage of port be unsigned short.
|
||||
@@ -603,7 +606,6 @@ void freeBeaconHash(struct ca_static *ca_temp);
|
||||
void removeBeaconInetAddr(const struct in_addr *pnet_addr);
|
||||
bhe *lookupBeaconInetAddr(const struct in_addr *pnet_addr);
|
||||
bhe *createBeaconHashEntry(const struct in_addr *pnet_addr);
|
||||
void close_ioc(IIU *piiu);
|
||||
void notify_ca_repeater(void);
|
||||
void cac_clean_iiu_list(void);
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.16 1995/10/12 01:35:28 jhill
|
||||
* Moved cac_mux_io() to iocinf.c
|
||||
*
|
||||
* Revision 1.15 1995/08/22 00:22:07 jhill
|
||||
* Dont recompute connection timers if the time stamp hasnt changed
|
||||
*
|
||||
@@ -223,11 +226,11 @@ void ca_spawn_repeater()
|
||||
* if here
|
||||
*/
|
||||
pImageName = "caRepeater";
|
||||
status = execlp(pImageName, NULL);
|
||||
status = execlp(pImageName, pImageName, NULL);
|
||||
if(status<0){
|
||||
ca_printf("!!WARNING!!\n");
|
||||
ca_printf("The executable \"%s\" couldnt be located\n", pImageName);
|
||||
ca_printf("because - %s\n", strerror(MYERRNO));
|
||||
ca_printf("because of errno = \"%s\"\n", strerror(MYERRNO));
|
||||
ca_printf("You may need to modify your PATH environment variable.\n");
|
||||
ca_printf("Creating CA repeater with fork() system call.\n");
|
||||
ca_printf("Repeater will inherit parents process name and resources.\n");
|
||||
|
||||
@@ -795,7 +795,7 @@ const struct in_addr *pnet_addr
|
||||
|
||||
pNode = (caAddrNode *) chpiiu->destAddr.node.next;
|
||||
assert(pNode);
|
||||
if (pNode->destAddr.inetAddr.sin_addr.s_addr !=
|
||||
if (pNode->destAddr.in.sin_addr.s_addr !=
|
||||
pnet_addr->s_addr) {
|
||||
|
||||
caHostFromInetAddr(pnet_addr,rej,sizeof(rej));
|
||||
|
||||
12
src/ca/ucx.h
12
src/ca/ucx.h
@@ -8,6 +8,9 @@
|
||||
* CJM 13-Jul-1994 add fd_set etc for R3.12
|
||||
* CJM 09-Dec-1994 define fd_set etc. so it will compile for
|
||||
* both DEC C and Vax C
|
||||
* CJM 19-Nov-1995 use memset instead of bzero following advice
|
||||
* from Jeff Hill and add a definition of struct
|
||||
* timezone to support gettimeofday
|
||||
*
|
||||
*/
|
||||
#ifndef _UCX_H_
|
||||
@@ -85,7 +88,14 @@ typedef int fd_set ;
|
||||
#include <iodef.h>
|
||||
#define IO$_RECEIVE (IO$_WRITEVBLK)
|
||||
|
||||
struct timezone {
|
||||
int tz_minuteswest ; /* minutes west of Greenwich */
|
||||
int tz_dsttime ; /* type of dst correction */
|
||||
};
|
||||
|
||||
#define TWOPOWER32 4294967296.0
|
||||
#define TWOPOWER31 2147483648.0
|
||||
#define UNIX_EPOCH_AS_MJD 40587.0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -26,9 +26,15 @@
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* cjm 20-Nov-95 Add code for gettimeofday
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.18 1995/10/12 01:35:30 jhill
|
||||
* Moved cac_mux_io() to iocinf.c
|
||||
*
|
||||
* Revision 1.17 1995/08/22 00:27:56 jhill
|
||||
* added cvs style mod log
|
||||
*
|
||||
@@ -44,7 +50,13 @@
|
||||
|
||||
#include "iocinf.h"
|
||||
|
||||
#ifdef UCX
|
||||
#include "ucx.h"
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define CONNECTION_TIMER_ID 56
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -59,6 +71,51 @@ void cac_gettimeval(struct timeval *pt)
|
||||
assert(status==0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gettimeofday
|
||||
*/
|
||||
#ifndef MULTINET
|
||||
int gettimeofday(struct timeval *tp, struct timezone *tzp)
|
||||
{
|
||||
|
||||
unsigned int quadtime[2] ;
|
||||
int status ;
|
||||
int nanosecs ;
|
||||
double secs ;
|
||||
int bit31 ;
|
||||
double dtime ; /* vax 64 bit integer as a double */
|
||||
|
||||
if (tp != (struct timeval *)NULL)
|
||||
{
|
||||
status = sys$gettim(&quadtime) ;
|
||||
if (status != SS$_NORMAL)
|
||||
return -1 ;
|
||||
else
|
||||
{
|
||||
bit31 = quadtime[0] & 0x80000000 ;
|
||||
dtime = quadtime[1]*TWOPOWER32 + (quadtime[0] & 0x7fffffff) ;
|
||||
if (bit31 != 0)
|
||||
dtime = (dtime + TWOPOWER31)/ 10000000.0 ;
|
||||
else
|
||||
dtime = dtime / 10000000.0 ;
|
||||
secs = dtime - UNIX_EPOCH_AS_MJD * 86400. ;
|
||||
tp->tv_sec = (int)secs ;
|
||||
tp->tv_usec = (int)((secs - tp->tv_sec)*1000000.0) ;
|
||||
}
|
||||
}
|
||||
|
||||
if (tzp != (struct timezone *)NULL)
|
||||
{
|
||||
tzp->tz_minuteswest = 0 ;
|
||||
tzp->tz_dsttime = 0 ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* cac_block_for_io_completion()
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.19 1995/11/29 19:15:42 jhill
|
||||
* added $Log$ to the header
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -279,10 +282,10 @@ void caDiscoverInterfaces(ELLLIST *pList, SOCKET socket, int port)
|
||||
return;
|
||||
}
|
||||
broadcast_addr(&bcast_addr);
|
||||
pNode->destAddr.inetAddr.sin_addr.s_addr = bcast_addr.s_addr; //broadcast addr
|
||||
pNode->destAddr.inetAddr.sin_port = htons(port);
|
||||
pNode->destAddr.inetAddr.sin_family = AF_INET;
|
||||
//pNode->srcAddr.inetAddr = 0 ;//localAddr;
|
||||
pNode->destAddr.in.sin_addr.s_addr = bcast_addr.s_addr; //broadcast addr
|
||||
pNode->destAddr.in.sin_port = htons(port);
|
||||
pNode->destAddr.in.sin_family = AF_INET;
|
||||
//pNode->srcAddr.in = 0 ;//localAddr;
|
||||
|
||||
/*
|
||||
* LOCK applied externally
|
||||
|
||||
@@ -93,7 +93,7 @@ int main(int argc,char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
fclose(fp);
|
||||
strcpy(pfilename,"device.ascii");
|
||||
strcpy(pfilename,"device.db");
|
||||
fp = fopen(pfilename,"w");
|
||||
if(!fp) {
|
||||
printf("Error opening file %s\n",pfilename);
|
||||
|
||||
@@ -69,7 +69,7 @@ int main(int argc,char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
fclose(fp);
|
||||
strcpy(pfilename,"driver.ascii");
|
||||
strcpy(pfilename,"driver.db");
|
||||
fp = fopen(pfilename,"w");
|
||||
if(!fp) {
|
||||
printf("Error opening file %s\n",pfilename);
|
||||
|
||||
@@ -89,7 +89,7 @@ int main(int argc,char **argv)
|
||||
fclose(fp);
|
||||
for(i=0; i<NUM_GBL_MENUS; i++) {
|
||||
strcpy(pfilename,aiMenuName[i]);
|
||||
strcat(pfilename,".ascii");
|
||||
strcat(pfilename,".db");
|
||||
fp = fopen(pfilename,"w");
|
||||
if(!fp) {
|
||||
printf("Error opening file %s\n",pfilename);
|
||||
|
||||
@@ -195,7 +195,7 @@ int main(int argc,char **argv)
|
||||
strcpy(pfilename,recordtypeName);
|
||||
strcat(pfilename,"Record");
|
||||
}
|
||||
strcat(pfilename,".ascii");
|
||||
strcat(pfilename,".db");
|
||||
fp = fopen(pfilename,"w");
|
||||
if(!fp) {
|
||||
fprintf(stderr,"Error opening file %s\n",pfilename);
|
||||
@@ -248,7 +248,7 @@ gen_rectype:
|
||||
indFldDes=-1;
|
||||
} else {
|
||||
fprintf(fp,"recordtype(%s) {\n",recordtypeName);
|
||||
fprintf(fp,"\tinclude \"dbCommon.ascii\" \n");
|
||||
fprintf(fp,"\tinclude \"dbCommon.db\" \n");
|
||||
/*Skip fields in dbCommon*/
|
||||
for(indFldDes=0; indFldDes< precTypDes->no_fields; indFldDes++) {
|
||||
if(strcmp(precTypDes->papFldDes[indFldDes]->fldname,"FLNK")==0) break;
|
||||
|
||||
49
src/cvtDctsdr/test/generateAllAscii
Executable file
49
src/cvtDctsdr/test/generateAllAscii
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
BIN=../O.solaris
|
||||
H=/usr/local/epics/R3.12.2/base/rec
|
||||
/bin/rm *.db
|
||||
$BIN/sdr2gblmenu
|
||||
$BIN/sdr2recordtype dbCommon $H/dbCommon.h
|
||||
$BIN/sdr2recordtype ai $H/aiRecord.h
|
||||
$BIN/sdr2recordtype ao $H/aoRecord.h
|
||||
$BIN/sdr2recordtype aai $H/aaiRecord.h
|
||||
$BIN/sdr2recordtype aao $H/aaoRecord.h
|
||||
$BIN/sdr2recordtype bi $H/biRecord.h
|
||||
$BIN/sdr2recordtype bo $H/boRecord.h
|
||||
$BIN/sdr2recordtype calc $H/calcRecord.h
|
||||
$BIN/sdr2recordtype compress $H/compressRecord.h
|
||||
$BIN/sdr2recordtype dfanout $H/dfanoutRecord.h
|
||||
$BIN/sdr2recordtype eg $H/egRecord.h
|
||||
$BIN/sdr2recordtype egevent $H/egeventRecord.h
|
||||
$BIN/sdr2recordtype er $H/erRecord.h
|
||||
$BIN/sdr2recordtype erevent $H/ereventRecord.h
|
||||
$BIN/sdr2recordtype event $H/eventRecord.h
|
||||
$BIN/sdr2recordtype fanout $H/fanoutRecord.h
|
||||
$BIN/sdr2recordtype histogram $H/histogramRecord.h
|
||||
$BIN/sdr2recordtype longin $H/longinRecord.h
|
||||
$BIN/sdr2recordtype longout $H/longoutRecord.h
|
||||
$BIN/sdr2recordtype mbbiDirect $H/mbbiDirectRecord.h
|
||||
$BIN/sdr2recordtype mbbi $H/mbbiRecord.h
|
||||
$BIN/sdr2recordtype mbboDirect $H/mbboDirectRecord.h
|
||||
$BIN/sdr2recordtype mbbo $H/mbboRecord.h
|
||||
$BIN/sdr2recordtype permissive $H/permissiveRecord.h
|
||||
$BIN/sdr2recordtype pid $H/pidRecord.h
|
||||
$BIN/sdr2recordtype pulseCounter $H/pulseCounterRecord.h
|
||||
$BIN/sdr2recordtype pulseDelay $H/pulseDelayRecord.h
|
||||
$BIN/sdr2recordtype pulseTrain $H/pulseTrainRecord.h
|
||||
$BIN/sdr2recordtype scan $H/scanRecord.h
|
||||
$BIN/sdr2recordtype sel $H/selRecord.h
|
||||
$BIN/sdr2recordtype seq $H/seqRecord.h
|
||||
$BIN/sdr2recordtype state $H/stateRecord.h
|
||||
$BIN/sdr2recordtype steppermotor $H/steppermotorRecord.h
|
||||
$BIN/sdr2recordtype stringin $H/stringinRecord.h
|
||||
$BIN/sdr2recordtype stringout $H/stringoutRecord.h
|
||||
$BIN/sdr2recordtype subArray $H/subArrayRecord.h
|
||||
$BIN/sdr2recordtype sub $H/subRecord.h
|
||||
$BIN/sdr2recordtype gsub $H/gsubRecord.h
|
||||
$BIN/sdr2recordtype pal $H/palRecord.h
|
||||
$BIN/sdr2recordtype timer $H/timerRecord.h
|
||||
$BIN/sdr2recordtype wait $H/waitRecord.h
|
||||
$BIN/sdr2recordtype waveform $H/waveformRecord.h
|
||||
$BIN/sdr2device
|
||||
$BIN/sdr2driver
|
||||
26
src/db/Makefile.Unix
Normal file
26
src/db/Makefile.Unix
Normal file
@@ -0,0 +1,26 @@
|
||||
EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
INC += drvTS.h
|
||||
INC += drvSup.h
|
||||
INC += callback.h
|
||||
INC += dbLock.h
|
||||
INC += dbAccess.h
|
||||
INC += dbConvert.h
|
||||
INC += dbEvent.h
|
||||
INC += dbScan.h
|
||||
INC += db_access.h
|
||||
INC += db_addr.h
|
||||
INC += db_field_log.h
|
||||
INC += fast_lock.h
|
||||
INC += initHooks.h
|
||||
INC += recSup.h
|
||||
INC += devSup.h
|
||||
INC += task_params.h
|
||||
INC += taskwd.h
|
||||
INC += recGbl.h
|
||||
INC += dbBkpt.h
|
||||
INC += devLib.h
|
||||
|
||||
include $(EPICS)/config/RULES.Unix
|
||||
@@ -19,9 +19,13 @@ MENUS += menuYesNo.h
|
||||
|
||||
RECTYPES += dbCommon.h
|
||||
|
||||
ASCII = dbCommonRecord.ascii menuGlobal.ascii all.ascii
|
||||
DBINSTALL += dbCommonRecord.db
|
||||
DBINSTALL += menuGlobal.db
|
||||
DBINSTALL += epics.db
|
||||
DBINSTALL += epicsLIBOBJS
|
||||
|
||||
SRCS.c = \
|
||||
../dbLock.c\
|
||||
../dbAccess.c\
|
||||
../dbBkpt.c\
|
||||
../dbConvert.c\
|
||||
@@ -37,12 +41,13 @@ SRCS.c = \
|
||||
../recGbl.c\
|
||||
../callback.c\
|
||||
../taskwd.c \
|
||||
../dbCaLink.c\
|
||||
../dbCaDblink.c\
|
||||
../dbCa.c\
|
||||
../dbcar.c\
|
||||
../devLib.c\
|
||||
../initHooks.c
|
||||
|
||||
LIBOBJS = \
|
||||
dbLock.o\
|
||||
dbAccess.o\
|
||||
dbBkpt.o\
|
||||
dbConvert.o\
|
||||
@@ -58,8 +63,8 @@ LIBOBJS = \
|
||||
recGbl.o\
|
||||
callback.o\
|
||||
taskwd.o\
|
||||
dbCaLink.o \
|
||||
dbCaDblink.o\
|
||||
dbCa.o \
|
||||
dbcar.o \
|
||||
devLib.o
|
||||
|
||||
PROD = initHooks.o
|
||||
@@ -68,12 +73,12 @@ LIBNAME = dbLib
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
dbCommon.h: ../dbCommonRecord.ascii dbCommon.ascii
|
||||
dbCommon.h: ../dbCommonRecord.db dbCommon.db
|
||||
$(RM) $@
|
||||
$(EPICS_BASE)/bin/$(HOST_ARCH)/dbAsciiToRecordtypeH $<
|
||||
$(EPICS_BASE)/bin/$(HOST_ARCH)/dbToRecordtypeH $<
|
||||
|
||||
dbCommon.ascii: ../dbCommon.ascii
|
||||
dbCommon.db: ../dbCommon.db
|
||||
@test -f $@ || ln -s $< $@
|
||||
|
||||
clean::
|
||||
@$(RM) dbCommon.ascii rec base
|
||||
@$(RM) dbCommon.db rec base
|
||||
|
||||
234
src/db/all.ascii
234
src/db/all.ascii
@@ -1,234 +0,0 @@
|
||||
path "./base/rec"
|
||||
include "menuGlobal.ascii"
|
||||
include "menuConvert.ascii"
|
||||
include "aiRecord.ascii"
|
||||
#include "aaiRecord.ascii"
|
||||
include "aoRecord.ascii"
|
||||
#include "aaoRecord.ascii"
|
||||
include "biRecord.ascii"
|
||||
include "boRecord.ascii"
|
||||
include "calcRecord.ascii"
|
||||
include "compressRecord.ascii"
|
||||
include "dfanoutRecord.ascii"
|
||||
include "egRecord.ascii"
|
||||
include "egeventRecord.ascii"
|
||||
include "erRecord.ascii"
|
||||
include "ereventRecord.ascii"
|
||||
include "eventRecord.ascii"
|
||||
include "fanoutRecord.ascii"
|
||||
include "histogramRecord.ascii"
|
||||
include "longinRecord.ascii"
|
||||
include "longoutRecord.ascii"
|
||||
include "mbbiRecord.ascii"
|
||||
include "mbbiDirectRecord.ascii"
|
||||
include "mbboRecord.ascii"
|
||||
include "mbboDirectRecord.ascii"
|
||||
include "permissiveRecord.ascii"
|
||||
include "pidRecord.ascii"
|
||||
include "pulseCounterRecord.ascii"
|
||||
include "pulseDelayRecord.ascii"
|
||||
include "pulseTrainRecord.ascii"
|
||||
include "scanRecord.ascii"
|
||||
include "selRecord.ascii"
|
||||
include "seqRecord.ascii"
|
||||
include "stateRecord.ascii"
|
||||
include "steppermotorRecord.ascii"
|
||||
include "stringinRecord.ascii"
|
||||
include "stringoutRecord.ascii"
|
||||
include "subRecord.ascii"
|
||||
#include "gsubRecord.ascii"
|
||||
#include "palRecord.ascii"
|
||||
include "subArrayRecord.ascii"
|
||||
include "timerRecord.ascii"
|
||||
include "waitRecord.ascii"
|
||||
include "waveformRecord.ascii"
|
||||
device(ai,CONSTANT,devAiSoft,"Soft Channel")
|
||||
device(ai,CONSTANT,devAiSoftRaw,"Raw Soft Channel")
|
||||
device(ai,VME_IO,devAiXy566Se,"XYCOM-566 SE Scanned")
|
||||
device(ai,VME_IO,devAiXy566Di,"XYCOM-566 Dif Scanned")
|
||||
device(ai,VME_IO,devAiXy566DiL,"XYCOM-566 Dif Latched")
|
||||
device(ai,VME_IO,devAiDvx2502,"DVX-2502")
|
||||
device(ai,CONSTANT,devAiTestAsyn,"Test Asyn")
|
||||
device(ai,CONSTANT,devAiSymb,"vxWorks Variable")
|
||||
device(ai,AB_IO,devAiAb1771Il,"AB-1771IL-Analog In")
|
||||
device(ai,AB_IO,devAiAb1771Ife,"AB-1771IFE")
|
||||
device(ai,AB_IO,devAiAb1771Ixe,"AB-1771IXE-Millivolt In")
|
||||
device(ai,AB_IO,devAiAb1771IfeSe,"AB-1771IFE-SE")
|
||||
device(ai,AB_IO,devAiAb1771IfeMa,"AB-1771IFE-4to20MA")
|
||||
device(ai,AB_IO,devAiAb1771Ife0to5V,"AB-1771IFE-0to5Volt")
|
||||
device(ai,AB_IO,devAiAb1771IrPlatinum,"AB-1771RTD-Platinum")
|
||||
device(ai,AB_IO,devAiAb1771IrCopper,"AB-1771RTD-Copper")
|
||||
#device(ai,CAMAC_IO,devAiCamac,"Camac")
|
||||
device(ai,VME_IO,devAiAt5Vxi,"VXI-AT5-AI")
|
||||
#device(ai,GPIB_IO,devAiK486Gpib,"Keithley-486")
|
||||
#device(ai,VME_IO,devAiKscV215,"KSC-V215")
|
||||
device(ai,VME_IO,devAiSysmon,"SYSMON")
|
||||
#device(aai,CAMAC_IO,devAaiCamac,"Camac")
|
||||
device(ao,CONSTANT,devAoSoft,"Soft Channel")
|
||||
device(ao,CONSTANT,devAoSoftRaw,"Raw Soft Channel")
|
||||
device(ao,VME_IO,devAoVmiVme4100,"VMIVME-4100")
|
||||
device(ao,CONSTANT,devAoTestAsyn,"Test Asyn")
|
||||
device(ao,CONSTANT,devAoSymb,"vxWorks Variable")
|
||||
device(ao,AB_IO,devAoAb1771Ofe,"AB-1771OFE")
|
||||
#device(ao,CAMAC_IO,devAoCamac,"Camac")
|
||||
device(ao,VME_IO,devAoAt5Vxi,"VXI-AT5-AO")
|
||||
device(bi,CONSTANT,devBiSoft,"Soft Channel")
|
||||
device(bi,CONSTANT,devBiSoftRaw,"Raw Soft Channel")
|
||||
device(bi,VME_IO,devBiMpv910,"MPV-910")
|
||||
device(bi,VME_IO,devBiXVme210,"XVME-210")
|
||||
device(bi,CONSTANT,devBiTestAsyn,"Test Asyn")
|
||||
device(bi,AB_IO,devBiAb,"AB-Binary Input")
|
||||
device(bi,AB_IO,devBiAb16,"AB-16 bit BI")
|
||||
device(bi,AB_IO,devBiAb32,"AB-32 bit BI")
|
||||
#device(bi,CAMAC_IO,devBiCamac,"Camac")
|
||||
device(bi,VME_IO,devBiAt5Vxi,"VXI-AT5-BI")
|
||||
#device(bi,VME_IO,devBiXy240,"XYCOM-240")
|
||||
device(bi,VME_IO,devBiHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(bi,VME_IO,devBiAt8Fp,"AT8-FP10S")
|
||||
device(bi,VME_IO,devBiAvme9440,"AVME9440 I")
|
||||
device(bi,VME_IO,devBiSysmon,"SYSMON")
|
||||
device(bi,VME_IO,devBiMpc,"MPC")
|
||||
device(bo,CONSTANT,devBoSoft,"Soft Channel")
|
||||
device(bo,CONSTANT,devBoSoftRaw,"Raw Soft Channel")
|
||||
device(bo,VME_IO,devBoMpv902,"MPV-902")
|
||||
device(bo,VME_IO,devBoXVme220,"XVME-220")
|
||||
device(bo,CONSTANT,devBoTestAsyn,"Test Asyn")
|
||||
device(bo,AB_IO,devBoAb,"AB-Binary Output")
|
||||
device(bo,AB_IO,devBoAb16,"AB-16 bit BO")
|
||||
device(bo,AB_IO,devBoAb32,"AB-32 bit BO")
|
||||
#device(bo,CAMAC_IO,devBoCamac,"Camac")
|
||||
device(bo,VME_IO,devBoAt5Vxi,"VXI-AT5-BO")
|
||||
#device(bo,GPIB_IO,devBoK486Gpib,"Keithley-486")
|
||||
#device(bo,VME_IO,devBoXy240,"XYCOM-240")
|
||||
device(bo,VME_IO,devBoHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(bo,VME_IO,devBoAt8Fp,"AT8-FP10S")
|
||||
device(bo,VME_IO,devBoAvme9440,"AVME9440 O")
|
||||
device(bo,VME_IO,devBoSysmon,"SYSMON")
|
||||
device(bo,VME_IO,devBoMpc,"MPC")
|
||||
device(event,CONSTANT,devEventSoft,"Soft Channel")
|
||||
device(event,VME_IO,devEventMz8310,"Mizar-8310")
|
||||
device(event,CONSTANT,devEventTestIoEvent,"Test IoEvent")
|
||||
device(event,VME_IO,devErEpicsEvent,"APS event receiver")
|
||||
device(histogram,CONSTANT,devHistogramSoft,"Soft Channel")
|
||||
device(histogram,CONSTANT,devHistogramTestAsyn,"Test Asyn")
|
||||
device(longin,CONSTANT,devLiSoft,"Soft Channel")
|
||||
device(longin,CONSTANT,devLiSymb,"vxWorks Variable")
|
||||
#device(longin,CAMAC_IO,devLiCamac,"Camac")
|
||||
device(longout,CONSTANT,devLoSoft,"Soft Channel")
|
||||
device(longout,CONSTANT,devLoSymb,"vxWorks Variable")
|
||||
#device(longout,CAMAC_IO,devLoCamac,"Camac")
|
||||
device(mbbi,CONSTANT,devMbbiSoft,"Soft Channel")
|
||||
device(mbbi,CONSTANT,devMbbiSoftRaw,"Raw Soft Channel")
|
||||
device(mbbi,VME_IO,devMbbiMpv910,"MPV-910")
|
||||
device(mbbi,VME_IO,devMbbiXVme210,"XVME-210")
|
||||
device(mbbi,CONSTANT,devMbbiTestAsyn,"Test Asyn")
|
||||
device(mbbi,AB_IO,devMbbiAb,"AB-Binary Input")
|
||||
device(mbbi,AB_IO,devMbbiAb16,"AB-16 bit BI")
|
||||
device(mbbi,AB_IO,devMbbiAb32,"AB-32 bit BI")
|
||||
device(mbbi,AB_IO,devMbbiAbAdapterStat,"AB-Adapter Status")
|
||||
device(mbbi,AB_IO,devMbbiAbCardStat,"AB-Card Status")
|
||||
#device(mbbi,CAMAC_IO,devMbbiCamac,"Camac")
|
||||
device(mbbi,VME_IO,devMbbiAt5Vxi,"VXI-AT5-BI")
|
||||
#device(mbbi,VME_IO,devMbbiXy240,"XYCOM-240")
|
||||
device(mbbi,VME_IO,devMbbiHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(mbbi,VME_IO,devMbbiAt8Fp,"AT8-FP10S")
|
||||
device(mbbi,VME_IO,devMbbiAvme9440,"AVME9440 I")
|
||||
device(mbbi,VME_IO,devMbbiSysmon,"SYSMON")
|
||||
device(mbbiDirect,CONSTANT,devMbbiDirectSoft,"Soft Channel")
|
||||
device(mbbiDirect,CONSTANT,devMbbiDirectSoftRaw,"Raw Soft Channel")
|
||||
device(mbbiDirect,VME_IO,devMbbiDirectMpv910,"MPV-910")
|
||||
device(mbbiDirect,VME_IO,devMbbiDirectXVme210,"XVME-210")
|
||||
device(mbbiDirect,AB_IO,devMbbiDirectAb,"AB-Binary Input")
|
||||
device(mbbiDirect,AB_IO,devMbbiDirectAb16,"AB-16 bit BI")
|
||||
device(mbbiDirect,AB_IO,devMbbiDirectAb32,"AB-32 bit BI")
|
||||
#device(mbbiDirect,CAMAC_IO,devMbbiDirectCamac,"Camac")
|
||||
device(mbbiDirect,VME_IO,devMbbiDirectAt5Vxi,"VXI-AT5-BI")
|
||||
device(mbbo,CONSTANT,devMbboSoft,"Soft Channel")
|
||||
device(mbbo,CONSTANT,devMbboSoftRaw,"Raw Soft Channel")
|
||||
device(mbbo,VME_IO,devMbboMpv902,"MPV-902")
|
||||
device(mbbo,VME_IO,devMbboXVme220,"XVME-220")
|
||||
device(mbbo,CONSTANT,devMbboTestAsyn,"Test Asyn")
|
||||
device(mbbo,AB_IO,devMbboAb,"AB-Binary Output")
|
||||
device(mbbo,AB_IO,devMbboAb16,"AB-16 bit BO")
|
||||
device(mbbo,AB_IO,devMbboAb32,"AB-32 bit BO")
|
||||
device(mbbo,VME_IO,devMbboAt5Vxi,"VXI-AT5-BO")
|
||||
#device(mbbo,GPIB_IO,devMbboK486Gpib,"Keithley-486")
|
||||
#device(mbbo,VME_IO,devMbboXy240,"XYCOM-240")
|
||||
device(mbbo,VME_IO,devMbboHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(mbbo,VME_IO,devMbboAt8Fp,"AT8-FP10S")
|
||||
device(mbbo,VME_IO,devMbboAvme9440,"AVME9440 O")
|
||||
device(mbbo,VME_IO,devMbboSysmon,"SYSMON")
|
||||
device(mbboDirect,CONSTANT,devMbboDirectSoft,"Soft Channel")
|
||||
device(mbboDirect,CONSTANT,devMbboDirectSoftRaw,"Raw Soft Channel")
|
||||
device(mbboDirect,VME_IO,devMbboDirectMpv902,"MPV-902")
|
||||
device(mbboDirect,VME_IO,devMbboDirectXVme220,"XVME-220")
|
||||
device(mbboDirect,AB_IO,devMbboDirectAb,"AB-Binary Output")
|
||||
device(mbboDirect,AB_IO,devMbboDirectAb16,"AB-16 bit BO")
|
||||
device(mbboDirect,AB_IO,devMbboDirectAb32,"AB-32 bit BO")
|
||||
#device(mbboDirect,CAMAC_IO,devMbboDirectCamac,"Camac")
|
||||
device(mbboDirect,VME_IO,devMbboDirectAt5Vxi,"VXI-AT5-BO")
|
||||
device(pulseCounter,VME_IO,devPcMz8310,"Mizar-8310")
|
||||
device(pulseDelay,VME_IO,devPdMz8310,"Mizar-8310")
|
||||
device(pulseDelay,VXI_IO,devPdVxiTDM,"VXI Time Delay Module")
|
||||
device(pulseTrain,CONSTANT,devPtSoft,"Soft Channel")
|
||||
device(pulseTrain,VME_IO,devPtMz8310,"Mizar-8310")
|
||||
device(steppermotor,VME_IO,devSmCompumotor1830,"Compumotor 1830")
|
||||
device(steppermotor,VME_IO,devSmOms6Axis,"OMS 6-Axis")
|
||||
device(stringin,CONSTANT,devSiSoft,"Soft Channel")
|
||||
device(stringin,CONSTANT,devSiTestAsyn,"Test Asyn")
|
||||
device(stringin,CONSTANT,devSiSymb,"vxWorks Variable")
|
||||
device(stringout,CONSTANT,devSoSoft,"Soft Channel")
|
||||
device(stringout,CONSTANT,devSoTestAsyn,"Test Asyn")
|
||||
device(stringout,CONSTANT,devSoSymb,"vxWorks Variable")
|
||||
device(subArray,CONSTANT,devSASoft,"Soft Channel")
|
||||
device(timer,VME_IO,devTmMizar8310,"Mizar-8310")
|
||||
device(timer,VME_IO,devTmDg535,"DG 535")
|
||||
device(timer,VME_IO,devTmAt5Vxi,"VXI-AT5-TIME")
|
||||
device(waveform,CONSTANT,devWfSoft,"Soft Channel")
|
||||
device(waveform,VME_IO,devWfXy566Sc,"XYCOM-566 Single Channel")
|
||||
device(waveform,VME_IO,devWfComet,"Comet Digitizer")
|
||||
device(waveform,VME_IO,devWfJoergerVtr1,"Joerger Digitizer")
|
||||
device(waveform,CONSTANT,devWfTestAsyn,"Test Asyn")
|
||||
device(waveform,VME_IO,devWfDvx2502,"DVX-2502")
|
||||
device(waveform,VME_IO,devWfPentek4261,"Pentek 4261")
|
||||
#device(waveform,CAMAC_IO,devWfCamac,"Camac")
|
||||
#device(waveform,VME_IO,devWfJoergerVtr1,"Joerger-VTR1")
|
||||
#device(waveform,VME_IO,devWfComet,"Omnibyte-COMET")
|
||||
device(eg,VME_IO,devEg,"APS event generator G")
|
||||
device(egevent,VME_IO,devEgEvent,"APS event generator E")
|
||||
device(er,VME_IO,devEr,"APS event receiver")
|
||||
device(erevent,VME_IO,devErevent,"APS event receiver")
|
||||
device(wait,CONSTANT,devWaitIoEvent,"Soft Channel")
|
||||
#device(ai,INST_IO,devAiCan,"CANbus")
|
||||
#device(ao,INST_IO,devAoCan,"CANbus")
|
||||
#device(bi,INST_IO,devBiCan,"CANbus")
|
||||
#device(bo,INST_IO,devBoCan,"CANbus")
|
||||
#device(mbbi,INST_IO,devMbbiCan,"CANbus")
|
||||
#device(mbbo,INST_IO,devMbboCan,"CANbus")
|
||||
#device(mbbiDirect,INST_IO,devMbbiDirectCan,"CANbus")
|
||||
#device(mbboDirect,INST_IO,devMbboDirectCan,"CANbus")
|
||||
driver(drvXy010)
|
||||
driver(drvVxi)
|
||||
driver(drvGpib)
|
||||
driver(drvBitBus)
|
||||
driver(drvBb910)
|
||||
driver(drvXy210)
|
||||
driver(drvBb902)
|
||||
driver(drvXy220)
|
||||
driver(drvXy566)
|
||||
driver(drvDvx)
|
||||
driver(drvVmi4100)
|
||||
driver(drvAb)
|
||||
driver(drvAt5Vxi)
|
||||
driver(drvCompuSm)
|
||||
driver(drvOms)
|
||||
driver(drvMz8310)
|
||||
driver(drvHpe1368a)
|
||||
#driver(drvXy240)
|
||||
#driver(drvKscV215)
|
||||
#driver(drvComet)
|
||||
#driver(drvJgvtr1)
|
||||
#driver(drvFp)
|
||||
#driver(drvFpm)
|
||||
#driver(drvIpac)
|
||||
#driver(drvTip810)
|
||||
@@ -48,9 +48,10 @@
|
||||
#include <taskwd.h>
|
||||
#include <errMdef.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <task_params.h>
|
||||
|
||||
#define QUEUESIZE 1000
|
||||
int callbackQueueSize = 2000;
|
||||
static SEM_ID callbackSem[NUM_CALLBACK_PRIORITIES];
|
||||
static RING_ID callbackQ[NUM_CALLBACK_PRIORITIES];
|
||||
static int callbackTaskId[NUM_CALLBACK_PRIORITIES];
|
||||
@@ -62,6 +63,12 @@ static void wdCallback(long ind); /*callback from taskwd*/
|
||||
static void start(int ind); /*start or restart a callbackTask*/
|
||||
|
||||
/*public routines */
|
||||
int callbackSetQueueSize(int size)
|
||||
{
|
||||
callbackQueueSize = size;
|
||||
return(0);
|
||||
}
|
||||
|
||||
long callbackInit()
|
||||
{
|
||||
int i;
|
||||
@@ -129,9 +136,11 @@ void callbackRequest(CALLBACK *pcallback)
|
||||
}
|
||||
}
|
||||
|
||||
static char *priorityName[3] = {"Low","Medium","High"};
|
||||
static void start(int ind)
|
||||
{
|
||||
int priority;
|
||||
char taskName[20];
|
||||
|
||||
if((callbackSem[ind] = semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL)
|
||||
errMessage(0,"semBcreate failed while starting a callback task\n");
|
||||
@@ -142,9 +151,10 @@ static void start(int ind)
|
||||
errMessage(0,"semBcreate failed while starting a callback task\n");
|
||||
return;
|
||||
}
|
||||
if((callbackQ[ind] = rngCreate(sizeof(CALLBACK *) * QUEUESIZE)) == NULL)
|
||||
if((callbackQ[ind]=rngCreate(sizeof(CALLBACK *)*callbackQueueSize)) == NULL)
|
||||
errMessage(0,"rngCreate failed while starting a callback task");
|
||||
callbackTaskId[ind] = taskSpawn(CALLBACK_NAME,priority,
|
||||
sprintf(taskName,"cb%s",priorityName[ind]);
|
||||
callbackTaskId[ind] = taskSpawn(taskName,priority,
|
||||
CALLBACK_OPT,CALLBACK_STACK,
|
||||
(FUNCPTR)callbackTask,ind,
|
||||
0,0,0,0,0,0,0,0,0);
|
||||
|
||||
88
src/db/callback.h
Normal file
88
src/db/callback.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* $Id$ */
|
||||
|
||||
/* includes for general purpose callback tasks */
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
* Date: 07-18-91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 12-12-91 mrk Initial version
|
||||
* .02 04-05-94 mrk Remove casts on Lvalues (ANSI forbids)
|
||||
* .02 02-09-95 joh if def'd out typedef CALLBACK for
|
||||
* windows
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INCcallbackh
|
||||
#define INCcallbackh 1
|
||||
|
||||
/*
|
||||
* WINDOWS also has a "CALLBACK" type def
|
||||
*/
|
||||
#ifdef WIN32
|
||||
# ifdef CALLBACK
|
||||
# undef CALLBACK
|
||||
# endif /*CALLBACK*/
|
||||
#endif /*WIN32*/
|
||||
|
||||
#define NUM_CALLBACK_PRIORITIES 3
|
||||
#define priorityLow 0
|
||||
#define priorityMedium 1
|
||||
#define priorityHigh 2
|
||||
|
||||
typedef struct callbackPvt {
|
||||
#ifdef __cplusplus
|
||||
void (*callback)(struct callbackPvt*);
|
||||
#else
|
||||
void (*callback)();
|
||||
#endif
|
||||
int priority;
|
||||
void *user; /*for use by callback user*/
|
||||
}CALLBACK;
|
||||
|
||||
#define callbackSetCallback(PFUN,PCALLBACK)\
|
||||
( (PCALLBACK)->callback = (PFUN) )
|
||||
#define callbackSetPriority(PRIORITY,PCALLBACK)\
|
||||
( (PCALLBACK)->priority = (PRIORITY) )
|
||||
#define callbackSetUser(USER,PCALLBACK)\
|
||||
( (PCALLBACK)->user = (VOID *)(USER) )
|
||||
#define callbackGetUser(USER,PCALLBACK)\
|
||||
( (USER) = (void *)((CALLBACK *)(PCALLBACK))->user )
|
||||
|
||||
#ifdef __STDC__
|
||||
long callbackInit();
|
||||
void callbackRequest(CALLBACK *);
|
||||
void callbackRequestProcessCallback(CALLBACK *pCallback,
|
||||
int Priority, void *pRec);
|
||||
int callbackSetQueueSize(int size);
|
||||
#else
|
||||
long callbackInit();
|
||||
void callbackRequest();
|
||||
void callbackRequestProcessCallback();
|
||||
int callbackSetQueueSize();
|
||||
#endif /*__STDC__*/
|
||||
|
||||
|
||||
#endif /*INCcallbackh*/
|
||||
1426
src/db/dbAccess.c
1426
src/db/dbAccess.c
File diff suppressed because it is too large
Load Diff
329
src/db/dbAccess.h
Normal file
329
src/db/dbAccess.h
Normal file
@@ -0,0 +1,329 @@
|
||||
/* dbAccess.h */
|
||||
/* $Id$
|
||||
*
|
||||
* Original Author: Bob Dalesio
|
||||
* Current Author: Marty Kraimer
|
||||
* Date: 6-1-90
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 12-18-91 jba Changed caddr_t to void *
|
||||
* .02 03-04-92 jba Replaced dbr_value_size with dbrValueSize in dbAccess
|
||||
* .03 05-28-92 mrk cleanup
|
||||
* .04 08-19-92 jba added prototypes dbCaAddInlink,dbCaAddOutlink
|
||||
* .05 08-19-92 jba added prototypes dbCaPutLink,dbCaGetLink
|
||||
* .06 02-02-94 mrk added definitions for dbPutNotify
|
||||
* .07 03-18-94 mcn added breakpoint codes, fast link protos
|
||||
*/
|
||||
|
||||
#ifndef INCdbAccessh
|
||||
#define INCdbAccessh
|
||||
#include <dbDefs.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <link.h>
|
||||
#ifdef vxWorks
|
||||
#include <dbCommon.h>
|
||||
#endif
|
||||
#include <dbLock.h>
|
||||
#include <tsDefs.h>
|
||||
#include <callback.h>
|
||||
#include <ellLib.h>
|
||||
#include <caeventmask.h>
|
||||
|
||||
typedef struct dbAddr{
|
||||
struct dbCommon *precord;/* address of record */
|
||||
void *pfield; /* address of field */
|
||||
void *pfldDes; /* address of struct fldDes */
|
||||
void *asPvt; /* Access Security Private */
|
||||
long no_elements; /* number of elements (arrays) */
|
||||
short field_type; /* type of database field */
|
||||
short field_size; /* size (bytes) of the field being accessed */
|
||||
short special; /* special processing */
|
||||
short dbr_field_type; /* field type as seen by database request*/
|
||||
/*DBR_STRING,...,DBR_ENUM,DBR_NOACCESS*/
|
||||
}DBADDR;
|
||||
|
||||
/*If the following structures changes then db_access.h must also be changed*/
|
||||
typedef struct pnRestartNode {
|
||||
ELLNODE node;
|
||||
struct putNotify *ppn;
|
||||
struct putNotify *ppnrestartList; /*ppn with restartList*/
|
||||
}PNRESTARTNODE;
|
||||
|
||||
|
||||
typedef struct putNotify{
|
||||
/*The following members MUST be set by user*/
|
||||
#ifdef __STDC__
|
||||
void (*userCallback)(struct putNotify *); /*callback provided by user*/
|
||||
#else
|
||||
void (*userCallback)(); /*callback provided by user*/
|
||||
#endif
|
||||
struct dbAddr *paddr; /*dbAddr set by dbNameToAddr*/
|
||||
void *pbuffer; /*address of data*/
|
||||
long nRequest; /*number of elements to be written*/
|
||||
short dbrType; /*database request type*/
|
||||
void *usrPvt; /*for private use of user*/
|
||||
/*The following is status of request. Set by dbPutNotify*/
|
||||
long status;
|
||||
/*The following are private to database access*/
|
||||
CALLBACK callback;
|
||||
ELLLIST waitList; /*list of records for which to wait*/
|
||||
ELLLIST restartList; /*list of PUTNOTIFYs to restart*/
|
||||
PNRESTARTNODE restartNode;
|
||||
short restart;
|
||||
short callbackState;
|
||||
void *waitForCallback;
|
||||
}PUTNOTIFY;
|
||||
|
||||
/* The database field and request types are defined in dbFldTypes.h*/
|
||||
/* Data Base Request Options */
|
||||
#define DBR_STATUS 0x00000001
|
||||
#define DBR_UNITS 0x00000002
|
||||
#define DBR_PRECISION 0x00000004
|
||||
#define DBR_TIME 0x00000008
|
||||
#define DBR_ENUM_STRS 0x00000010
|
||||
#define DBR_GR_LONG 0x00000020
|
||||
#define DBR_GR_DOUBLE 0x00000040
|
||||
#define DBR_CTRL_LONG 0x00000080
|
||||
#define DBR_CTRL_DOUBLE 0x00000100
|
||||
#define DBR_AL_LONG 0x00000200
|
||||
#define DBR_AL_DOUBLE 0x00000400
|
||||
|
||||
/**********************************************************************
|
||||
* The next page contains macros for defining requests.
|
||||
* As an example the following defines a buffer to accept an array
|
||||
* of 10 float values + DBR_STATUS and DBR_TIME options
|
||||
*
|
||||
* struct {
|
||||
* DBRstatus
|
||||
* DBRtime
|
||||
* float value[10]
|
||||
* } buffer;
|
||||
*
|
||||
* IMPORTANT!! The DBRoptions must be given in the order that they
|
||||
* appear in the Data Base Request Options #defines
|
||||
*
|
||||
* The associated dbGetField call is:
|
||||
*
|
||||
* long options,number_elements;
|
||||
* ...
|
||||
* options = DBR_STATUS|DBR_TIME;
|
||||
* number_elements = 10;
|
||||
* rtnval=dbGetField(paddr,DBR_FLOAT,&buffer,&options,&number_elements);
|
||||
*
|
||||
* When dbGetField returns:
|
||||
* rtnval is error status (0 means success)
|
||||
* options has a bit set for each option that was accepted
|
||||
* number_elements is actual number of elements obtained
|
||||
*
|
||||
* The individual items can be refered to by the expressions::
|
||||
*
|
||||
* buffer.status
|
||||
* buffer.severity
|
||||
* buffer.err_status
|
||||
* buffer.epoch_seconds
|
||||
* buffer.nano_seconds
|
||||
* buffer.value[i]
|
||||
*
|
||||
* The following is also a valid declaration:
|
||||
*
|
||||
* typedef struct {
|
||||
* DBRstatus
|
||||
* DBRtime
|
||||
* float value[10]
|
||||
* } MYBUFFER;
|
||||
*
|
||||
* With this definition you can give definitions such as the following:
|
||||
*
|
||||
* MYBUFFER *pbuf1;
|
||||
* MYBUFFER buf;
|
||||
*************************************************************************/
|
||||
|
||||
/* Macros for defining each option */
|
||||
#define DBRstatus \
|
||||
unsigned short status; /* alarm status */\
|
||||
unsigned short severity; /* alarm severity*/\
|
||||
unsigned short acks; /* alarm ack severity*/\
|
||||
unsigned short ackt; /* Acknowledge transient alarms?*/
|
||||
#define DB_UNITS_SIZE 16
|
||||
#define DBRunits \
|
||||
char units[DB_UNITS_SIZE]; /* units */
|
||||
#define DBRprecision \
|
||||
long precision; /* number of decimal places*/\
|
||||
long field_width; /* field width */
|
||||
#define DBRtime \
|
||||
TS_STAMP time; /* time stamp*/
|
||||
#define DBRenumStrs \
|
||||
unsigned long no_str; /* number of strings*/\
|
||||
long padenumStrs; /*padding to force 8 byte align*/\
|
||||
char strs[DB_MAX_CHOICES][MAX_STRING_SIZE]; /* string values */
|
||||
#define DBRgrLong \
|
||||
long upper_disp_limit; /*upper limit of graph*/\
|
||||
long lower_disp_limit; /*lower limit of graph*/
|
||||
#define DBRgrDouble \
|
||||
double upper_disp_limit; /*upper limit of graph*/\
|
||||
double lower_disp_limit; /*lower limit of graph*/
|
||||
#define DBRctrlLong \
|
||||
long upper_ctrl_limit; /*upper limit of graph*/\
|
||||
long lower_ctrl_limit; /*lower limit of graph*/
|
||||
#define DBRctrlDouble \
|
||||
double upper_ctrl_limit; /*upper limit of graph*/\
|
||||
double lower_ctrl_limit; /*lower limit of graph*/
|
||||
#define DBRalLong \
|
||||
long upper_alarm_limit;\
|
||||
long upper_warning_limit;\
|
||||
long lower_warning_limit;\
|
||||
long lower_alarm_limit;
|
||||
#define DBRalDouble \
|
||||
double upper_alarm_limit;\
|
||||
double upper_warning_limit;\
|
||||
double lower_warning_limit;\
|
||||
double lower_alarm_limit;
|
||||
|
||||
/* structures for each option type */
|
||||
struct dbr_status {DBRstatus};
|
||||
struct dbr_units {DBRunits};
|
||||
struct dbr_precision {DBRprecision};
|
||||
struct dbr_time {DBRtime};
|
||||
struct dbr_enumStrs {DBRenumStrs};
|
||||
struct dbr_grLong {DBRgrLong};
|
||||
struct dbr_grDouble {DBRgrDouble};
|
||||
struct dbr_ctrlLong {DBRctrlLong};
|
||||
struct dbr_ctrlDouble {DBRctrlDouble};
|
||||
struct dbr_alLong {DBRalLong};
|
||||
struct dbr_alDouble {DBRalDouble};
|
||||
/* sizes for each option structure */
|
||||
#define dbr_status_size sizeof(struct dbr_status)
|
||||
#define dbr_units_size sizeof(struct dbr_units)
|
||||
#define dbr_precision_size sizeof(struct dbr_precision)
|
||||
#define dbr_time_size sizeof(struct dbr_time)
|
||||
#define dbr_enumStrs_size sizeof(struct dbr_enumStrs)
|
||||
#define dbr_grLong_size sizeof(struct dbr_grLong)
|
||||
#define dbr_grDouble_size sizeof(struct dbr_grDouble)
|
||||
#define dbr_ctrlLong_size sizeof(struct dbr_ctrlLong)
|
||||
#define dbr_ctrlDouble_size sizeof(struct dbr_ctrlDouble)
|
||||
#define dbr_alLong_size sizeof(struct dbr_alLong)
|
||||
#define dbr_alDouble_size sizeof(struct dbr_alDouble)
|
||||
|
||||
#ifndef INCerrMdefh
|
||||
#include <errMdef.h>
|
||||
#endif
|
||||
#define S_db_notFound (M_dbAccess| 1) /*Process Variable Not Found*/
|
||||
#define S_db_badDbrtype (M_dbAccess| 3) /*Illegal Database Request Type*/
|
||||
#define S_db_noMod (M_dbAccess| 5) /*Attempt to modify noMod field*/
|
||||
#define S_db_badLset (M_dbAccess| 7) /*Illegal Lock Set*/
|
||||
#define S_db_precision (M_dbAccess| 9) /*get precision failed */
|
||||
#define S_db_onlyOne (M_dbAccess|11) /*Only one element allowed*/
|
||||
#define S_db_badChoice (M_dbAccess|13) /*Illegal choice*/
|
||||
#define S_db_badField (M_dbAccess|15) /*Illegal field value*/
|
||||
#define S_db_lsetLogic (M_dbAccess|17) /*Logic error generating lock sets*/
|
||||
#define S_db_noRSET (M_dbAccess|31) /*missing record support entry table*/
|
||||
#define S_db_noSupport (M_dbAccess|33) /*RSET routine not defined*/
|
||||
#define S_db_BadSub (M_dbAccess|35) /*Subroutine not found*/
|
||||
/*!!!! Do not change next two lines without changing src/rsrv/server.h!!!!!!!!*/
|
||||
#define S_db_Pending (M_dbAccess|37) /*Request is pending*/
|
||||
#define S_db_Blocked (M_dbAccess|39) /*Request is Blocked*/
|
||||
#define S_db_putDisabled (M_dbAccess|41) /*putFields are disabled*/
|
||||
#define S_db_bkptSet (M_dbAccess|53) /*Breakpoint already set*/
|
||||
#define S_db_bkptNotSet (M_dbAccess|55) /*No breakpoint set in record*/
|
||||
#define S_db_notStopped (M_dbAccess|57) /*Record not stopped*/
|
||||
#define S_db_errArg (M_dbAccess|59) /*Error in argument*/
|
||||
#define S_db_bkptLogic (M_dbAccess|61) /*Logic error in breakpoint routine*/
|
||||
#define S_db_cntSpwn (M_dbAccess|63) /*Cannot spawn dbContTask*/
|
||||
#define S_db_cntCont (M_dbAccess|65) /*Cannot resume dbContTask*/
|
||||
|
||||
/* Global Database Access Routines*/
|
||||
#define dbGetLink(PLNK,DBRTYPE,PBUFFER,OPTIONS,NREQUEST) \
|
||||
(((((PLNK)->type == CONSTANT)&&(!(NREQUEST))) ||\
|
||||
(! (((PLNK)->type == DB_LINK) || ((PLNK)->type == CA_LINK)) ))\
|
||||
? 0\
|
||||
: dbGetLinkValue((PLNK),(DBRTYPE), \
|
||||
(void *)(PBUFFER),(OPTIONS),(NREQUEST)))
|
||||
#define dbPutLink(PLNK,DBRTYPE,PBUFFER,NREQUEST) \
|
||||
((((PLNK)->type == CONSTANT) ||\
|
||||
(! (((PLNK)->type == DB_LINK) || ((PLNK)->type == CA_LINK)) ))\
|
||||
? 0\
|
||||
: dbPutLinkValue((PLNK),(DBRTYPE),(void *)(PBUFFER),(NREQUEST)))
|
||||
#ifdef __STDC__
|
||||
struct rset *dbGetRset(struct dbAddr *paddr);
|
||||
int dbIsValueField(struct dbFldDes *pdbFldDes);
|
||||
int dbGetFieldIndex(struct dbAddr *paddr);
|
||||
long dbScanLink(struct dbCommon *pfrom, struct dbCommon *pto);
|
||||
long dbScanPassive(struct dbCommon *pfrom,struct dbCommon *pto);
|
||||
long dbProcess(struct dbCommon *precord);
|
||||
long dbNameToAddr(char *pname,struct dbAddr *);
|
||||
long dbGetLinkValue(struct link *,short dbrType,
|
||||
void *pbuffer,long *options,long *nRequest);
|
||||
long dbGetField(struct dbAddr *,short dbrType,void *pbuffer,long *options,
|
||||
long *nRequest,void *pfl);
|
||||
long dbGet(struct dbAddr *,short dbrType,void *pbuffer,long *options,
|
||||
long *nRequest,void *pfl);
|
||||
long dbPutLinkValue(struct link *,short dbrType,void *pbuffer,long nRequest);
|
||||
long dbPutField(struct dbAddr *,short dbrType,void *pbuffer,long nRequest);
|
||||
long dbPut(struct dbAddr *,short dbrType,void *pbuffer,long nRequest);
|
||||
long dbPutNotify(PUTNOTIFY *pputnotify);
|
||||
/*dbNotifyAdd called by dbScanPassive and dbScanLink*/
|
||||
void dbNotifyAdd(struct dbCommon *pfrom,struct dbCommon *pto);
|
||||
void dbNotifyCancel(PUTNOTIFY *pputnotify);
|
||||
/*dbNotifyCompletion called by recGblFwdLink */
|
||||
void dbNotifyCompletion(struct dbCommon *precord);
|
||||
long dbBufferSize(short dbrType,long options,long nRequest);
|
||||
long dbValueSize(short dbrType);
|
||||
|
||||
void dbCaLinkInit(void);
|
||||
void dbCaAddLink(struct link *plink);
|
||||
void dbCaRemoveLink(struct link *plink);
|
||||
long dbCaGetLink(struct link *plink,short dbrType,void *pbuffer,
|
||||
unsigned short *psevr,long *nRequest);
|
||||
long dbCaPutLink(struct link *plink,short dbrType,void *pbuffer,long nRequest);
|
||||
|
||||
#else
|
||||
struct rset *dbGetRset();
|
||||
int dbIsValueField();
|
||||
int dbGetFieldIndex();
|
||||
long dbScanPassive();
|
||||
long dbScanLink();
|
||||
long dbProcess();
|
||||
long dbNameToAddr();
|
||||
long dbGetLinkValue();
|
||||
long dbGetField();
|
||||
long dbGet();
|
||||
long dbPutLinkValue();
|
||||
long dbPutField();
|
||||
long dbPut();
|
||||
long dbPutNotify();
|
||||
void dbNotifyAdd();
|
||||
void dbNotifyCancel();
|
||||
void dbNotifyCompletion();
|
||||
long dbBufferSize();
|
||||
long dbValueSize();
|
||||
void dbCaLinkInit();
|
||||
void dbCaAddLink();
|
||||
void dbCaRemoveLink();
|
||||
long dbCaGetLink();
|
||||
long dbCaPutLink();
|
||||
#endif /*__STDC__*/
|
||||
|
||||
#endif /*INCdbAccessh*/
|
||||
@@ -28,6 +28,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.6 1995/11/29 14:23:28 mrk
|
||||
* Changes for replacing default.dctsdr by all ascii files
|
||||
*
|
||||
* Revision 1.5 1995/02/23 21:45:03 mcn
|
||||
* Fixed locking error. OOPS.
|
||||
*
|
||||
@@ -76,6 +79,7 @@
|
||||
#include <dbAccess.h>
|
||||
#include <dbScan.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <dbBkpt.h>
|
||||
#include <db_field_log.h>
|
||||
@@ -174,7 +178,7 @@ static SEM_ID bkpt_stack_sem;
|
||||
* lockset to be continued from differs from this
|
||||
* variable.
|
||||
*/
|
||||
static short last_lset = 0;
|
||||
static unsigned long last_lset = 0;
|
||||
|
||||
/*
|
||||
* FIND_LOCKSET() finds the stack entry
|
||||
@@ -185,7 +189,7 @@ static short last_lset = 0;
|
||||
#define FIND_LOCKSET(precord, pnode) \
|
||||
pnode = (struct LS_LIST *) lstFirst(&lset_stack); \
|
||||
while ((pnode) != NULL) { \
|
||||
if ((pnode)->l_num == (precord)->lset) break; \
|
||||
if (pnode->l_num == dbLockGetLockId(precord)) break; \
|
||||
pnode = (struct LS_LIST *) lstNext((NODE *)pnode); \
|
||||
} \
|
||||
|
||||
@@ -346,7 +350,7 @@ long dbb(char *record_name)
|
||||
|
||||
pnode->taskid = 0;
|
||||
pnode->step = 0;
|
||||
pnode->l_num = precord->lset;
|
||||
pnode->l_num = dbLockGetLockId(precord);
|
||||
lstAdd(&lset_stack, (NODE *)pnode);
|
||||
}
|
||||
|
||||
@@ -639,7 +643,7 @@ static void dbBkptCont(struct dbCommon *precord)
|
||||
/* remove execution semaphore */
|
||||
semDelete(pnode->ex_sem);
|
||||
|
||||
printf("\n BKPT> End debug of lockset %d\n-> ", pnode->l_num);
|
||||
printf("\n BKPT> End debug of lockset %lu\n-> ", pnode->l_num);
|
||||
|
||||
/* free list node */
|
||||
free(pnode);
|
||||
@@ -698,8 +702,7 @@ int dbBkpt(struct dbCommon *precord)
|
||||
}
|
||||
|
||||
/* Check disable flag */
|
||||
recGblGetFastLink(&precord->sdis, (void *) precord, &precord->disa);
|
||||
|
||||
dbGetLink(&(precord->sdis),DBR_SHORT,&(precord->disa),0,0);
|
||||
if (precord->disa == precord->disv) {
|
||||
/*
|
||||
* Do not process breakpoints if the record is disabled,
|
||||
@@ -917,7 +920,7 @@ long dbstat()
|
||||
while (pnode != NULL) {
|
||||
if (pnode->precord != NULL) {
|
||||
|
||||
printf("LSet: %5.5d Stopped at: %-28.28s #B: %5.5d T: 0x%7.7x\n",
|
||||
printf("LSet: %lu Stopped at: %-28.28s #B: %5.5d T: 0x%7.7x\n",
|
||||
pnode->l_num, pnode->precord->name, lstCount(&pnode->bp_list), pnode->taskid);
|
||||
|
||||
/* for each entrypoint detected, print out entrypoint statistics */
|
||||
@@ -932,7 +935,7 @@ long dbstat()
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("LSet: %5.5d #B: %5.5d T: 0x%7.7x\n",
|
||||
printf("LSet: %lu #B: %5.5d T: 0x%7.7x\n",
|
||||
pnode->l_num, lstCount(&pnode->bp_list), pnode->taskid);
|
||||
}
|
||||
|
||||
|
||||
106
src/db/dbBkpt.h
Normal file
106
src/db/dbBkpt.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* dbBkpt.h */
|
||||
/* base/include $Id$ */
|
||||
/*
|
||||
* Author: Matthew Needes
|
||||
* Date: 8-30-93
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
|
||||
#ifndef INCdbBkptsh
|
||||
#define INCdbBkptsh 1
|
||||
|
||||
#include <lstLib.h>
|
||||
/* Needs to be put into dbTest.h ! */
|
||||
long dbpr(char *name, int level);
|
||||
|
||||
/*
|
||||
* Structure containing a list of set breakpoints
|
||||
* in a lockset
|
||||
*/
|
||||
|
||||
struct BP_LIST {
|
||||
NODE *next_list;
|
||||
NODE *prev_list;
|
||||
struct dbCommon *precord;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure containing queue of entrypoints
|
||||
* detected for a lockset.
|
||||
*/
|
||||
struct EP_LIST {
|
||||
NODE *next_list;
|
||||
NODE *prev_list;
|
||||
struct dbCommon *entrypoint; /* pointer to entry point in lockset */
|
||||
unsigned long count; /* number of times record processed */
|
||||
unsigned long time; /* time record first logged */
|
||||
char sched; /* schedule record for next dbContTask() pass */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for stack of lock sets that
|
||||
* currently contain breakpoints. (uses lstLib)
|
||||
*/
|
||||
struct LS_LIST {
|
||||
NODE *next_list;
|
||||
NODE *prev_list;
|
||||
struct dbCommon *precord;/* points to where execution is currently stopped */
|
||||
struct dbCommon *current_ep; /* current entrypoint */
|
||||
LIST bp_list; /* list of records containing breakpoints in a lockset */
|
||||
LIST ep_queue; /* queue of entrypoints found so far */
|
||||
SEM_ID ex_sem; /* semaphore for execution queue */
|
||||
int taskid; /* saved taskid for the task in stepping mode */
|
||||
int step; /* one if currently "stepping," else zero */
|
||||
unsigned long l_num; /* lockset number */
|
||||
};
|
||||
|
||||
/* Values for BKPT (breakpoint) field in record */
|
||||
|
||||
/* 1st bit = 0 if breakpoint is not set, */
|
||||
/* 1 if breakpoint set */
|
||||
/* 2nd bit = 0 if no printing after processing */
|
||||
/* 1 if print after processing set */
|
||||
|
||||
/* Breakpoint Masks */
|
||||
#define BKPT_ON_MASK 0x001
|
||||
#define BKPT_OFF_MASK 0x0FE
|
||||
#define BKPT_PRINT_MASK 0x002
|
||||
#define BKPT_PRINT_OFF_MASK 0x0FD
|
||||
|
||||
#define MAX_EP_COUNT 99999
|
||||
|
||||
long dbb();
|
||||
long dbd();
|
||||
long dbc();
|
||||
long dbs();
|
||||
long dbstat();
|
||||
long dbtap();
|
||||
int dbBkpt();
|
||||
void dbPrint();
|
||||
|
||||
extern long lset_stack_not_empty;
|
||||
|
||||
#endif
|
||||
475
src/db/dbCa.c
Normal file
475
src/db/dbCa.c
Normal file
@@ -0,0 +1,475 @@
|
||||
/* dbCa.c */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1991 Regents of the University of California,
|
||||
and the University of Chicago Board of Governors.
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_Combined file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Current Author: Bob Dalesio
|
||||
* Contributing Author: Marty Kraimer
|
||||
* Date: 26MAR96
|
||||
*
|
||||
* Complete replacement for dbCaDblink.c dbCaLink.c (Nicholas T. Karonis)
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 26MAR96 lrd rewritten for simplicity, robustness and flexibility
|
||||
****************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include "cadef.h"
|
||||
#include "caerr.h"
|
||||
#include "alarm.h"
|
||||
#include "db_access.h"
|
||||
#include "link.h"
|
||||
#include "task_params.h"
|
||||
#include "errMdef.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbCa.h"
|
||||
/*Following is because dbScan.h causes include for dbAccess.h*/
|
||||
void scanOnce(void *precord);
|
||||
|
||||
static ELLLIST caList; /* Work list for dbCaTask */
|
||||
static SEM_ID caListSem; /*Mutual exclusions semaphores for caList*/
|
||||
static SEM_ID caWakeupSem; /*wakeup semaphore for dbCaTask*/
|
||||
void dbCaTask(); /*The Channel Access Task*/
|
||||
|
||||
void dbCaLinkInit(void)
|
||||
{
|
||||
ellInit(&caList);
|
||||
caListSem = semBCreate(SEM_Q_PRIORITY,SEM_FULL);
|
||||
caWakeupSem = semBCreate(SEM_Q_PRIORITY,SEM_EMPTY);
|
||||
if(!caListSem || !caWakeupSem) {
|
||||
printf("dbCaLinkInit: semBCreate failed\n");
|
||||
return;
|
||||
}
|
||||
taskSpawn("dbCaLink", DB_CA_PRI, DB_CA_OPT,
|
||||
DB_CA_STACK, (FUNCPTR) dbCaTask,
|
||||
0,0,0,0,0,0,0,0,0,0);
|
||||
}
|
||||
|
||||
void dbCaAddLink( struct link *plink)
|
||||
{
|
||||
caLink *pca;
|
||||
|
||||
pca = (caLink*)dbCalloc(1,sizeof(caLink));
|
||||
pca->plink = plink;
|
||||
plink->type = CA_LINK;
|
||||
plink->value.pv_link.pvt = pca;
|
||||
if((pca->lock = semBCreate(SEM_Q_PRIORITY,SEM_FULL)) == NULL){
|
||||
printf("dbCaAddLink: semBCreate failed\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
pca->link_action = CA_CONNECT;
|
||||
ellAdd(&caList,&pca->node);
|
||||
semGive(caListSem);
|
||||
semGive(caWakeupSem);
|
||||
return;
|
||||
}
|
||||
|
||||
void dbCaRemoveLink( struct link *plink)
|
||||
{
|
||||
caLink *pca = (caLink *)plink->value.pv_link.pvt;
|
||||
|
||||
if(!pca) return;
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
pca->link_action = CA_DELETE;
|
||||
if(!pca->link_action){/*If not on work list add it*/
|
||||
ellAdd(&caList,&pca->node);
|
||||
}
|
||||
plink->value.pv_link.pvt = 0;
|
||||
pca->plink = 0;
|
||||
semGive(caListSem);
|
||||
semGive(caWakeupSem);
|
||||
}
|
||||
|
||||
|
||||
long dbCaGetLink(struct link *plink,short dbrType, char *pdest,
|
||||
unsigned short *psevr,long *nelements)
|
||||
{
|
||||
caLink *pca = (caLink *)plink->value.pv_link.pvt;
|
||||
long status = 0;
|
||||
long (*pconvert)();
|
||||
STATUS semStatus;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("dbCaGetLink: record %s pv_link.pvt is NULL\n",
|
||||
plink->value.pv_link.precord);
|
||||
return(-1);
|
||||
}
|
||||
semStatus = semTake(pca->lock,WAIT_FOREVER);
|
||||
if(semStatus!=OK) {
|
||||
epicsPrintf("dbCaGetLink: semStatus!OK\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
if(ca_field_type(pca->chid) == TYPENOTCONN){
|
||||
pca->sevr = INVALID_ALARM;
|
||||
goto done;
|
||||
}
|
||||
if(!ca_read_access(pca->chid)) {
|
||||
pca->sevr = INVALID_ALARM;
|
||||
goto done;
|
||||
}
|
||||
if((pca->dbrType == DBR_ENUM)
|
||||
&& (dbDBRnewToDBRold[dbrType] == DBR_STRING)) {
|
||||
/*Must ask server for DBR_STRING*/
|
||||
if(!pca->pgetString) {
|
||||
pca->pgetString = dbCalloc(MAX_STRING_SIZE,sizeof(char));
|
||||
semGive(pca->lock);
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
if(!pca->link_action){/*If not on work list add it*/
|
||||
pca->link_action = CA_MONITOR_STRING;
|
||||
ellAdd(&caList,&pca->node);
|
||||
}
|
||||
semGive(caListSem);
|
||||
semGive(caWakeupSem);
|
||||
semStatus = semTake(pca->lock,WAIT_FOREVER);
|
||||
if(semStatus!=OK) {
|
||||
epicsPrintf("dbCaGetLink: semStatus!OK\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
}
|
||||
if(!pca->gotInString) {
|
||||
pca->sevr = INVALID_ALARM;
|
||||
goto done;
|
||||
}
|
||||
if(nelements) *nelements = 1;
|
||||
pconvert=dbFastGetConvertRoutine[dbDBRoldToDBFnew[DBR_STRING]][dbrType];
|
||||
status = (*(pconvert))(pca->pgetString, pdest, 0);
|
||||
goto done;
|
||||
}
|
||||
if(!pca->gotInNative){
|
||||
pca->sevr = INVALID_ALARM;
|
||||
goto done;
|
||||
}
|
||||
if(!nelements || *nelements == 1){
|
||||
pconvert=
|
||||
dbFastGetConvertRoutine[dbDBRoldToDBFnew[pca->dbrType]][dbrType];
|
||||
/*Ignore error routine*/
|
||||
(*(pconvert))(pca->pgetNative, pdest, 0);
|
||||
}else{
|
||||
unsigned long ntoget = *nelements;
|
||||
struct db_addr dbAddr;
|
||||
|
||||
if(ntoget > pca->nelements) ntoget = pca->nelements;
|
||||
*nelements = ntoget;
|
||||
pconvert = dbGetConvertRoutine[dbDBRoldToDBFnew[pca->dbrType]][dbrType];
|
||||
memset((void *)&dbAddr,0,sizeof(dbAddr));
|
||||
dbAddr.pfield = pca->pgetNative;
|
||||
/*Following will only be used for pca->dbrType == DBR_STRING*/
|
||||
dbAddr.field_size = MAX_STRING_SIZE;
|
||||
/*Ignore error routine*/
|
||||
(*(pconvert))(&dbAddr,pdest,ntoget,ntoget,0);
|
||||
}
|
||||
done:
|
||||
if(psevr) *psevr = pca->sevr;
|
||||
semGive(pca->lock);
|
||||
return(status);
|
||||
}
|
||||
|
||||
long dbCaPutLink(struct link *plink,short dbrType,
|
||||
void *psource,long nelements)
|
||||
{
|
||||
caLink *pca = (caLink *)plink->value.pv_link.pvt;
|
||||
long (*pconvert)();
|
||||
long status = 0;
|
||||
STATUS semStatus;
|
||||
short link_action;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("dbCaPutLink: record %s pv_link.pvt is NULL\n",
|
||||
plink->value.pv_link.precord);
|
||||
return(-1);
|
||||
}
|
||||
/* put the new value in */
|
||||
semStatus = semTake(pca->lock,WAIT_FOREVER);
|
||||
if(semStatus!=OK) {
|
||||
epicsPrintf("dbCaGetLink: semStatus!OK\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
if(ca_state(pca->chid) != cs_conn) {
|
||||
semGive(pca->lock);
|
||||
return(-1);
|
||||
}
|
||||
if((pca->dbrType == DBR_ENUM)
|
||||
&& (dbDBRnewToDBRold[dbrType] == DBR_STRING)) {
|
||||
/*Must send DBR_STRING*/
|
||||
if(!pca->pputString)
|
||||
pca->pputString = dbCalloc(MAX_STRING_SIZE,sizeof(char));
|
||||
pconvert=dbFastPutConvertRoutine[dbrType][dbDBRoldToDBFnew[DBR_STRING]];
|
||||
status = (*(pconvert))(psource,pca->pputString, 0);
|
||||
link_action = CA_WRITE_STRING;
|
||||
pca->gotOutString = TRUE;
|
||||
} else {
|
||||
if(nelements == 1){
|
||||
pconvert = dbFastPutConvertRoutine
|
||||
[dbrType][dbDBRoldToDBFnew[pca->dbrType]];
|
||||
status = (*(pconvert))(psource,pca->pputNative, 0);
|
||||
}else{
|
||||
struct db_addr dbAddr;
|
||||
pconvert = dbPutConvertRoutine
|
||||
[dbrType][dbDBRoldToDBFnew[pca->dbrType]];
|
||||
memset((void *)&dbAddr,0,sizeof(dbAddr));
|
||||
dbAddr.pfield = pca->pputNative;
|
||||
/*Following only used for DBF_STRING*/
|
||||
dbAddr.field_size = MAX_STRING_SIZE;
|
||||
status = (*(pconvert))(&dbAddr,psource,nelements,pca->nelements,0);
|
||||
}
|
||||
link_action = CA_WRITE_NATIVE;
|
||||
pca->gotOutNative = TRUE;
|
||||
}
|
||||
if(pca->newWrite) pca->nNoWrite++;
|
||||
pca->newWrite = TRUE;
|
||||
semGive(pca->lock);
|
||||
/* link it into the action list */
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
if(!pca->link_action && ca_write_access(pca->chid)){
|
||||
pca->link_action = link_action;
|
||||
ellAdd(&caList,&pca->node);
|
||||
}
|
||||
semGive(caListSem);
|
||||
semGive(caWakeupSem);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static void eventCallback(struct event_handler_args arg)
|
||||
{
|
||||
caLink *pca = (caLink *)arg.usr;
|
||||
struct link *plink;
|
||||
long size;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("eventCallback why was arg.usr NULL\n");
|
||||
return;
|
||||
}
|
||||
plink = pca->plink;
|
||||
if(arg.status != ECA_NORMAL) {
|
||||
dbCommon *precord = 0;
|
||||
|
||||
if(plink) precord = (dbCommon *)plink->value.pv_link.precord;
|
||||
if(precord) {
|
||||
if(arg.status!=ECA_NORDACCESS)
|
||||
epicsPrintf("dbCa: eventCallback record %s error %s\n",
|
||||
precord->name,ca_message(arg.status));
|
||||
} else {
|
||||
epicsPrintf("dbCa: eventCallback error %s\n",
|
||||
ca_message(arg.status));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!arg.dbr) {
|
||||
epicsPrintf("eventCallback why was arg.dbr NULL\n");
|
||||
return;
|
||||
}
|
||||
semTake(pca->lock,WAIT_FOREVER);
|
||||
size = arg.count * dbr_value_size[arg.type];
|
||||
if((arg.type==DBR_STS_STRING)
|
||||
&& (ca_field_type(pca->chid)==DBR_ENUM)) {
|
||||
memcpy(pca->pgetString,dbr_value_ptr(arg.dbr,arg.type),size);
|
||||
pca->gotInString = TRUE;
|
||||
} else switch (arg.type){
|
||||
case DBR_STS_STRING:
|
||||
case DBR_STS_SHORT:
|
||||
case DBR_STS_FLOAT:
|
||||
case DBR_STS_ENUM:
|
||||
case DBR_STS_CHAR:
|
||||
case DBR_STS_LONG:
|
||||
case DBR_STS_DOUBLE:
|
||||
memcpy(pca->pgetNative,dbr_value_ptr(arg.dbr,arg.type),size);
|
||||
pca->gotInNative = TRUE;
|
||||
break;
|
||||
default:
|
||||
errMessage(-1,"dbCa: eventCallback Logic Error\n");
|
||||
break;
|
||||
}
|
||||
pca->sevr=(unsigned short)((struct dbr_sts_double *)arg.dbr)->severity;
|
||||
plink = pca->plink;
|
||||
if(plink) {
|
||||
struct pv_link *ppv_link = &(plink->value.pv_link);
|
||||
dbCommon *precord = ppv_link->precord;
|
||||
|
||||
if(precord) {
|
||||
if((ppv_link->pvlMask&pvlOptCP)
|
||||
|| ((ppv_link->pvlMask&pvlOptCPP)&&(precord->scan==0)))
|
||||
scanOnce(precord);
|
||||
}
|
||||
}
|
||||
semGive(pca->lock);
|
||||
}
|
||||
|
||||
static void accessRightsCallback(struct access_rights_handler_args arg)
|
||||
{
|
||||
caLink *pca = (caLink *)ca_puser(arg.chid);
|
||||
struct link *plink;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("accessRightsCallback why was arg.usr NULL\n");
|
||||
return;
|
||||
}
|
||||
if(ca_read_access(arg.chid) || ca_write_access(arg.chid)) return;
|
||||
plink = pca->plink;
|
||||
if(plink) {
|
||||
struct pv_link *ppv_link = &(plink->value.pv_link);
|
||||
dbCommon *precord = ppv_link->precord;
|
||||
|
||||
if(precord) {
|
||||
if((ppv_link->pvlMask&pvlOptCP)
|
||||
|| ((ppv_link->pvlMask&pvlOptCPP)&&(precord->scan==0)))
|
||||
scanOnce(precord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void connectionCallback(struct connection_handler_args arg)
|
||||
{
|
||||
caLink *pca;
|
||||
int status;
|
||||
|
||||
pca = ca_puser(arg.chid);
|
||||
if(!pca) return;
|
||||
if(ca_state(arg.chid) != cs_conn){
|
||||
pca->nDisconnect++;
|
||||
return;
|
||||
}
|
||||
semTake(pca->lock,WAIT_FOREVER);
|
||||
if((pca->nelements != ca_element_count(arg.chid))
|
||||
|| (pca->dbrType != ca_field_type(arg.chid))){
|
||||
DBLINK *plink = pca->plink;
|
||||
|
||||
if(plink) plink->value.pv_link.getCvt = 0;
|
||||
free(pca->pgetNative);
|
||||
free(pca->pputNative);
|
||||
pca->pgetNative = NULL;
|
||||
pca->pputNative = NULL;
|
||||
pca->gotInNative = FALSE;
|
||||
pca->gotOutNative = FALSE;
|
||||
pca->gotInString = FALSE;
|
||||
}
|
||||
if(pca->pgetNative == NULL){
|
||||
short element_size;
|
||||
|
||||
pca->nelements = ca_element_count(arg.chid);
|
||||
pca->dbrType = ca_field_type(arg.chid);
|
||||
element_size = dbr_value_size[ca_field_type(arg.chid)];
|
||||
pca->pgetNative = dbCalloc(pca->nelements,element_size);
|
||||
pca->pputNative = dbCalloc(pca->nelements,element_size);
|
||||
status = ca_add_array_event(
|
||||
ca_field_type(arg.chid)+DBR_STS_STRING, ca_element_count(arg.chid),
|
||||
arg.chid, eventCallback,pca,0.0,0.0,0.0,0);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
|
||||
ca_message(status));
|
||||
if(pca->pgetString) {
|
||||
status = ca_add_array_event(DBR_STS_STRING,1,
|
||||
arg.chid, eventCallback,pca,0.0,0.0,0.0,0);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
|
||||
ca_message(status));
|
||||
}
|
||||
}
|
||||
semGive(pca->lock);
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
if(pca->gotOutNative && !pca->link_action) {
|
||||
pca->link_action = CA_WRITE_NATIVE;
|
||||
ellAdd(&caList,&pca->node);
|
||||
}
|
||||
semGive(caListSem);
|
||||
}
|
||||
|
||||
void dbCaTask()
|
||||
{
|
||||
caLink *pca;
|
||||
short link_action;
|
||||
int status;
|
||||
|
||||
SEVCHK(ca_task_initialize(),NULL);
|
||||
/* channel access event loop */
|
||||
while (TRUE){
|
||||
semTake(caWakeupSem,WAIT_FOREVER);
|
||||
while(TRUE) { /* process all requests in caList*/
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
if(pca = (caLink *)ellFirst(&caList)){/*Take off list head*/
|
||||
ellDelete(&caList,&pca->node);
|
||||
link_action = pca->link_action;
|
||||
pca->link_action = 0;
|
||||
semGive(caListSem); /*Give it back immediately*/
|
||||
switch(link_action) {
|
||||
case CA_CONNECT:
|
||||
status = ca_search_and_connect(
|
||||
pca->plink->value.pv_link.pvname,
|
||||
&(pca->chid),
|
||||
connectionCallback,(void *)pca);
|
||||
if(status!=ECA_NORMAL) {
|
||||
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
|
||||
ca_message(status));
|
||||
break;
|
||||
}
|
||||
status = ca_replace_access_rights_event(pca->chid,
|
||||
accessRightsCallback);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_replace_access_rights_event %s\n",
|
||||
ca_message(status));
|
||||
break;
|
||||
case CA_DELETE:
|
||||
if(pca->chid) ca_clear_channel(pca->chid);
|
||||
free(pca->pgetNative);
|
||||
free(pca->pputNative);
|
||||
free(pca->pgetString);
|
||||
free(pca->pputString);
|
||||
semDelete(pca->lock);
|
||||
free(pca);
|
||||
break;
|
||||
case CA_WRITE_NATIVE:
|
||||
if(ca_state(pca->chid) == cs_conn){
|
||||
status = ca_array_put(
|
||||
pca->dbrType,pca->nelements,
|
||||
pca->chid,pca->pputNative);
|
||||
if(status==ECA_NORMAL){
|
||||
pca->newWrite = FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CA_WRITE_STRING:
|
||||
if(ca_state(pca->chid) == cs_conn){
|
||||
status = ca_array_put(
|
||||
DBR_STRING,1,
|
||||
pca->chid,pca->pputString);
|
||||
if(status==ECA_NORMAL) {
|
||||
pca->newWrite = FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CA_MONITOR_STRING:
|
||||
if(ca_state(pca->chid) == cs_conn){
|
||||
status = ca_add_array_event(DBR_STS_STRING,1,
|
||||
pca->chid, eventCallback,pca,0.0,0.0,0.0,0);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_add_array_event %s\n",
|
||||
ca_message(status));
|
||||
}
|
||||
break;
|
||||
}/*switch*/
|
||||
} else {
|
||||
semGive(caListSem);
|
||||
break; /*caList is empty*/
|
||||
}
|
||||
}
|
||||
SEVCHK(ca_flush_io(),0);
|
||||
}
|
||||
}
|
||||
53
src/db/dbCa.h
Normal file
53
src/db/dbCa.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* dbCa.h.c */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1991 Regents of the University of California,
|
||||
and the University of Chicago Board of Governors.
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_Combined file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Current Author: Bob Dalesio
|
||||
* Contributing Author: Marty Kraimer
|
||||
* Date: 08APR96
|
||||
*
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 08APR96 mrk Made separate module for dbcal
|
||||
****************************************************************/
|
||||
|
||||
/* for input links */
|
||||
#define CA_CONNECT 1
|
||||
#define CA_DELETE 2
|
||||
#define CA_WRITE_NATIVE 3
|
||||
#define CA_WRITE_STRING 4
|
||||
#define CA_MONITOR_STRING 5
|
||||
typedef struct caLink
|
||||
{
|
||||
ELLNODE node;
|
||||
struct link *plink;
|
||||
chid chid;
|
||||
void *pgetNative;
|
||||
void *pputNative;
|
||||
char *pgetString;
|
||||
char *pputString;
|
||||
long nelements;
|
||||
SEM_ID lock;
|
||||
unsigned long nDisconnect;
|
||||
unsigned long nNoWrite;
|
||||
short dbrType;
|
||||
short link_action;
|
||||
unsigned short sevr;
|
||||
char gotInNative;
|
||||
char gotOutNative;
|
||||
char gotInString;
|
||||
char gotOutString;
|
||||
char newWrite;
|
||||
}caLink;
|
||||
@@ -1,757 +0,0 @@
|
||||
/* dbCaDblink.c */
|
||||
/* base/src/db $Id$ */
|
||||
/****************************************************************
|
||||
*
|
||||
* Author: Nicholas T. Karonis
|
||||
* Date: 01-01-92
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* This file exists because it is currently not possible to have a single .c
|
||||
* file that contains BOTH channel access calls AND calls to the NEW db
|
||||
* functions. This file calls a number of NEW db functions (dbNameToAddr(),
|
||||
* dbScanLock(), dbScanUnlock(), and dbPut()). If it were possible to mix
|
||||
* channel access calls and new db calls, the contents of this file should be
|
||||
* placed into dbCaLink.c as the all the externally visible functions in this
|
||||
* file are only called from functions in that file. Additionally, many of the
|
||||
* data structures found in this file would no longer be necessary.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
/* needed for NULL */
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* needed for PVNAME_SZ and FLDNAME_SZ ... must be before dbAccess.h */
|
||||
#include <dbDefs.h>
|
||||
#include <recGbl.h>
|
||||
|
||||
/* needed for dbNameToAddr() */
|
||||
#include <dbAccess.h>
|
||||
|
||||
/* needed for struct dbCommon ... should be removed when */
|
||||
/* MAXSEVERITY_FROM_PDBADDR moved to another header file */
|
||||
#include <dbCommon.h>
|
||||
|
||||
/* needed for (db_field_log *) NULL parm passed to dbGet() */
|
||||
#include <db_field_log.h>
|
||||
|
||||
#include <errMdef.h>
|
||||
#include <calink.h>
|
||||
|
||||
/* needed for recGblSetSevr() macro */
|
||||
#include <recSup.h>
|
||||
|
||||
/* these should be in dbFldTypes.h where */
|
||||
/* the valid DBF and DBR types are defined */
|
||||
|
||||
#define INVALID_DBR -1
|
||||
#define INVALID_DBF -1
|
||||
|
||||
/* this macro was defined by list of DBF and DBR types */
|
||||
/* found in dbFldTypes.h and belongs in that header file. */
|
||||
|
||||
#define DBF_TO_DBR(DBF) \
|
||||
((DBF) == DBF_STRING ? DBR_STRING : \
|
||||
((DBF) == DBF_CHAR ? DBR_CHAR : \
|
||||
((DBF) == DBF_UCHAR ? DBR_UCHAR : \
|
||||
((DBF) == DBF_SHORT ? DBR_SHORT : \
|
||||
((DBF) == DBF_USHORT ? DBR_USHORT : \
|
||||
((DBF) == DBF_LONG ? DBR_LONG : \
|
||||
((DBF) == DBF_ULONG ? DBR_ULONG : \
|
||||
((DBF) == DBF_FLOAT ? DBR_FLOAT : \
|
||||
((DBF) == DBF_DOUBLE ? DBR_DOUBLE : \
|
||||
((DBF) == DBF_ENUM ? DBR_ENUM : \
|
||||
((DBF) == DBF_MENU ? DBR_ENUM : \
|
||||
((DBF) == DBF_DEVICE ? DBR_ENUM : \
|
||||
INVALID_DBF ))))))))))))
|
||||
|
||||
/* this macro should be in recSup.h */
|
||||
/* to hide the fact that the precord */
|
||||
/* field needs to be accessed from a */
|
||||
/* dbaddr to set a new severity. */
|
||||
#define MAXSEVERITY_FROM_PDBADDR(PDBADDR, NEWSTATUS, NEWSEVERITY) \
|
||||
recGblSetSevr((struct dbCommon *) (PDBADDR)->precord, \
|
||||
(NEWSTATUS), (NEWSEVERITY));
|
||||
|
||||
/* START definitions from db_access.c */
|
||||
|
||||
#define oldDBF_STRING 0
|
||||
#define oldDBF_INT 1
|
||||
#define oldDBF_SHORT 1
|
||||
#define oldDBF_FLOAT 2
|
||||
#define oldDBF_ENUM 3
|
||||
#define oldDBF_CHAR 4
|
||||
#define oldDBF_LONG 5
|
||||
#define oldDBF_DOUBLE 6
|
||||
|
||||
/* data request buffer types */
|
||||
#define oldDBR_STRING oldDBF_STRING
|
||||
#define oldDBR_INT oldDBF_INT
|
||||
#define oldDBR_SHORT oldDBF_INT
|
||||
#define oldDBR_FLOAT oldDBF_FLOAT
|
||||
#define oldDBR_ENUM oldDBF_ENUM
|
||||
#define oldDBR_CHAR oldDBF_CHAR
|
||||
#define oldDBR_LONG oldDBF_LONG
|
||||
#define oldDBR_DOUBLE oldDBF_DOUBLE
|
||||
#define oldDBR_STS_STRING 7
|
||||
#define oldDBR_STS_INT 8
|
||||
#define oldDBR_STS_SHORT 8
|
||||
#define oldDBR_STS_FLOAT 9
|
||||
#define oldDBR_STS_ENUM 10
|
||||
#define oldDBR_STS_CHAR 11
|
||||
#define oldDBR_STS_LONG 12
|
||||
#define oldDBR_STS_DOUBLE 13
|
||||
#define oldDBR_TIME_STRING 14
|
||||
#define oldDBR_TIME_INT 15
|
||||
#define oldDBR_TIME_SHORT 15
|
||||
#define oldDBR_TIME_FLOAT 16
|
||||
#define oldDBR_TIME_ENUM 17
|
||||
#define oldDBR_TIME_CHAR 18
|
||||
#define oldDBR_TIME_LONG 19
|
||||
#define oldDBR_TIME_DOUBLE 20
|
||||
#define oldDBR_GR_STRING 21
|
||||
#define oldDBR_GR_INT 22
|
||||
#define oldDBR_GR_SHORT 22
|
||||
#define oldDBR_GR_FLOAT 23
|
||||
#define oldDBR_GR_ENUM 24
|
||||
#define oldDBR_GR_CHAR 25
|
||||
#define oldDBR_GR_LONG 26
|
||||
#define oldDBR_GR_DOUBLE 27
|
||||
#define oldDBR_CTRL_STRING 28
|
||||
#define oldDBR_CTRL_INT 29
|
||||
#define oldDBR_CTRL_SHORT 29
|
||||
#define oldDBR_CTRL_FLOAT 30
|
||||
#define oldDBR_CTRL_ENUM 31
|
||||
#define oldDBR_CTRL_CHAR 32
|
||||
#define oldDBR_CTRL_LONG 33
|
||||
#define oldDBR_CTRL_DOUBLE 34
|
||||
|
||||
/* END definitions from db_access.c */
|
||||
|
||||
/**************************************/
|
||||
/* */
|
||||
/* Externally Visible Local Functions */
|
||||
/* */
|
||||
/**************************************/
|
||||
|
||||
long dbCaCopyPvar(); /* called from dbCaLink.c */
|
||||
long dbCaDbPut(); /* called from dbCaLink.c */
|
||||
long dbCaMaximizeSeverity(); /* called from dbCaLink.c */
|
||||
long dbCaNameToAddr(); /* called from dbCaLink.c */
|
||||
|
||||
/* conversion routines */
|
||||
|
||||
short dbCaNewDbfToNewDbr(); /* called from dbCaLink.c */
|
||||
/* these two go away when channel access learns new db technology */
|
||||
short dbCaNewDbrToOldDbr(); /* called from dbCaLink.c */
|
||||
short dbCaOldDbrToNewDbr(); /* called from dbCaLink.c */
|
||||
short dbCaOldDbrToOldDbrSts(); /* called from dbCaLink.c */
|
||||
|
||||
/* these should be moved to db access */
|
||||
char *dbCaRecnameFromDbCommon(); /* called from dbCaLink.c */
|
||||
short dbCaDbfFromDbAddr(); /* called from dbCaLink.c */
|
||||
long dbCaNelementsFromDbAddr(); /* called from dbCaLink.c */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* EXTERNALLY VISIBLE FUNCTIONS
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Logic:
|
||||
*
|
||||
* Notes:
|
||||
* Typically this routine is called from a place that has no
|
||||
* knowledge about struct dbAddr, therefore pdbaddr comes in as
|
||||
* a void *.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaDbfFromDbAddr(pdbaddr)
|
||||
void *pdbaddr;
|
||||
{
|
||||
|
||||
short rc;
|
||||
|
||||
if (pdbaddr)
|
||||
rc = ((struct dbAddr *) pdbaddr)->field_type;
|
||||
else
|
||||
rc = (short) INVALID_DBF;
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaDbfFromDbAddr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* long dbCaNameToAddr(pvarname)
|
||||
* char *pvarname;
|
||||
*
|
||||
* Description:
|
||||
* During record initialization a record was found to have an input link
|
||||
* whose source is in a different physical database (on another IOC). This
|
||||
* function registers that input link as remote.
|
||||
*
|
||||
* Input:
|
||||
* char *pvarname name of destination pvar for input link
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* any rc from dbNameToAddr()
|
||||
* S_dbCa_nullarg - received a NULL pointer in one of the args
|
||||
* S_dbCa_failedmalloc - could not dynamically allocate memory
|
||||
*
|
||||
* Notes:
|
||||
* The name of the destination pvar for this input link serves as
|
||||
* the primary key when relating the the Input List in this file
|
||||
* to the Input List in dbCaLink.c as each input link has exactly one source
|
||||
* (i.e., name of destination of input link --FD--> input link).
|
||||
*
|
||||
* This function is called by dbCaAddInlink() in dbCaLink.c.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaNameToAddr(pvarname, ppdbaddr)
|
||||
char *pvarname;
|
||||
void **ppdbaddr;
|
||||
{
|
||||
|
||||
char errmsg[100];
|
||||
long rc;
|
||||
|
||||
if (pvarname)
|
||||
{
|
||||
if (ppdbaddr)
|
||||
{
|
||||
if (*ppdbaddr = (void *) calloc
|
||||
((unsigned) 1, (unsigned) sizeof (struct dbAddr)))
|
||||
{
|
||||
rc = dbNameToAddr(pvarname, (struct dbAddr *) *ppdbaddr);
|
||||
|
||||
if (!RTN_SUCCESS(rc))
|
||||
free(*ppdbaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_failedmalloc;
|
||||
sprintf(errmsg,
|
||||
"ERROR: dbCaNameToAddr() could not calloc dbAddr for dpvar >%s<",
|
||||
pvarname);
|
||||
errMessage(S_dbCa_failedmalloc, errmsg);
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaNameToAddr() got NULL ppdest_dbaddr");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaNameToAddr() got NULL pvarname");
|
||||
} /* endif */
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaNameToAddr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
* A record is being processed that has an output link that refers to a
|
||||
* process variable on another physical database (another IOC). This function
|
||||
* copies the value from the source pvar into the temporary store of the output
|
||||
* node.
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* any rc from dbGet()
|
||||
* S_dbCa_nullarg - received a NULL pointer in one of the args
|
||||
*
|
||||
* Notes:
|
||||
* The source pvar name is used as the primary key to index the Output List
|
||||
* in this file.
|
||||
* The two arguments poptions and pnrequest are passed because this function
|
||||
* uses dbGet() to transfer the data from the record to the temporary store
|
||||
* in the Output List.
|
||||
* This function is called by dbCaPutLink() in dbCaLink.c.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaCopyPvar(psource_dbaddr, dest_old_dbr_type, pval,
|
||||
poptions, pnrequest)
|
||||
void *psource_dbaddr;
|
||||
short dest_old_dbr_type;
|
||||
void *pval;
|
||||
long *poptions;
|
||||
long *pnrequest;
|
||||
{
|
||||
|
||||
long rc;
|
||||
|
||||
if (psource_dbaddr)
|
||||
{
|
||||
if (pval)
|
||||
{
|
||||
if (poptions)
|
||||
{
|
||||
if (pnrequest)
|
||||
rc = dbGet((struct dbAddr *) psource_dbaddr,
|
||||
dest_old_dbr_type, (caddr_t) pval,
|
||||
poptions, pnrequest, (db_field_log *) NULL);
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaCopyPvar() got NULL pnrequest");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaCopyPvar() got NULL poptions");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg, "ERROR: dbCaCopyPvar() got NULL pval");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaCopyPvar() got NULL psource_dbaddr");
|
||||
} /* endif */
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaCopyPvar() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* long dbCaMaximizeSeverity(dest_pvarname, new_severity, new_status)
|
||||
* char dest_pvarname;
|
||||
* unsigned short new_severity;
|
||||
* unsigned short new_status;
|
||||
*
|
||||
* Description:
|
||||
* A record is being processed that has an input link that refers to a
|
||||
* process variable on another physical database (another IOC) and the input
|
||||
* link is MS. The severity of the source record is appropriately propogated
|
||||
* to the destination record.
|
||||
*
|
||||
* Input:
|
||||
* char dest_pvarname destination pvar name
|
||||
* unsigned short new_severity new alarm severity
|
||||
* unsigned short new_status new alarm status
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Success
|
||||
* S_dbCa_foundnull - found a NULL pointer where one should not be
|
||||
* S_dbCa_nullarg - encountered a NULL pointer in one of the input args
|
||||
*
|
||||
* Notes:
|
||||
* The dest pvar name is used as the primary key to index the Input List
|
||||
* in this file.
|
||||
* This function is called by dbCaGetLink() in dbCaLink.c.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaMaximizeSeverity(pdest_dbaddr, new_severity, new_status)
|
||||
void *pdest_dbaddr;
|
||||
unsigned short new_severity;
|
||||
unsigned short new_status;
|
||||
{
|
||||
|
||||
long rc;
|
||||
|
||||
if (pdest_dbaddr)
|
||||
{
|
||||
rc = 0L;
|
||||
|
||||
MAXSEVERITY_FROM_PDBADDR ((struct dbAddr *) pdest_dbaddr,
|
||||
new_status, new_severity)
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR:dbCaMaximizeSeverity() got NULL pdest_dbaddr");
|
||||
} /* endif */
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaMaximizeSeverity() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
* A record is being processed that has an input link that refers to a
|
||||
* process variable on another physical database (another IOC). This function
|
||||
* copies the value in the temporary store of the input node into the
|
||||
* destination.
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* any rc from dbPut()
|
||||
* S_dbCa_nullarg - encountered a NULL pointer in one of the input args
|
||||
*
|
||||
* Notes:
|
||||
* The source pvar name is used as the primary key to index the Input List
|
||||
* in this file.
|
||||
* This function is called by dbCaGetLink() in dbCaLink.c.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaDbPut(pdest_dbaddr, dest_revised_new_dbr_type, pval, nelements)
|
||||
void *pdest_dbaddr;
|
||||
short dest_revised_new_dbr_type;
|
||||
void *pval;
|
||||
long nelements;
|
||||
{
|
||||
|
||||
long rc;
|
||||
|
||||
if (pdest_dbaddr)
|
||||
{
|
||||
if (nelements > 0L)
|
||||
{
|
||||
/* printf("dbCaDbPut(): writing to >%s< link revised new dbr type %d nelements %ld\n", (((struct dbAddr *) pdest_dbaddr)->precord)->name, dest_revised_new_dbr_type, nelements); */
|
||||
if (pval)
|
||||
/* this stuff is copied from dbPutField() without */
|
||||
/* honoring the ascii definition process passive */
|
||||
/* for writing to this field within the record. */
|
||||
/* */
|
||||
/* since this function is called during record */
|
||||
/* processing, it is assumed that the record has */
|
||||
/* been successfully locked. */
|
||||
|
||||
rc = dbPut((struct dbAddr *) pdest_dbaddr,
|
||||
dest_revised_new_dbr_type, (caddr_t) pval, nelements);
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg, "ERROR: dbCaDbPut() got NULL pval");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg,
|
||||
"ERROR: dbCaDbPut() got non-positive nelements");
|
||||
} /* endif */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = S_dbCa_nullarg;
|
||||
errMessage(S_dbCa_nullarg, "ERROR: dbCaDbPut() got NULL ppdest_dbaddr");
|
||||
} /* endif */
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaDbPut() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Logic:
|
||||
*
|
||||
* Notes:
|
||||
* Typically this routine is called from a place that has no
|
||||
* knowledge about struct dbAddr, therefore pdbaddr comes in as
|
||||
* a void *.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long dbCaNelementsFromDbAddr(pdbaddr)
|
||||
void *pdbaddr;
|
||||
{
|
||||
|
||||
long rc;
|
||||
|
||||
if (pdbaddr)
|
||||
rc = ((struct dbAddr *) pdbaddr)->no_elements;
|
||||
else
|
||||
rc = -1L;
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaNelementsFromDbAddr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* short dbCaNewDbfToNewDbr(new_dbf_type)
|
||||
* short new_dbf_type;
|
||||
*
|
||||
* Description:
|
||||
* This function converts DBF_XXX -> DBR_XXX both using new db technology.
|
||||
*
|
||||
* Input:
|
||||
* short new_dbf_type DBF type to be converted.
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* -1 - conversion failed
|
||||
* new DBR type
|
||||
*
|
||||
* Notes:
|
||||
* It is assumed that -1 is an invalid new DBR type and that DBF_INT and
|
||||
* DBF_SHORT are defined to be the same thing.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaNewDbfToNewDbr(new_dbf_type)
|
||||
short new_dbf_type;
|
||||
{
|
||||
|
||||
return ((short) DBF_TO_DBR(new_dbf_type));
|
||||
|
||||
} /* end dbCaNewDbfToNewDbr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* short dbCaNewDbrToOldDbr(new_dbr_type)
|
||||
* short new_dbr_type;
|
||||
*
|
||||
* Description:
|
||||
* This function converts new DBR_XXX types old DBR_XXX types.
|
||||
*
|
||||
* Input:
|
||||
* short new_dbr_type new DBR type to be converted
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* -1 - conversion failed
|
||||
* old DBR type
|
||||
*
|
||||
* Notes:
|
||||
* It is assumed that -1 is an invalid old DBR type and that DBR_INT and
|
||||
* DBR_SHORT are defined to be the same thing.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaNewDbrToOldDbr(new_dbr_type)
|
||||
short new_dbr_type;
|
||||
{
|
||||
|
||||
short old_dbr_type;
|
||||
|
||||
switch (new_dbr_type)
|
||||
{
|
||||
case DBR_STRING: old_dbr_type = oldDBR_STRING; break;
|
||||
case DBR_CHAR: old_dbr_type = oldDBR_CHAR; break;
|
||||
/* case DBR_UCHAR: old_dbr_type = oldDBR_CHAR; break; */
|
||||
case DBR_UCHAR: old_dbr_type = oldDBR_SHORT; break;
|
||||
case DBR_SHORT: old_dbr_type = oldDBR_SHORT; break;
|
||||
/* case DBR_USHORT: old_dbr_type = oldDBR_ENUM; break; */
|
||||
case DBR_USHORT: old_dbr_type = oldDBR_LONG; break;
|
||||
case DBR_LONG: old_dbr_type = oldDBR_LONG; break;
|
||||
case DBR_ULONG: old_dbr_type = oldDBR_LONG; break;
|
||||
case DBR_FLOAT: old_dbr_type = oldDBR_FLOAT; break;
|
||||
case DBR_DOUBLE: old_dbr_type = oldDBR_DOUBLE; break;
|
||||
case DBR_ENUM: old_dbr_type = oldDBR_ENUM; break;
|
||||
|
||||
/* Unrecognizable ... don't know what to do for now */
|
||||
default: old_dbr_type = -1; break;
|
||||
} /* end switch() */
|
||||
|
||||
return old_dbr_type;
|
||||
|
||||
} /* end dbCaNewDbrToOldDbr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* short dbCaOldDbrToNewDbr(new_dbr_type)
|
||||
* short new_dbr_type;
|
||||
*
|
||||
* Description:
|
||||
* This function converts old DBR_XXX types new DBR_XXX types.
|
||||
*
|
||||
* Input:
|
||||
* short old_dbr_type old DBR type to be converted
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* -1 - conversion failed
|
||||
* new DBR type
|
||||
*
|
||||
* Notes:
|
||||
* It is assumed that -1 is an invalid new DBR type and that oldDBR_INT and
|
||||
* oldDBR_SHORT are defined to be the same thing.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaOldDbrToNewDbr(old_dbr_type)
|
||||
short old_dbr_type;
|
||||
{
|
||||
|
||||
short new_dbr_type;
|
||||
|
||||
switch (old_dbr_type)
|
||||
{
|
||||
|
||||
case oldDBR_STRING: new_dbr_type = DBR_STRING; break;
|
||||
/* case oldDBR_INT: */
|
||||
case oldDBR_SHORT: new_dbr_type = DBR_SHORT; break;
|
||||
case oldDBR_FLOAT: new_dbr_type = DBR_FLOAT; break;
|
||||
case oldDBR_ENUM: new_dbr_type = DBR_ENUM; break;
|
||||
case oldDBR_CHAR: new_dbr_type = DBR_UCHAR; break;
|
||||
case oldDBR_LONG: new_dbr_type = DBR_LONG; break;
|
||||
case oldDBR_DOUBLE: new_dbr_type = DBR_DOUBLE; break;
|
||||
|
||||
/* Unrecognizable ... don't know what to do for now */
|
||||
default: new_dbr_type = -1; break;
|
||||
} /* end switch() */
|
||||
|
||||
return new_dbr_type;
|
||||
|
||||
} /* end dbCaOldDbrToNewDbr() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* short dbCaOldDbrToOldDbrSts(old_dbr_type)
|
||||
* short old_dbr_type;
|
||||
*
|
||||
* Description:
|
||||
* This function converts old DBR_XXX types to old DBR_STS_XXX types.
|
||||
*
|
||||
* Input:
|
||||
* short old_dbr_type old DBR type to be converted
|
||||
*
|
||||
* Output: None.
|
||||
*
|
||||
* Returns:
|
||||
* -1 - conversion failed
|
||||
* old DBR_STS type
|
||||
*
|
||||
* Logic:
|
||||
* convert
|
||||
*
|
||||
* Notes:
|
||||
* It is assumed that -1 is an invalid old DBR_STS type and that oldDBR_INT
|
||||
* and oldDBR_SHORT are defined to be the same thing.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
short dbCaOldDbrToOldDbrSts(old_dbr_type)
|
||||
short old_dbr_type;
|
||||
{
|
||||
|
||||
short old_dbr_sts_type;
|
||||
|
||||
switch (old_dbr_type)
|
||||
{
|
||||
|
||||
case oldDBR_STRING: old_dbr_sts_type = oldDBR_STS_STRING; break;
|
||||
/* case oldDBR_INT: */
|
||||
case oldDBR_SHORT: old_dbr_sts_type = oldDBR_STS_SHORT; break;
|
||||
case oldDBR_FLOAT: old_dbr_sts_type = oldDBR_STS_FLOAT; break;
|
||||
case oldDBR_ENUM: old_dbr_sts_type = oldDBR_STS_ENUM; break;
|
||||
case oldDBR_CHAR: old_dbr_sts_type = oldDBR_STS_CHAR; break;
|
||||
case oldDBR_LONG: old_dbr_sts_type = oldDBR_STS_LONG; break;
|
||||
case oldDBR_DOUBLE: old_dbr_sts_type = oldDBR_STS_DOUBLE; break;
|
||||
|
||||
/* Unrecognizable ... don't know what to do for now */
|
||||
default: old_dbr_sts_type = -1; break;
|
||||
} /* end switch() */
|
||||
|
||||
return old_dbr_sts_type;
|
||||
|
||||
} /* end dbCaOldDbrToOldDbrSts() */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Output:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Logic:
|
||||
*
|
||||
* Notes:
|
||||
* Typically this routine is called from a place that has no
|
||||
* knowledge about struct dbCommon, therefore precord comes in as
|
||||
* a void *.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
char *dbCaRecnameFromDbCommon(precord)
|
||||
void *precord;
|
||||
{
|
||||
|
||||
char *rc;
|
||||
|
||||
if (precord)
|
||||
rc = ((struct dbCommon *) precord)->name;
|
||||
else
|
||||
rc = (char *) NULL;
|
||||
|
||||
return rc;
|
||||
|
||||
} /* end dbCaRecnameFromDbCommon() */
|
||||
2366
src/db/dbCaLink.c
2366
src/db/dbCaLink.c
File diff suppressed because it is too large
Load Diff
@@ -46,13 +46,11 @@
|
||||
field(TSEL,DBF_INLINK) {
|
||||
prompt("Time Stamp Link")
|
||||
promptgroup(GUI_SCAN)
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(DTYP,DBF_DEVICE) {
|
||||
prompt("Device Type")
|
||||
promptgroup(GUI_LINKS)
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(DISV,DBF_SHORT) {
|
||||
@@ -66,7 +64,6 @@
|
||||
field(SDIS,DBF_INLINK) {
|
||||
prompt("Scanning Disable")
|
||||
promptgroup(GUI_SCAN)
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(MLOK,DBF_NOACCESS) {
|
||||
@@ -134,11 +131,6 @@
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSET,DBF_SHORT) {
|
||||
prompt("Lock Set")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
}
|
||||
field(LCNT,DBF_UCHAR) {
|
||||
prompt("Lock Count")
|
||||
special(SPC_NOMOD)
|
||||
@@ -208,6 +200,20 @@
|
||||
size(4)
|
||||
extra("void *dpvt")
|
||||
}
|
||||
field(RDES,DBF_NOACCESS) {
|
||||
prompt("Address of dbRecDes")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
size(4)
|
||||
extra("void *rdes")
|
||||
}
|
||||
field(LSET,DBF_NOACCESS) {
|
||||
prompt("Lock Set")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
size(4)
|
||||
extra("void *lset")
|
||||
}
|
||||
field(PRIO,DBF_MENU) {
|
||||
prompt("Scheduling Priority")
|
||||
promptgroup(GUI_SCAN)
|
||||
@@ -241,6 +247,5 @@
|
||||
field(FLNK,DBF_FWDLINK) {
|
||||
prompt("Forward Process Link")
|
||||
promptgroup(GUI_LINKS)
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
recordtype(dbCommon) {
|
||||
include "dbCommon.ascii"
|
||||
}
|
||||
3
src/db/dbCommonRecord.db
Normal file
3
src/db/dbCommonRecord.db
Normal file
@@ -0,0 +1,3 @@
|
||||
recordtype(dbCommon) {
|
||||
include "dbCommon.db"
|
||||
}
|
||||
@@ -45,9 +45,8 @@
|
||||
#include <recSup.h>
|
||||
#include <recGbl.h>
|
||||
|
||||
|
||||
/* DATABASE ACCESS GET CONVERSION SUPPORT */
|
||||
|
||||
|
||||
static long getStringString (
|
||||
DBADDR *paddr, void *pto, long nRequest, long no_elements, long offset)
|
||||
{
|
||||
@@ -90,15 +89,21 @@ static long getStringChar(
|
||||
if(sscanf(psrc,"%hd",&value) == 1) {
|
||||
*pbuffer = (char)value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = '0';
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%hd",&value) == 1) {
|
||||
*pbuffer = (char)value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = '0';
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -121,15 +126,21 @@ static long getStringUchar(
|
||||
if(sscanf(psrc,"%hu",&value) == 1) {
|
||||
*pbuffer = (unsigned char)value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = '0';
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%hu",&value) == 1) {
|
||||
*pbuffer = (unsigned char)value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = '0';
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -152,15 +163,21 @@ static long getStringShort(
|
||||
if(sscanf(psrc,"%hd",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%hd",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -183,15 +200,21 @@ static long getStringUshort(
|
||||
if(sscanf(psrc,"%hu",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%hu",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -214,15 +237,21 @@ static long getStringLong(
|
||||
if(sscanf(psrc,"%ld",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%ld",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -239,21 +268,29 @@ static long getStringUlong(
|
||||
{
|
||||
unsigned long *pbuffer = (unsigned long *)pto;
|
||||
char *psrc=(char *)paddr->pfield;
|
||||
unsigned long value;
|
||||
double value;
|
||||
|
||||
/*Convert to double first so that numbers like 1.0e3 convert properly*/
|
||||
/*Problem was old database access said to get unsigned long as double*/
|
||||
if(nRequest==1 && offset==0) {
|
||||
if(sscanf(psrc,"%lu",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
if(sscanf(psrc,"%lf",&value) == 1) {
|
||||
*pbuffer = (unsigned long)value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%lu",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
if(sscanf(psrc,"%lf",&value) == 1) {
|
||||
*pbuffer = (unsigned long)value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -276,16 +313,21 @@ static long getStringFloat(
|
||||
if(sscanf(psrc,"%f",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0.0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%f",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0.0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -308,16 +350,21 @@ static long getStringDouble(
|
||||
if(sscanf(psrc,"%lf",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0.0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%lf",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0.0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -1502,22 +1549,18 @@ static long getFloatString(
|
||||
{
|
||||
char *pbuffer = (char *)pto;
|
||||
float *psrc=(float *)(paddr->pfield);
|
||||
long status;
|
||||
int precision;
|
||||
struct rset *prset;
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset = 0;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
if(prset && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
if(status) {
|
||||
recGblRecSupError(status,paddr,"dbGet","get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
cvtFloatToString(*psrc,pbuffer,precision);
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
psrc += offset;
|
||||
while (nRequest) {
|
||||
@@ -1529,7 +1572,7 @@ static long getFloatString(
|
||||
psrc++;
|
||||
nRequest--;
|
||||
}
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long getFloatChar(
|
||||
@@ -1632,17 +1675,14 @@ static long getFloatUlong(
|
||||
{
|
||||
unsigned long *pbuffer = (unsigned long *)pto;
|
||||
float *psrc=(float *)(paddr->pfield);
|
||||
long ltemp; /*vxWorks does not support float to unsigned long*/
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
ltemp = *psrc;
|
||||
*pbuffer = ltemp;
|
||||
*pbuffer = *psrc;
|
||||
return(0);
|
||||
}
|
||||
psrc += offset;
|
||||
while (nRequest) {
|
||||
ltemp = *psrc++;
|
||||
*pbuffer++ = ltemp;
|
||||
*pbuffer++ = *psrc++;
|
||||
if(++offset==no_elements) psrc=(float *)paddr->pfield;
|
||||
nRequest--;
|
||||
}
|
||||
@@ -1711,22 +1751,18 @@ static long getDoubleString(
|
||||
{
|
||||
char *pbuffer = (char *)pto;
|
||||
double *psrc=(double *)(paddr->pfield);
|
||||
long status;
|
||||
int precision;
|
||||
struct rset *prset;
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset = 0;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
if(prset && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
if(status) {
|
||||
recGblRecSupError(status,paddr,"dbGet","get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
cvtDoubleToString(*psrc,pbuffer,precision);
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
psrc += offset;
|
||||
while (nRequest) {
|
||||
@@ -1738,7 +1774,7 @@ static long getDoubleString(
|
||||
psrc++;
|
||||
nRequest--;
|
||||
}
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long getDoubleChar(
|
||||
@@ -1841,17 +1877,14 @@ static long getDoubleUlong(
|
||||
{
|
||||
unsigned long *pbuffer = (unsigned long *)pto;
|
||||
double *psrc=(double *)(paddr->pfield);
|
||||
long ltemp; /*vxWorks does not support double to unsigned long*/
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
ltemp = *psrc;
|
||||
*pbuffer = ltemp;
|
||||
*pbuffer = *psrc;
|
||||
return(0);
|
||||
}
|
||||
psrc += offset;
|
||||
while (nRequest) {
|
||||
ltemp = *psrc++;
|
||||
*pbuffer++ = ltemp;
|
||||
*pbuffer++ = *psrc++;
|
||||
if(++offset==no_elements) psrc=(double *)paddr->pfield;
|
||||
nRequest--;
|
||||
}
|
||||
@@ -2105,7 +2138,7 @@ static long getMenuString(DBADDR *paddr, void *pto,
|
||||
{
|
||||
char *pbuffer = (char *)pto;
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbMenu *pdbMenu = (dbMenu *)pdbFldDes->ftPvt;
|
||||
dbMenu *pdbMenu;
|
||||
char **papChoiceValue;
|
||||
char *pchoice;
|
||||
unsigned short choice_ind= *((unsigned short*)paddr->pfield);
|
||||
@@ -2114,7 +2147,9 @@ static long getMenuString(DBADDR *paddr, void *pto,
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbGet(getMenuString)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if( !pdbMenu || choice_ind>=pdbMenu->nChoice
|
||||
if(!pdbFldDes
|
||||
|| !(pdbMenu = (dbMenu *)pdbFldDes->ftPvt)
|
||||
|| (choice_ind>=pdbMenu->nChoice)
|
||||
|| !(papChoiceValue = pdbMenu->papChoiceValue)
|
||||
|| !(pchoice=papChoiceValue[choice_ind])) {
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbGet(getMenuString)");
|
||||
@@ -2129,7 +2164,7 @@ static long getDeviceString(DBADDR *paddr, void *pto,
|
||||
{
|
||||
char *pbuffer = (char *)pto;
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbDeviceMenu *pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt;
|
||||
dbDeviceMenu *pdbDeviceMenu;
|
||||
char **papChoice;
|
||||
char *pchoice;
|
||||
unsigned short choice_ind= *((unsigned short*)paddr->pfield);
|
||||
@@ -2138,7 +2173,9 @@ static long getDeviceString(DBADDR *paddr, void *pto,
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbGet(getDeviceString)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if( !pdbDeviceMenu || choice_ind>=pdbDeviceMenu->nChoice
|
||||
if(!pdbFldDes
|
||||
|| !(pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt)
|
||||
|| (choice_ind>=pdbDeviceMenu->nChoice )
|
||||
|| !(papChoice = pdbDeviceMenu->papChoice)
|
||||
|| !(pchoice=papChoice[choice_ind])) {
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbGet(getDeviceString)");
|
||||
@@ -2274,21 +2311,19 @@ static long putStringUshort(
|
||||
{
|
||||
char *pbuffer = (char *)pfrom;
|
||||
unsigned short *pdest=(unsigned short *)paddr->pfield;
|
||||
float value;
|
||||
unsigned short value;
|
||||
|
||||
/*Convert to float first so that numbers like 1.0e3 convert properly*/
|
||||
/*Problem was old database access said to get unsigned short as float*/
|
||||
if(nRequest==1 && offset==0) {
|
||||
if(sscanf(pbuffer,"%f",&value) == 1) {
|
||||
*pdest = (unsigned short)value;
|
||||
if(sscanf(pbuffer,"%hu",&value) == 1) {
|
||||
*pdest = value;
|
||||
return(0);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
pdest += offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(pbuffer,"%f",&value) == 1) {
|
||||
*pdest = (unsigned short)value;
|
||||
if(sscanf(pbuffer,"%hu",&value) == 1) {
|
||||
*pdest = value;
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
@@ -2465,7 +2500,7 @@ static long putStringEnum(
|
||||
if(status == S_db_noRSET) {
|
||||
recGblRecSupError(status,paddr,"dbPutField","put_enum_str");
|
||||
} else {
|
||||
recGblDbaddrError(status,paddr,"dbPut(putStringEnum)");
|
||||
recGblRecordError(status,(void *)paddr->precord,pbuffer);
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
@@ -2475,7 +2510,7 @@ static long putStringMenu(
|
||||
{
|
||||
char *pbuffer = (char *)pfrom;
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbMenu *pdbMenu = (dbMenu *)pdbFldDes->ftPvt;
|
||||
dbMenu *pdbMenu;
|
||||
char **papChoiceValue;
|
||||
char *pchoice;
|
||||
unsigned short *pfield= (unsigned short*)(paddr->pfield);
|
||||
@@ -2486,7 +2521,9 @@ static long putStringMenu(
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringMenu)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if( pdbMenu && (papChoiceValue = pdbMenu->papChoiceValue)) {
|
||||
if(pdbFldDes
|
||||
&& (pdbMenu = (dbMenu *)pdbFldDes->ftPvt)
|
||||
&& (papChoiceValue = pdbMenu->papChoiceValue)) {
|
||||
nChoice = pdbMenu->nChoice;
|
||||
for(ind=0; ind<nChoice; ind++) {
|
||||
if(!(pchoice=papChoiceValue[ind])) continue;
|
||||
@@ -2521,7 +2558,9 @@ static long putStringDevice(
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringDevice)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if( pdbDeviceMenu && (papChoice = pdbDeviceMenu->papChoice)) {
|
||||
if(pdbFldDes
|
||||
&& (pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt)
|
||||
&& (papChoice = pdbDeviceMenu->papChoice)) {
|
||||
nChoice = pdbDeviceMenu->nChoice;
|
||||
for(ind=0; ind<nChoice; ind++) {
|
||||
if(!(pchoice=papChoice[ind])) continue;
|
||||
@@ -3721,23 +3760,20 @@ static long putFloatString(
|
||||
{
|
||||
float *pbuffer = (float *)pfrom;
|
||||
char *pdest=(char *)(paddr->pfield);
|
||||
long status;
|
||||
int precision;
|
||||
struct rset *prset;
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset = 0;
|
||||
short size=paddr->field_size;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
if(prset && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
if(status) {
|
||||
recGblRecSupError(status,paddr,"dbPutField","get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
cvtFloatToString(*pbuffer,pdest,precision);
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
pdest += (size*offset);
|
||||
while (nRequest) {
|
||||
@@ -3749,7 +3785,7 @@ static long putFloatString(
|
||||
pdest += size;
|
||||
nRequest--;
|
||||
}
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long putFloatChar(
|
||||
@@ -3852,17 +3888,14 @@ static long putFloatUlong(
|
||||
{
|
||||
float *pbuffer = (float *)pfrom;
|
||||
unsigned long *pdest=(unsigned long *)(paddr->pfield);
|
||||
long ltemp;/*vxWorks does not support float to unsigned long*/
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
ltemp = *pbuffer;
|
||||
*pdest = ltemp;
|
||||
*pdest = *pbuffer;
|
||||
return(0);
|
||||
}
|
||||
pdest += offset;
|
||||
while (nRequest) {
|
||||
ltemp = *pbuffer++;
|
||||
*pdest++ = ltemp;
|
||||
*pdest++ = *pbuffer++;
|
||||
if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield;
|
||||
nRequest--;
|
||||
}
|
||||
@@ -3931,23 +3964,20 @@ static long putDoubleString(
|
||||
{
|
||||
double *pbuffer = (double *)pfrom;
|
||||
char *pdest=(char *)(paddr->pfield);
|
||||
long status;
|
||||
int precision;
|
||||
struct rset *prset;
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset = 0;
|
||||
short size=paddr->field_size;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
if(prset && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
if(status) {
|
||||
recGblRecSupError(status,paddr,"dbPutField","get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
cvtDoubleToString(*pbuffer,pdest,precision);
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
pdest += (size*offset);
|
||||
while (nRequest) {
|
||||
@@ -3959,7 +3989,7 @@ static long putDoubleString(
|
||||
pdest += size;
|
||||
nRequest--;
|
||||
}
|
||||
return(0);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long putDoubleChar(
|
||||
@@ -4062,17 +4092,14 @@ static long putDoubleUlong(
|
||||
{
|
||||
double *pbuffer = (double *)pfrom;
|
||||
unsigned long *pdest=(unsigned long *)(paddr->pfield);
|
||||
long ltemp;/*vxWorks does not support double to unsigned long*/
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
ltemp = *pbuffer;
|
||||
*pdest = ltemp;
|
||||
*pdest = *pbuffer;
|
||||
return(0);
|
||||
}
|
||||
pdest += offset;
|
||||
while (nRequest) {
|
||||
ltemp = *pbuffer++;
|
||||
*pdest++ = ltemp;
|
||||
*pdest++ = *pbuffer++;
|
||||
if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield;
|
||||
nRequest--;
|
||||
}
|
||||
|
||||
40
src/db/dbConvert.h
Normal file
40
src/db/dbConvert.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* dbConvert.h */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 13OCT95
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 13OCT95 mrk Created header file as part of extracting convert from
|
||||
* dbLink
|
||||
*/
|
||||
|
||||
|
||||
#include <dbFldTypes.h>
|
||||
extern long (*dbGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1])
|
||||
(DBADDR *paddr, void *pbuffer,long nRequest, long no_elements, long offset);
|
||||
extern long (*dbPutConvertRoutine[DBR_ENUM+1][DBF_DEVICE+1])
|
||||
(DBADDR *paddr, void *pbuffer,long nRequest, long no_elements, long offset);
|
||||
extern long (*dbFastGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1])();
|
||||
extern long (*dbFastPutConvertRoutine[DBR_ENUM+1][DBF_DEVICE+1])();
|
||||
173
src/db/dbEvent.h
Normal file
173
src/db/dbEvent.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/* $Id$
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 030393
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 021494 joh updated ANSI func proto and added extra labor
|
||||
* call back
|
||||
*/
|
||||
|
||||
#ifndef INCLdbEventh
|
||||
#define INCLdbEventh
|
||||
|
||||
/*
|
||||
* collides with db_access.h used in the CA client
|
||||
*/
|
||||
#ifndef caClient
|
||||
#include <dbCommon.h>
|
||||
#endif /*caClient*/
|
||||
|
||||
#include <db_field_log.h>
|
||||
|
||||
struct event_block{
|
||||
ELLNODE node;
|
||||
struct db_addr *paddr;
|
||||
void (*user_sub)(
|
||||
void *user_arg,
|
||||
struct db_addr *paddr,
|
||||
int eventsRemaining,
|
||||
db_field_log *pfl);
|
||||
void *user_arg;
|
||||
struct event_que *ev_que;
|
||||
unsigned char select;
|
||||
char valque;
|
||||
unsigned long npend; /* n times this event is on the que */
|
||||
};
|
||||
|
||||
typedef void EVENTFUNC(
|
||||
void *user_arg,
|
||||
struct db_addr *paddr,
|
||||
int eventsRemaining,
|
||||
db_field_log *pfl);
|
||||
|
||||
|
||||
#define EVENTQUESIZE EVENTENTRIES *32
|
||||
#define EVENTENTRIES 16 /* the number of que entries for each event */
|
||||
#define EVENTQEMPTY ((struct event_block *)NULL)
|
||||
|
||||
|
||||
/*
|
||||
* really a ring buffer
|
||||
*/
|
||||
struct event_que{
|
||||
struct event_block *evque[EVENTQUESIZE];
|
||||
db_field_log valque[EVENTQUESIZE];
|
||||
unsigned short putix;
|
||||
unsigned short getix;
|
||||
unsigned short quota; /* the number of assigned entries*/
|
||||
|
||||
/* lock writers to the ring buffer only */
|
||||
/* readers must never slow up writers */
|
||||
FAST_LOCK writelock;
|
||||
|
||||
struct event_que *nextque; /* in case que quota exceeded */
|
||||
struct event_user *evuser; /* event user parent struct */
|
||||
};
|
||||
|
||||
struct event_user{
|
||||
int taskid; /* event handler task id */
|
||||
|
||||
char pendlck; /* Only one task can pend */
|
||||
SEM_ID ppendsem; /* Wait while empty */
|
||||
SEM_ID pflush_sem; /* wait for flush */
|
||||
unsigned char pendexit; /* exit pend task */
|
||||
unsigned char extra_labor; /* if set call extra labor func */
|
||||
|
||||
unsigned short queovr; /* event que overflow count */
|
||||
void (*overflow_sub)(/* called when overflow detect */
|
||||
void *overflow_arg, unsigned count);
|
||||
void *overflow_arg; /* parameter to above */
|
||||
|
||||
void (*extralabor_sub)/* off load to event task */
|
||||
(void *extralabor_arg);
|
||||
void *extralabor_arg;/* parameter to above */
|
||||
|
||||
struct event_que firstque; /* the first event que */
|
||||
};
|
||||
|
||||
typedef void OVRFFUNC(void *overflow_arg, unsigned count);
|
||||
typedef void EXTRALABORFUNC(void *extralabor_arg);
|
||||
|
||||
int db_event_list(char *name);
|
||||
struct event_user *db_init_events(void);
|
||||
int db_close_events(struct event_user *evuser);
|
||||
unsigned db_sizeof_event_block(void);
|
||||
|
||||
int db_add_event(
|
||||
struct event_user *evuser,
|
||||
struct db_addr *paddr,
|
||||
EVENTFUNC *user_sub,
|
||||
void *user_arg,
|
||||
unsigned int select,
|
||||
struct event_block *pevent /* ptr to event blk (not required) */
|
||||
);
|
||||
|
||||
int db_cancel_event(struct event_block *pevent);
|
||||
|
||||
int db_add_overflow_event(
|
||||
struct event_user *evuser,
|
||||
OVRFFUNC *overflow_sub,
|
||||
void *overflow_arg
|
||||
);
|
||||
|
||||
int db_add_extra_labor_event(
|
||||
struct event_user *evuser,
|
||||
EXTRALABORFUNC *func,
|
||||
void *arg);
|
||||
|
||||
int db_flush_extra_labor_event(
|
||||
struct event_user *evuser
|
||||
);
|
||||
|
||||
int db_post_single_event(struct event_block *pevent);
|
||||
|
||||
int db_post_extra_labor(struct event_user *evuser);
|
||||
|
||||
int db_post_events(
|
||||
void *precord,
|
||||
void *pvalue,
|
||||
unsigned int select
|
||||
);
|
||||
|
||||
int db_start_events(
|
||||
struct event_user *evuser,
|
||||
char *taskname, /* defaulted if NULL */
|
||||
void (*init_func)(int),
|
||||
int init_func_arg,
|
||||
int priority_offset
|
||||
);
|
||||
|
||||
int event_task(
|
||||
struct event_user *evuser,
|
||||
void (*init_func)(int),
|
||||
int init_func_arg
|
||||
);
|
||||
|
||||
int db_event_enable(struct event_block *pevent);
|
||||
int db_event_disable(struct event_block *pevent);
|
||||
|
||||
#endif /*INCLdbEventh*/
|
||||
|
||||
@@ -85,41 +85,21 @@ extern struct dbBase *pdbbase;
|
||||
* will have this conversion.
|
||||
*/
|
||||
|
||||
/* Uninitialized Conversion */
|
||||
long cvt_uninit(
|
||||
void *from,
|
||||
void *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
recGblDbaddrError(-1,paddr,"cvt_uninit: uninitialized link");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dummy Conversion
|
||||
* In the case of an unsupported conversion, run this
|
||||
* dummy function instead to avoid a bus error.
|
||||
*/
|
||||
long cvt_dummy(
|
||||
void *from,
|
||||
void *to,
|
||||
struct dbAddr *paddr)
|
||||
{ return(-1); }
|
||||
|
||||
/* Convert String to String */
|
||||
static long cvt_st_st(
|
||||
char *from,
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
char size = paddr->field_size;
|
||||
|
||||
if (size >= MAX_STRING_SIZE)
|
||||
size = MAX_STRING_SIZE - 1;
|
||||
char size;
|
||||
|
||||
if(paddr && paddr->field_size<MAX_STRING_SIZE) {
|
||||
size = paddr->field_size - 1;
|
||||
} else {
|
||||
size = MAX_STRING_SIZE - 1;
|
||||
}
|
||||
strncpy(to, from, size);
|
||||
*(to+size) = '\000';
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -135,7 +115,10 @@ static long cvt_st_c(
|
||||
*to = (char) value;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(strlen(from) == 0) {
|
||||
*to = '0';
|
||||
return(0);
|
||||
}
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
|
||||
@@ -145,10 +128,14 @@ static long cvt_st_uc(
|
||||
unsigned char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
short value;
|
||||
unsigned short value;
|
||||
|
||||
if (sscanf(from, "%hu", &value) == 1) {
|
||||
*to = (unsigned char) value;
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = '0';
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -167,6 +154,10 @@ static long cvt_st_s(
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
@@ -177,12 +168,16 @@ static long cvt_st_us(
|
||||
unsigned short *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
short value;
|
||||
unsigned short value;
|
||||
|
||||
if (sscanf(from, "%hu", &value) == 1) {
|
||||
*to = (unsigned short) value;
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
@@ -199,6 +194,10 @@ static long cvt_st_l(
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
@@ -209,10 +208,16 @@ static long cvt_st_ul(
|
||||
unsigned long *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
unsigned long value;
|
||||
double value;
|
||||
|
||||
if (sscanf(from, "%lu", &value) == 1) {
|
||||
*to = value;
|
||||
/*Convert to double first so that numbers like 1.0e3 convert properly*/
|
||||
/*Problem was old database access said to get unsigned long as double*/
|
||||
if (sscanf(from, "%lf", &value) == 1) {
|
||||
*to = (unsigned long)value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -231,6 +236,10 @@ static long cvt_st_f(
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0.0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
@@ -247,6 +256,10 @@ static long cvt_st_d(
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0.0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
@@ -257,10 +270,10 @@ static long cvt_st_e(
|
||||
unsigned short *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
long status;
|
||||
|
||||
prset = dbGetRset(paddr);
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
|
||||
if (prset && prset->put_enum_str)
|
||||
return (*prset->put_enum_str)(paddr, from);
|
||||
@@ -760,24 +773,17 @@ static long cvt_f_st(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
long status = 0;
|
||||
long precision = 2;
|
||||
long precision = 0;
|
||||
|
||||
prset = dbGetRset(paddr);
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
|
||||
if (prset && prset->get_precision)
|
||||
(*prset->get_precision)(paddr, &precision);
|
||||
status = (*prset->get_precision)(paddr, &precision);
|
||||
else
|
||||
status = S_db_precision;
|
||||
|
||||
if (status) {
|
||||
recGblRecSupError(status, paddr, "dbGetField", "get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
cvtFloatToString(*from, to, precision);
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -850,24 +856,17 @@ static long cvt_d_st(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
long status = 0;
|
||||
long precision = 2;
|
||||
long precision = 0;
|
||||
|
||||
prset = dbGetRset(paddr);
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
|
||||
if (prset && prset->get_precision)
|
||||
(*prset->get_precision)(paddr, &precision);
|
||||
status = (*prset->get_precision)(paddr, &precision);
|
||||
else
|
||||
status = S_db_precision;
|
||||
|
||||
if (status) {
|
||||
recGblRecSupError(status, paddr, "dbGetField", "get_precision");
|
||||
return(status);
|
||||
}
|
||||
|
||||
cvtDoubleToString(*from, to, precision);
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -1005,10 +1004,10 @@ static long cvt_e_st_get(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
long status;
|
||||
|
||||
prset = dbGetRset(paddr);
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
|
||||
if (prset && prset->get_enum_str)
|
||||
return (*prset->get_enum_str)(paddr, to);
|
||||
@@ -1032,12 +1031,15 @@ static long cvt_menu_st(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbMenu *pdbMenu = (dbMenu *)pdbFldDes->ftPvt;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbMenu *pdbMenu;
|
||||
char **papChoiceValue;
|
||||
char *pchoice;
|
||||
|
||||
if( !pdbMenu || *from>=pdbMenu->nChoice
|
||||
if(! paddr
|
||||
|| !(pdbFldDes = (dbFldDes *)paddr->pfldDes)
|
||||
|| !(pdbMenu = (dbMenu *)pdbFldDes->ftPvt)
|
||||
|| *from>=pdbMenu->nChoice
|
||||
|| !(papChoiceValue = pdbMenu->papChoiceValue)
|
||||
|| !(pchoice=papChoiceValue[*from])) {
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_menu_st)");
|
||||
@@ -1054,12 +1056,15 @@ static long cvt_device_st(
|
||||
char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
dbFldDes *pdbFldDes = (dbFldDes *)paddr->pfldDes;
|
||||
dbDeviceMenu *pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbDeviceMenu *pdbDeviceMenu;
|
||||
char **papChoice;
|
||||
char *pchoice;
|
||||
|
||||
if( !pdbDeviceMenu || *from>=pdbDeviceMenu->nChoice
|
||||
if(!paddr
|
||||
|| !(pdbFldDes = (dbFldDes *)paddr->pfldDes)
|
||||
|| !(pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt)
|
||||
|| *from>=pdbDeviceMenu->nChoice
|
||||
|| !(papChoice= pdbDeviceMenu->papChoice)
|
||||
|| !(pchoice=papChoice[*from])) {
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_device_st)");
|
||||
|
||||
495
src/db/dbLock.c
Normal file
495
src/db/dbLock.c
Normal file
@@ -0,0 +1,495 @@
|
||||
/* dbLock.c */
|
||||
/* Author: Marty Kraimer Date: 12MAR96 */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1991 Regents of the University of California,
|
||||
and the University of Chicago Board of Governors.
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_Combined file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/* Modification Log:
|
||||
* -----------------
|
||||
* .01 12MAR96 mrk Initial Implementation
|
||||
*/
|
||||
|
||||
/************** DISCUSSION OF DYNAMIC LINK MODIFICATION **********************
|
||||
|
||||
Since the purpose of lock sets is to prevent multiple tasks from simultaneously
|
||||
accessing records in set, dynamically changing lock sets presents a problem.
|
||||
|
||||
Four problems arise:
|
||||
|
||||
1) Two tasks simultaneoulsy trying to change lock sets
|
||||
2) Another task has successfully issued a dbScanLock and currently owns it.
|
||||
3) A task is waiting for dbScanLock.
|
||||
4) While lock set is being changed, a task issues a dbScanLock.
|
||||
|
||||
Solution:
|
||||
|
||||
A routine attempting to modify a link must do the following:
|
||||
|
||||
Call dbLockSetGblLock before modifying any link and dbLockSetGblUnlock after.
|
||||
Call dbLockSetRecordLock for any record referenced during change.
|
||||
Call dbLockSetSplit before changing any link that is originally a DB_LINK
|
||||
Call dbLockSetMerge if changed link becomes a DB_LINK.
|
||||
|
||||
Discussion:
|
||||
|
||||
|
||||
Each problem above is solved as follows:
|
||||
1) dbLockGlobal solves this problem.
|
||||
2) dbLockSetRecordLock solves this problem.
|
||||
3) After changing lock sets original semId id deleted.
|
||||
This makes all tasks in semTake for that semaphore fail.
|
||||
The code in dbScanLock makes task recover.
|
||||
4) The global variable changingLockSets and code in
|
||||
dbScanLock and semFlush in dbLockSetGblUnlock solves
|
||||
this problem.
|
||||
|
||||
Note that all other tasks are prevented from processing records between
|
||||
dbLockSetGblLock and dbLockSetGblUnlock.
|
||||
|
||||
dblsr may crash if executed while lock sets are being modified.
|
||||
It is NOT a good idea to make it more robust by issuing dbLockSetGblLock
|
||||
since this will delay all other tasks.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <lstLib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <semLib.h>
|
||||
#include <tickLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <dbBase.h>
|
||||
#include <ellLib.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbStaticLib.h>
|
||||
#include <dbConvert.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <epicsPrint.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <errMdef.h>
|
||||
|
||||
#define STATIC static
|
||||
|
||||
STATIC int lockListInitialized = FALSE;
|
||||
|
||||
STATIC ELLLIST lockList;
|
||||
STATIC SEM_ID globalLockSemId;
|
||||
STATIC SEM_ID globalWaitSemid;
|
||||
STATIC unsigned long id = 0;
|
||||
STATIC int changingLockSets = FALSE;
|
||||
|
||||
typedef struct lockSet {
|
||||
ELLNODE node;
|
||||
ELLLIST recordList;
|
||||
SEM_ID semId;
|
||||
ULONG start_time;
|
||||
int task_id;
|
||||
dbCommon *precord;
|
||||
unsigned long id;
|
||||
} lockSet;
|
||||
|
||||
typedef struct lockRecord {
|
||||
ELLNODE node;
|
||||
lockSet *plockSet;
|
||||
dbCommon *precord;
|
||||
} lockRecord;
|
||||
|
||||
/*private routines */
|
||||
STATIC void initLockList(void)
|
||||
{
|
||||
ellInit(&lockList);
|
||||
if((globalLockSemId = semBCreate(SEM_Q_FIFO,SEM_FULL))==0) {
|
||||
errMessage(0,"allocLockNode called semBCreate\n");
|
||||
exit(-1);
|
||||
}
|
||||
if((globalWaitSemid = semBCreate(SEM_Q_FIFO,SEM_EMPTY))==0) {
|
||||
errMessage(0,"allocLockNode called semBCreate\n");
|
||||
exit(-1);
|
||||
}
|
||||
lockListInitialized = TRUE;
|
||||
}
|
||||
|
||||
STATIC lockSet * allocLock(lockRecord *plockRecord)
|
||||
{
|
||||
lockSet *plockSet;
|
||||
|
||||
if(!lockListInitialized) initLockList();
|
||||
plockSet = dbCalloc(1,sizeof(lockSet));
|
||||
ellInit(&plockSet->recordList);
|
||||
plockRecord->plockSet = plockSet;
|
||||
id++;
|
||||
plockSet->id = id;
|
||||
ellAdd(&plockSet->recordList,&plockRecord->node);
|
||||
ellAdd(&lockList,&plockSet->node);
|
||||
if((plockSet->semId = semBCreate(SEM_Q_FIFO,SEM_FULL))==0) {
|
||||
errMessage(0,"allocLockNode called semBCreate\n");
|
||||
exit(-1);
|
||||
}
|
||||
return(plockSet);
|
||||
}
|
||||
|
||||
/*Add new lockRecord to lockSet list*/
|
||||
STATIC void lockAddRecord(lockSet *plockSet,lockRecord *pnew)
|
||||
{
|
||||
pnew->plockSet = plockSet;
|
||||
ellAdd(&plockSet->recordList,&pnew->node);
|
||||
}
|
||||
|
||||
void dbLockSetGblLock(void)
|
||||
{
|
||||
STATUS status;
|
||||
|
||||
if(!lockListInitialized) initLockList();
|
||||
status = semTake(globalLockSemId,WAIT_FOREVER);
|
||||
if(status!=OK) {
|
||||
epicsPrintf("dbLockSetGblLock failure\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
changingLockSets = TRUE;
|
||||
}
|
||||
|
||||
void dbLockSetGblUnlock(void)
|
||||
{
|
||||
taskLock();
|
||||
changingLockSets = FALSE;
|
||||
semFlush(globalWaitSemid);
|
||||
taskUnlock();
|
||||
semGive(globalLockSemId);
|
||||
return;
|
||||
}
|
||||
|
||||
void dbLockSetRecordLock(dbCommon *precord)
|
||||
{
|
||||
lockRecord *plockRecord = (lockRecord *)precord->lset;
|
||||
lockSet *plockSet;
|
||||
STATUS status;
|
||||
|
||||
/*Make sure that dbLockSetGblLock was called*/
|
||||
if(!changingLockSets) {
|
||||
epicsPrintf("dbLockSetRecordLock called before dbLockSetGblLock\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
/*Must make sure that no other task has lock*/
|
||||
if(!plockRecord) return;
|
||||
plockSet = plockRecord->plockSet;
|
||||
if(!plockSet) return;
|
||||
if(plockSet->task_id==taskIdSelf()) return;
|
||||
/*Wait for up to 1 minute*/
|
||||
status = semTake(plockRecord->plockSet->semId,sysClkRateGet()*60);
|
||||
if(status==OK) {
|
||||
plockSet->start_time = tickGet();
|
||||
plockSet->task_id = taskIdSelf();
|
||||
plockSet->precord = (void *)precord;
|
||||
/*give it back in case it will not be changed*/
|
||||
semGive(plockRecord->plockSet->semId);
|
||||
return;
|
||||
}
|
||||
/*Should never reach this point*/
|
||||
epicsPrintf("dbLockSetRecordLock timeout caller 0x%x owner 0x%x",
|
||||
taskIdSelf(),plockSet->task_id);
|
||||
epicsPrintf(" record %s\n",precord->name);
|
||||
return;
|
||||
}
|
||||
|
||||
void dbScanLock(dbCommon *precord)
|
||||
{
|
||||
lockRecord *plockRecord = (lockRecord *)precord->lset;
|
||||
lockSet *plockSet;
|
||||
STATUS status;
|
||||
|
||||
while(TRUE) {
|
||||
if(changingLockSets) {
|
||||
semTake(globalWaitSemid,WAIT_FOREVER);
|
||||
continue;
|
||||
}
|
||||
status = semTake(plockRecord->plockSet->semId,WAIT_FOREVER);
|
||||
/*semTake fails if semDelete was called while active*/
|
||||
if(status==OK) break;
|
||||
}
|
||||
plockSet = plockRecord->plockSet;
|
||||
plockSet->start_time = tickGet();
|
||||
plockSet->task_id = taskIdSelf();
|
||||
plockSet->precord = (void *)precord;
|
||||
return;
|
||||
}
|
||||
|
||||
void dbScanUnlock(dbCommon *precord)
|
||||
{
|
||||
lockRecord *plockRecord = (lockRecord *)precord->lset;
|
||||
|
||||
if(!plockRecord || !plockRecord->plockSet) {
|
||||
epicsPrintf("dbScanUnlock plockRecord or plockRecord->plockSet NULL\n");
|
||||
return;
|
||||
}
|
||||
semGive(plockRecord->plockSet->semId);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long dbLockGetLockId(dbCommon *precord)
|
||||
{
|
||||
lockRecord *plockRecord = (lockRecord *)precord->lset;
|
||||
lockSet *plockSet;
|
||||
|
||||
if(!plockRecord) return(0);
|
||||
plockSet = plockRecord->plockSet;
|
||||
if(!plockSet) return(0);
|
||||
return(plockSet->id);
|
||||
}
|
||||
|
||||
void dbLockInitRecords(dbBase *pdbbase)
|
||||
{
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbRecordNode *pdbRecordNode;
|
||||
dbCommon *precord;
|
||||
DBLINK *plink;
|
||||
int nrecords=0;
|
||||
lockRecord *plockRecord;
|
||||
|
||||
/*Allocate and initialize a lockRecord for each record instance*/
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
nrecords += ellCount(&pdbRecDes->recList);
|
||||
}
|
||||
/*Allocate all of them at once */
|
||||
plockRecord = dbCalloc(nrecords,sizeof(lockRecord));
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
plockRecord->precord = precord;
|
||||
precord->lset = plockRecord;
|
||||
plockRecord++;
|
||||
}
|
||||
}
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
for(link=0; link<pdbRecDes->no_links; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.pv_link.pvt);
|
||||
/* The current record is in a different lockset -IF-
|
||||
* 1. Input link
|
||||
* 2. Not Process Passive
|
||||
* 3. Not Maximize Severity
|
||||
* 4. Not An Array Operation - single element only
|
||||
*/
|
||||
if (pdbFldDes->field_type==DBF_INLINK
|
||||
&& !(plink->value.pv_link.pvlMask&pvlOptPP)
|
||||
&& !(plink->value.pv_link.pvlMask&pvlOptMS)
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
dbLockSetMerge(precord,pdbAddr->precord);
|
||||
}
|
||||
plockRecord = (lockRecord *)precord->lset;
|
||||
if(!plockRecord->plockSet) allocLock(plockRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dbLockSetMerge(dbCommon *pfirst,dbCommon *psecond)
|
||||
{
|
||||
lockRecord *p1lockRecord = (lockRecord *)pfirst->lset;
|
||||
lockRecord *p2lockRecord = (lockRecord *)psecond->lset;
|
||||
lockSet *p1lockSet;
|
||||
lockSet *p2lockSet;
|
||||
|
||||
p1lockSet = p1lockRecord->plockSet;
|
||||
p2lockSet = p2lockRecord->plockSet;
|
||||
if(!p1lockSet) {
|
||||
if(p2lockSet) {
|
||||
lockAddRecord(p2lockSet,p1lockRecord);
|
||||
return;
|
||||
}
|
||||
p1lockSet = allocLock(p1lockRecord);
|
||||
}
|
||||
if(p1lockSet == p2lockSet) return;
|
||||
if(!p2lockSet) {
|
||||
lockAddRecord(p1lockSet,p2lockRecord);
|
||||
return;
|
||||
}
|
||||
/*Move entire second list to first*/
|
||||
p2lockRecord = (lockRecord *)ellFirst(&p2lockSet->recordList);
|
||||
while(p2lockRecord) {
|
||||
p2lockRecord->plockSet = p1lockSet;
|
||||
p2lockRecord = (lockRecord *)ellNext(&p2lockRecord->node);
|
||||
}
|
||||
ellConcat(&p1lockSet->recordList,&p2lockSet->recordList);
|
||||
if(semDelete(p2lockSet->semId)!=OK) {
|
||||
errMessage(0,"dbLockSetMerge calling semDelete");
|
||||
taskSuspend(0);
|
||||
}
|
||||
ellDelete(&lockList,&p2lockSet->node);
|
||||
free((void *)p2lockSet);
|
||||
return;
|
||||
}
|
||||
|
||||
void dbLockSetSplit(dbCommon *psource)
|
||||
{
|
||||
lockSet *plockSet;
|
||||
lockRecord *plockRecord;
|
||||
dbCommon *precord;
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
DBLINK *plink;
|
||||
int nrecordsInSet,i;
|
||||
dbCommon **paprecord;
|
||||
|
||||
plockRecord = (lockRecord *)psource->lset;
|
||||
if(!plockRecord) {
|
||||
errMessage(-1,"dbLockSetSplit called before lockRecord allocated");
|
||||
return;
|
||||
}
|
||||
plockSet = plockRecord->plockSet;
|
||||
if(!plockSet) {
|
||||
errMessage(-1,"dbLockSetSplit called without lockSet allocated");
|
||||
return;
|
||||
}
|
||||
/*First remove all records from lock set*/
|
||||
nrecordsInSet = ellCount(&plockSet->recordList);
|
||||
paprecord = dbCalloc(nrecordsInSet,sizeof(dbCommon *));
|
||||
for(plockRecord = (lockRecord *)ellFirst(&plockSet->recordList), i=0;
|
||||
plockRecord;
|
||||
plockRecord = (lockRecord *)ellNext(&plockRecord->node), i++) {
|
||||
paprecord[i] = plockRecord->precord;
|
||||
plockRecord->plockSet = 0;
|
||||
}
|
||||
/*Now recompute lock sets */
|
||||
for(i=0; i<nrecordsInSet; i++) {
|
||||
precord = paprecord[i];
|
||||
plockRecord = (lockRecord *)precord->lset;
|
||||
if(!(precord->name[0])) continue;
|
||||
pdbRecDes = (dbRecDes *)precord->rdes;
|
||||
for(link=0; link<pdbRecDes->no_links; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
|
||||
pdbAddr = (DBADDR *)(plink->value.pv_link.pvt);
|
||||
if (pdbFldDes->field_type==DBF_INLINK
|
||||
&& !(plink->value.pv_link.pvlMask&pvlOptPP)
|
||||
&& !(plink->value.pv_link.pvlMask&pvlOptMS)
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
dbLockSetMerge(precord,pdbAddr->precord);
|
||||
}
|
||||
if(!plockRecord->plockSet) allocLock(plockRecord);
|
||||
}
|
||||
if(semDelete(plockSet->semId)!=OK) {
|
||||
errMessage(0,"dbLockSetSplit calling semDelete");
|
||||
taskSuspend(0);
|
||||
}
|
||||
ellDelete(&lockList,&plockSet->node);
|
||||
free((void *)plockSet);
|
||||
free((void *)paprecord);
|
||||
}
|
||||
|
||||
extern struct dbBase *pdbbase;
|
||||
long dblsr(char *recordname,int level)
|
||||
{
|
||||
int link;
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
dbCommon *precord;
|
||||
lockSet *plockSet;
|
||||
lockRecord *plockRecord;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
DBLINK *plink;
|
||||
|
||||
if(recordname) {
|
||||
dbInitEntry(pdbbase,pdbentry);
|
||||
status = dbFindRecord(pdbentry,recordname);
|
||||
if(status) {
|
||||
printf("Record not found\n");
|
||||
dbFinishEntry(pdbentry);
|
||||
return(0);
|
||||
}
|
||||
precord = pdbentry->precnode->precord;
|
||||
dbFinishEntry(pdbentry);
|
||||
plockRecord = (lockRecord *)precord->lset;
|
||||
if(!plockRecord) return(0);
|
||||
plockSet = plockRecord->plockSet;
|
||||
} else {
|
||||
plockSet = (lockSet *)ellFirst(&lockList);
|
||||
}
|
||||
for( ; plockSet; plockSet = (lockSet *)ellNext(&plockSet->node)) {
|
||||
double lockSeconds;
|
||||
|
||||
printf("Lock Set %lu %d members",
|
||||
plockSet->id,ellCount(&plockSet->recordList));
|
||||
if(semTake(plockSet->semId,NO_WAIT)==OK) {
|
||||
semGive(plockSet->semId);
|
||||
printf(" Not Locked\n");
|
||||
} else {
|
||||
lockSeconds = plockSet->start_time;
|
||||
lockSeconds = (tickGet() - lockSeconds) / sysClkRateGet();
|
||||
printf(" Locked %f seconds", lockSeconds);
|
||||
printf(" task 0x%x",plockSet->task_id);
|
||||
if(! plockSet->precord || !plockSet->precord->name)
|
||||
printf(" NULL record or record name\n");
|
||||
else
|
||||
printf(" record %s\n",plockSet->precord->name);
|
||||
}
|
||||
if(level==0) {
|
||||
if(recordname) break;
|
||||
continue;
|
||||
}
|
||||
for(plockRecord = (lockRecord *)ellFirst(&plockSet->recordList);
|
||||
plockRecord; plockRecord = (lockRecord *)ellNext(&plockRecord->node)) {
|
||||
precord = plockRecord->precord;
|
||||
pdbRecDes = (dbRecDes *)precord->rdes;
|
||||
printf("%s\n",precord->name);
|
||||
if(level<=1) continue;
|
||||
for(link=0; (link<pdbRecDes->no_links) ; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.pv_link.pvt);
|
||||
printf("\t%s",pdbFldDes->name);
|
||||
if(pdbFldDes->field_type==DBF_INLINK) {
|
||||
printf("\t INLINK");
|
||||
} else if(pdbFldDes->field_type==DBF_OUTLINK) {
|
||||
printf("\tOUTLINK");
|
||||
} else if(pdbFldDes->field_type==DBF_FWDLINK) {
|
||||
printf("\tFWDLINK");
|
||||
}
|
||||
printf(" %s %s",
|
||||
((plink->value.pv_link.pvlMask&pvlOptPP)?" PP":"NPP"),
|
||||
((plink->value.pv_link.pvlMask&pvlOptMS)?" MS":"NMS"));
|
||||
printf(" %s\n",pdbAddr->precord->name);
|
||||
}
|
||||
}
|
||||
if(recordname) break;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
36
src/db/dbLock.h
Normal file
36
src/db/dbLock.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* dbLock.h */
|
||||
/* Author: Marty Kraimer Date: 12MAR96 */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/* Modification Log:
|
||||
* -----------------
|
||||
* .01 12MAR96 mrk Initial Implementation
|
||||
*/
|
||||
#ifndef INCdbLockh
|
||||
#define INCdbLockh
|
||||
void dbScanLock(struct dbCommon *precord);
|
||||
void dbScanUnlock(struct dbCommon *precord);
|
||||
unsigned long dbLockGetLockId(struct dbCommon *precord);
|
||||
|
||||
void dbLockInitRecords(dbBase *pdbbase);
|
||||
void dbLockSetMerge(struct dbCommon *pfirst,struct dbCommon *psecond);
|
||||
void dbLockSetSplit(struct dbCommon *psource);
|
||||
/*The following are for code that modifies lock sets*/
|
||||
void dbLockSetGblLock(void);
|
||||
void dbLockSetGblUnlock(void);
|
||||
void dbLockSetRecordLock(struct dbCommon *precord);
|
||||
|
||||
long dblsr(char *recordname,int level);/*Lock Set Report */
|
||||
/* If recordname NULL then all records*/
|
||||
/* level = (0,1,2) (lock set state, + recordname, +DB links) */
|
||||
|
||||
#endif /*INCdbLockh*/
|
||||
351
src/db/dbScan.c
351
src/db/dbScan.c
@@ -1,5 +1,4 @@
|
||||
/* dbScan.c */
|
||||
/* base/src/db $Id$ */
|
||||
/* tasks and subroutines to scan the database */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
@@ -40,6 +39,7 @@
|
||||
* .09 02-03-94 mrk If scanAdd fails set precord->scan=SCAN_PASSIVE
|
||||
* .10 02-22-94 mrk Make init work if 1st record has 28 char name
|
||||
* .11 05-04-94 mrk Call taskwdRemove only if spawing again
|
||||
* .12 05-02-96 mrk Allow multiple priority event scan
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
@@ -63,6 +63,7 @@
|
||||
#include <callback.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <devSup.h>
|
||||
#include <recGbl.h>
|
||||
#include <task_params.h>
|
||||
@@ -72,66 +73,65 @@
|
||||
extern struct dbBase *pdbbase;
|
||||
|
||||
/* SCAN ONCE */
|
||||
#define ONCE_QUEUE_SIZE 256
|
||||
int onceQueueSize = 1000;
|
||||
static SEM_ID onceSem;
|
||||
static RING_ID onceQ;
|
||||
static int onceTaskId;
|
||||
|
||||
/*all other scan types */
|
||||
struct scan_list{
|
||||
typedef struct scan_list{
|
||||
FAST_LOCK lock;
|
||||
ELLLIST list;
|
||||
short modified;/*has list been modified?*/
|
||||
long ticks; /*ticks per period for periodic*/
|
||||
};
|
||||
}scan_list;
|
||||
/*scan_elements are allocated and the address stored in dbCommon.spvt*/
|
||||
struct scan_element{
|
||||
typedef struct scan_element{
|
||||
ELLNODE node;
|
||||
struct scan_list *pscan_list;
|
||||
scan_list *pscan_list;
|
||||
struct dbCommon *precord;
|
||||
};
|
||||
}scan_element;
|
||||
|
||||
int volatile scanRestart=FALSE;
|
||||
|
||||
/* PERIODIC SCANNER */
|
||||
static int nPeriodic=0;
|
||||
static struct scan_list **papPeriodic; /* pointer to array of pointers*/
|
||||
static int *periodicTaskId; /*array of integers after allocation*/
|
||||
static char *priorityName[NUM_CALLBACK_PRIORITIES] = {
|
||||
"Low","Medium","High"};
|
||||
|
||||
/* EVENT */
|
||||
#define MAX_EVENTS 256
|
||||
#define EVENT_QUEUE_SIZE 1000
|
||||
static struct scan_list *papEvent[MAX_EVENTS];/*array of pointers*/
|
||||
static SEM_ID eventSem;
|
||||
static RING_ID eventQ;
|
||||
static int eventTaskId;
|
||||
typedef struct event_scan_list {
|
||||
CALLBACK callback;
|
||||
scan_list scan_list;
|
||||
}event_scan_list;
|
||||
static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES][MAX_EVENTS];
|
||||
|
||||
/* IO_EVENT*/
|
||||
struct io_scan_list {
|
||||
typedef struct io_scan_list {
|
||||
CALLBACK callback;
|
||||
struct scan_list scan_list;
|
||||
scan_list scan_list;
|
||||
struct io_scan_list *next;
|
||||
};
|
||||
}io_scan_list;
|
||||
static io_scan_list *iosl_head[NUM_CALLBACK_PRIORITIES]={NULL,NULL,NULL};
|
||||
|
||||
static struct io_scan_list *iosl_head[NUM_CALLBACK_PRIORITIES]={NULL,NULL,NULL};
|
||||
/* PERIODIC SCANNER */
|
||||
static int nPeriodic=0;
|
||||
static scan_list **papPeriodic; /* pointer to array of pointers*/
|
||||
static int *periodicTaskId; /*array of integers after allocation*/
|
||||
|
||||
/* Private routines */
|
||||
static void onceTask(void);
|
||||
static void initOnce(void);
|
||||
static void periodicTask(struct scan_list *psl);
|
||||
static void periodicTask(scan_list *psl);
|
||||
static void initPeriodic(void);
|
||||
static void spawnPeriodic(int ind);
|
||||
static void wdPeriodic(long ind);
|
||||
static void eventTask(void);
|
||||
static void initEvent(void);
|
||||
static void spawnEvent(void);
|
||||
static void wdEvent(void);
|
||||
static void ioeventCallback(struct io_scan_list *piosl);
|
||||
static void printList(struct scan_list *psl,char *message);
|
||||
static void scanList(struct scan_list *psl);
|
||||
static void eventCallback(event_scan_list *pevent_scan_list);
|
||||
static void ioeventCallback(io_scan_list *piosl);
|
||||
static void printList(scan_list *psl,char *message);
|
||||
static void scanList(scan_list *psl);
|
||||
static void buildScanLists(void);
|
||||
static void addToList(struct dbCommon *precord,struct scan_list *psl);
|
||||
static void deleteFromList(struct dbCommon *precord,struct scan_list *psl);
|
||||
static void addToList(struct dbCommon *precord,scan_list *psl);
|
||||
static void deleteFromList(struct dbCommon *precord,scan_list *psl);
|
||||
|
||||
long scanInit()
|
||||
{
|
||||
@@ -142,38 +142,13 @@ long scanInit()
|
||||
initEvent();
|
||||
buildScanLists();
|
||||
for (i=0;i<nPeriodic; i++) spawnPeriodic(i);
|
||||
spawnEvent();
|
||||
return(0);
|
||||
}
|
||||
|
||||
void post_event(int event)
|
||||
{
|
||||
unsigned char evnt;
|
||||
static int newOverflow=TRUE;
|
||||
|
||||
if (!interruptAccept) return; /* not awake yet */
|
||||
if(event<0 || event>=MAX_EVENTS) {
|
||||
errMessage(-1,"illegal event passed to post_event");
|
||||
return;
|
||||
}
|
||||
evnt = (unsigned)event;
|
||||
/*multiple writers can exist. Thus if evnt is ever changed to use*/
|
||||
/*something bigger than a character interrupts will have to be blocked*/
|
||||
if(rngBufPut(eventQ,(void *)&evnt,sizeof(unsigned char))
|
||||
!=sizeof(unsigned char)) {
|
||||
if(newOverflow) errMessage(0,"rngBufPut overflow in post_event");
|
||||
newOverflow = FALSE;
|
||||
} else {
|
||||
newOverflow = TRUE;
|
||||
}
|
||||
semGive(eventSem);
|
||||
}
|
||||
|
||||
|
||||
void scanAdd(struct dbCommon *precord)
|
||||
{
|
||||
short scan;
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
|
||||
/* get the list on which this record belongs */
|
||||
scan = precord->scan;
|
||||
@@ -182,7 +157,9 @@ void scanAdd(struct dbCommon *precord)
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanAdd detected illegal SCAN value");
|
||||
}else if(scan==SCAN_EVENT) {
|
||||
unsigned char evnt;
|
||||
unsigned char evnt;
|
||||
int priority;
|
||||
event_scan_list *pevent_scan_list;
|
||||
|
||||
if(precord->evnt<0 || precord->evnt>=MAX_EVENTS) {
|
||||
recGblRecordError(S_db_badField,(void *)precord,
|
||||
@@ -191,16 +168,25 @@ void scanAdd(struct dbCommon *precord)
|
||||
return;
|
||||
}
|
||||
evnt = (signed)precord->evnt;
|
||||
psl = papEvent[evnt];
|
||||
if(psl==NULL) {
|
||||
psl = dbCalloc(1,sizeof(struct scan_list));
|
||||
papEvent[precord->evnt] = psl;
|
||||
FASTLOCKINIT(&psl->lock);
|
||||
ellInit(&psl->list);
|
||||
priority = precord->prio;
|
||||
if(priority<0 || priority>=NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanAdd: illegal prio field");
|
||||
precord->scan = SCAN_PASSIVE;
|
||||
return;
|
||||
}
|
||||
pevent_scan_list = pevent_list[priority][evnt];
|
||||
if(!pevent_scan_list ) {
|
||||
pevent_scan_list = dbCalloc(1,sizeof(event_scan_list));
|
||||
pevent_list[priority][evnt] = pevent_scan_list;
|
||||
pevent_scan_list->callback.callback = eventCallback;
|
||||
pevent_scan_list->callback.priority = priority;
|
||||
ellInit(&pevent_scan_list->scan_list.list);
|
||||
}
|
||||
psl = &pevent_scan_list->scan_list;
|
||||
addToList(precord,psl);
|
||||
} else if(scan==SCAN_IO_EVENT) {
|
||||
struct io_scan_list *piosl=NULL;
|
||||
io_scan_list *piosl=NULL;
|
||||
int priority;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
|
||||
@@ -249,7 +235,7 @@ void scanAdd(struct dbCommon *precord)
|
||||
void scanDelete(struct dbCommon *precord)
|
||||
{
|
||||
short scan;
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
|
||||
/* get the list on which this record belongs */
|
||||
scan = precord->scan;
|
||||
@@ -258,22 +244,33 @@ void scanDelete(struct dbCommon *precord)
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanDelete detected illegal SCAN value");
|
||||
}else if(scan==SCAN_EVENT) {
|
||||
unsigned char evnt;
|
||||
unsigned char evnt;
|
||||
int priority;
|
||||
event_scan_list *pevent_scan_list;
|
||||
|
||||
if(precord->evnt<0 || precord->evnt>=MAX_EVENTS) {
|
||||
recGblRecordError(S_db_badField,(void *)precord,
|
||||
"scanDelete detected illegal EVNT value");
|
||||
"scanAdd detected illegal EVNT value");
|
||||
precord->scan = SCAN_PASSIVE;
|
||||
return;
|
||||
}
|
||||
evnt = (signed)precord->evnt;
|
||||
psl = papEvent[evnt];
|
||||
if(psl==NULL)
|
||||
priority = precord->prio;
|
||||
if(priority<0 || priority>=NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanAdd: illegal prio field");
|
||||
precord->scan = SCAN_PASSIVE;
|
||||
return;
|
||||
}
|
||||
pevent_scan_list = pevent_list[priority][evnt];
|
||||
if(pevent_scan_list) psl = &pevent_scan_list->scan_list;
|
||||
if(!pevent_scan_list || !psl)
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanDelete for bad evnt");
|
||||
else
|
||||
else
|
||||
deleteFromList(precord,psl);
|
||||
} else if(scan==SCAN_IO_EVENT) {
|
||||
struct io_scan_list *piosl=NULL;
|
||||
io_scan_list *piosl=NULL;
|
||||
int priority;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
|
||||
@@ -314,7 +311,7 @@ void scanDelete(struct dbCommon *precord)
|
||||
|
||||
int scanppl() /*print periodic list*/
|
||||
{
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
char message[80];
|
||||
double period;
|
||||
int i;
|
||||
@@ -324,7 +321,7 @@ int scanppl() /*print periodic list*/
|
||||
if(psl==NULL) continue;
|
||||
period = psl->ticks;
|
||||
period /= vxTicksPerSecond;
|
||||
sprintf(message,"Scan Period= %f seconds\n",period);
|
||||
sprintf(message,"Scan Period= %f seconds ",period);
|
||||
printList(psl,message);
|
||||
}
|
||||
return(0);
|
||||
@@ -332,22 +329,25 @@ int scanppl() /*print periodic list*/
|
||||
|
||||
int scanpel() /*print event list */
|
||||
{
|
||||
struct scan_list *psl;
|
||||
char message[80];
|
||||
int i;
|
||||
char message[80];
|
||||
int priority,evnt;
|
||||
event_scan_list *pevent_scan_list;
|
||||
|
||||
for (i=0; i<MAX_EVENTS; i++) {
|
||||
psl = papEvent[i];
|
||||
if(psl==NULL) continue;
|
||||
sprintf(message,"Event %d\n",i);
|
||||
printList(psl,message);
|
||||
for(evnt=0; evnt<MAX_EVENTS; evnt++) {
|
||||
for(priority=0; priority<NUM_CALLBACK_PRIORITIES; priority++) {
|
||||
pevent_scan_list = pevent_list[priority][evnt];
|
||||
if(!pevent_scan_list) continue;
|
||||
if(ellCount(&pevent_scan_list->scan_list) ==0) continue;
|
||||
sprintf(message,"Event %d Priority %s",evnt,priorityName[priority]);
|
||||
printList(&pevent_scan_list->scan_list,message);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int scanpiol() /* print io_event list */
|
||||
{
|
||||
struct io_scan_list *piosl;
|
||||
io_scan_list *piosl;
|
||||
int priority;
|
||||
char message[80];
|
||||
|
||||
@@ -363,14 +363,50 @@ int scanpiol() /* print io_event list */
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void eventCallback(event_scan_list *pevent_scan_list)
|
||||
{
|
||||
scanList(&pevent_scan_list->scan_list);
|
||||
}
|
||||
|
||||
static void initEvent(void)
|
||||
{
|
||||
int evnt,priority;
|
||||
|
||||
for(priority=0; priority<NUM_CALLBACK_PRIORITIES; priority++) {
|
||||
for(evnt=0; evnt<MAX_EVENTS; evnt++) {
|
||||
pevent_list[priority][evnt] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void post_event(int event)
|
||||
{
|
||||
unsigned char evnt;
|
||||
int priority;
|
||||
event_scan_list *pevent_scan_list;
|
||||
|
||||
if (!interruptAccept) return; /* not awake yet */
|
||||
if(event<0 || event>=MAX_EVENTS) {
|
||||
errMessage(-1,"illegal event passed to post_event");
|
||||
return;
|
||||
}
|
||||
evnt = (unsigned)event;
|
||||
for(priority=0; priority<NUM_CALLBACK_PRIORITIES; priority++) {
|
||||
pevent_scan_list = pevent_list[priority][evnt];
|
||||
if(!pevent_scan_list) continue;
|
||||
if(ellCount(&pevent_scan_list->scan_list) >0)
|
||||
callbackRequest((void *)pevent_scan_list);
|
||||
}
|
||||
}
|
||||
|
||||
void scanIoInit(IOSCANPVT *ppioscanpvt)
|
||||
{
|
||||
struct io_scan_list *piosl;
|
||||
io_scan_list *piosl;
|
||||
int priority;
|
||||
|
||||
/* allocate an array of io_scan_lists. One for each priority */
|
||||
/* IOSCANPVT will hold the address of this array of structures */
|
||||
*ppioscanpvt=dbCalloc(NUM_CALLBACK_PRIORITIES,sizeof(struct io_scan_list));
|
||||
*ppioscanpvt=dbCalloc(NUM_CALLBACK_PRIORITIES,sizeof(io_scan_list));
|
||||
for(priority=0, piosl=*ppioscanpvt;
|
||||
priority<NUM_CALLBACK_PRIORITIES; priority++, piosl++){
|
||||
piosl->callback.callback = ioeventCallback;
|
||||
@@ -386,7 +422,7 @@ void scanIoInit(IOSCANPVT *ppioscanpvt)
|
||||
|
||||
void scanIoRequest(IOSCANPVT pioscanpvt)
|
||||
{
|
||||
struct io_scan_list *piosl;
|
||||
io_scan_list *piosl;
|
||||
int priority;
|
||||
|
||||
if(!interruptAccept) return;
|
||||
@@ -426,9 +462,15 @@ static void onceTask(void)
|
||||
}
|
||||
}
|
||||
|
||||
int scanOnceSetQueueSize(int size)
|
||||
{
|
||||
onceQueueSize = size;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void initOnce(void)
|
||||
{
|
||||
if((onceQ = rngCreate(sizeof(void *) * ONCE_QUEUE_SIZE))==NULL){
|
||||
if((onceQ = rngCreate(sizeof(void *) * onceQueueSize))==NULL){
|
||||
errMessage(0,"dbScan: initOnce failed");
|
||||
exit(1);
|
||||
}
|
||||
@@ -440,7 +482,7 @@ static void initOnce(void)
|
||||
taskwdInsert(onceTaskId,NULL,0L);
|
||||
}
|
||||
|
||||
static void periodicTask(struct scan_list *psl)
|
||||
static void periodicTask(scan_list *psl)
|
||||
{
|
||||
|
||||
unsigned long start_time,end_time;
|
||||
@@ -453,7 +495,7 @@ static void periodicTask(struct scan_list *psl)
|
||||
delay = psl->ticks - (end_time - start_time);
|
||||
if(delay<=0) delay=1;
|
||||
taskDelay(delay);
|
||||
start_time = end_time + delay;
|
||||
start_time = tickGet();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,7 +503,7 @@ static void periodicTask(struct scan_list *psl)
|
||||
static void initPeriodic()
|
||||
{
|
||||
dbMenu *pmenu;
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
float temp;
|
||||
int i;
|
||||
|
||||
@@ -471,10 +513,10 @@ static void initPeriodic()
|
||||
return;
|
||||
}
|
||||
nPeriodic = pmenu->nChoice - SCAN_1ST_PERIODIC;
|
||||
papPeriodic = dbCalloc(nPeriodic,sizeof(struct scan_list*));
|
||||
papPeriodic = dbCalloc(nPeriodic,sizeof(scan_list*));
|
||||
periodicTaskId = dbCalloc(nPeriodic,sizeof(int));
|
||||
for(i=0; i<nPeriodic; i++) {
|
||||
psl = dbCalloc(1,sizeof(struct scan_list));
|
||||
psl = dbCalloc(1,sizeof(scan_list));
|
||||
papPeriodic[i] = psl;
|
||||
FASTLOCKINIT(&psl->lock);
|
||||
ellInit(&psl->list);
|
||||
@@ -485,10 +527,12 @@ static void initPeriodic()
|
||||
|
||||
static void spawnPeriodic(int ind)
|
||||
{
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
char taskName[20];
|
||||
|
||||
psl = papPeriodic[ind];
|
||||
periodicTaskId[ind] = taskSpawn(PERIODSCAN_NAME,PERIODSCAN_PRI-ind,
|
||||
sprintf(taskName,"scan%d",psl->ticks);
|
||||
periodicTaskId[ind] = taskSpawn(taskName,PERIODSCAN_PRI-ind,
|
||||
PERIODSCAN_OPT,PERIODSCAN_STACK,
|
||||
(FUNCPTR )periodicTask,(int)psl,
|
||||
0,0,0,0,0,0,0,0,0);
|
||||
@@ -497,7 +541,7 @@ static void spawnPeriodic(int ind)
|
||||
|
||||
static void wdPeriodic(long ind)
|
||||
{
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
|
||||
if(!scanRestart)return;
|
||||
psl = papPeriodic[ind];
|
||||
@@ -507,83 +551,20 @@ static void wdPeriodic(long ind)
|
||||
spawnPeriodic(ind);
|
||||
}
|
||||
|
||||
static void eventTask(void)
|
||||
static void ioeventCallback(io_scan_list *piosl)
|
||||
{
|
||||
unsigned char event;
|
||||
struct scan_list *psl;
|
||||
|
||||
while(TRUE) {
|
||||
if(semTake(eventSem,WAIT_FOREVER)!=OK)
|
||||
errMessage(0,"semTake returned error in eventTask");
|
||||
while (rngNBytes(eventQ)>=sizeof(unsigned char)){
|
||||
if(rngBufGet(eventQ,(void *)&event,sizeof(unsigned char))!=sizeof(unsigned char))
|
||||
errMessage(0,"rngBufGet returned error in eventTask");
|
||||
if(event>MAX_EVENTS-1) {
|
||||
errMessage(-1,"eventTask received an illegal event");
|
||||
continue;
|
||||
}
|
||||
if(papEvent[event]==NULL) continue;
|
||||
psl = papEvent[event];
|
||||
if(psl) scanList(psl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void initEvent(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAX_EVENTS; i++) papEvent[i] = 0;
|
||||
eventQ = rngCreate(sizeof(unsigned char) * EVENT_QUEUE_SIZE);
|
||||
if(eventQ==NULL) {
|
||||
errMessage(0,"initEvent failed");
|
||||
exit(1);
|
||||
}
|
||||
if((eventSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL)
|
||||
errMessage(0,"semBcreate failed in initEvent");
|
||||
}
|
||||
|
||||
static void spawnEvent(void)
|
||||
{
|
||||
|
||||
eventTaskId = taskSpawn(EVENTSCAN_NAME,EVENTSCAN_PRI,EVENTSCAN_OPT,
|
||||
EVENTSCAN_STACK,(FUNCPTR)eventTask,
|
||||
0,0,0,0,0,0,0,0,0,0);
|
||||
taskwdInsert(eventTaskId,wdEvent,0L);
|
||||
}
|
||||
|
||||
static void wdEvent(void)
|
||||
{
|
||||
int i;
|
||||
struct scan_list *psl;
|
||||
|
||||
if(!scanRestart) return;
|
||||
taskwdRemove(eventTaskId);
|
||||
if(semFlush(eventSem)!=OK)
|
||||
errMessage(0,"semFlush failed while restarting eventTask");
|
||||
rngFlush(eventQ);
|
||||
for (i=0; i<MAX_EVENTS; i++) {
|
||||
psl = papEvent[i];
|
||||
if(psl==NULL) continue;
|
||||
FASTUNLOCK(&psl->lock);
|
||||
}
|
||||
spawnEvent();
|
||||
}
|
||||
|
||||
static void ioeventCallback(struct io_scan_list *piosl)
|
||||
{
|
||||
struct scan_list *psl=&piosl->scan_list;
|
||||
scan_list *psl=&piosl->scan_list;
|
||||
|
||||
scanList(psl);
|
||||
}
|
||||
|
||||
|
||||
static void printList(struct scan_list *psl,char *message)
|
||||
static void printList(scan_list *psl,char *message)
|
||||
{
|
||||
struct scan_element *pse;
|
||||
scan_element *pse;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
pse = (struct scan_element *)ellFirst(&psl->list);
|
||||
pse = (scan_element *)ellFirst(&psl->list);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
if(pse==NULL) return;
|
||||
printf("%s\n",message);
|
||||
@@ -595,23 +576,23 @@ static void printList(struct scan_list *psl,char *message)
|
||||
printf("Returning because list changed while processing.");
|
||||
return;
|
||||
}
|
||||
pse = (struct scan_element *)ellNext((void *)pse);
|
||||
pse = (scan_element *)ellNext((void *)pse);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void scanList(struct scan_list *psl)
|
||||
static void scanList(scan_list *psl)
|
||||
{
|
||||
/*In reading this code remember that the call to dbProcess can result*/
|
||||
/*in the SCAN field being changed in an arbitrary number of records */
|
||||
|
||||
struct scan_element *pse,*prev,*next;
|
||||
scan_element *pse,*prev,*next;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
psl->modified = FALSE;
|
||||
pse = (struct scan_element *)ellFirst(&psl->list);
|
||||
pse = (scan_element *)ellFirst(&psl->list);
|
||||
prev = NULL;
|
||||
next = (struct scan_element *)ellNext((void *)pse);
|
||||
next = (scan_element *)ellNext((void *)pse);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
while(pse!=NULL) {
|
||||
struct dbCommon *precord = pse->precord;
|
||||
@@ -622,27 +603,27 @@ static void scanList(struct scan_list *psl)
|
||||
FASTLOCK(&psl->lock);
|
||||
if(!psl->modified) {
|
||||
prev = pse;
|
||||
pse = (struct scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
|
||||
pse = (scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (scan_element *)ellNext((void *)pse);
|
||||
} else if (pse->pscan_list==psl) {
|
||||
/*This scan element is still in same scan list*/
|
||||
prev = pse;
|
||||
pse = (struct scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
|
||||
pse = (scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (scan_element *)ellNext((void *)pse);
|
||||
psl->modified = FALSE;
|
||||
} else if (prev!=NULL && prev->pscan_list==psl) {
|
||||
/*Previous scan element is still in same scan list*/
|
||||
pse = (struct scan_element *)ellNext((void *)prev);
|
||||
pse = (scan_element *)ellNext((void *)prev);
|
||||
if(pse!=NULL) {
|
||||
prev = (struct scan_element *)ellPrevious((void *)pse);
|
||||
next = (struct scan_element *)ellNext((void *)pse);
|
||||
prev = (scan_element *)ellPrevious((void *)pse);
|
||||
next = (scan_element *)ellNext((void *)pse);
|
||||
}
|
||||
psl->modified = FALSE;
|
||||
} else if (next!=NULL && next->pscan_list==psl) {
|
||||
/*Next scan element is still in same scan list*/
|
||||
pse = next;
|
||||
prev = (struct scan_element *)ellPrevious((void *)pse);
|
||||
next = (struct scan_element *)ellNext((void *)pse);
|
||||
prev = (scan_element *)ellPrevious((void *)pse);
|
||||
next = (scan_element *)ellNext((void *)pse);
|
||||
psl->modified = FALSE;
|
||||
} else {
|
||||
/*Too many changes. Just wait till next period*/
|
||||
@@ -672,26 +653,26 @@ static void buildScanLists(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void addToList(struct dbCommon *precord,struct scan_list *psl)
|
||||
static void addToList(struct dbCommon *precord,scan_list *psl)
|
||||
{
|
||||
struct scan_element *pse,*ptemp;
|
||||
scan_element *pse,*ptemp;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
pse = (struct scan_element *)(precord->spvt);
|
||||
pse = (scan_element *)(precord->spvt);
|
||||
if(pse==NULL) {
|
||||
pse = dbCalloc(1,sizeof(struct scan_element));
|
||||
pse = dbCalloc(1,sizeof(scan_element));
|
||||
precord->spvt = (void *)pse;
|
||||
pse->precord = precord;
|
||||
}
|
||||
pse ->pscan_list = psl;
|
||||
ptemp = (struct scan_element *)ellFirst(&psl->list);
|
||||
ptemp = (scan_element *)ellFirst(&psl->list);
|
||||
while(ptemp!=NULL) {
|
||||
if(ptemp->precord->phas>precord->phas) {
|
||||
ellInsert(&psl->list,
|
||||
ellPrevious((void *)ptemp),(void *)pse);
|
||||
break;
|
||||
}
|
||||
ptemp = (struct scan_element *)ellNext((void *)ptemp);
|
||||
ptemp = (scan_element *)ellNext((void *)ptemp);
|
||||
}
|
||||
if(ptemp==NULL) ellAdd(&psl->list,(void *)pse);
|
||||
psl->modified = TRUE;
|
||||
@@ -699,16 +680,16 @@ static void addToList(struct dbCommon *precord,struct scan_list *psl)
|
||||
return;
|
||||
}
|
||||
|
||||
static void deleteFromList(struct dbCommon *precord,struct scan_list *psl)
|
||||
static void deleteFromList(struct dbCommon *precord,scan_list *psl)
|
||||
{
|
||||
struct scan_element *pse;
|
||||
scan_element *pse;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
if(precord->spvt==NULL) {
|
||||
FASTUNLOCK(&psl->lock);
|
||||
return;
|
||||
}
|
||||
pse = (struct scan_element *)(precord->spvt);
|
||||
pse = (scan_element *)(precord->spvt);
|
||||
if(pse==NULL || pse->pscan_list!=psl) {
|
||||
FASTUNLOCK(&psl->lock);
|
||||
errMessage(-1,"deleteFromList failed");
|
||||
|
||||
71
src/db/dbScan.h
Normal file
71
src/db/dbScan.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* $Id$
|
||||
*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 07-17-91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 mm-dd-yy mrk Initial version
|
||||
*/
|
||||
|
||||
#ifndef INCdbScanh
|
||||
#define INCdbScanh 1
|
||||
#include <ellLib.h>
|
||||
#include <dbAccess.h>
|
||||
#include <callback.h>
|
||||
/* Note that these must match the first three definitions in choiceGbl.ascii*/
|
||||
#define SCAN_PASSIVE 0
|
||||
#define SCAN_EVENT 1
|
||||
#define SCAN_IO_EVENT 2
|
||||
#define SCAN_1ST_PERIODIC 3
|
||||
|
||||
/*definitions for SCAN_IO_EVENT */
|
||||
typedef void * IOSCANPVT;
|
||||
extern volatile int interruptAccept;
|
||||
|
||||
#ifdef __STDC__
|
||||
long scanInit(void);
|
||||
void post_event(int event);
|
||||
void scanAdd(struct dbCommon *);
|
||||
void scanDelete(struct dbCommon *);
|
||||
void scanOnce(void *precord);
|
||||
int scanOnceSetQueueSize(int size);
|
||||
int scanppl(void); /*print periodic lists*/
|
||||
int scanpel(void); /*print event lists*/
|
||||
int scanpiol(void); /*print io_event list*/
|
||||
void scanIoInit(IOSCANPVT *);
|
||||
void scanIoRequest(IOSCANPVT);
|
||||
|
||||
#else
|
||||
long scanInit();
|
||||
void post_event();
|
||||
void scanAdd();
|
||||
void scanDelete();
|
||||
void scanppl();
|
||||
void scanpel();
|
||||
void scanpiol();
|
||||
void scanIoInit();
|
||||
void scanIoRequest();
|
||||
#endif /*__STDC__*/
|
||||
#endif
|
||||
240
src/db/dbTest.c
240
src/db/dbTest.c
@@ -57,8 +57,6 @@ long dbtgf(char *pname); /*test get field*/
|
||||
long dbtpf(char *pname,char *pvalue); /*test put field*/
|
||||
long dbior(char *pdrvName,int type); /*I/O report */
|
||||
int dbhcr(void); /*Hardware Configuration Report*/
|
||||
long dblls(int lockset); /*list lock sets*/
|
||||
int dbllsdblinks(int lset); /*List dblinks for each record in lock set*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
@@ -72,6 +70,7 @@ int dbllsdblinks(int lset); /*List dblinks for each record in lock set*/
|
||||
#include <dbAccess.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbLock.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <drvSup.h>
|
||||
@@ -110,8 +109,8 @@ static void dbpr_init_msg(TAB_BUFFER *pMsgBuff,int tab_size);
|
||||
static void dbpr_insert_msg(TAB_BUFFER *pMsgBuff,int len,int tab_size);
|
||||
static void dbpr_msg_flush(TAB_BUFFER *pMsgBuff,int tab_size);
|
||||
static void dbprReportLink(
|
||||
TAB_BUFFER *pMsgBuff,char *pfield_name,struct link *plink,
|
||||
short field_type,int tab_size);
|
||||
TAB_BUFFER *pMsgBuff,char *precord_name, char *pfield_name,
|
||||
struct link *plink, short field_type,int tab_size);
|
||||
static void dbprReportMenu(
|
||||
TAB_BUFFER *pMsgBuff,struct dbCommon *precord,dbFldDes *pdbFldDes,
|
||||
unsigned short choice_value,int tab_size);
|
||||
@@ -190,17 +189,20 @@ long dbnr(int verbose)
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
int nrecords;
|
||||
int total=0;
|
||||
|
||||
dbInitEntry(pdbbase,pdbentry);
|
||||
status = dbFirstRecdes(pdbentry);
|
||||
if(status) printf("No record description\n");
|
||||
while(!status) {
|
||||
nrecords = dbGetNRecords(pdbentry);
|
||||
total += nrecords;
|
||||
if(verbose || nrecords)
|
||||
printf("%.4d %s\n",nrecords,dbGetRecdesName(pdbentry));
|
||||
status = dbNextRecdes(pdbentry);
|
||||
}
|
||||
dbFinishEntry(pdbentry);
|
||||
printf("Total Records: %d\n",total);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -690,37 +692,6 @@ int dbhcr(void)
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dblls(int lockset)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
struct dbCommon *precord;
|
||||
|
||||
dbInitEntry(pdbbase,pdbentry);
|
||||
status = dbFirstRecdes(pdbentry);
|
||||
printf(" lset lcnt disv disa pact\n");
|
||||
while(!status) {
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while(!status) {
|
||||
precord = pdbentry->precnode->precord;
|
||||
if(lockset==0 || lockset==precord->lset) {
|
||||
printf("%5.5d %5.5d %5.5d %5.5d %5.5d %s\n",
|
||||
precord->lset,
|
||||
precord->lcnt,
|
||||
precord->disv,
|
||||
precord->disa,
|
||||
precord->pact,
|
||||
precord->name);
|
||||
}
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
status = dbNextRecdes(pdbentry);
|
||||
}
|
||||
dbFinishEntry(pdbentry);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static char *dbf[DBF_NTYPES]={
|
||||
"STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG",
|
||||
"FLOAT","DOUBLE","ENUM","MENU","DEVICE",
|
||||
@@ -1147,18 +1118,11 @@ static int dbpr_report(
|
||||
*(unsigned short *)pfield, tab_size);
|
||||
break;
|
||||
case DBF_INLINK:
|
||||
dbprReportLink(pMsgBuff, pfield_name,
|
||||
(struct link *) pfield, pdbFldDes->field_type, tab_size);
|
||||
break;
|
||||
case DBF_OUTLINK:
|
||||
dbprReportLink(pMsgBuff, pfield_name,
|
||||
(struct link *) pfield, pdbFldDes->field_type, tab_size);
|
||||
break;
|
||||
case DBF_FWDLINK:
|
||||
dbprReportLink(pMsgBuff, pfield_name,
|
||||
dbprReportLink(pMsgBuff, paddr->precord->name,pfield_name,
|
||||
(struct link *) pfield, pdbFldDes->field_type, tab_size);
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
sprintf(pmsg, "%s: dbpr: Unknown field_type", pfield_name);
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
@@ -1266,129 +1230,39 @@ static void dbpr_msg_flush(TAB_BUFFER *pMsgBuff,int tab_size)
|
||||
}
|
||||
|
||||
static void dbprReportLink(
|
||||
TAB_BUFFER *pMsgBuff,char *pfield_name,struct link *plink,
|
||||
short field_type,int tab_size)
|
||||
TAB_BUFFER *pMsgBuff,char *precordname,char *pfield_name,
|
||||
struct link *plink, short field_type,int tab_size)
|
||||
{
|
||||
char *pmsg = pMsgBuff->message;
|
||||
switch(plink->type) {
|
||||
case CONSTANT:
|
||||
sprintf(pmsg,"%4s: %s", pfield_name, plink->value.constantStr);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case PV_LINK:
|
||||
if(field_type != DBF_FWDLINK) {
|
||||
sprintf(pmsg,"%4s: PV_LINK pp=%1d ms=%1d %s",
|
||||
pfield_name,
|
||||
plink->value.pv_link.process_passive,
|
||||
plink->value.pv_link.maximize_sevr,
|
||||
plink->value.pv_link.pvname);
|
||||
} else {
|
||||
sprintf(pmsg,"%4s: PV_LINK %s",
|
||||
pfield_name,
|
||||
plink->value.pv_link.pvname);
|
||||
}
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case VME_IO:
|
||||
sprintf(pmsg,"%4s: VME card=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.vmeio.card,plink->value.vmeio.signal,
|
||||
plink->value.vmeio.parm);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case VXI_IO:
|
||||
if(plink->value.vxiio.flag==0)
|
||||
{
|
||||
sprintf(pmsg,"%4s: VXI frame=%2d slot=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.vxiio.frame,
|
||||
plink->value.vxiio.slot,
|
||||
plink->value.vxiio.signal,
|
||||
plink->value.vxiio.parm);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(pmsg,"%4s: VXI la=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.vxiio.la,
|
||||
plink->value.vxiio.signal,
|
||||
plink->value.vxiio.parm);
|
||||
}
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case CAMAC_IO:
|
||||
sprintf(pmsg,"%4s: CAMAC b=%2d c=%2d n=%2d a=%2d f=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.camacio.b,plink->value.camacio.c,
|
||||
plink->value.camacio.n,plink->value.camacio.a,
|
||||
plink->value.camacio.f,plink->value.camacio.parm);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case AB_IO:
|
||||
sprintf(pmsg,"%4s: ABIO link=%2d adaptor=%2d card=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.abio.link,plink->value.abio.adapter,
|
||||
plink->value.abio.card,plink->value.abio.signal,
|
||||
plink->value.abio.parm);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case GPIB_IO:
|
||||
sprintf(pmsg,"%4s: GPIB link=%2d addr=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.gpibio.link, plink->value.gpibio.addr,
|
||||
&plink->value.gpibio.parm[0]);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case BITBUS_IO:
|
||||
sprintf(pmsg,"%4s: BITBUS link=%2d node=%2d port=%2d signal=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.bitbusio.link,plink->value.bitbusio.node,
|
||||
plink->value.bitbusio.port,plink->value.bitbusio.signal,
|
||||
&plink->value.bitbusio.parm[0]);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case BBGPIB_IO:
|
||||
sprintf(pmsg,"%4s: BBGPIBIO link=%2d bbaddr=%2d gpibio=%2d parm=%s",
|
||||
pfield_name,
|
||||
plink->value.bbgpibio.link,plink->value.bbgpibio.bbaddr,
|
||||
plink->value.bbgpibio.gpibaddr,
|
||||
&plink->value.bbgpibio.parm[0]);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case INST_IO:
|
||||
sprintf(pmsg,"%4s: INSTIO parm=%s",
|
||||
pfield_name,
|
||||
&plink->value.instio.string[0]);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case DB_LINK:
|
||||
if(field_type != DBF_FWDLINK) {
|
||||
DBADDR *paddr = (DBADDR *)plink->value.db_link.pdbAddr;
|
||||
char *pmsg = pMsgBuff->message;
|
||||
DBENTRY dbEntry;
|
||||
DBENTRY *pdbEntry;
|
||||
long status;
|
||||
char *pvalue;
|
||||
|
||||
sprintf(pmsg,"%4s: DB_LINK pp=%1d ms=%1d %s",
|
||||
pfield_name,
|
||||
plink->value.db_link.process_passive,
|
||||
plink->value.db_link.maximize_sevr,
|
||||
paddr->precord->name);
|
||||
}else{
|
||||
sprintf(pmsg,"%4s: DB_LINK %.32s",
|
||||
pfield_name,
|
||||
((struct dbCommon *)(
|
||||
((DBADDR *)plink->value.db_link.pdbAddr)
|
||||
->precord))->name);
|
||||
pdbEntry = &dbEntry;
|
||||
dbInitEntry(pdbbase,pdbEntry);
|
||||
status = dbFindRecord(pdbEntry,precordname);
|
||||
if(!status) status = dbFindField(pdbEntry,pfield_name);
|
||||
if(status) {
|
||||
sprintf(pmsg,"%4s: dbGetString Failed", pfield_name);
|
||||
} else {
|
||||
int ind;
|
||||
|
||||
for(ind=0; ind<LINK_NTYPES; ind++) {
|
||||
if(pamaplinkType[ind].value == plink->type) break;
|
||||
}
|
||||
if(ind>=LINK_NTYPES) {
|
||||
sprintf(pmsg,"%4s: Illegal Link Type", pfield_name);
|
||||
} else {
|
||||
pvalue = dbGetString(pdbEntry);
|
||||
sprintf(pmsg,"%4s:%s %s",
|
||||
pfield_name,
|
||||
pamaplinkType[ind].strvalue,
|
||||
pvalue);
|
||||
}
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
case CA_LINK:
|
||||
sprintf(pmsg,"%4s: CA_LINK",pfield_name);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
default:
|
||||
sprintf(pmsg,"%4s: dbprReportLink: Illegal link.type",
|
||||
pfield_name);
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
break;
|
||||
}
|
||||
dbpr_msgOut(pMsgBuff,tab_size);
|
||||
dbFinishEntry(&dbEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1475,45 +1349,3 @@ char *record_name;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int dbllsdblinks(int lset)
|
||||
{
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbRecordNode *pdbRecordNode;
|
||||
dbCommon *precord;
|
||||
DBLINK *plink;
|
||||
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
if(precord->lset != lset) continue;
|
||||
printf("%s\n",precord->name);
|
||||
for(link=0; (link<pdbRecDes->no_links) ; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.db_link.pdbAddr);
|
||||
if(pdbFldDes->field_type==DBF_INLINK) {
|
||||
printf("\t INLINK");
|
||||
} else if(pdbFldDes->field_type==DBF_OUTLINK) {
|
||||
printf("\tOUTLINK");
|
||||
} else if(pdbFldDes->field_type==DBF_FWDLINK) {
|
||||
printf("\tFWDLINK");
|
||||
}
|
||||
printf(" %s %s",
|
||||
((plink->value.db_link.process_passive)?" PP":"NPP"),
|
||||
((plink->value.db_link.maximize_sevr)?" MS":"NMS"));
|
||||
printf(" %s\n",pdbAddr->precord->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -116,6 +116,9 @@
|
||||
#define oldDBR_PUT_ACKT oldDBR_CTRL_DOUBLE + 1
|
||||
#define oldDBR_PUT_ACKS oldDBR_PUT_ACKT + 1
|
||||
#define oldDBR_STSACK_STRING oldDBR_PUT_ACKS + 1
|
||||
|
||||
/*Following is defined in db_access.h*/
|
||||
extern unsigned short dbDBRnewToDBRold[DBR_ENUM+1];
|
||||
|
||||
|
||||
/* function declarations */
|
||||
@@ -572,8 +575,6 @@ void fill(pbuffer,size,fillchar)
|
||||
/*
|
||||
* DB_NAME_TO_ADDR
|
||||
*/
|
||||
static short mapNewToOld[]={0,4,4,1,2,5,6,2,6,3};
|
||||
|
||||
short db_name_to_addr(pname,paddr)
|
||||
char *pname;
|
||||
struct dbAddr *paddr;
|
||||
@@ -588,7 +589,7 @@ short db_name_to_addr(pname,paddr)
|
||||
recGblDbaddrError(S_db_badDbrtype,paddr,"db_name_to_addr error");
|
||||
return(-2);
|
||||
}
|
||||
paddr->dbr_field_type = mapNewToOld[ftype];
|
||||
paddr->dbr_field_type = dbDBRnewToDBRold[ftype];
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
|
||||
1185
src/db/db_access.h
Normal file
1185
src/db/db_access.h
Normal file
File diff suppressed because it is too large
Load Diff
49
src/db/db_addr.h
Normal file
49
src/db/db_addr.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* $Id$
|
||||
*
|
||||
* Author: Bob Dalesio
|
||||
* Date: 4-4-88
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
#ifndef INC_db_addrh
|
||||
#define INC_db_addrh
|
||||
/*
|
||||
*database access address structure
|
||||
*/
|
||||
struct db_addr{
|
||||
char *precord; /* record number of specified type */
|
||||
char *pfield; /* offset from the record origin */
|
||||
char *pad0; /* not used by old */
|
||||
void *asPvt; /*Access Security Private */
|
||||
short pad1; /*not used by old */
|
||||
short no_elements; /* number of elements in arrays of data */
|
||||
short new_field_type; /* field type for new database access*/
|
||||
short field_size; /* size of the field being accessed */
|
||||
/* from database for values of waveforms */
|
||||
short special; /* special processing */
|
||||
short field_type; /* field type as seen by database request*/
|
||||
/*DBR_STRING,...,DBR_ENUM,DBR_NOACCESS*/
|
||||
};
|
||||
#endif
|
||||
67
src/db/db_field_log.h
Normal file
67
src/db/db_field_log.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* $Id$
|
||||
* Author: Jeffrey O. Hill
|
||||
* Date: 4-1-89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
#ifndef INCLdb_field_logh
|
||||
#define INCLdb_field_logh
|
||||
|
||||
/*
|
||||
* Simple native types (anything which is not a string or an array for
|
||||
* now) logged by db_post_events() for reliable interprocess communication.
|
||||
* (for other types they get whatever happens to be there when the lower
|
||||
* priority task pending on the event queue wakes up). Strings would slow down
|
||||
* events for more reasonable size values. DB fields of native type string
|
||||
* will most likely change infrequently.
|
||||
*
|
||||
*/
|
||||
union native_value{
|
||||
short dbf_int;
|
||||
short dbf_short;
|
||||
float dbf_float;
|
||||
short dbf_enum;
|
||||
char dbf_char;
|
||||
long dbf_long;
|
||||
double dbf_double;
|
||||
#ifdef DB_EVENT_LOG_STRINGS
|
||||
char dbf_string[MAXSTRINGSIZE];
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* structure to log the state of a data base field at the time
|
||||
* an event is triggered.
|
||||
*/
|
||||
typedef struct{
|
||||
unsigned short stat; /* Alarm Status */
|
||||
unsigned short sevr; /* Alarm Severity */
|
||||
TS_STAMP time; /* time stamp */
|
||||
union native_value field; /* field value */
|
||||
}db_field_log;
|
||||
|
||||
#endif /*INCLdb_field_logh*/
|
||||
125
src/db/dbcar.c
Normal file
125
src/db/dbcar.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/* dbcar.c */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1991 Regents of the University of California,
|
||||
and the University of Chicago Board of Governors.
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_Combined file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Current Author: Marty Kraimer
|
||||
* Date: 10APR96
|
||||
*
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 10APR96 mrk list db to CA links
|
||||
****************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include "dbStaticLib.h"
|
||||
#include "link.h"
|
||||
/*definitions needed because of old vs new database access*/
|
||||
#undef DBR_SHORT
|
||||
#undef DBR_PUT_ACKT
|
||||
#undef DBR_PUT_ACKS
|
||||
#undef VALID_DB_REQ
|
||||
#undef INVALID_DB_REQ
|
||||
/*end of conflicting definitions*/
|
||||
#include "cadef.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbCa.h"
|
||||
extern struct dbBase *pdbbase;
|
||||
|
||||
long dbcar(char *precordname,int level)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
dbCommon *precord;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
DBLINK *plink;
|
||||
int ncalinks=0;
|
||||
int nconnected=0;
|
||||
int noReadAccess=0;
|
||||
int noWriteAccess=0;
|
||||
unsigned long nDisconnect=0;
|
||||
unsigned long nNoWrite=0;
|
||||
caLink *pca;
|
||||
int j;
|
||||
|
||||
|
||||
dbInitEntry(pdbbase,pdbentry);
|
||||
status = dbFirstRecdes(pdbentry);
|
||||
while(!status) {
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while(!status) {
|
||||
if(!precordname
|
||||
|| (strcmp(precordname,dbGetRecordName(pdbentry)) ==0)) {
|
||||
pdbRecDes = pdbentry->precdes;
|
||||
precord = (dbCommon *)pdbentry->precnode->precord;
|
||||
for(j=0; j<pdbRecDes->no_links; j++) {
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[j]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if (plink->type == CA_LINK) {
|
||||
ncalinks++;
|
||||
pca = (caLink *)plink->value.pv_link.pvt;
|
||||
if(pca && (ca_field_type(pca->chid) != TYPENOTCONN)) {
|
||||
nconnected++;
|
||||
nDisconnect += pca->nDisconnect;
|
||||
nNoWrite += pca->nNoWrite;
|
||||
if(!ca_read_access(pca->chid)) noReadAccess++;
|
||||
if(!ca_write_access(pca->chid)) noWriteAccess++;
|
||||
if(level>1) {
|
||||
printf(" connected");
|
||||
printf("%s",ca_host_name(pca->chid));
|
||||
if(!ca_read_access(pca->chid))
|
||||
printf(" no_read_access");
|
||||
if(!ca_write_access(pca->chid))
|
||||
printf(" no_write_access");
|
||||
printf(" %s.%s %s",
|
||||
precord->name,
|
||||
pdbFldDes->name,
|
||||
plink->value.pv_link.pvname);
|
||||
printf(" nDisconnect %lu nNoWrite %lu\n",
|
||||
pca->nDisconnect,pca->nNoWrite);
|
||||
}
|
||||
} else {
|
||||
if(level>0) {
|
||||
printf("not_connected %s.%s",
|
||||
precord->name,pdbFldDes->name);
|
||||
printf(" nDisconnect %lu nNoWrite %lu\n",
|
||||
pca->nDisconnect,pca->nNoWrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(precordname) goto done;
|
||||
}
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
status = dbNextRecdes(pdbentry);
|
||||
}
|
||||
done:
|
||||
printf("ncalinks %d",ncalinks);
|
||||
printf(" not connected %d",(ncalinks - nconnected));
|
||||
printf(" no_read_access %d",noReadAccess);
|
||||
printf(" no_write_access %d\n",noWriteAccess);
|
||||
printf(" nDisconnect %lu nNoWrite %lu\n",nDisconnect,nNoWrite);
|
||||
dbFinishEntry(pdbentry);
|
||||
return(0);
|
||||
}
|
||||
230
src/db/devLib.h
Normal file
230
src/db/devLib.h
Normal file
@@ -0,0 +1,230 @@
|
||||
/* devLib.h */
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
* Author: Jeff Hill
|
||||
* Date: 03-10-93
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 03-10-93 joh original
|
||||
* .02 03-18-93 joh added fundamental address type mapping
|
||||
* .03 03-23-93 joh changed input parameter to be a fund
|
||||
* address type in favor of the argument
|
||||
* that the BSP will be reconfigured
|
||||
* to use an EPICS standard address
|
||||
* mode
|
||||
* .04 05-06-93 joh added new parameter to devDisconnectInterrupt().
|
||||
* See comment below.
|
||||
* .05 05-28-93 joh Added an argument to devRegisterAddress()
|
||||
* .06 05-28-93 joh Added devAddressMap()
|
||||
* .07 06-14-93 joh Added devAllocAddress()
|
||||
*
|
||||
* Notes:
|
||||
* ------
|
||||
* .01 03-23-93 joh We will only have problems with mod .03
|
||||
* above if the CPU maintains the different
|
||||
* address modes in different address spaces
|
||||
* and we have a card or a user that insists
|
||||
* on not using the default address type
|
||||
* .02 06-14-93 joh needs devAllocInterruptVector() routine
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INCdevLibh
|
||||
#define INCdevLibh 1
|
||||
|
||||
#if defined(devLibGlobal) && !defined(INCvmeh)
|
||||
#include "vme.h"
|
||||
#endif
|
||||
|
||||
#include <dbDefs.h>
|
||||
|
||||
/*
|
||||
* epdevAddressType & EPICStovxWorksAddrType
|
||||
* devLib.c must change in unison
|
||||
*/
|
||||
typedef enum {
|
||||
atVMEA16,
|
||||
atVMEA24,
|
||||
atVMEA32,
|
||||
atLast /* atLast must be the last enum in this list */
|
||||
} epicsAddressType;
|
||||
|
||||
#ifdef devLibGlobal
|
||||
char *epicsAddressTypeName[]
|
||||
= {
|
||||
"VME A16",
|
||||
"VME A24",
|
||||
"VME A32"
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* we use a translation between an EPICS encoding
|
||||
* and a vxWorks encoding here
|
||||
* to reduce dependency of drivers on vxWorks
|
||||
*
|
||||
* we assume that the BSP are configured to use these
|
||||
* address modes by default
|
||||
*/
|
||||
#ifdef devLibGlobal
|
||||
int EPICStovxWorksAddrType[]
|
||||
= {
|
||||
VME_AM_SUP_SHORT_IO,
|
||||
VME_AM_STD_SUP_DATA,
|
||||
VME_AM_EXT_SUP_DATA
|
||||
};
|
||||
#endif
|
||||
|
||||
long devAddressMap(void); /* print an address map */
|
||||
|
||||
long devRegisterAddress(
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
void *baseAddress,
|
||||
unsigned long size, /* bytes */
|
||||
void **pLocalAddress);
|
||||
|
||||
long devUnregisterAddress(
|
||||
epicsAddressType addrType,
|
||||
void *baseAddress,
|
||||
const char *pOwnerName);
|
||||
|
||||
/*
|
||||
* allocate and register an unoccupied address block
|
||||
*/
|
||||
long devAllocAddress(
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
unsigned long size,
|
||||
unsigned alignment, /*n ls bits zero in addr*/
|
||||
void **pLocalAddress);
|
||||
|
||||
/*
|
||||
* some CPU`s will maintain these in independent spaces
|
||||
*/
|
||||
typedef enum {intCPU, intVME, intVXI} epicsInterruptType;
|
||||
long devConnectInterrupt(
|
||||
epicsInterruptType intType,
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(),
|
||||
void *parameter);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* The parameter pFunction should be set to the C function pointer that
|
||||
* was connected. It is used as a key to prevent a driver from accidentally
|
||||
* removing an interrupt handler that it didn't install
|
||||
*/
|
||||
long devDisconnectInterrupt(
|
||||
epicsInterruptType intType,
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)());
|
||||
|
||||
long devEnableInterruptLevel(
|
||||
epicsInterruptType intType,
|
||||
unsigned level);
|
||||
|
||||
long devDisableInterruptLevel(
|
||||
epicsInterruptType intType,
|
||||
unsigned level);
|
||||
|
||||
|
||||
/*
|
||||
* Routines to allocate and free memory in the A24 memory region.
|
||||
*
|
||||
*/
|
||||
void *devLibA24Malloc(size_t);
|
||||
void *devLibA24Calloc(size_t);
|
||||
void devLibA24Free(void *pBlock);
|
||||
|
||||
/*
|
||||
* Normalize a digital value and convert it to type TYPE
|
||||
*
|
||||
* Ex:
|
||||
* float f;
|
||||
* int d;
|
||||
* f = devNormalizeDigital(d,12)
|
||||
*
|
||||
*/
|
||||
#define devCreateMask(NBITS) ((1<<(NBITS))-1)
|
||||
#define devDigToNml(DIGITAL,NBITS) \
|
||||
(((double)(DIGITAL))/devCreateMask(NBITS))
|
||||
#define devNmlToDig(NORMAL,NBITS) \
|
||||
(((long)(NORMAL)) * devCreateMask(NBITS))
|
||||
|
||||
/*
|
||||
*
|
||||
* Alignment mask
|
||||
* (for use when testing to see if the proper number of least
|
||||
* significant bits are zero)
|
||||
*
|
||||
*/
|
||||
#define devCreateAlignmentMask(CTYPE)\
|
||||
(sizeof(CTYPE)>sizeof(double)?sizeof(double)-1:sizeof(CTYPE)-1)
|
||||
|
||||
/*
|
||||
* pointer aligned test
|
||||
* (returns true if the pointer is on the worst case alignemnt
|
||||
* boundary for its type)
|
||||
*/
|
||||
#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR)))
|
||||
|
||||
/*
|
||||
* error codes (and messages) associated with devLib.c
|
||||
*/
|
||||
#define S_dev_vectorInUse (M_devLib| 1) /*Interrupt vector in use*/
|
||||
#define S_dev_vxWorksVecInstlFail (M_devLib| 2) /*vxWorks interrupt vector install failed*/
|
||||
#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/
|
||||
#define S_dev_vectorNotInUse (M_devLib| 4) /*Interrupt vector not in use by caller*/
|
||||
#define S_dev_badA16 (M_devLib| 5) /*Invalid VME A16 address*/
|
||||
#define S_dev_badA24 (M_devLib| 6) /*Invalid VME A24 address*/
|
||||
#define S_dev_badA32 (M_devLib| 7) /*Invalid VME A32 address*/
|
||||
#define S_dev_uknAddrType (M_devLib| 8) /*Unrecognized address space type*/
|
||||
#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/
|
||||
#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/
|
||||
#define S_dev_vxWorksAddrMapFail (M_devLib| 11) /*vxWorks refused address map*/
|
||||
#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/
|
||||
#define S_dev_internal (M_devLib| 13) /*Internal failure*/
|
||||
#define S_dev_vxWorksIntEnFail (M_devLib| 14) /*vxWorks interrupt enable failure*/
|
||||
#define S_dev_vxWorksIntDissFail (M_devLib| 15) /*vxWorks interrupt disable failure*/
|
||||
#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/
|
||||
#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/
|
||||
#define S_dev_noDevice (M_devLib| 18) /*No device at specified address*/
|
||||
#define S_dev_wrongDevice (M_devLib| 19) /*Wrong device type found at specified address*/
|
||||
#define S_dev_badSignalNumber (M_devLib| 20) /*Signal number (offset) to large*/
|
||||
#define S_dev_badSignalCount (M_devLib| 21) /*Signal count to large*/
|
||||
#define S_dev_badRequest (M_devLib| 22) /*Device does not support requested operation*/
|
||||
#define S_dev_highValue (M_devLib| 23) /*Parameter to high*/
|
||||
#define S_dev_lowValue (M_devLib| 24) /*Parameter to low*/
|
||||
#define S_dev_multDevice (M_devLib| 25) /*Specified address is ambiguous (more than one device responds)*/
|
||||
#define S_dev_badSelfTest (M_devLib| 26) /*Device self test failed*/
|
||||
#define S_dev_badInit (M_devLib| 27) /*Device failed during initialization*/
|
||||
#define S_dev_hdwLimit (M_devLib| 28) /*Input exceeds Hardware Limit*/
|
||||
#define S_dev_deviceDoesNotFit (M_devLib| 29) /*Unable to locate address space for device*/
|
||||
#define S_dev_deviceTMO (M_devLib| 30) /*device timed out*/
|
||||
#endif /* devLib.h*/
|
||||
66
src/db/devSup.h
Normal file
66
src/db/devSup.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* devSup.h Device Support */
|
||||
/* share/epicsH $Id$ */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 6-1-90
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 10-04-91 jba Added error message
|
||||
* .02 05-18-92 rcz Changed macro "GET_DEVSUP(" to "GET_PDEVSUP(precDevSup,"
|
||||
* .03 05-18-92 rcz Structure devSup changed element name from dsetName to papDsetName
|
||||
* .04 05-18-92 rcz New database access
|
||||
*/
|
||||
|
||||
#ifndef INCdevSuph
|
||||
#define INCdevSuph 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef long (*DEVSUPFUN)(void*); /* ptr to device support function*/
|
||||
#else
|
||||
typedef long (*DEVSUPFUN)(); /* ptr to device support function*/
|
||||
#endif
|
||||
|
||||
struct dset { /* device support entry table */
|
||||
long number; /*number of support routines*/
|
||||
DEVSUPFUN report; /*print report*/
|
||||
DEVSUPFUN init; /*init support*/
|
||||
DEVSUPFUN init_record; /*init support for particular record*/
|
||||
DEVSUPFUN get_ioint_info; /* get io interrupt information*/
|
||||
/*other functions are record dependent*/
|
||||
};
|
||||
|
||||
#define S_dev_noDevSup (M_devSup| 1) /*SDR_DEVSUP: Device support missing*/
|
||||
#define S_dev_noDSET (M_devSup| 3) /*Missing device support entry table*/
|
||||
#define S_dev_missingSup (M_devSup| 5) /*Missing device support routine*/
|
||||
#define S_dev_badInpType (M_devSup| 7) /*Bad INP link type*/
|
||||
#define S_dev_badOutType (M_devSup| 9) /*Bad OUT link type*/
|
||||
#define S_dev_badInitRet (M_devSup|11) /*Bad init_rec return value */
|
||||
#define S_dev_badBus (M_devSup|13) /*Illegal bus type*/
|
||||
#define S_dev_badCard (M_devSup|15) /*Illegal or nonexistant module*/
|
||||
#define S_dev_badSignal (M_devSup|17) /*Illegal signal*/
|
||||
#define S_dev_NoInit (M_devSup|19) /*No init*/
|
||||
#define S_dev_Conflict (M_devSup|21) /*Multiple records accessing same signal*/
|
||||
|
||||
#endif
|
||||
52
src/db/drvSup.h
Normal file
52
src/db/drvSup.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* drvSup.h Driver Support */
|
||||
/* share/epicsH $Id$ */
|
||||
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 6-1-90
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 05-21-92 rcz changed drvetName to papDrvName
|
||||
* .02 05-18-92 rcz New database access (removed extern)
|
||||
*/
|
||||
|
||||
#ifndef INCdrvSuph
|
||||
#define INCdrvSuph 1
|
||||
|
||||
typedef long (*DRVSUPFUN) (); /* ptr to driver support function*/
|
||||
|
||||
struct drvet { /* driver entry table */
|
||||
long number; /*number of support routines*/
|
||||
DRVSUPFUN report; /*print report*/
|
||||
DRVSUPFUN init; /*init support*/
|
||||
DRVSUPFUN reboot; /*reboot support*/
|
||||
/*other functions are device dependent*/
|
||||
};
|
||||
#define DRVETNUMBER ( (sizeof(struct drvet) -sizeof(long))/sizeof(DRVSUPFUN) )
|
||||
|
||||
#define S_drv_noDrvSup (M_drvSup| 1) /*SDR_DRVSUP: Driver support missing*/
|
||||
#define S_drv_noDrvet (M_drvSup| 3) /*Missing driver support entry table*/
|
||||
|
||||
#endif
|
||||
266
src/db/drvTS.h
Normal file
266
src/db/drvTS.h
Normal file
@@ -0,0 +1,266 @@
|
||||
#ifndef __DRVTS_h__
|
||||
#define __DRVTS_h__
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.12 1995/08/30 15:39:07 jbk
|
||||
* Added global variables for force accurate time stamps and direct time.
|
||||
*
|
||||
* Revision 1.11 1995/08/18 13:18:13 mrk
|
||||
* Added function prototypes for ansi c
|
||||
*
|
||||
* Revision 1.10 1995/08/17 20:35:52 jbk
|
||||
* fixed the debug macro to work with -pendantic option (yuck)
|
||||
*
|
||||
* Revision 1.9 1995/08/17 19:44:08 jbk
|
||||
* Added a new utility function to get the first of the year time stamp.
|
||||
*
|
||||
* Revision 1.8 1995/08/16 19:04:20 jbk
|
||||
* corrected vxworks time troubles
|
||||
*
|
||||
* Revision 1.7 1995/05/22 15:22:24 jbk
|
||||
* changes TS_EXTERN thing
|
||||
*
|
||||
* Revision 1.6 1995/02/01 15:30:17 winans
|
||||
* Added a type field to the configure command to disable the use of the event
|
||||
* system hardware if desired.
|
||||
*
|
||||
* Revision 1.5 1994/10/31 20:36:17 jbk
|
||||
* added new stuff
|
||||
*
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Author: Jim Kowalkowski
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 01-06-94 jbk initial version
|
||||
*
|
||||
***********************************************************************/
|
||||
/*
|
||||
*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE,
|
||||
AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE
|
||||
AND IN ALL SOURCE LISTINGS OF THE CODE.
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
Argonne National Laboratory (ANL), with facilities in the States of
|
||||
Illinois and Idaho, is owned by the United States Government, and
|
||||
operated by the University of Chicago under provision of a contract
|
||||
with the Department of Energy.
|
||||
|
||||
Portions of this material resulted from work developed under a U.S.
|
||||
Government contract and are subject to the following license: For
|
||||
a period of five years from March 30, 1993, the Government is
|
||||
granted for itself and others acting on its behalf a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, and perform
|
||||
publicly and display publicly. With the approval of DOE, this
|
||||
period may be renewed for two additional five year periods.
|
||||
Following the expiration of this period or periods, the Government
|
||||
is granted for itself and others acting on its behalf, a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, distribute copies
|
||||
to the public, perform publicly and display publicly, and to permit
|
||||
others to do so.
|
||||
|
||||
*****************************************************************
|
||||
DISCLAIMER
|
||||
*****************************************************************
|
||||
|
||||
NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR
|
||||
THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS,
|
||||
MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
|
||||
LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
|
||||
USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS
|
||||
DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
|
||||
OWNED RIGHTS.
|
||||
|
||||
*****************************************************************
|
||||
LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
|
||||
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <timers.h>
|
||||
#include <semLib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <tsDefs.h>
|
||||
|
||||
#ifdef TS_DRIVER
|
||||
#define TS_EXTERN
|
||||
#else
|
||||
#define TS_EXTERN extern
|
||||
#endif
|
||||
|
||||
#define ER_EVENT_RESET_TICK 0x7d /* Reset the tick counter */
|
||||
|
||||
#define TS_MAGIC ('T'<<24|'S'<<16|'d'<<8|'r')
|
||||
#define TS_SLAVE_PORT 18322
|
||||
#define TS_MASTER_PORT 18323
|
||||
#define TS_RETRY_COUNT 4
|
||||
#define TS_TIME_OUT_MS 250
|
||||
#define TS_SECS_ASYNC_TRY_MASTER (60*5) /* every five minutes */
|
||||
#define TS_SECS_SYNC_TRY_MASTER (60*1) /* every one minute */
|
||||
|
||||
#define UDP_TIME_PORT 37
|
||||
#define UDP_NTP_PORT 123
|
||||
|
||||
#define TS_BILLION 1000000000
|
||||
#define TS_SYNC_RATE_SEC 10
|
||||
#define TS_CLOCK_RATE_HZ 1000
|
||||
#define TS_TOTAL_EVENTS 128
|
||||
#define TS_SEC_IN_DAY (24*60*60)
|
||||
#define TS_SEC_IN_YEAR (TS_SEC_IN_DAY*365)
|
||||
#define TS_LEAPS_SINCE_1900 23
|
||||
#define TS_1900_TO_EPICS_EPOCH ((TS_SEC_IN_YEAR*90)+(22*TS_SEC_IN_DAY))
|
||||
#define TS_1900_TO_VXWORKS_EPOCH ((TS_SEC_IN_YEAR*70)+(17*TS_SEC_IN_DAY))
|
||||
#define TS_VXWORKS_TO_EPICS_EPOCH ((TS_SEC_IN_YEAR*20)+(5*TS_SEC_IN_DAY))
|
||||
|
||||
#define TS_STAMP_SERVER_PRI 70
|
||||
#define TS_SYNC_SERVER_PRI 70
|
||||
#define TS_SYNC_CLIENT_PRI 70
|
||||
#define TS_ASYNC_CLIENT_PRI 70
|
||||
|
||||
typedef enum { TS_time_request, TS_sync_request, TS_sync_msg } TStype;
|
||||
typedef enum { TS_master_alive, TS_master_dead } TSstate;
|
||||
typedef enum { TS_async_none, TS_async_private,
|
||||
TS_async_ntp, TS_async_time } TStime_protocol;
|
||||
typedef enum { TS_sync_master, TS_async_master,
|
||||
TS_sync_slave, TS_async_slave,
|
||||
TS_direct_master, TS_direct_slave } TStime_type;
|
||||
|
||||
struct TSstampTransStruct {
|
||||
unsigned long magic; /* identifier */
|
||||
TStype type; /* transaction type */
|
||||
struct timespec master_time; /* master time stamp - last sync time */
|
||||
struct timespec current_time; /* master current time stamp 1990 epoch */
|
||||
struct timespec unix_time; /* time using 1900 epoch */
|
||||
unsigned long sync_rate; /* master sends sync at this rate */
|
||||
unsigned long clock_hz; /* master clock this frequency (tick rate) */
|
||||
};
|
||||
typedef struct TSstampTransStruct TSstampTrans;
|
||||
|
||||
struct TSinfoStruct {
|
||||
TSstate state;
|
||||
TStime_type type;
|
||||
TStime_protocol async_type;
|
||||
int ts_sync_valid;
|
||||
|
||||
struct timespec *event_table; /* timestamp table */
|
||||
|
||||
unsigned long sync_rate; /* master send sync at this rate */
|
||||
unsigned long clock_hz; /* master clock is this frequency */
|
||||
unsigned long clock_conv; /* conversion factor for tick_rate->ns */
|
||||
unsigned long time_out; /* udp packet time-out in milliseconds */
|
||||
int master_timing_IOC; /* 1=master, 0=slave */
|
||||
int master_port; /* port that master listens on */
|
||||
int slave_port; /* port that slave listens on */
|
||||
int total_events; /* this is the total event in the event system */
|
||||
int sync_event; /* this is the sync event number */
|
||||
int has_event_system; /* 1=has event system, 0=no event system */
|
||||
int has_direct_time; /* 1=has direct time, 0=no direct time */
|
||||
int UserRequestedType; /* let user force the setting of type */
|
||||
|
||||
SEM_ID sync_occurred;
|
||||
|
||||
struct sockaddr hunt; /* broadcast address info */
|
||||
struct sockaddr master; /* socket info for contacting master */
|
||||
};
|
||||
typedef struct TSinfoStruct TSinfo;
|
||||
|
||||
/* global functions */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
TS_EXTERN long TSinit(void);
|
||||
TS_EXTERN long TSgetTimeStamp(int event_number,struct timespec* sp);
|
||||
TS_EXTERN long TScurrentTimeStamp(struct timespec* sp);
|
||||
TS_EXTERN long TSaccurateTimeStamp(struct timespec* sp);
|
||||
TS_EXTERN long TSgetFirstOfYearVx(struct timespec* sp);
|
||||
TS_EXTERN void TSconfigure(int master, int sync_rate_sec, int clock_rate_hz,
|
||||
int master_port, int slave_port,
|
||||
unsigned long millisecond_request_time_out, int type);
|
||||
|
||||
#ifndef TS_DRIVER
|
||||
TS_EXTERN TSinfo TSdata;
|
||||
TS_EXTERN TSdirectTimeVar; /* set to !=0 to indicate direct time available */
|
||||
TS_EXTERN TSgoodTimeStamps; /* force best time stamps by setting != 0 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
/* NTP information - all this is backwards and documentation only */
|
||||
#define VN_SHIFT 2 /* Version - 3 bits */
|
||||
#define VN_version 3<<VN_SHIFT
|
||||
|
||||
#define LI_SHIFT 0 /* Leap Indicator LI - 2 bits */
|
||||
#define LI_no_warning (0x00<<LI_SHIFT)
|
||||
#define LI_61_sec_minute (0x01<<LI_SHIFT)
|
||||
#define LI_59_sec_minute (0x02<<LI_SHIFT)
|
||||
#define LI_alarm_condition (0x03<<LI_SHIFT)
|
||||
|
||||
#define MODE_SHIFT 5 /* Mode MODE - 3 bits */
|
||||
#define MODE_reserved (0x00<<MODE_SHIFT)
|
||||
#define MODE_sym_active (0x01<<MODE_SHIFT)
|
||||
#define MODE_sym_passive (0x02<<MODE_SHIFT)
|
||||
#define MODE_client (0x03<<MODE_SHIFT)
|
||||
#define MODE_server (0x04<<MODE_SHIFT)
|
||||
#define MODE_broadcast (0x05<<MODE_SHIFT)
|
||||
#define MODE_reserved_NTP (0x06<<MODE_SHIFT)
|
||||
#define MODE_reserved_pvt (0x07<<MODE_SHIFT)
|
||||
|
||||
#define STRAT_SHIFT 8 /* Stratum STRAT - 8 bits */
|
||||
#define STRAT_unspecified (0x00<<STRAT_SHIFT)
|
||||
#define STRAT_ascii (0x00<<STRAT_SHIFT)
|
||||
#define STRAT_GPS (0x01<<STRAT_SHIFT)
|
||||
#define STRAT_ATOM (0x01<<STRAT_SHIFT)
|
||||
#define STRAT_address (0x02<<STRAT_SHIFT)
|
||||
|
||||
#define POLL_SHIFT 16 /* eight bits */
|
||||
#define PREC_SHIFT 24 /* eight bits */
|
||||
|
||||
struct TS_ntp {
|
||||
/* unsigned int info; */
|
||||
unsigned char info[4];
|
||||
unsigned int root_delay;
|
||||
unsigned int root_disp;
|
||||
unsigned int reference_id;
|
||||
struct timespec reference_ts;
|
||||
struct timespec originate_ts;
|
||||
struct timespec receive_ts;
|
||||
struct timespec transmit_ts;
|
||||
/* char authenticator[96]; (optional) */
|
||||
};
|
||||
typedef struct TS_ntp TS_NTP;
|
||||
|
||||
|
||||
/* debug macro creation */
|
||||
#ifdef NODEBUG
|
||||
#define Debug(l,f,v) ;
|
||||
#else
|
||||
#ifdef MAKE_DEBUG
|
||||
volatile int MAKE_DEBUG = 0;
|
||||
#define Debug(l,f,v) { if(l<= MAKE_DEBUG ) \
|
||||
{ printf("%s:%d: ",__FILE__,__LINE__); printf(f,v); }}
|
||||
#define Debug0(l,f) { if(l<= MAKE_DEBUG ) \
|
||||
{ printf("%s:%d: ",__FILE__,__LINE__); printf(f); }}
|
||||
#else
|
||||
#define Debug(l,f,v) { if(l) \
|
||||
{ printf("%s:%d: ",__FILE__,__LINE__); printf(f,v); }}
|
||||
#define Debug0(l,f) { if(l) \
|
||||
{ printf("%s:%d: ",__FILE__,__LINE__); printf(f); }}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
243
src/db/epics.db
Normal file
243
src/db/epics.db
Normal file
@@ -0,0 +1,243 @@
|
||||
include "menuGlobal.db"
|
||||
include "menuConvert.db"
|
||||
include "aiRecord.db"
|
||||
#include "aaiRecord.db"
|
||||
include "aoRecord.db"
|
||||
#include "aaoRecord.db"
|
||||
include "biRecord.db"
|
||||
include "boRecord.db"
|
||||
include "calcRecord.db"
|
||||
include "compressRecord.db"
|
||||
include "dfanoutRecord.db"
|
||||
#include "egRecord.db"
|
||||
#include "egeventRecord.db"
|
||||
#include "erRecord.db"
|
||||
#include "ereventRecord.db"
|
||||
include "eventRecord.db"
|
||||
include "fanoutRecord.db"
|
||||
#include "histogramRecord.db"
|
||||
include "longinRecord.db"
|
||||
include "longoutRecord.db"
|
||||
include "mbbiRecord.db"
|
||||
include "mbbiDirectRecord.db"
|
||||
include "mbboRecord.db"
|
||||
include "mbboDirectRecord.db"
|
||||
include "permissiveRecord.db"
|
||||
include "pidRecord.db"
|
||||
#include "pulseCounterRecord.db"
|
||||
#include "pulseDelayRecord.db"
|
||||
#include "pulseTrainRecord.db"
|
||||
#include "scanRecord.db"
|
||||
include "selRecord.db"
|
||||
include "seqRecord.db"
|
||||
include "stateRecord.db"
|
||||
#include "steppermotorRecord.db"
|
||||
include "stringinRecord.db"
|
||||
include "stringoutRecord.db"
|
||||
include "subRecord.db"
|
||||
#include "gsubRecord.db"
|
||||
#include "palRecord.db"
|
||||
include "subArrayRecord.db"
|
||||
#include "timerRecord.db"
|
||||
#include "waitRecord.db"
|
||||
include "waveformRecord.db"
|
||||
device(ai,CONSTANT,devAiSoft,"Soft Channel")
|
||||
#device(ai,CONSTANT,devAiSoftRaw,"Raw Soft Channel")
|
||||
#device(ai,VME_IO,devAiXy566Se,"XYCOM-566 SE Scanned")
|
||||
#device(ai,VME_IO,devAiXy566Di,"XYCOM-566 Dif Scanned")
|
||||
#device(ai,VME_IO,devAiXy566DiL,"XYCOM-566 Dif Latched")
|
||||
#device(ai,VME_IO,devAiDvx2502,"DVX-2502")
|
||||
#device(ai,CONSTANT,devAiTestAsyn,"Test Asyn")
|
||||
#device(ai,CONSTANT,devAiSymb,"vxWorks Variable")
|
||||
#device(ai,AB_IO,devAiAb1771Il,"AB-1771IL-Analog In")
|
||||
#device(ai,AB_IO,devAiAb1771Ife,"AB-1771IFE")
|
||||
#device(ai,AB_IO,devAiAb1771Ixe,"AB-1771IXE-Millivolt In")
|
||||
#device(ai,AB_IO,devAiAb1771IfeSe,"AB-1771IFE-SE")
|
||||
#device(ai,AB_IO,devAiAb1771IfeMa,"AB-1771IFE-4to20MA")
|
||||
#device(ai,AB_IO,devAiAb1771Ife0to5V,"AB-1771IFE-0to5Volt")
|
||||
#device(ai,AB_IO,devAiAb1771IrPlatinum,"AB-1771RTD-Platinum")
|
||||
#device(ai,AB_IO,devAiAb1771IrCopper,"AB-1771RTD-Copper")
|
||||
#device(ai,CAMAC_IO,devAiCamac,"Camac")
|
||||
#device(ai,VME_IO,devAiAt5Vxi,"VXI-AT5-AI")
|
||||
#device(ai,GPIB_IO,devAiK486Gpib,"Keithley-486")
|
||||
#device(ai,VME_IO,devAiKscV215,"KSC-V215")
|
||||
#device(ai,VME_IO,devAiSysmon,"SYSMON")
|
||||
#device(aai,CAMAC_IO,devAaiCamac,"Camac")
|
||||
device(ao,CONSTANT,devAoSoft,"Soft Channel")
|
||||
#device(ao,CONSTANT,devAoSoftRaw,"Raw Soft Channel")
|
||||
#device(ao,VME_IO,devAoVmiVme4100,"VMIVME-4100")
|
||||
#device(ao,CONSTANT,devAoTestAsyn,"Test Asyn")
|
||||
#device(ao,CONSTANT,devAoSymb,"vxWorks Variable")
|
||||
#device(ao,AB_IO,devAoAb1771Ofe,"AB-1771OFE")
|
||||
#device(ao,CAMAC_IO,devAoCamac,"Camac")
|
||||
#device(ao,VME_IO,devAoAt5Vxi,"VXI-AT5-AO")
|
||||
device(bi,CONSTANT,devBiSoft,"Soft Channel")
|
||||
#device(bi,CONSTANT,devBiSoftRaw,"Raw Soft Channel")
|
||||
#device(bi,VME_IO,devBiMpv910,"MPV-910")
|
||||
#device(bi,VME_IO,devBiXVme210,"XVME-210")
|
||||
#device(bi,CONSTANT,devBiTestAsyn,"Test Asyn")
|
||||
#device(bi,AB_IO,devBiAb,"AB-Binary Input")
|
||||
#device(bi,AB_IO,devBiAb16,"AB-16 bit BI")
|
||||
#device(bi,AB_IO,devBiAb32,"AB-32 bit BI")
|
||||
#device(bi,CAMAC_IO,devBiCamac,"Camac")
|
||||
#device(bi,VME_IO,devBiAt5Vxi,"VXI-AT5-BI")
|
||||
#device(bi,VME_IO,devBiXy240,"XYCOM-240")
|
||||
#device(bi,VME_IO,devBiHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(bi,VME_IO,devBiAt8Fp,"AT8-FP10S")
|
||||
#device(bi,VME_IO,devBiAvme9440,"AVME9440 I")
|
||||
#device(bi,VME_IO,devBiSysmon,"SYSMON")
|
||||
#device(bi,VME_IO,devBiMpc,"MPC")
|
||||
device(bo,CONSTANT,devBoSoft,"Soft Channel")
|
||||
#device(bo,CONSTANT,devBoSoftRaw,"Raw Soft Channel")
|
||||
#device(bo,VME_IO,devBoMpv902,"MPV-902")
|
||||
#device(bo,VME_IO,devBoXVme220,"XVME-220")
|
||||
#device(bo,CONSTANT,devBoTestAsyn,"Test Asyn")
|
||||
#device(bo,AB_IO,devBoAb,"AB-Binary Output")
|
||||
#device(bo,AB_IO,devBoAb16,"AB-16 bit BO")
|
||||
#device(bo,AB_IO,devBoAb32,"AB-32 bit BO")
|
||||
#device(bo,CAMAC_IO,devBoCamac,"Camac")
|
||||
#device(bo,VME_IO,devBoAt5Vxi,"VXI-AT5-BO")
|
||||
#device(bo,GPIB_IO,devBoK486Gpib,"Keithley-486")
|
||||
#device(bo,VME_IO,devBoXy240,"XYCOM-240")
|
||||
#device(bo,VME_IO,devBoHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(bo,VME_IO,devBoAt8Fp,"AT8-FP10S")
|
||||
#device(bo,VME_IO,devBoAvme9440,"AVME9440 O")
|
||||
#device(bo,VME_IO,devBoSysmon,"SYSMON")
|
||||
#device(bo,VME_IO,devBoMpc,"MPC")
|
||||
device(event,CONSTANT,devEventSoft,"Soft Channel")
|
||||
#device(event,VME_IO,devEventMz8310,"Mizar-8310")
|
||||
#device(event,CONSTANT,devEventTestIoEvent,"Test IoEvent")
|
||||
#device(event,VME_IO,devErEpicsEvent,"APS event receiver")
|
||||
#device(histogram,CONSTANT,devHistogramSoft,"Soft Channel")
|
||||
#device(histogram,CONSTANT,devHistogramTestAsyn,"Test Asyn")
|
||||
device(longin,CONSTANT,devLiSoft,"Soft Channel")
|
||||
device(longin,CONSTANT,devLiSymb,"vxWorks Variable")
|
||||
#device(longin,CAMAC_IO,devLiCamac,"Camac")
|
||||
device(longout,CONSTANT,devLoSoft,"Soft Channel")
|
||||
device(longout,CONSTANT,devLoSymb,"vxWorks Variable")
|
||||
#device(longout,CAMAC_IO,devLoCamac,"Camac")
|
||||
device(mbbi,CONSTANT,devMbbiSoft,"Soft Channel")
|
||||
#device(mbbi,CONSTANT,devMbbiSoftRaw,"Raw Soft Channel")
|
||||
#device(mbbi,VME_IO,devMbbiMpv910,"MPV-910")
|
||||
#device(mbbi,VME_IO,devMbbiXVme210,"XVME-210")
|
||||
#device(mbbi,CONSTANT,devMbbiTestAsyn,"Test Asyn")
|
||||
#device(mbbi,AB_IO,devMbbiAb,"AB-Binary Input")
|
||||
#device(mbbi,AB_IO,devMbbiAb16,"AB-16 bit BI")
|
||||
#device(mbbi,AB_IO,devMbbiAb32,"AB-32 bit BI")
|
||||
#device(mbbi,AB_IO,devMbbiAbAdapterStat,"AB-Adapter Status")
|
||||
#device(mbbi,AB_IO,devMbbiAbCardStat,"AB-Card Status")
|
||||
#device(mbbi,CAMAC_IO,devMbbiCamac,"Camac")
|
||||
#device(mbbi,VME_IO,devMbbiAt5Vxi,"VXI-AT5-BI")
|
||||
#device(mbbi,VME_IO,devMbbiXy240,"XYCOM-240")
|
||||
#device(mbbi,VME_IO,devMbbiHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(mbbi,VME_IO,devMbbiAt8Fp,"AT8-FP10S")
|
||||
#device(mbbi,VME_IO,devMbbiAvme9440,"AVME9440 I")
|
||||
#device(mbbi,VME_IO,devMbbiSysmon,"SYSMON")
|
||||
device(mbbiDirect,CONSTANT,devMbbiDirectSoft,"Soft Channel")
|
||||
#device(mbbiDirect,CONSTANT,devMbbiDirectSoftRaw,"Raw Soft Channel")
|
||||
#device(mbbiDirect,VME_IO,devMbbiDirectMpv910,"MPV-910")
|
||||
#device(mbbiDirect,VME_IO,devMbbiDirectXVme210,"XVME-210")
|
||||
#device(mbbiDirect,AB_IO,devMbbiDirectAb,"AB-Binary Input")
|
||||
#device(mbbiDirect,AB_IO,devMbbiDirectAb16,"AB-16 bit BI")
|
||||
#device(mbbiDirect,AB_IO,devMbbiDirectAb32,"AB-32 bit BI")
|
||||
#device(mbbiDirect,CAMAC_IO,devMbbiDirectCamac,"Camac")
|
||||
#device(mbbiDirect,VME_IO,devMbbiDirectAt5Vxi,"VXI-AT5-BI")
|
||||
device(mbbo,CONSTANT,devMbboSoft,"Soft Channel")
|
||||
#device(mbbo,CONSTANT,devMbboSoftRaw,"Raw Soft Channel")
|
||||
#device(mbbo,VME_IO,devMbboMpv902,"MPV-902")
|
||||
#device(mbbo,VME_IO,devMbboXVme220,"XVME-220")
|
||||
#device(mbbo,CONSTANT,devMbboTestAsyn,"Test Asyn")
|
||||
#device(mbbo,AB_IO,devMbboAb,"AB-Binary Output")
|
||||
#device(mbbo,AB_IO,devMbboAb16,"AB-16 bit BO")
|
||||
#device(mbbo,AB_IO,devMbboAb32,"AB-32 bit BO")
|
||||
#device(mbbo,VME_IO,devMbboAt5Vxi,"VXI-AT5-BO")
|
||||
#device(mbbo,GPIB_IO,devMbboK486Gpib,"Keithley-486")
|
||||
#device(mbbo,VME_IO,devMbboXy240,"XYCOM-240")
|
||||
#device(mbbo,VME_IO,devMbboHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(mbbo,VME_IO,devMbboAt8Fp,"AT8-FP10S")
|
||||
#device(mbbo,VME_IO,devMbboAvme9440,"AVME9440 O")
|
||||
#device(mbbo,VME_IO,devMbboSysmon,"SYSMON")
|
||||
device(mbboDirect,CONSTANT,devMbboDirectSoft,"Soft Channel")
|
||||
#device(mbboDirect,CONSTANT,devMbboDirectSoftRaw,"Raw Soft Channel")
|
||||
#device(mbboDirect,VME_IO,devMbboDirectMpv902,"MPV-902")
|
||||
#device(mbboDirect,VME_IO,devMbboDirectXVme220,"XVME-220")
|
||||
#device(mbboDirect,AB_IO,devMbboDirectAb,"AB-Binary Output")
|
||||
#device(mbboDirect,AB_IO,devMbboDirectAb16,"AB-16 bit BO")
|
||||
#device(mbboDirect,AB_IO,devMbboDirectAb32,"AB-32 bit BO")
|
||||
#device(mbboDirect,CAMAC_IO,devMbboDirectCamac,"Camac")
|
||||
#device(mbboDirect,VME_IO,devMbboDirectAt5Vxi,"VXI-AT5-BO")
|
||||
#device(pulseCounter,VME_IO,devPcMz8310,"Mizar-8310")
|
||||
#device(pulseDelay,VME_IO,devPdMz8310,"Mizar-8310")
|
||||
#device(pulseDelay,VXI_IO,devPdVxiTDM,"VXI Time Delay Module")
|
||||
#device(pulseTrain,CONSTANT,devPtSoft,"Soft Channel")
|
||||
#device(pulseTrain,VME_IO,devPtMz8310,"Mizar-8310")
|
||||
#device(steppermotor,VME_IO,devSmCompumotor1830,"Compumotor 1830")
|
||||
#device(steppermotor,VME_IO,devSmOms6Axis,"OMS 6-Axis")
|
||||
#device(steppermotor,AB_IO,devSmAB1746Hstp1,"Allen Bradley 1746-HTSP1")
|
||||
device(stringin,CONSTANT,devSiSoft,"Soft Channel")
|
||||
#device(stringin,CONSTANT,devSiTestAsyn,"Test Asyn")
|
||||
#device(stringin,CONSTANT,devSiSymb,"vxWorks Variable")
|
||||
device(stringout,CONSTANT,devSoSoft,"Soft Channel")
|
||||
#device(stringout,CONSTANT,devSoTestAsyn,"Test Asyn")
|
||||
#device(stringout,CONSTANT,devSoSymb,"vxWorks Variable")
|
||||
device(subArray,CONSTANT,devSASoft,"Soft Channel")
|
||||
#device(timer,VME_IO,devTmMizar8310,"Mizar-8310")
|
||||
#device(timer,VME_IO,devTmDg535,"DG 535")
|
||||
#device(timer,VME_IO,devTmAt5Vxi,"VXI-AT5-TIME")
|
||||
device(waveform,CONSTANT,devWfSoft,"Soft Channel")
|
||||
#device(waveform,VME_IO,devWfXy566Sc,"XYCOM-566 Single Channel")
|
||||
#device(waveform,VME_IO,devWfComet,"Comet Digitizer")
|
||||
#device(waveform,VME_IO,devWfJoergerVtr1,"Joerger Digitizer")
|
||||
#device(waveform,CONSTANT,devWfTestAsyn,"Test Asyn")
|
||||
#device(waveform,VME_IO,devWfDvx2502,"DVX-2502")
|
||||
#device(waveform,VME_IO,devWfPentek4261,"Pentek 4261")
|
||||
#device(waveform,CAMAC_IO,devWfCamac,"Camac")
|
||||
#device(waveform,VME_IO,devWfJoergerVtr1,"Joerger-VTR1")
|
||||
#device(waveform,VME_IO,devWfComet,"Omnibyte-COMET")
|
||||
#device(eg,VME_IO,devEg,"APS event generator G")
|
||||
#device(egevent,VME_IO,devEgEvent,"APS event generator E")
|
||||
#device(er,VME_IO,devEr,"APS event receiver")
|
||||
#device(erevent,VME_IO,devErevent,"APS event receiver")
|
||||
#device(wait,CONSTANT,devWaitIoEvent,"Soft Channel")
|
||||
#device(ai,INST_IO,devAiCan,"CANbus")
|
||||
#device(ao,INST_IO,devAoCan,"CANbus")
|
||||
#device(bi,INST_IO,devBiCan,"CANbus")
|
||||
#device(bo,INST_IO,devBoCan,"CANbus")
|
||||
#device(mbbi,INST_IO,devMbbiCan,"CANbus")
|
||||
#device(mbbo,INST_IO,devMbboCan,"CANbus")
|
||||
#device(mbbiDirect,INST_IO,devMbbiDirectCan,"CANbus")
|
||||
#device(mbboDirect,INST_IO,devMbboDirectCan,"CANbus")
|
||||
#device(bi,VME_IO,devBiVmic2534,"Vmic2534")
|
||||
#device(bo,VME_IO,devBoVmic2534,"Vmic2534")
|
||||
#device(mbbi,VME_IO,devMbbiVmic2534,"Vmic2534")
|
||||
#device(mbbo,VME_IO,devMbboVmic2534,"Vmic2534")
|
||||
#driver(drvXy010)
|
||||
#driver(drvVxi)
|
||||
#driver(drvGpib)
|
||||
#driver(drvBitBus)
|
||||
#driver(drvBb910)
|
||||
#driver(drvXy210)
|
||||
#driver(drvBb902)
|
||||
#driver(drvXy220)
|
||||
#driver(drvXy566)
|
||||
#driver(drvDvx)
|
||||
#driver(drvVmi4100)
|
||||
#driver(drvAb)
|
||||
#driver(drvAt5Vxi)
|
||||
#driver(drvCompuSm)
|
||||
#driver(drvOms)
|
||||
#driver(drvMz8310)
|
||||
#driver(drvHpe1368a)
|
||||
#driver(drvXy240)
|
||||
#driver(drvKscV215)
|
||||
#driver(drvComet)
|
||||
#driver(drvJgvtr1)
|
||||
#driver(drvFp)
|
||||
#driver(drvFpm)
|
||||
#driver(drvIpac)
|
||||
#driver(drvTip810)
|
||||
#driver(drvVmi2534)
|
||||
#include "bptTypeJdegC.db"
|
||||
#include "bptTypeJdegF.db"
|
||||
#include "bptTypeKdegC.db"
|
||||
#include "bptTypeKdegF.db"
|
||||
204
src/db/epicsLIBOBJS
Normal file
204
src/db/epicsLIBOBJS
Normal file
@@ -0,0 +1,204 @@
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/aaiRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/aaoRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/aiRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/aoRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/biRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/boRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/calcRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/compressRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/dfanoutRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/egRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/egeventRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/erRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/ereventRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/eventRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/fanoutRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/gsubRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/histogramRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/longinRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/longoutRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/mbbiRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/mbbiDirectRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/mbboRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/mbboDirectRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/palRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/permissiveRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/pidRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/pulseCounterRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/pulseDelayRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/pulseTrainRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/scanRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/recWaitCa.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/recDynLink.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/recDynLinkTest.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/selRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/seqRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/stateRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/steppermotorRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/stringinRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/stringoutRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/subRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/subArrayRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/timerRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/waitRecord.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/waveformRecord.o
|
||||
#
|
||||
# Device Support
|
||||
#
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAaiCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiDvx2502.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiKscV215.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAiSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAiSoftRaw.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAiSymb.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAiTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiXy566Di.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiXy566DiL.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiXy566Se.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAaoCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAoCamac.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAoSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAoSoftRaw.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAoSymb.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAoTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAoVmiVme4100.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devApsEg.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devApsEr.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAt5Vxi.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAt8Fp.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAvme9440.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devBiCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devBiMpv910.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devBiSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devBiSoftRaw.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devBiTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devBiXVme210.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devBoCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devBoMpv902.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devBoSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devBoSoftRaw.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devBoTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devBoXVme220.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devCommonGpib.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devEventSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devEventTestIoEvent.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devHistogramSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devHistogramTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devHpe1368a.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devLiCamac.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devLiSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devLiSymb.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devLoCamac.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devLoSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devLoSymb.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbbiCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbbiDirectCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbbiDirectMpv910.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbbiDirectSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbbiDirectSoftRaw.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbbiDirectXVme210.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbbiMpv910.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbbiSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbbiSoftRaw.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbbiTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbbiXVme210.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbboCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbboDirectCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbboDirectMpv902.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbboDirectSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbboDirectSoftRaw.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbboDirectXVme220.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbboMpv902.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbboSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbboSoftRaw.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devMbboTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbboXVme220.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMz8310.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devPtSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSASoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSiSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSiSymb.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSiTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devSmCompumotor1830.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devSmOms6Axis.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSoSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSoSymb.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSoTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devSysmon.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devTimerMz8310.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devVxiTDM.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devWfCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devWfComet.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devWfDvx2502.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devWfJoergerVtr1.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devWfSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devWfTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devWfXy566Sc.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devWfPentek4261.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devXy240.o
|
||||
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAB1771IFE.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAB1771IL.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAB1771IR.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAB1771IXE.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAB1771OFE.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devABBINARY.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devABStatus.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMpc.o
|
||||
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiCan.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAoCan.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devBiCan.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devBoCan.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbbiCan.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbboCan.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbbiDirectCan.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMbboDirectCan.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devVmic2534.o
|
||||
#
|
||||
# Driver support ANSI
|
||||
#
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvAb.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvAt5Vxi.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/drvEpvxi.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/drvEpvxiMsg.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/drvHp1404a.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvHpe1368a.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvHpe1445a.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvKscV215.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvMz8310.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvStc.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvTime.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvCaenV265.o
|
||||
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvVipc310.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvVipc610.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvIpMv162.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvIpac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvTip810.o
|
||||
#
|
||||
# Driver support NON ANSI
|
||||
#
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/module_types.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvBB232.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvBb902.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvBb910.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvBitBus.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvComet.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvCompuSm.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvDvx.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvFp.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvFpm.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvGpib.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvJgvtr1.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvMsg.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvOms.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvTranServ.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvVmi4100.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvXy010.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvXy210.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvXy220.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvXy240.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvXy566.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvVmic2534.o
|
||||
191
src/db/fast_lock.h
Normal file
191
src/db/fast_lock.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/* fast_lock.h */
|
||||
/* share/epicsH $Id$ */
|
||||
|
||||
/*
|
||||
* Author: Jeff Hill
|
||||
* Date: 4-11-89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 joh 041189 initial release into middle age
|
||||
* .02 joh 071989 added fast lock test
|
||||
* .03 joh 090391 VRTX kernel ifdef for V5 vxWorks
|
||||
* .04 joh 091091 Now uses V5 vxWorks binary semaphore
|
||||
* .05 joh 092491 Dont use V5 semaphore on V3 EPICS yet
|
||||
* .06 jba 030692 added cast to vxTas arg in FASTLOCK vxWorks5
|
||||
* .07 jba 081092 added cast to vxTas arg in FASTLOCKNOWAIT
|
||||
* .08 mgb 082493 Removed V5/V4 conditional defines
|
||||
* .09 joh 082493 include vxLib.h for vxWorks V5.1
|
||||
* .10 joh 082593 made lock char as vxTas expects
|
||||
* (padded structure to identical size)
|
||||
* .11 joh 082593 made fast lock structure fields volatile
|
||||
* .12 joh 091493 added sem and task lock based fast locks
|
||||
* with ifdefs - removed volatile
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Macros and data structures for a much faster (than vrtx semaphore)
|
||||
* mutual exclusion lock/unlock.
|
||||
* (semaphore in this case is only used to wait for unlock)
|
||||
*
|
||||
* On a 68020 the following times include lock and unlock
|
||||
*
|
||||
* FASTLOCK-FASTUNLOCK 8 microsecs
|
||||
* semTake-semGive(Macro) 80 microsecs
|
||||
* semTake-semGive 92 microsecs
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INCLfast_lockh
|
||||
#define INCLfast_lockh
|
||||
|
||||
#ifndef INCLsemLibh
|
||||
#include <semLib.h>
|
||||
#endif
|
||||
#ifndef INCLvxLibh
|
||||
#include <vxLib.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro equivalent of vxWorks glue for better performance
|
||||
*/
|
||||
#ifdef VRTX_KERNEL
|
||||
# define semGive(SEMID)\
|
||||
{ if ((SEMID)->count == 0)vrtxPost (&((SEMID)->count), 1); }
|
||||
|
||||
# define semTake(SEMID)\
|
||||
{int dummy; vrtxPend (&((SEMID)->count), 0, &dummy); }
|
||||
#endif
|
||||
|
||||
typedef struct{
|
||||
SEM_ID ppend; /* wait for lock sem */
|
||||
unsigned short count; /* cnt of tasks waiting for lock */
|
||||
unsigned char lock; /* test and set lock bit */
|
||||
char pad; /* structure alignment */
|
||||
}FAST_LOCK;
|
||||
|
||||
#define SEM_FAST_LOCK
|
||||
|
||||
#if defined(SEM_FAST_LOCK) /* no lock test */
|
||||
|
||||
#define FASTLOCKINIT(PFAST_LOCK)\
|
||||
(((FAST_LOCK *)(PFAST_LOCK))->ppend = \
|
||||
semBCreate(SEM_Q_PRIORITY, SEM_FULL))
|
||||
#define FASTLOCKFREE(PFAST_LOCK)\
|
||||
semDelete( ((FAST_LOCK *)(PFAST_LOCK))->ppend )
|
||||
#define FASTLOCK(PFAST_LOCK)\
|
||||
semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend, WAIT_FOREVER);
|
||||
#define FASTUNLOCK(PFAST_LOCK)\
|
||||
semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend);
|
||||
#define FASTLOCKNOWAIT(PFAST_LOCK) \
|
||||
((semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend,NO_WAIT)==0) ? TRUE : FALSE)
|
||||
#define FASTLOCKTEST(PFAST_LOCK) \
|
||||
(\
|
||||
(semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend,NO_WAIT)==0 )\
|
||||
? (semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend),FALSE)\
|
||||
: TRUE \
|
||||
)
|
||||
|
||||
|
||||
#elif defined(TASK_LOCK_FAST_LOCK)
|
||||
|
||||
#define FASTLOCKINIT(PFAST_LOCK)\
|
||||
(\
|
||||
((FAST_LOCK *)(PFAST_LOCK))->count =0, \
|
||||
((FAST_LOCK *)(PFAST_LOCK))->lock =0, \
|
||||
((FAST_LOCK *)(PFAST_LOCK))->ppend = \
|
||||
semBCreate(SEM_Q_PRIORITY, SEM_EMPTY) \
|
||||
)
|
||||
#define FASTLOCKFREE(PFAST_LOCK)\
|
||||
semDelete( ((FAST_LOCK *)(PFAST_LOCK))->ppend )
|
||||
|
||||
#define FASTLOCK(PFAST_LOCK)\
|
||||
{\
|
||||
TASK_LOCK;\
|
||||
while( ((FAST_LOCK *)(PFAST_LOCK))->lock ){\
|
||||
((FAST_LOCK *)(PFAST_LOCK))->count++;\
|
||||
TASK_UNLOCK;\
|
||||
semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend, WAIT_FOREVER);\
|
||||
TASK_LOCK;\
|
||||
(((FAST_LOCK *)(PFAST_LOCK))->count)--;\
|
||||
}\
|
||||
((FAST_LOCK *)(PFAST_LOCK))->lock= TRUE;
|
||||
TASK_UNLOCK;
|
||||
}
|
||||
|
||||
#define FASTUNLOCK(PFAST_LOCK)\
|
||||
{\
|
||||
((FAST_LOCK *)(PFAST_LOCK))->lock = FALSE;\
|
||||
if( ((FAST_LOCK *)(PFAST_LOCK))->count )\
|
||||
semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend);\
|
||||
};
|
||||
|
||||
#define FASTLOCKTEST(PFAST_LOCK)\
|
||||
( ((FAST_LOCK *)(PFAST_LOCK))->lock )
|
||||
|
||||
#else /* vxTas() fast lock */
|
||||
|
||||
/*
|
||||
* extra paren avoids order of ops problems
|
||||
* (returns what semBCreate returns on v5 vxWorks)
|
||||
*/
|
||||
#define FASTLOCKINIT(PFAST_LOCK)\
|
||||
(\
|
||||
((FAST_LOCK *)(PFAST_LOCK))->count =0, \
|
||||
((FAST_LOCK *)(PFAST_LOCK))->lock =0, \
|
||||
((FAST_LOCK *)(PFAST_LOCK))->ppend = \
|
||||
semBCreate(SEM_Q_PRIORITY, SEM_EMPTY) \
|
||||
)
|
||||
|
||||
/*
|
||||
* new requirement with v5 vxWorks
|
||||
*/
|
||||
#define FASTLOCKFREE(PFAST_LOCK)\
|
||||
semDelete( ((FAST_LOCK *)(PFAST_LOCK))->ppend )
|
||||
|
||||
#define FASTLOCK(PFAST_LOCK)\
|
||||
{\
|
||||
((FAST_LOCK *)(PFAST_LOCK))->count++;\
|
||||
while(!vxTas( (char *)&( ((FAST_LOCK *)(PFAST_LOCK))->lock ) ))\
|
||||
semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend, WAIT_FOREVER);\
|
||||
( ((FAST_LOCK *)(PFAST_LOCK))->count)--;\
|
||||
}
|
||||
|
||||
#define FASTUNLOCK(PFAST_LOCK)\
|
||||
{\
|
||||
((FAST_LOCK *)(PFAST_LOCK))->lock = FALSE;\
|
||||
if( ((FAST_LOCK *)(PFAST_LOCK))->count )\
|
||||
semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend);\
|
||||
};
|
||||
|
||||
#define FASTLOCKNOWAIT(PFAST_LOCK) (vxTas((char *)&(((FAST_LOCK *)(PFAST_LOCK))->lock)))
|
||||
|
||||
#define FASTLOCKTEST(PFAST_LOCK)\
|
||||
( ((FAST_LOCK *)(PFAST_LOCK))->lock )
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* Nothing after this endif */
|
||||
@@ -61,7 +61,7 @@ int callNumber;
|
||||
break;
|
||||
case INITHOOKafterCallbackInit :
|
||||
break;
|
||||
case INITHOOKafterCaLinkInit1 :
|
||||
case INITHOOKafterCaLinkInit :
|
||||
break;
|
||||
case INITHOOKafterInitDrvSup :
|
||||
break;
|
||||
@@ -73,8 +73,6 @@ int callNumber;
|
||||
break;
|
||||
case INITHOOKafterInitDatabase :
|
||||
break;
|
||||
case INITHOOKafterCaLinkInit2 :
|
||||
break;
|
||||
case INITHOOKafterFinishDevSup :
|
||||
break;
|
||||
case INITHOOKafterScanInit :
|
||||
|
||||
54
src/db/initHooks.h
Normal file
54
src/db/initHooks.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* share/src/db $Id$ */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 06-01-91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 09-05-92 rcz initial version
|
||||
* .02 09-10-92 rcz changed completely
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INCinitHooksh
|
||||
#define INCinitHooksh 1
|
||||
|
||||
#define INITHOOKatBeginning 0
|
||||
#define INITHOOKafterGetResources 1
|
||||
#define INITHOOKafterLogInit 2
|
||||
#define INITHOOKafterCallbackInit 3
|
||||
#define INITHOOKafterCaLinkInit 4
|
||||
#define INITHOOKafterInitDrvSup 5
|
||||
#define INITHOOKafterInitRecSup 6
|
||||
#define INITHOOKafterInitDevSup 7
|
||||
#define INITHOOKafterTS_init 8
|
||||
#define INITHOOKafterInitDatabase 9
|
||||
#define INITHOOKafterFinishDevSup 10
|
||||
#define INITHOOKafterScanInit 11
|
||||
#define INITHOOKafterInterruptAccept 12
|
||||
#define INITHOOKafterInitialProcess 13
|
||||
#define INITHOOKatEnd 14
|
||||
|
||||
#endif /*INCinitHooksh*/
|
||||
286
src/db/iocInit.c
286
src/db/iocInit.c
@@ -79,12 +79,13 @@
|
||||
#include <ellLib.h>
|
||||
#include <fast_lock.h>
|
||||
#include <dbDefs.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbScan.h>
|
||||
#include <taskwd.h>
|
||||
#include <callback.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbLock.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <devSup.h>
|
||||
#include <drvSup.h>
|
||||
@@ -115,9 +116,6 @@ LOCAL long initRecSup(void);
|
||||
LOCAL long initDevSup(void);
|
||||
LOCAL long finishDevSup(void);
|
||||
LOCAL long initDatabase(void);
|
||||
LOCAL void createLockSets(void);
|
||||
LOCAL void createLockSetsExtraPass(int *anyChange);
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr,short set,int *anyChange);
|
||||
LOCAL long initialProcess(void);
|
||||
LOCAL long getResources(char *fname);
|
||||
LOCAL int getResourceToken(FILE *fp, char *pToken, unsigned maxToken);
|
||||
@@ -142,7 +140,7 @@ int iocInit(char * pResourceFilename)
|
||||
}
|
||||
|
||||
if (!pdbbase) {
|
||||
logMsg("iocInit aborting because No database loaded by dbAsciiRead\n",
|
||||
logMsg("iocInit aborting because No database\n",
|
||||
0,0,0,0,0,0);
|
||||
return(-1);
|
||||
}
|
||||
@@ -182,9 +180,9 @@ int iocInit(char * pResourceFilename)
|
||||
(void)taskDelay(sysClkRateGet()/10);
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterCallbackInit);
|
||||
|
||||
/* Initialize Channel Access Link mechanism. Pass #1 */
|
||||
dbCaLinkInit((int) 1);
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterCaLinkInit1);
|
||||
/* Initialize Channel Access Link mechanism. */
|
||||
dbCaLinkInit();
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterCaLinkInit);
|
||||
|
||||
if (initDrvSup() != 0)
|
||||
logMsg("iocInit: Drivers Failed during Initialization\n",0,0,0,0,0,0);
|
||||
@@ -207,19 +205,19 @@ int iocInit(char * pResourceFilename)
|
||||
if (initDatabase() != 0)
|
||||
logMsg("iocInit: Database Failed during Initialization\n",0,0,0,0,0,0);
|
||||
|
||||
createLockSets();
|
||||
dbLockInitRecords(pdbbase);
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterInitDatabase);
|
||||
|
||||
dbCaLinkInit((int) 2);
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterCaLinkInit2);
|
||||
|
||||
if (finishDevSup() != 0)
|
||||
logMsg("iocInit: Device Support Failed during Finalization\n",
|
||||
0,0,0,0,0,0);
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterFinishDevSup);
|
||||
|
||||
scanInit();
|
||||
asInit();
|
||||
if(asInit()) {
|
||||
logMsg("iocInit: asInit Failed during initialization\n",0,0,0,0,0,0);
|
||||
return(-1);
|
||||
}
|
||||
(void)taskDelay(sysClkRateGet()/2);
|
||||
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterScanInit);
|
||||
@@ -425,6 +423,7 @@ LOCAL long initDatabase(void)
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
precord->rset = prset;
|
||||
precord->rdes = pdbRecDes;
|
||||
FASTLOCKINIT(&precord->mlok);
|
||||
ellInit(&(precord->mlis));
|
||||
|
||||
@@ -435,8 +434,6 @@ LOCAL long initDatabase(void)
|
||||
pdevSup = (devSup *)ellNth(&pdbRecDes->devList,precord->dtyp+1);
|
||||
pdset = (pdevSup ? pdevSup->pdset : 0);
|
||||
precord->dset = pdset;
|
||||
/* Initialize dbCommon - First pass (pass=0) */
|
||||
rtnval = dbCommonInit(precord,0);
|
||||
if(!prset->init_record) continue;
|
||||
rtnval = (*prset->init_record)(precord,0);
|
||||
if (status==0) status = rtnval;
|
||||
@@ -454,50 +451,29 @@ LOCAL long initDatabase(void)
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
/*
|
||||
* Convert all PV_LINKs to DB_LINKs or CA_LINKs
|
||||
* Figures out what type of link to use. A
|
||||
* database link local to the IOC, or a channel
|
||||
* access link across the network.
|
||||
*/
|
||||
/* Convert all PV_LINKs to DB_LINKs or CA_LINKs */
|
||||
/* For all the links in the record type... */
|
||||
for(j=0; j<pdbRecDes->no_links; j++) {
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[j]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if (plink->type == PV_LINK) {
|
||||
/*
|
||||
* Lookup record name in database
|
||||
* If a record is _not_ local to the IOC, it is a
|
||||
* channel access link, otherwise it is a
|
||||
* database link.
|
||||
*/
|
||||
if(dbNameToAddr(plink->value.pv_link.pvname,&dbaddr) == 0) {
|
||||
if(!(plink->value.pv_link.pvlMask&(pvlOptCA|pvlOptCP|pvlOptCPP))
|
||||
&& (dbNameToAddr(plink->value.pv_link.pvname,&dbaddr)==0)) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
plink->type = DB_LINK;
|
||||
pdbAddr = dbCalloc(1,sizeof(struct dbAddr));
|
||||
*pdbAddr = dbaddr; /*structure copy*/;
|
||||
plink->value.db_link.pdbAddr = pdbAddr;
|
||||
/*Initialize conversion to "uninitialized" conversion */
|
||||
plink->value.db_link.conversion = cvt_uninit;
|
||||
} else {
|
||||
/*
|
||||
* Not a local process variable ... assuming a CA_LINK
|
||||
* Only supporting Non Process Passive links,
|
||||
* Input Maximize Severity/No Maximize Severity(MS/NMS)
|
||||
* , and output NMS
|
||||
* links ... The following code checks for this.
|
||||
*/
|
||||
if (errVerbose &&
|
||||
(plink->value.db_link.process_passive
|
||||
|| (pdbFldDes->field_type == DBF_OUTLINK
|
||||
&& plink->value.db_link.maximize_sevr))) {
|
||||
status = S_db_badField;
|
||||
errPrintf(status,__FILE__,__LINE__,"%s.%s %s",
|
||||
precord->name,pdbFldDes->name,
|
||||
" PP and/or MS illegal");
|
||||
status = 0;
|
||||
}
|
||||
plink->value.pv_link.pvt = pdbAddr;
|
||||
} else {/*It is a CA link*/
|
||||
char *pperiod;
|
||||
|
||||
dbCaAddLink(plink);
|
||||
if(pdbFldDes->field_type==DBF_FWDLINK) {
|
||||
pperiod = strrchr(plink->value.pv_link.pvname,'.');
|
||||
if(pperiod && strstr(pperiod,"PROC"))
|
||||
plink->value.pv_link.pvlMask |= pvlOptFWD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -515,8 +491,6 @@ LOCAL long initDatabase(void)
|
||||
/* Find pointer to record instance */
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
rtnval = dbCommonInit(precord,1);
|
||||
if (status==0) status = rtnval;
|
||||
precord->rset = prset;
|
||||
if(!prset->init_record) continue;
|
||||
rtnval = (*prset->init_record)(precord,1);
|
||||
@@ -526,199 +500,6 @@ LOCAL long initDatabase(void)
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL void createLockSets(void)
|
||||
{
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbRecordNode *pdbRecordNode;
|
||||
dbCommon *precord;
|
||||
DBLINK *plink;
|
||||
short nset,maxnset,newset;
|
||||
int again;
|
||||
int anyChange;
|
||||
|
||||
nset = 0;
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
if(precord->lset) continue; /*already in a lock set*/
|
||||
/*
|
||||
* At First, assume record is in a different lockset
|
||||
* We shall see later if this assumption is incorrect.
|
||||
*/
|
||||
precord->lset = maxnset = ++nset;
|
||||
/*
|
||||
* Use the process active flag to eliminate traversing
|
||||
* cycles in the database "graph"
|
||||
*/
|
||||
precord->pact = TRUE; again = TRUE;
|
||||
while(again) {
|
||||
again = FALSE;
|
||||
for(link=0; (link<pdbRecDes->no_links&&!again) ; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
|
||||
pdbAddr = (DBADDR *)(plink->value.db_link.pdbAddr);
|
||||
|
||||
/* The current record is in a different lockset -IF-
|
||||
* 1. Input link
|
||||
* 2. Not Process Passive
|
||||
* 3. Not Maximize Severity
|
||||
* 4. Not An Array Operation - single element only
|
||||
*/
|
||||
if (pdbFldDes->field_type==DBF_INLINK
|
||||
&& ( !(plink->value.db_link.process_passive)
|
||||
&& !(plink->value.db_link.maximize_sevr))
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
|
||||
/*
|
||||
* Combine the lock sets of the current record with the
|
||||
* remote record pointed to by the link. (recursively)
|
||||
*/
|
||||
newset = makeSameSet(pdbAddr,precord->lset,&anyChange);
|
||||
|
||||
/*
|
||||
* Perform an iteration of the while-loop again
|
||||
* if we find that the record pointed to by
|
||||
* the link has its lockset set earlier. If
|
||||
* it has, set the current record's lockset to
|
||||
* that of the link's endpoint.
|
||||
*/
|
||||
if (newset!=precord->lset) {
|
||||
if(precord->lset==maxnset && maxnset==nset) nset--;
|
||||
precord->lset = newset;
|
||||
again = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
precord->pact = FALSE;
|
||||
}
|
||||
}
|
||||
anyChange = TRUE;
|
||||
while(anyChange) {
|
||||
anyChange = FALSE;
|
||||
createLockSetsExtraPass(&anyChange);
|
||||
}
|
||||
dbScanLockInit(nset);
|
||||
}
|
||||
|
||||
LOCAL void createLockSetsExtraPass(int *anyChange)
|
||||
{
|
||||
int link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbRecordNode *pdbRecordNode;
|
||||
dbCommon *precord;
|
||||
DBLINK *plink;
|
||||
int again;
|
||||
|
||||
for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); pdbRecDes;
|
||||
pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) {
|
||||
for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecDes->recList);
|
||||
pdbRecordNode;
|
||||
pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) {
|
||||
precord = pdbRecordNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
/*Prevent cycles in database graph*/
|
||||
precord->pact = TRUE; again = TRUE;
|
||||
while(again) {
|
||||
short newset;
|
||||
|
||||
again = FALSE;
|
||||
for(link=0; (link<pdbRecDes->no_links&&!again) ; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.db_link.pdbAddr);
|
||||
if(pdbFldDes->field_type==DBF_INLINK
|
||||
&& ( !(plink->value.db_link.process_passive)
|
||||
&& !(plink->value.db_link.maximize_sevr))
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
|
||||
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
|
||||
if (newset!=precord->lset) {
|
||||
precord->lset = newset;
|
||||
*anyChange = TRUE;
|
||||
again = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
precord->pact = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr, short lset,int *anyChange)
|
||||
{
|
||||
dbCommon *precord = paddr->precord;
|
||||
short link;
|
||||
dbRecDes *pdbRecDes;
|
||||
dbFldDes *pdbFldDes;
|
||||
DBLINK *plink;
|
||||
int again;
|
||||
|
||||
/*Prevent cycles in database graph*/
|
||||
if(precord->pact) return(((precord->lset<lset) ? precord->lset : lset));
|
||||
|
||||
/*
|
||||
* If the lock set of the link's endpoint is already set
|
||||
* to the lockset we are setting it to, return...
|
||||
*/
|
||||
if(lset == precord->lset) return(lset);
|
||||
|
||||
/*
|
||||
* If the record has an uninitialized lock set field,
|
||||
* we set it here.
|
||||
*/
|
||||
if(precord->lset == 0) precord->lset = lset;
|
||||
|
||||
/*
|
||||
* If the record is already in a lockset determined earlier,
|
||||
* return that lock set.
|
||||
*/
|
||||
if(precord->lset < lset) return(precord->lset);
|
||||
/* set pact to prevent cycles */
|
||||
precord->lset = lset; precord->pact = TRUE; again = TRUE;
|
||||
while(again) {
|
||||
again = FALSE;
|
||||
pdbRecDes = ((dbFldDes *)paddr->pfldDes)->pdbRecDes;
|
||||
for(link=0; link<pdbRecDes->no_links; link++) {
|
||||
DBADDR *pdbAddr;
|
||||
short newset;
|
||||
|
||||
pdbFldDes = pdbRecDes->papFldDes[pdbRecDes->link_ind[link]];
|
||||
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (DBADDR *)(plink->value.db_link.pdbAddr);
|
||||
if( pdbFldDes->field_type==DBF_INLINK
|
||||
&& ( !(plink->value.db_link.process_passive)
|
||||
&& !(plink->value.db_link.maximize_sevr) )
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
|
||||
if(newset != precord->lset) {
|
||||
precord->lset = newset;
|
||||
again = TRUE;
|
||||
*anyChange = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
precord->pact = FALSE;
|
||||
return(precord->lset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process database records at initialization if
|
||||
* their pini (process at init) field is set.
|
||||
@@ -742,7 +523,15 @@ LOCAL long initialProcess(void)
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int dbLoadDatabase(char *filename,char *path)
|
||||
{
|
||||
return(dbReadDatabase(&pdbbase,filename,path));
|
||||
}
|
||||
|
||||
/*Remaining code supplied by Bob Zieman*/
|
||||
#define MAX 256
|
||||
#define SAME 0
|
||||
|
||||
@@ -1095,12 +884,3 @@ LOCAL int getResourceTokenInternal(FILE *fp, char *pToken, unsigned maxToken)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dbLoadAscii(char *filename)
|
||||
{
|
||||
if(pdbbase) {
|
||||
epicsPrintf("Ascii file was already loaded\n");
|
||||
return(-1);
|
||||
}
|
||||
return(dbAsciiRead(&pdbbase,filename));
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
include "menuAlarmSevr.ascii"
|
||||
include "menuAlarmStat.ascii"
|
||||
include "menuArrType.ascii"
|
||||
include "menuCompress.ascii"
|
||||
include "menuFtype.ascii"
|
||||
include "menuIvoa.ascii"
|
||||
include "menuLinr.ascii"
|
||||
include "menuOmsl.ascii"
|
||||
include "menuPriority.ascii"
|
||||
include "menuScan.ascii"
|
||||
include "menuYesNo.ascii"
|
||||
11
src/db/menuGlobal.db
Normal file
11
src/db/menuGlobal.db
Normal file
@@ -0,0 +1,11 @@
|
||||
include "menuAlarmSevr.db"
|
||||
include "menuAlarmStat.db"
|
||||
include "menuArrType.db"
|
||||
include "menuCompress.db"
|
||||
include "menuFtype.db"
|
||||
include "menuIvoa.db"
|
||||
include "menuLinr.db"
|
||||
include "menuOmsl.db"
|
||||
include "menuPriority.db"
|
||||
include "menuScan.db"
|
||||
include "menuYesNo.db"
|
||||
240
src/db/recGbl.c
240
src/db/recGbl.c
@@ -111,27 +111,32 @@ void recGblRecSupError(long status,struct dbAddr *paddr,char *pcaller_name,
|
||||
{
|
||||
char buffer[200];
|
||||
struct dbCommon *precord;
|
||||
dbFldDes *pdbFldDes=(dbFldDes *)(paddr->pfldDes);
|
||||
dbRecDes *pdbRecDes = pdbFldDes->pdbRecDes;
|
||||
dbFldDes *pdbFldDes = 0;
|
||||
dbRecDes *pdbRecDes = 0;
|
||||
|
||||
if(paddr) pdbFldDes=(dbFldDes *)(paddr->pfldDes);
|
||||
if(pdbFldDes) pdbRecDes = pdbFldDes->pdbRecDes;
|
||||
buffer[0]=0;
|
||||
strcat(buffer,"Record Support Routine (");
|
||||
if(psupport_name)
|
||||
strcat(buffer,psupport_name);
|
||||
else
|
||||
strcat(buffer,"Unknown");
|
||||
strcat(buffer,") not available.\nRecord Type is ");
|
||||
strcat(buffer,pdbRecDes->name);
|
||||
if(paddr) { /* print process variable name */
|
||||
strcat(buffer,") not available.\n");
|
||||
if(pdbRecDes) {
|
||||
strcat(buffer,"Record Type is ");
|
||||
strcat(buffer,pdbRecDes->name);
|
||||
if(paddr) { /* print process variable name */
|
||||
precord=(struct dbCommon *)(paddr->precord);
|
||||
strcat(buffer,", PV is ");
|
||||
strcat(buffer,precord->name);
|
||||
strcat(buffer,".");
|
||||
strcat(buffer,pdbFldDes->name);
|
||||
strcat(buffer," ");
|
||||
strcat(buffer,"\n");
|
||||
}
|
||||
}
|
||||
if(pcaller_name) {
|
||||
strcat(buffer,"\nerror detected in routine: ");
|
||||
strcat(buffer,"error detected in routine: ");
|
||||
strcat(buffer,pcaller_name);
|
||||
}
|
||||
errMessage(status,buffer);
|
||||
@@ -164,7 +169,7 @@ void recGblGetPrec(struct dbAddr *paddr,long *precision)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void recGblGetGraphicDouble(struct dbAddr *paddr,struct dbr_grDouble *pgd)
|
||||
{
|
||||
dbFldDes *pdbFldDes=(dbFldDes *)(paddr->pfldDes);
|
||||
@@ -174,7 +179,7 @@ void recGblGetGraphicDouble(struct dbAddr *paddr,struct dbr_grDouble *pgd)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void recGblGetAlarmDouble(struct dbAddr *paddr,struct dbr_alDouble *pad)
|
||||
{
|
||||
pad->upper_alarm_limit = 0;
|
||||
@@ -184,7 +189,7 @@ void recGblGetAlarmDouble(struct dbAddr *paddr,struct dbr_alDouble *pad)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void recGblGetControlDouble(struct dbAddr *paddr,struct dbr_ctrlDouble *pcd)
|
||||
{
|
||||
dbFldDes *pdbFldDes=(dbFldDes *)(paddr->pfldDes);
|
||||
@@ -246,70 +251,6 @@ int recGblInitConstantLink(struct link *plink,short dbftype,void *pdest)
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
long recGblGetLinkValue(struct link *plink,void *pdbc,short dbrType,
|
||||
void *pdest,long *poptions,long *pnRequest)
|
||||
{
|
||||
struct dbCommon *precord = pdbc;
|
||||
long status=0;
|
||||
unsigned char pact;
|
||||
|
||||
pact = precord->pact;
|
||||
precord->pact = TRUE;
|
||||
switch (plink->type){
|
||||
case(CONSTANT):
|
||||
*pnRequest = 0;
|
||||
break;
|
||||
case(DB_LINK):
|
||||
status=dbGetLink(&(plink->value.db_link),
|
||||
precord,dbrType,pdest,poptions,pnRequest);
|
||||
if(status)
|
||||
recGblSetSevr(precord,LINK_ALARM,INVALID_ALARM);
|
||||
break;
|
||||
case(CA_LINK):
|
||||
status=dbCaGetLink(plink);
|
||||
if(status)
|
||||
recGblSetSevr(precord,LINK_ALARM,INVALID_ALARM);
|
||||
break;
|
||||
default:
|
||||
status=-1;
|
||||
recGblSetSevr(precord,SOFT_ALARM,INVALID_ALARM);
|
||||
}
|
||||
precord->pact = pact;
|
||||
return(status);
|
||||
}
|
||||
|
||||
long recGblPutLinkValue(struct link *plink,void *pdbc,short dbrType,
|
||||
void *psource,long *pnRequest)
|
||||
{
|
||||
struct dbCommon *precord = pdbc;
|
||||
long options=0;
|
||||
long status=0;
|
||||
unsigned char pact;
|
||||
|
||||
pact = precord->pact;
|
||||
precord->pact = TRUE;
|
||||
switch (plink->type){
|
||||
case(CONSTANT):
|
||||
break;
|
||||
case(DB_LINK):
|
||||
status=dbPutLink(&(plink->value.db_link),
|
||||
precord,dbrType,psource,*pnRequest);
|
||||
if(status)
|
||||
recGblSetSevr(precord,LINK_ALARM,INVALID_ALARM);
|
||||
break;
|
||||
case(CA_LINK):
|
||||
status = dbCaPutLink(plink, &options, pnRequest);
|
||||
if(status)
|
||||
recGblSetSevr(precord,LINK_ALARM,INVALID_ALARM);
|
||||
break;
|
||||
default:
|
||||
status=-1;
|
||||
recGblSetSevr(precord,SOFT_ALARM,INVALID_ALARM);
|
||||
}
|
||||
precord->pact = pact;
|
||||
return(status);
|
||||
}
|
||||
|
||||
unsigned short recGblResetAlarms(void *precord)
|
||||
{
|
||||
struct dbCommon *pdbc = precord;
|
||||
@@ -342,10 +283,15 @@ unsigned short recGblResetAlarms(void *precord)
|
||||
void recGblFwdLink(void *precord)
|
||||
{
|
||||
struct dbCommon *pdbc = precord;
|
||||
static short fwdLinkValue = 1;
|
||||
|
||||
if(pdbc->flnk.type==DB_LINK ) {
|
||||
struct dbAddr *paddr = pdbc->flnk.value.db_link.pdbAddr;
|
||||
struct dbAddr *paddr = pdbc->flnk.value.pv_link.pvt;
|
||||
dbScanPassive(precord,paddr->precord);
|
||||
} else
|
||||
if((pdbc->flnk.type==CA_LINK)
|
||||
&& (pdbc->flnk.value.pv_link.pvlMask & pvlOptFWD)) {
|
||||
dbCaPutLink(&pdbc->flnk,DBR_SHORT,&fwdLinkValue,1);
|
||||
}
|
||||
/*Handle dbPutFieldNotify record completions*/
|
||||
if(pdbc->ppn) dbNotifyCompletion(pdbc);
|
||||
@@ -358,18 +304,14 @@ void recGblFwdLink(void *precord)
|
||||
pdbc->putf = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void recGblGetTimeStamp(void* prec)
|
||||
{
|
||||
struct dbCommon* pr = (struct dbCommon*)prec;
|
||||
long nRequest=1;
|
||||
long options=0;
|
||||
|
||||
if(pr->tsel.type!=CONSTANT)
|
||||
{
|
||||
recGblGetLinkValue(&(pr->tsel),(void*)pr,
|
||||
DBR_SHORT,&(pr->tse),&options,&nRequest);
|
||||
|
||||
dbGetLink(&(pr->tsel), DBR_SHORT,&(pr->tse),0,0);
|
||||
TSgetTimeStamp((int)pr->tse,(struct timespec*)&pr->time);
|
||||
}
|
||||
else
|
||||
@@ -383,6 +325,14 @@ static void getMaxRangeValues(field_type,pupper_limit,plower_limit)
|
||||
double *plower_limit;
|
||||
{
|
||||
switch(field_type){
|
||||
case(DBF_CHAR):
|
||||
*pupper_limit = -128.0;
|
||||
*plower_limit = 127.0;
|
||||
break;
|
||||
case(DBF_UCHAR):
|
||||
*pupper_limit = 255.0;
|
||||
*plower_limit = 0.0;
|
||||
break;
|
||||
case(DBF_SHORT):
|
||||
*pupper_limit = (double)SHRT_MAX;
|
||||
*plower_limit = (double)SHRT_MIN;
|
||||
@@ -412,131 +362,3 @@ static void getMaxRangeValues(field_type,pupper_limit,plower_limit)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fast link initialization routines */
|
||||
|
||||
/*
|
||||
* String if bad database request type chosen
|
||||
*/
|
||||
static char *bad_in_req_type = "recGblInitFastInLink: Bad database request type";
|
||||
static char *bad_out_req_type = "recGblInitFastInLink: Bad database request type";
|
||||
|
||||
/*
|
||||
* Initialize fast input links.
|
||||
*/
|
||||
long recGblInitFastInLink(
|
||||
struct link *plink,
|
||||
void *precord,
|
||||
short dbrType,
|
||||
char *fld_name)
|
||||
{
|
||||
long status = 0;
|
||||
struct db_link *pdb_link = &(plink->value.db_link);
|
||||
struct dbAddr *pdb_addr = (struct dbAddr *) (pdb_link->pdbAddr);
|
||||
long (*cvt_func)();
|
||||
|
||||
/*
|
||||
* Check for CA_LINK
|
||||
*/
|
||||
if (plink->type == PV_LINK) {
|
||||
status = dbCaAddInlink(plink, (struct dbCommon *) precord, fld_name);
|
||||
return(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return if not database link (A constant link, for example)
|
||||
*/
|
||||
if (plink->type != DB_LINK)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* Check for legal conversion range...
|
||||
*/
|
||||
if ((pdb_addr->field_type < DBF_STRING) ||
|
||||
(pdb_addr->field_type > DBF_DEVICE) ||
|
||||
( dbrType < DBR_STRING) ||
|
||||
( dbrType > DBR_ENUM)) {
|
||||
|
||||
pdb_link->conversion = cvt_dummy;
|
||||
recGblDbaddrError(S_db_badDbrtype, pdb_addr, bad_in_req_type);
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup conversion function
|
||||
*/
|
||||
cvt_func = dbFastGetConvertRoutine[pdb_addr->field_type][dbrType];
|
||||
|
||||
if (cvt_func == NULL) {
|
||||
pdb_link->conversion = cvt_dummy;
|
||||
recGblDbaddrError(S_db_badDbrtype, pdb_addr, bad_in_req_type);
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put function it into conversion field (Run Time Link)
|
||||
*/
|
||||
pdb_link->conversion = cvt_func;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize fast output links.
|
||||
*/
|
||||
long recGblInitFastOutLink(
|
||||
struct link *plink,
|
||||
void *precord,
|
||||
short dbrType,
|
||||
char *fld_name)
|
||||
{
|
||||
long status = 0;
|
||||
struct db_link *pdb_link = &(plink->value.db_link);
|
||||
struct dbAddr *pdb_addr = (struct dbAddr *) (pdb_link->pdbAddr);
|
||||
long (*cvt_func)();
|
||||
|
||||
/*
|
||||
* Check for CA_LINK
|
||||
*/
|
||||
if (plink->type == PV_LINK) {
|
||||
status = dbCaAddOutlink(plink, (struct dbCommon *) precord, fld_name);
|
||||
return(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return if not database link (A constant link, for example)
|
||||
*/
|
||||
if (plink->type != DB_LINK)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* Check for legal conversion range...
|
||||
*/
|
||||
if ((pdb_addr->field_type < DBF_STRING) ||
|
||||
(pdb_addr->field_type > DBF_DEVICE) ||
|
||||
( dbrType < DBR_STRING) ||
|
||||
( dbrType > DBR_ENUM)) {
|
||||
|
||||
pdb_link->conversion = cvt_dummy;
|
||||
recGblDbaddrError(S_db_badDbrtype, pdb_addr, bad_out_req_type);
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
/*
|
||||
* Lookup conversion function
|
||||
*/
|
||||
cvt_func = dbFastPutConvertRoutine[dbrType][pdb_addr->field_type];
|
||||
|
||||
if (cvt_func == NULL) {
|
||||
pdb_link->conversion = cvt_dummy;
|
||||
recGblDbaddrError(S_db_badDbrtype, pdb_addr, bad_out_req_type);
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put function it into conversion field (Run Time Link)
|
||||
*/
|
||||
pdb_link->conversion = cvt_func;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
85
src/db/recGbl.h
Normal file
85
src/db/recGbl.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* recGbl.h */
|
||||
/* Record Global
|
||||
* Author: Marty Kraimer
|
||||
* Date: 13Jun95
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 12Jun95 mrk Removed from recSup.h
|
||||
*/
|
||||
#ifndef INCrecGblh
|
||||
#define INCrecGblh 1
|
||||
|
||||
|
||||
#ifdef vxWorks
|
||||
#ifndef INCdbCommonh
|
||||
#include <dbCommon.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* One ABSOLUTELY must include dbAccess.h before the
|
||||
* definitions in this file
|
||||
*/
|
||||
|
||||
#ifndef INCdbAccessh
|
||||
#include <dbAccess.h>
|
||||
#endif
|
||||
#ifndef INCalarmh
|
||||
#include <alarm.h>
|
||||
#endif
|
||||
#include <dbFldTypes.h>
|
||||
|
||||
/*************************************************************************
|
||||
* The following must match definitions in global menu definitions
|
||||
*************************************************************************/
|
||||
|
||||
/* GBL_IVOA */
|
||||
#define IVOA_CONTINUE 0
|
||||
#define IVOA_NO_OUTPUT 1
|
||||
#define IVOA_OUTPUT_IVOV 2
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
#define recGblSetSevr(PREC,NSTA,NSEV) \
|
||||
(\
|
||||
((PREC)->nsev<(NSEV))\
|
||||
? ((PREC)->nsta=(NSTA),(PREC)->nsev=(NSEV),TRUE)\
|
||||
: FALSE\
|
||||
)
|
||||
|
||||
|
||||
/* Global Record Support Routines*/
|
||||
void recGblDbaddrError(long status, struct dbAddr *paddr, char *pcaller_name);
|
||||
void recGblRecordError(long status, void *precord, char *pcaller_name);
|
||||
void recGblRecSupError(long status, struct dbAddr *paddr, char *pcaller_name, char *psupport_name);
|
||||
void recGblGetGraphicDouble(struct dbAddr *paddr, struct dbr_grDouble *pgd);
|
||||
void recGblGetControlDouble(struct dbAddr *paddr, struct dbr_ctrlDouble *pcd);
|
||||
void recGblGetAlarmDouble(struct dbAddr *paddr, struct dbr_alDouble *pad);
|
||||
void recGblGetPrec(struct dbAddr *paddr, long *pprecision);
|
||||
int recGblInitConstantLink(struct link *plink,short dbftype,void *pdest);
|
||||
unsigned short recGblResetAlarms(void *precord);
|
||||
void recGblFwdLink(void *precord);
|
||||
void recGblGetTimeStamp(void *precord);
|
||||
#endif /*INCrecGblh*/
|
||||
106
src/db/recSup.h
Normal file
106
src/db/recSup.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* recSup.h
|
||||
* Record Support
|
||||
* Author: Marty Kraimer
|
||||
* Date: 6-1-90
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 11-11-91 jba Added include dbCommon.h,recGblSetSevr,recGblResetSevr
|
||||
* .02 12-18-91 jba Changed caddr_t to void *
|
||||
* .03 03-04-92 jba Added include for dbAccess.h
|
||||
* .04 05-18-92 rcz removed extern
|
||||
* .05 05-18-92 rcz Changed macro "GET_PRSET(" to "GET_PRSET(precSup,"
|
||||
* .06 05-18-92 rcz New database access (removed extern)
|
||||
* .07 07-16-92 jba Added macro recGblFwdLink
|
||||
* .08 07-16-92 jba changed VALID_ALARM to INVALID_ALARM
|
||||
* .09 08-10-92 jba added #defines for SIMM processing
|
||||
* .10 08-11-92 jba added DB_INTEREST masks
|
||||
* .11 08-13-92 jba added prototype for recGblGetAlarmDouble,
|
||||
* .12 08-14-92 jba added prototypes recGblGetLinkValue,recGblPutLinkValue
|
||||
* .13 09-15-92 jba added vxWorks ifdef
|
||||
* .14 -7-27-93 mrk remove recGblResetSevr add recGblResetAlarms
|
||||
* .15 03-18-94 mcn added fast link macros and prototypes
|
||||
* .16 06-13-95 mrk moved recGbl defs to recGbl.h
|
||||
*/
|
||||
|
||||
#ifndef INCrecSuph
|
||||
#define INCrecSuph 1
|
||||
#include <recGbl.h>
|
||||
typedef long (*RECSUPFUN) (); /* ptr to record support function*/
|
||||
|
||||
struct rset { /* record support entry table */
|
||||
long number; /*number of support routines */
|
||||
RECSUPFUN report; /*print report */
|
||||
RECSUPFUN init; /*init support */
|
||||
RECSUPFUN init_record; /*init record */
|
||||
RECSUPFUN process; /*process record */
|
||||
RECSUPFUN special; /*special processing */
|
||||
RECSUPFUN get_value; /*get value field */
|
||||
RECSUPFUN cvt_dbaddr; /*cvt dbAddr */
|
||||
RECSUPFUN get_array_info;
|
||||
RECSUPFUN put_array_info;
|
||||
RECSUPFUN get_units;
|
||||
RECSUPFUN get_precision;
|
||||
RECSUPFUN get_enum_str; /*get string from enum item*/
|
||||
RECSUPFUN get_enum_strs; /*get all enum strings */
|
||||
RECSUPFUN put_enum_str; /*put string from enum item*/
|
||||
RECSUPFUN get_graphic_double;
|
||||
RECSUPFUN get_control_double;
|
||||
RECSUPFUN get_alarm_double;
|
||||
};
|
||||
#define RSETNUMBER ( (sizeof(struct rset) - sizeof(long))/sizeof(RECSUPFUN) )
|
||||
|
||||
#define S_rec_noRSET (M_recSup| 1) /*Missing record support entry table*/
|
||||
#define S_rec_noSizeOffset (M_recSup| 2) /*Missing SizeOffset Routine*/
|
||||
#define S_rec_outMem (M_recSup| 3) /*Out of Memory*/
|
||||
|
||||
|
||||
/* Definition os structure for routine get_value */
|
||||
|
||||
struct valueDes {
|
||||
long field_type;
|
||||
long no_elements;
|
||||
void * pvalue;
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* report(FILE fp,void *precord);
|
||||
* init();
|
||||
* init_record(precord,pass);
|
||||
* process(void *precord);
|
||||
* special(struct dbAddr *paddr, after);
|
||||
* get_value(precord,struct valueDes *p);
|
||||
* cvt_dbaddr(struct dbAddr *paddr);
|
||||
* get_array_info(paddr,long *no_elements,long *offset);
|
||||
* put_array_info(paddr,nNew);
|
||||
* get_units(paddr,char units[8]);
|
||||
* get_precision(struct dbAddr *paddr,long *precision);
|
||||
* get_enum_str(paddr,pbuffer);
|
||||
* get_enum_strs(paddr,struct dbr_enumStrs *p);
|
||||
* put_enum_str(paddr,pbuffer);
|
||||
* get_graphic_double(paddr,struct dbr_grDouble *p);
|
||||
* get_control_double(paddr,struct dbr_ctrlDouble *p);
|
||||
* get_alarm_double(paddr,struct dbr_ctrlDouble *p);
|
||||
***********************************************************************/
|
||||
#endif /*INCrecSuph*/
|
||||
224
src/db/task_params.h
Normal file
224
src/db/task_params.h
Normal file
@@ -0,0 +1,224 @@
|
||||
/* task_params.h */
|
||||
/* $Id$ */
|
||||
|
||||
/* Parameters for tasks on IOC */
|
||||
/*
|
||||
* Authors: Andy Kozubal, Jeff Hill, and Bob Dalesio
|
||||
* Date: 2-24-89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 07-23-91 ges Add time-stamp task.
|
||||
* .02 09-12-91 joh stack sizes increased for v5 vxWorks.
|
||||
* .03 10-24-91 lrd Increased stack sizes for scan tasks
|
||||
* .04 12-12-91 joh Increased stack size for the
|
||||
* wfDoneTask
|
||||
* .05 12-18-91 mrk Added callback task priorities
|
||||
* Changed def of PERIODSCAN_PRI and SEQUENCER_PRI
|
||||
* Shortened length of task names
|
||||
* .06 12-18-91 jba Global change of WDSCAN to TASKWD
|
||||
* .07 01-21-92 rcz Increased all stack sizes by 1000 for V5
|
||||
* .08 01-21-92 jrw added the GPIB & BB driver task info
|
||||
* .09 01-04-92 jba Added callback task priorities
|
||||
* .10 03-16-92 jrw added BB rx and tx specific task info
|
||||
* .11 05-22-92 lrd added the allen-bradley binary input Change of State scanner
|
||||
* .12 08-26-92 joh added xy 240 stuff
|
||||
* .13 08-26-92 joh added FP to CA repeater and on line to be safe
|
||||
* .14 02-16-92 joh removed historical items
|
||||
* .15 11-19-93 joh moved CA client priority up by one notch
|
||||
* .16 09-13-93 joh incresed CA on line beacon maximum delay
|
||||
* to 60 sec
|
||||
* .17 03-18-94 mcn added entries for breakpoint tasks
|
||||
* $Log$
|
||||
* Revision 1.1 1996/01/25 21:13:29 mrk
|
||||
* moved includes; .ascii=> .db; path changes
|
||||
*
|
||||
* Revision 1.27 1995/11/29 19:27:59 jhill
|
||||
* added $Log$
|
||||
* added Revision 1.1 1996/01/25 21:13:29 mrk
|
||||
* added moved includes; .ascii=> .db; path changes
|
||||
* added
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INCtaskLibh
|
||||
#include <taskLib.h>
|
||||
#endif
|
||||
|
||||
#define VXTASKIDSELF 0
|
||||
|
||||
/* Task Names */
|
||||
#define IOEVENTSCAN_NAME "scanIo"
|
||||
#define EVENTSCAN_NAME "scanEvent"
|
||||
#define SCANONCE_NAME "scanOnce"
|
||||
#define SMCMD_NAME "smCommand"
|
||||
#define SMRESP_NAME "smResponse"
|
||||
#define ABDONE_NAME "abDone"
|
||||
#define ABSCAN_NAME "abScan"
|
||||
#define ABCOS_NAME "abBiCosScanner"
|
||||
#define MOMENTARY_NAME "momentary"
|
||||
#define WFDONE_NAME "wfDone"
|
||||
#define SEQUENCER_NAME "sequencer"
|
||||
#define BKPT_CONT_NAME "bkptCont"
|
||||
#define SCANNER_NAME "scanner"
|
||||
#define REQ_SRVR_NAME "CA TCP"
|
||||
#define CA_CLIENT_NAME "CA client"
|
||||
#define CA_EVENT_NAME "CA event"
|
||||
#define CAST_SRVR_NAME "CA UDP"
|
||||
#define CA_REPEATER_NAME "CA repeater"
|
||||
#define CA_ONLINE_NAME "CA online"
|
||||
#define TASKWD_NAME "taskwd"
|
||||
#define SMIOTEST_NAME "smInout"
|
||||
#define SMROTTEST_NAME "smRotate"
|
||||
#define EVENT_PEND_NAME "event task"
|
||||
#define TIMESTAMP_NAME "timeStamp"
|
||||
#define XY240_NAME "xy 240 scan"
|
||||
#define GPIBLINK_NAME "gpibLink"
|
||||
#define BBLINK_NAME "bbLinkTask"
|
||||
#define BBTXLINK_NAME "bbTx"
|
||||
#define BBRXLINK_NAME "bbRx"
|
||||
#define BBWDTASK_NAME "bbwd"
|
||||
#define EPICSPRINT_NAME "epicsPrint"
|
||||
#define LOG_RESTART_NAME "logRestart"
|
||||
|
||||
/* Task priorities */
|
||||
#define EPICSPRINT_PRI 70
|
||||
#define SCANONCE_PRI 65 /* scan one time */
|
||||
/*DO NOT RUN ANY RECORD PROCESSING TASKS AT HIGHER PRIORITY THAN _netTask=50*/
|
||||
#define CALLBACK_PRI_LOW 65 /* callback task - generall callback task */
|
||||
#define CALLBACK_PRI_MEDIUM 57 /* callback task - generall callback task */
|
||||
#define CALLBACK_PRI_HIGH 51 /* callback task - generall callback task */
|
||||
#define IOEVENTSCAN_PRI 51 /* I/O Event Scanner - Runs on I/O interrupt */
|
||||
#define EVENTSCAN_PRI 52 /* Event Scanner - Runs on a global event */
|
||||
#define TIMESTAMP_PRI 32 /* Time-stamp task - interrupt */
|
||||
#define SMCMD_PRI 42 /* Stepper Motor Command Task - Waits for cmds */
|
||||
#define SMRESP_PRI 43 /* Stepper Motor Resp Task - Waits for resps */
|
||||
#define ABCOS_PRI 43 /* Allen-Bradley Binary Input COS io_event wakeup */
|
||||
#define ABDONE_PRI 44 /* Allen-Bradley Resp Task - Interrupt Driven */
|
||||
#define ABSCAN_PRI 45 /* Allen-Bradley Scan Task - Base Rate .1 secs */
|
||||
#define BBLINK_PRI 46
|
||||
#define BBWDTASK_PRI 45 /* BitBus watchdog task */
|
||||
#define BBRXLINK_PRI 46 /* BitBus link task */
|
||||
#define BBTXLINK_PRI 47 /* BitBus link task */
|
||||
#define GPIBLINK_PRI 47 /* GPIB link task */
|
||||
#define MOMENTARY_PRI 48 /* Momentary output - posted from watchdog */
|
||||
#define WFDONE_PRI 49 /* Waveform Task - Base Rate of .1 second */
|
||||
#define PERIODSCAN_PRI 59 /* Periodic Scanners - Slowest rate */
|
||||
#define SEQUENCER_PRI 70
|
||||
#define XY240_PRI 111 /* xy 240 dio scanner */
|
||||
#define DB_CA_PRI 100
|
||||
#define SCANNER_PRI 150
|
||||
#define REQ_SRVR_PRI 181 /* Channel Access TCP request server*/
|
||||
#define CA_CLIENT_PRI 180 /* Channel Access clients */
|
||||
#define CA_REPEATER_PRI 181 /* Channel Access repeater */
|
||||
#define CAST_SRVR_PRI 182 /* Channel Access broadcast server */
|
||||
#define CA_ONLINE_PRI 183 /* Channel Access server online notify */
|
||||
#define TASKWD_PRI 200 /* Watchdog Scan Task - runs every 6 seconds */
|
||||
#define SMIOTEST_PRI 205 /* Stepper Mtr in/out test - runs every .1 sec */
|
||||
#define SMROTTEST_PRI 205 /* Stepper Mtr rotate test - runs every .1 sec */
|
||||
#define LOG_RESTART_PRI 200 /* Log server connection watch dog */
|
||||
|
||||
/* Task delay times (seconds) */
|
||||
#define TASKWD_DELAY 6
|
||||
|
||||
/* Task delay times (tics) */
|
||||
#define ABSCAN_RATE (sysClkRateGet()/6)
|
||||
#define SEQUENCER_DELAY (sysClkRateGet()/5)
|
||||
#define SCANNER_DELAY (sysClkRateGet()/5)
|
||||
#define CA_ONLINE_DELAY (sysClkRateGet()*15)
|
||||
#define LOG_RESTART_DELAY (sysClkRateGet()*30)
|
||||
|
||||
/* Task creation options */
|
||||
#define EPICSPRINT_OPT VX_FP_TASK
|
||||
#define IOEVENTSCAN_OPT VX_FP_TASK
|
||||
#define EVENTSCAN_OPT VX_FP_TASK
|
||||
#define SCANONCE_OPT VX_FP_TASK
|
||||
#define CALLBACK_OPT VX_FP_TASK
|
||||
#define SMCMD_OPT VX_FP_TASK
|
||||
#define SMRESP_OPT VX_FP_TASK
|
||||
#define ABDONE_OPT VX_FP_TASK
|
||||
#define ABCOS_OPT VX_FP_TASK
|
||||
#define ABSCAN_OPT VX_FP_TASK
|
||||
#define MOMENTARY_OPT VX_FP_TASK
|
||||
#define PERIODSCAN_OPT VX_FP_TASK
|
||||
#define WFDONE_OPT VX_FP_TASK
|
||||
#define SEQUENCER_OPT VX_FP_TASK | VX_STDIO
|
||||
#define BKPT_CONT_OPT VX_FP_TASK
|
||||
#define SCANNER_OPT VX_FP_TASK
|
||||
#define REQ_SRVR_OPT VX_FP_TASK
|
||||
#define CAST_SRVR_OPT VX_FP_TASK
|
||||
#define CA_CLIENT_OPT VX_FP_TASK
|
||||
#define CA_REPEATER_OPT VX_FP_TASK
|
||||
#define CA_ONLINE_OPT VX_FP_TASK
|
||||
#define TASKWD_OPT VX_FP_TASK
|
||||
#define SMIOTEST_OPT VX_FP_TASK
|
||||
#define SMROTTEST_OPT VX_FP_TASK
|
||||
#define EVENT_PEND_OPT VX_FP_TASK
|
||||
#define TIMESTAMP_OPT VX_FP_TASK
|
||||
#define GPIBLINK_OPT VX_FP_TASK|VX_STDIO
|
||||
#define BBLINK_OPT VX_FP_TASK|VX_STDIO
|
||||
#define BBTXLINK_OPT VX_FP_TASK|VX_STDIO
|
||||
#define BBRXLINK_OPT VX_FP_TASK|VX_STDIO
|
||||
#define BBWDTASK_OPT VX_FP_TASK|VX_STDIO
|
||||
#define DB_CA_OPT (VX_FP_TASK | VX_STDIO)
|
||||
#define XY_240_OPT (0) /* none */
|
||||
#define LOG_RESTART_OPT (VX_FP_TASK)
|
||||
|
||||
|
||||
/* Task stack sizes */
|
||||
#define EPICSPRINT_STACK 4000
|
||||
#define EVENTSCAN_STACK 10000
|
||||
#define SCANONCE_STACK 10000
|
||||
#define CALLBACK_STACK 10000
|
||||
#define SMCMD_STACK 3000
|
||||
#define SMRESP_STACK 3000
|
||||
#define ABCOS_STACK 3000
|
||||
#define ABDONE_STACK 3000
|
||||
#define ABSCAN_STACK 3000
|
||||
#define MOMENTARY_STACK 2000
|
||||
#define PERIODSCAN_STACK 10000
|
||||
#define WFDONE_STACK 9000
|
||||
#define SEQUENCER_STACK 5096
|
||||
#define BKPT_CONT_STACK 10000
|
||||
#define SCANNER_STACK 3048
|
||||
#define RSP_SRVR_STACK 5096
|
||||
#define REQ_SRVR_STACK 5096
|
||||
#define CAST_SRVR_STACK 5096
|
||||
#define CA_CLIENT_STACK 5096
|
||||
#define CA_REPEATER_STACK 5096
|
||||
#define CA_ONLINE_STACK 3048
|
||||
#define TASKWD_STACK 2000 /* moved up by 1000 for v5 vxWorks */
|
||||
#define SMIOTEST_STACK 2000
|
||||
#define SMROTTEST_STACK 2000
|
||||
#define EVENT_PEND_STACK 5096
|
||||
#define TIMESTAMP_STACK 4000
|
||||
#define GPIBLINK_STACK 5000
|
||||
#define BBLINK_STACK 5000
|
||||
#define BBRXLINK_STACK 5000
|
||||
#define BBTXLINK_STACK 5000
|
||||
#define BBWDTASK_STACK 5000
|
||||
#define DB_CA_STACK 10000
|
||||
#define XY_240_STACK 4096
|
||||
#define LOG_RESTART_STACK 0x1000
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user