Compare commits
44 Commits
R3.14.10-p
...
R3.14.10-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c73bf9545d | ||
|
|
917937b22f | ||
|
|
fb1d649290 | ||
|
|
227af040b0 | ||
|
|
078f919296 | ||
|
|
82e26e2d79 | ||
|
|
442633fc87 | ||
|
|
84f56e57f4 | ||
|
|
dff447028f | ||
|
|
1ba1909bdb | ||
|
|
2d5497fa07 | ||
|
|
32616ba5fa | ||
|
|
37f4457c03 | ||
|
|
896223e819 | ||
|
|
8b8f2bd0ed | ||
|
|
bc80fd0e35 | ||
|
|
6d99d6dd05 | ||
|
|
2e35ee986e | ||
|
|
9f71cf22cd | ||
|
|
fa161e4e5a | ||
|
|
506b303c3c | ||
|
|
1269897998 | ||
|
|
21e8912031 | ||
|
|
7f96b9c0fc | ||
|
|
91d9fdbda8 | ||
|
|
238ab41ba1 | ||
|
|
516a2cbf41 | ||
|
|
aa9b36d7f9 | ||
|
|
efa69eda5c | ||
|
|
7850ab921a | ||
|
|
c0dd8a788b | ||
|
|
65c2e51849 | ||
|
|
5d6b223229 | ||
|
|
1be79a4911 | ||
|
|
82abd96fc9 | ||
|
|
a149390015 | ||
|
|
2bf9959e11 | ||
|
|
a6f4c7efd9 | ||
|
|
c19d8848ed | ||
|
|
934f55b9cc | ||
|
|
3cc996a296 | ||
|
|
c0084256bd | ||
|
|
ba7b648bf8 | ||
|
|
92b991c857 |
@@ -1,5 +1,5 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
@@ -19,17 +19,25 @@
|
||||
|
||||
BASE_3_14=YES
|
||||
|
||||
# EPICS_VERSION must be a number >0 and <256
|
||||
EPICS_VERSION = 3
|
||||
|
||||
# EPICS_REVISION must be a number >=0 and <256
|
||||
EPICS_REVISION = 14
|
||||
|
||||
# This part may contain letters, eg 0beta1
|
||||
EPICS_MODIFICATION = 10pre1
|
||||
# EPICS_MODIFICATION must be a number >=0 and <256
|
||||
EPICS_MODIFICATION = 10
|
||||
|
||||
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
|
||||
# Not included if zero
|
||||
EPICS_PATCH_LEVEL = 0
|
||||
|
||||
# This will be -CVS or empty at an official release point
|
||||
EPICS_CVS_SNAPSHOT=
|
||||
# This will end in -CVS between official releases
|
||||
#EPICS_CVS_SNAPSHOT=-CVS
|
||||
#EPICS_CVS_SNAPSHOT=-pre1
|
||||
#EPICS_CVS_SNAPSHOT=-pre1-CVS
|
||||
EPICS_CVS_SNAPSHOT=-RC1
|
||||
#EPICS_CVS_SNAPSHOT=-RC1-CVS
|
||||
#EPICS_CVS_SNAPSHOT=
|
||||
|
||||
# No changes should be needed below here
|
||||
|
||||
@@ -268,17 +268,13 @@ endif # RANLIB
|
||||
|
||||
$(DLL_LINK_LIBNAME): $(LIBRARY_OBJS) $(LIBRARY_RESS) $(SHRLIB_DEPLIBS)
|
||||
|
||||
$(DLL_LINK_LIBNAME):$(SHRLIB_PREFIX)%.lib:
|
||||
@$(RM) $@
|
||||
$(LINK.shrlib)
|
||||
$(MT_DLL_COMMAND)
|
||||
|
||||
$(SHRLIBNAME): $(LIBRARY_OBJS) $(LIBRARY_RESS) $(SHRLIB_DEPLIBS)
|
||||
|
||||
ifneq ($(SHRLIB_SUFFIX),.dll)
|
||||
$(SHRLIBNAME):$(SHRLIB_PREFIX)%$(SHRLIB_SUFFIX):
|
||||
@$(RM) $@
|
||||
$(LINK.shrlib)
|
||||
$(MT_DLL_COMMAND)
|
||||
endif
|
||||
|
||||
$(LOADABLE_SHRLIBNAME): $(LIBRARY_OBJS) $(LIBRARY_RESS) $(SHRLIB_DEPLIBS)
|
||||
|
||||
@@ -438,6 +434,15 @@ $(INSTALL_TEMPLATES_SUBDIR)/%: %
|
||||
@echo "Installing $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
ifeq ($(SHRLIB_SUFFIX),.dll)
|
||||
ifeq ($(SHARED_LIBRARIES),YES)
|
||||
$(LIB_PREFIX)%$(LIB_SUFFIX) $(SHRLIB_PREFIX)%$(SHRLIB_SUFFIX):
|
||||
@$(RM) $(LIB_PREFIX)$*$(LIB_SUFFIX) $(SHRLIB_PREFIX)$*$(SHRLIB_SUFFIX)
|
||||
$(LINK.shrlib)
|
||||
$(MT_DLL_COMMAND)
|
||||
endif
|
||||
endif
|
||||
|
||||
-include $(CONFIG)/RULES_EXPAND
|
||||
|
||||
.PRECIOUS: %.i %.o %.c %.nm %.cpp %.cc
|
||||
|
||||
@@ -104,6 +104,10 @@ CODE_CXXFLAGS =
|
||||
CONFORM_CFLAGS_STRICT =
|
||||
CONFORM_CXXFLAGS_STRICT =
|
||||
|
||||
#--------------------------------------------------
|
||||
# Override the usual RTEMS verbosity from ar
|
||||
ARFLAGS = rc
|
||||
|
||||
#--------------------------------------------------
|
||||
# Command-line input support
|
||||
LDLIBS_LIBTECLA = -ltecla_r -lncurses
|
||||
|
||||
25
configure/os/CONFIG.Common.linux-xscale_be
Normal file
25
configure/os/CONFIG.Common.linux-xscale_be
Normal file
@@ -0,0 +1,25 @@
|
||||
# CONFIG.Common.linux-xscale_be
|
||||
#
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for linux-xscale_be (big-endian) target builds.
|
||||
# This target has been tested with the MOXA UC-7408-LX Plus.
|
||||
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.linux-xscale_be
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = xscale
|
||||
|
||||
#
|
||||
# The vendor's tool chain needs to be located here
|
||||
#
|
||||
GNU_DIR=/usr/local/xscale_be
|
||||
|
||||
ifeq ($(BUILD_CLASS),CROSS)
|
||||
VALID_BUILDS = Ioc
|
||||
GNU_TARGET = xscale_be
|
||||
CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET))
|
||||
endif
|
||||
14
configure/os/CONFIG.Common.vxWorks-486-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-486-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-486-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-486-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-486-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-486
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
14
configure/os/CONFIG.Common.vxWorks-68040lc-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-68040lc-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-68040lc-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-68040lc-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-68040lc-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-68040lc
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
14
configure/os/CONFIG.Common.vxWorks-68060-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-68060-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-68060-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-68060-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-68060-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-68060
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
14
configure/os/CONFIG.Common.vxWorks-mpc8540-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-mpc8540-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-mpc8540-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-mpc8540-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-mpc8540-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-mpc8540
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
14
configure/os/CONFIG.Common.vxWorks-pentium-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-pentium-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-pentium-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-pentium-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-pentium-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-pentium
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
14
configure/os/CONFIG.Common.vxWorks-ppc603-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-ppc603-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-ppc603-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-ppc603-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc603-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
14
configure/os/CONFIG.Common.vxWorks-ppc603_long-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-ppc603_long-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-ppc603_long-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-ppc603_long-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc603_long-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603_long
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
14
configure/os/CONFIG.Common.vxWorks-ppc604-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-ppc604-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-ppc604-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-ppc604-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc604-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
14
configure/os/CONFIG.Common.vxWorks-ppc604_altivec-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-ppc604_altivec-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-ppc604_altivec-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-ppc604_altivec-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc604_altivec-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_altivec
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
14
configure/os/CONFIG.Common.vxWorks-ppc604_long-debug
Normal file
14
configure/os/CONFIG.Common.vxWorks-ppc604_long-debug
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.vxWorks-ppc604_long-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for vxWorks-ppc604_long-debug target archs
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc604_long-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include definitions common to all vxWorks archs
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
13
configure/os/CONFIG.cygwin-x86.cygwin-x86-debug
Normal file
13
configure/os/CONFIG.cygwin-x86.cygwin-x86-debug
Normal file
@@ -0,0 +1,13 @@
|
||||
# CONFIG.cygwin-x86.cygwin-x86-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for cygwin-x86 host - cygwin-x86-debug target build
|
||||
# Sites may override these definitions in CONFIG_SITE.cygwin-x86.cygwin-x86-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.cygwin-x86
|
||||
include $(CONFIG)/os/CONFIG.cygwin-x86.cygwin-x86
|
||||
|
||||
CROSS_OPT = NO
|
||||
17
configure/os/CONFIG.darwin-ppc.darwin-ppc-debug
Normal file
17
configure/os/CONFIG.darwin-ppc.darwin-ppc-debug
Normal file
@@ -0,0 +1,17 @@
|
||||
# CONFIG.darwin-ppc.darwin-ppc-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for darwin-ppc host - darwin-ppc-debug target build with debug compiler flags
|
||||
# Sites may override these definitions in CONFIG_SITE.darwin-ppc.darwin-ppc-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.darwin-ppc
|
||||
include $(CONFIG)/os/CONFIG.darwin-ppc.darwin-ppc
|
||||
|
||||
# This will cause build failure when used with make -j option
|
||||
#BUILD_CLASS = HOST
|
||||
#HOST_OPT = NO
|
||||
|
||||
CROSS_OPT=NO
|
||||
17
configure/os/CONFIG.darwin-x86.darwin-x86-debug
Normal file
17
configure/os/CONFIG.darwin-x86.darwin-x86-debug
Normal file
@@ -0,0 +1,17 @@
|
||||
# CONFIG.darwin-x86.darwin-x86-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for darwin-x86 host - darwin-x86-debug target build with debug compiler flags
|
||||
# Sites may override these definitions in CONFIG_SITE.darwin-x86.darwin-x86-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.darwin-x86
|
||||
include $(CONFIG)/os/CONFIG.darwin-x86.darwin-x86
|
||||
|
||||
# This will cause build failure when used with make -j option
|
||||
#BUILD_CLASS = HOST
|
||||
#HOST_OPT = NO
|
||||
|
||||
CROSS_OPT=NO
|
||||
@@ -12,5 +12,6 @@ include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
# This will cause build failure when used with make -j option
|
||||
# See base/src/bpt MAKEBPT
|
||||
#BUILD_CLASS = HOST
|
||||
#HOST_OPT = NO
|
||||
|
||||
CROSS_OPT=NO
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for linux-x86 host - linux-x86-debug target build with debug compiler flags
|
||||
# Sites may override these definitions in CONFIG_SITE.linux-x86.linux-x86-debug
|
||||
# Definitions for linux-x86_64 host - linux-x86_64-debug target build with debug compiler flags
|
||||
# Sites may override these definitions in CONFIG_SITE.linux-x86_64.linux-x86_64-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.linux-x86_64
|
||||
|
||||
# This will cause build failure when used with make -j option
|
||||
# See base/src/bpt MAKEBPT
|
||||
#BUILD_CLASS = HOST
|
||||
|
||||
CROSS_OPT = NO
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
|
||||
include $(CONFIG)/os/CONFIG.solaris-sparc.solaris-sparc
|
||||
|
||||
BUILD_CLASS = HOST
|
||||
#BUILD_CLASS = HOST
|
||||
#HOST_OPT = NO
|
||||
|
||||
GNU = NO
|
||||
|
||||
# Removes -O optimization and adds -g compile option
|
||||
HOST_OPT=NO
|
||||
CROSS_OPT=NO
|
||||
|
||||
19
configure/os/CONFIG.solaris-sparc64.solaris-sparc64-debug
Normal file
19
configure/os/CONFIG.solaris-sparc64.solaris-sparc64-debug
Normal file
@@ -0,0 +1,19 @@
|
||||
# CONFIG.solaris-sparc64.solaris-sparc64-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for solaris-sparc64 host - solaris-sparc64-debug target build with debug compiler flags
|
||||
# Sites may override these definitions in CONFIG_SITE.solaris-sparc64.solaris-sparc64-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.solaris-sparc64
|
||||
include $(CONFIG)/os/CONFIG.solaris-sparc64.solaris-sparc64
|
||||
|
||||
#BUILD_CLASS = HOST
|
||||
#HOST_OPT = NO
|
||||
|
||||
GNU = NO
|
||||
|
||||
# Removes -O optimization and adds -g compile option
|
||||
CROSS_OPT=NO
|
||||
19
configure/os/CONFIG.solaris-x86.solaris-x86-debug
Normal file
19
configure/os/CONFIG.solaris-x86.solaris-x86-debug
Normal file
@@ -0,0 +1,19 @@
|
||||
# CONFIG.solaris-x86.solaris-x86-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for solaris-x86 host - solaris-x86-debug target build with debug compiler flags
|
||||
# Sites may override these definitions in CONFIG_SITE.solaris-x86.solaris-x86-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/Common.solaris-x86
|
||||
include $(CONFIG)/os/CONFIG.solaris-x86.solaris-x86
|
||||
|
||||
#BUILD_CLASS = HOST
|
||||
#HOST_OPT = NO
|
||||
|
||||
GNU = NO
|
||||
|
||||
# Removes -O optimization and adds -g compile option
|
||||
CROSS_OPT=NO
|
||||
19
configure/os/CONFIG.solaris-x86_64.solaris-x86_64-debug
Normal file
19
configure/os/CONFIG.solaris-x86_64.solaris-x86_64-debug
Normal file
@@ -0,0 +1,19 @@
|
||||
# CONFIG.solaris-x86_64.solaris-x86_64-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for solaris-x86_64 host - solaris-x86_64-debug target build with debug compiler flags
|
||||
# Sites may override these definitions in CONFIG_SITE.solaris-x86_64.solaris-x86_64-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.solaris-x86_64
|
||||
include $(CONFIG)/os/CONFIG.solaris-x86_64.solaris-x86_64
|
||||
|
||||
#BUILD_CLASS = HOST
|
||||
#HOST_OPT = NO
|
||||
|
||||
GNU = NO
|
||||
|
||||
# Removes -O optimization and adds -g compile option
|
||||
CROSS_OPT=NO
|
||||
13
configure/os/CONFIG.win32-x86-cygwin.win32-x86-cygwin-debug
Normal file
13
configure/os/CONFIG.win32-x86-cygwin.win32-x86-cygwin-debug
Normal file
@@ -0,0 +1,13 @@
|
||||
# CONFIG.win32-x86-cygwin.win32-x86-cygwin-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for win32-x86-cygwin compiler host - win32-x86-cygwin debug compiler target builds
|
||||
# Sites may override these definitions in CONFIG_SITE.win32-x86-cygwin.win32-x86-cygwin-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.win32-x86-cygwin
|
||||
include $(CONFIG)/os/CONFIG.win32-x86-cygwin.win32-x86-cygwin
|
||||
|
||||
CROSS_OPT=NO
|
||||
13
configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw-debug
Normal file
13
configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw-debug
Normal file
@@ -0,0 +1,13 @@
|
||||
# CONFIG.win32-x86-mingw.win32-x86-mingw-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for win32-x86-mingw compiler host - win32-x86-mingw debug compiler target builds
|
||||
# Sites may override these definitions in CONFIG_SITE.win32-x86-mingw.win32-x86-mingw-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.win32-x86-mingw
|
||||
include $(CONFIG)/os/CONFIG.win32-x86-mingw.win32-x86-mingw
|
||||
|
||||
CROSS_OPT=NO
|
||||
15
configure/os/CONFIG.win32-x86.win32-x86-debug
Normal file
15
configure/os/CONFIG.win32-x86.win32-x86-debug
Normal file
@@ -0,0 +1,15 @@
|
||||
# CONFIG.win32-x86.win32-x86-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for win32-x86 host - win32-x86-debug target build
|
||||
# Sites may override these definitions in CONFIG_SITE.win32-x86.win32-x86-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.win32-x86
|
||||
include $(CONFIG)/os/CONFIG.win32-x86.win32-x86
|
||||
|
||||
GNU = NO
|
||||
|
||||
CROSS_OPT = NO
|
||||
@@ -5,32 +5,34 @@
|
||||
|
||||
# Compiler options can vary with the vxWorks version number, so we
|
||||
# need to know that. However don't include any third-level digits
|
||||
# because we don't currently need them.
|
||||
# (the .2 in 5.4.2) because we don't currently need them.
|
||||
|
||||
# Note: vxWorks 5.3 (Tornado 1.x) is not supported
|
||||
|
||||
VXWORKS_VERSION = 5.4
|
||||
#VXWORKS_VERSION = 5.5
|
||||
#VXWORKS_VERSION = 5.4
|
||||
VXWORKS_VERSION = 5.5
|
||||
#VXWORKS_VERSION = 6.0
|
||||
#VXWORKS_VERSION = 6.1
|
||||
#VXWORKS_VERSION = 6.2
|
||||
#VXWORKS_VERSION = 6.3
|
||||
#VXWORKS_VERSION = 6.4
|
||||
#VXWORKS_VERSION = 6.5
|
||||
#VXWORKS_VERSION = 6.6
|
||||
|
||||
|
||||
# Sites may override the following path for a particular host
|
||||
# architecture by adding it to the appropriate
|
||||
# architecture by adding it to an appropriate
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).vxWorksCommon file.
|
||||
|
||||
# WIND_BASE is where you installed the Wind River software.
|
||||
# Under vxWorks 6.x this is not the same as the old VX_DIR setting
|
||||
# Under vxWorks 6.x this is *not* the same as the old VX_DIR setting
|
||||
|
||||
WIND_BASE = /usr/local/vw/tornado202p1
|
||||
#WIND_BASE = /usr/local/vw/tornado22-$(ARCH_CLASS)
|
||||
#WIND_BASE = /usr/local/vw/tornado202p1
|
||||
WIND_BASE = /usr/local/vw/tornado22-$(ARCH_CLASS)
|
||||
#WIND_BASE = /usr/local/vw/vxWorks-$(VXWORKS_VERSION)
|
||||
#WIND_BASE = /ade/vxWorks/$(VXWORKS_VERSION)
|
||||
|
||||
|
||||
# WorkBench Version number, used with vxWorks 6.6 and later
|
||||
|
||||
WORKBENCH_VERSION = 3.0
|
||||
#WORKBENCH_VERSION = 3.0
|
||||
|
||||
@@ -7,11 +7,31 @@
|
||||
</head>
|
||||
|
||||
<body lang="en">
|
||||
<h1 align="center">EPICS Base Release 3.14.x</h1>
|
||||
<h1 align="center">EPICS Base Release 3.14.10-RC1</h1>
|
||||
|
||||
<h2 align="center">Changes between 3.14.9 and 3.14.10</h2>
|
||||
<!-- Insert new items below here ... -->
|
||||
|
||||
<h4>camonitor timestamp support</h4>
|
||||
|
||||
<p>The <tt>camonitor</tt> program now supports the ability to display both
|
||||
server- and client-side timestamps, simultaneously if requested. The old
|
||||
command-line options <tt>-r</tt> <tt>-i</tt> and <tt>-I</tt> that controlled the
|
||||
timestamp display have been replaced with a new <tt>-t</tt> option that takes
|
||||
additional argument letters to control which timestamp sources and output format
|
||||
should be used.</p>
|
||||
|
||||
<p>See the Command Line Tools section of the Channel Access reference manual or
|
||||
run <tt>camonitor -h</tt> for a summary of the options.</p>
|
||||
|
||||
<h4>New "stdio" stringout device support</h4>
|
||||
|
||||
<p>A new device support has been added that allows a stringout record to output
|
||||
one-line messages to stdout, stderr or the errlog subsystem. Use DTYP="stdio"
|
||||
and set the OUT field to one of "@stdout", "@stderr" or "@errlog" to control the
|
||||
message destination. A newline is appended to the contents of the record's VAL
|
||||
field when printing.</p>
|
||||
|
||||
<h4>General Time subsystem</h4>
|
||||
|
||||
<p>The way in which EPICS gets the time has been significantly revised since
|
||||
@@ -106,7 +126,6 @@ prec->pact to <tt>TRUE</tt> before returning and arranging for the record's
|
||||
<tt>process()</tt> routine to be called to signal completion. The output links
|
||||
are not written until the asynchronous completion callback, and input links are
|
||||
not read at asnychronous completion.</li>
|
||||
<li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -1,475 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/4.06 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]">
|
||||
<TITLE>Synchronized Time Stamp Support</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<H1>
|
||||
Synchronized Time Stamp Support</H1>
|
||||
Author: Jim Kowalkowski
|
||||
<H2>
|
||||
MODIFICATION: 04AUG1998 (Marty Kraimer)</H2>
|
||||
The routine TSsetClockFromUnix was made global. Calling it forces a resynchronization
|
||||
with a host time server. This is useful to force a master timing ioc to
|
||||
resynchronize.
|
||||
<H2>
|
||||
Introduction</H2>
|
||||
|
||||
<H3>
|
||||
Purpose</H3>
|
||||
New software has been added to IOC core to maintain time stamps. The new
|
||||
software has the ability to maintain time stamps over all IOCs on a network.
|
||||
The purpose of this paper is to explain how EPICS will synchronize the
|
||||
time stamps. In addition, this paper will explain how to configure and
|
||||
use the new EPICS time stamp support software.
|
||||
<H3>
|
||||
Definitions</H3>
|
||||
Time Stamp: Two long words representing the time in seconds/nanoseconds
|
||||
past an epoch. The first long word represents the seconds past the epoch,
|
||||
the second long word represents the nanoseconds within the second. The
|
||||
EPICS epoch is currently January 1, 1990. A commonly used Unix epoch in
|
||||
January 1,1900 or in vxWorks case, January 1,1970.
|
||||
<P>Event System: A hardware based subsystem for delivering events to all
|
||||
IOCs on a network. Typical events are the "tick" event and the "reset counter"
|
||||
event.
|
||||
<P>Event System Synchronized Time: Time stamps maintained using an event
|
||||
system. The clock pulses which increment the time stamps are provided by
|
||||
a single source, all IOCs increment time stamps using the single source
|
||||
pulse.
|
||||
<P>Soft Time: Each IOC increments the time stamps using it's own internal
|
||||
clock.
|
||||
<P>Master Timing IOC: The IOC which knows the actual time and is the source
|
||||
of the actual time to all those who inquire.
|
||||
<P>Slave IOC: An IOC which relies on a master IOC to provide the actual
|
||||
time. This IOC will keep it's time stamp in sync with a master.
|
||||
<P>Soft Slave: An IOC which uses Soft Time and synchronizes it's time stamp
|
||||
with a master.
|
||||
<P>Event Slave: An IOC which uses Event System Synchronized Time to maintain
|
||||
it's time stamp. This type of IOC uses the master to verify that it's time
|
||||
stamp is correct.
|
||||
<P>Soft Master: A Master Timing IOC that maintains it's time stamp using
|
||||
a private clock.
|
||||
<P>Event Master: An IOC which uses Event System Synchronized Time and is
|
||||
a Master Timing IOC. In addition, this IOC is the source of the clock pulses.
|
||||
<H3>
|
||||
Overview</H3>
|
||||
Time stamps are maintained across IOCs using UDP with a master/slave relationship.
|
||||
A master timing IOC is responsible for knowing the actual time. A slave
|
||||
IOC uses the master to verify it's own time stamps. Time stamps are maintained
|
||||
in two fashions: using an event system or using IOC tick counters. Both
|
||||
differ radically and require some explanation.
|
||||
<H4>
|
||||
Event System Support</H4>
|
||||
The time stamp software has special requirements in order to provide event
|
||||
system synchronized time. The time stamp software assumes that hardware
|
||||
is present which has finite counters for counting pulses or ticks delivered
|
||||
to it from some master tick generator. The software further assumes that
|
||||
every so other, before the finite counters overflow, a signal or event
|
||||
will occur to reset the counters to zero. The software requires access
|
||||
to these counters at any time and notification when the "counter reset"
|
||||
arrives. The combination of hardware tick counters and reset event notification
|
||||
gives the software the ability to maintain time. If the event system supports
|
||||
other events, it is required that the software be notified of the occurrence
|
||||
of each event. The event time will be recorded in a table which holds one
|
||||
time stamp for each possible event so that a user can inquire as to when
|
||||
the event occurred.
|
||||
<H4>
|
||||
Soft Time Support</H4>
|
||||
If no event system is present, the time stamp software can operate in a
|
||||
software timing mode. In this mode, no events are available, only the current
|
||||
time can be retrieved. An IOC using soft time will increment a time stamp
|
||||
using the system clock (usually updated at 60Hz). The master/slave relationship
|
||||
allows a slave to periodically ask a master for the correct time. At this
|
||||
point the slave's time stamp can be adjusted to match the masters.
|
||||
<H4>
|
||||
Role of a Master Timing IOC</H4>
|
||||
A master timing IOC has difference responsibilities depending on if it
|
||||
is an event master or a soft master. An event master will be an event generator
|
||||
(create "tick" and "counter reset" events). When the event master detects
|
||||
a "counter reset", it broadcasts the time the event occurred to all event
|
||||
slaves on the network. The slaves can use the time stamp data to verify
|
||||
their own time. A soft timing master does not have any events, so no broadcasting
|
||||
is done. Both soft and event masters have the ability to be queried at
|
||||
any time by slaves for the current time.
|
||||
<H4>
|
||||
Role of a Slave Timing IOC</H4>
|
||||
A slave timing IOC also has difference responsibilities depending on if
|
||||
it is an event slave or a soft slave. An event slave contains hardware
|
||||
to manage "tick" and "counter reset" events. The time stamp support software
|
||||
uses this information to maintain time. An event slave will listen for
|
||||
broadcasts from the event master timing IOC and use the information to
|
||||
verify it's time. A soft slave periodically queries a master timing IOC
|
||||
to get the current time.
|
||||
<H3>
|
||||
Design Specifications Summary</H3>
|
||||
|
||||
<H4>
|
||||
Event System Synchronized Time</H4>
|
||||
All IOCs will have identical event times. In addition, all IOCs will maintain
|
||||
the same current time.
|
||||
<P>The minimum events which must be supported is two. One must be used
|
||||
as a "tick" event and one must be used as a "reset hardware tick counter"
|
||||
event. The second will be used to update the time stamp representing the
|
||||
current time.
|
||||
<P>An optional event can be used as a "heartbeat" event. This event can
|
||||
be used to signal errors.
|
||||
<H4>
|
||||
Soft Time</H4>
|
||||
All IOCs of this type will maintain time stamps which are within two clocks
|
||||
ticks or 1/30th of a second of a master. The master may be a designated
|
||||
IOC or the Unix boot server. A Unix boot server master or the server pointed
|
||||
to by the EPICS environment variable EPICS_TS_NTP_INET must have NTP available
|
||||
for polling.
|
||||
<H2>
|
||||
User Level Interface</H2>
|
||||
|
||||
<H3>
|
||||
General Use Functions</H3>
|
||||
Three functions exist in the synchronous time stamp support software for
|
||||
the user to retrieve time stamps:
|
||||
<UL>
|
||||
<LI>
|
||||
TSgetTimeStamp(event_number, struct timespec* time_stamp)</LI>
|
||||
|
||||
<LI>
|
||||
TScurrentTimeStamp(struct timespec* time_stamp)</LI>
|
||||
|
||||
<LI>
|
||||
TSgetFirstOfYearVx(struct timespec* time_stamp)</LI>
|
||||
|
||||
<LI>
|
||||
tsLocalTime(TS_STAMP*)</LI>
|
||||
</UL>
|
||||
To retrieve the time stamp which represents the time that an event occurred,
|
||||
use <B>TSgetTimeStamp()</B>. <B>TScurrentTimeStamp()</B> can be used to
|
||||
retrieve the time stamp which represents the time of day. <B>TsLocalTime()</B>
|
||||
is the function for returning the current time stamp in the old time stamp
|
||||
driver, the routine can still be used to retrieve this information. The
|
||||
function <B>TSgetFirstOfYear()</B> attempts to give the caller a time stamp
|
||||
representing January 1 of the current year relative to the vxWorks epoch
|
||||
1970.
|
||||
<P>An EPICS enironment variable named EPICS_TS_NTP_INET exists which can
|
||||
be set to point to an NTP server. The default NTP server is the IOC boot
|
||||
server.
|
||||
<H4>
|
||||
Test Functions</H4>
|
||||
The following functions can be run from the vxWorks shell to give information
|
||||
about the time stamp driver.
|
||||
<UL>
|
||||
<LI>
|
||||
<B>TSreport()</B>: Display all the information about the current configuration
|
||||
and status of this time stamp driver.</LI>
|
||||
|
||||
<LI>
|
||||
<B>TSprintRealTime()</B>: Call the ErGetTime() function described below
|
||||
(if present) and print the time stamp returned from it. Also print the
|
||||
current EPICS time stamp.</LI>
|
||||
|
||||
<LI>
|
||||
<B>TSprintTimeStamp(event_number)</B>: Print the EPICS time stamp for the
|
||||
given event_number.</LI>
|
||||
|
||||
<LI>
|
||||
<B>TSprintCurrentTime()</B>: Print the EPICS time stamp representing the
|
||||
current time.</LI>
|
||||
|
||||
<LI>
|
||||
<B>TSprintUnixTime()</B>: Send a time stamp query transaction to the boot
|
||||
server or NTP server and print the time stamp returned.</LI>
|
||||
|
||||
<LI>
|
||||
<B>TSprintMasterTime()</B>: Send a time stamp query transaction to the
|
||||
master time server and print the time stamp returned.</LI>
|
||||
</UL>
|
||||
|
||||
<H4>
|
||||
Debugging Information</H4>
|
||||
A global variable exists named <B>TSdriverDebug</B>. Setting this variable
|
||||
to a positive value in the vxWorks start up script will inform the time
|
||||
stamp driver to print information about what it is doing. The greater the
|
||||
value, the more information the driver will print. The number can be set
|
||||
and adjusted to any value any time while the IOC is running.
|
||||
<H3>
|
||||
Record Support</H3>
|
||||
Record support will have the ability to tie the record processing time
|
||||
to an event. This means that a user can specify that processing of a record
|
||||
is due to an event (from the event system). When the record gets processed,
|
||||
the time in the TIME field of the record will be the time when the event
|
||||
occurred. In order to support the event times from record support, two
|
||||
new fields will be added to dbCommon. The fields will be Time Stamp Event
|
||||
(TSE), and Time Stamp Event Link (TSEL). The TSE field will be the actual
|
||||
event time the user is interested in. The TSEL field will be a link used
|
||||
to populate the TSE.
|
||||
<P>To facilitate the use of the time stamp support software, a new record
|
||||
support function will be added:
|
||||
<UL>
|
||||
<LI>
|
||||
recGblGetTimeStamp((dbCommon*)prec).</LI>
|
||||
</UL>
|
||||
This routine uses TSgetTimeStamp(prec->tse, &prec->time) to set the
|
||||
processing time of the record. The new recGblGetTimeStamp() will replace
|
||||
the existing call to tsLocalTime(). If the TSE field is zero (the default),
|
||||
then TSgetTimeStamp() will report the current time. It is important to
|
||||
remember that if a TSE field is set, then the processing time (in field
|
||||
TIME) will always reflect the last time the event occurred.
|
||||
<H2>
|
||||
Driver Configuration</H2>
|
||||
The synchronous time stamp support software is configured by calling TSconfigure()
|
||||
from the "startup.cmd" file. The parameters to this routine are:
|
||||
<UL>
|
||||
<LI>
|
||||
<B>master_indicator</B>: 1=master timing IOC, 0=slave timing IOC, default
|
||||
is slave.</LI>
|
||||
|
||||
<LI>
|
||||
<B>sync_rate_seconds</B>: The clock sync rate in seconds. This rate tells
|
||||
how often the synchronous time stamp support software will confirm that
|
||||
an IOC clock is synchronized. The default is 10 seconds.</LI>
|
||||
|
||||
<LI>
|
||||
<B>clock_rate_hz</B>: The frequency in hertz of the clock, the default
|
||||
is 1000Hz for the event system. The value will be set to the IOC's internal
|
||||
clock rate when soft timing is used.</LI>
|
||||
|
||||
<LI>
|
||||
<B>master_port</B>: The UDP port which a master timing IOC will use to
|
||||
receive time stamp requests. The default is 18233.</LI>
|
||||
|
||||
<LI>
|
||||
<B>slave_port</B>: The UDP port which a slave will use to receive time
|
||||
stamp information from a master.</LI>
|
||||
|
||||
<LI>
|
||||
<B>time_out</B>: UDP information request time out in milliseconds, if zero
|
||||
is entered here, the default will be used which is 250ms.</LI>
|
||||
|
||||
<LI>
|
||||
<B>type</B>: 0=normal operation, 1=force soft timing type.</LI>
|
||||
</UL>
|
||||
This routine must be run before iocInit(). The synchronous time stamp support
|
||||
software is initialized as part of iocInit. Running <B>TSreport()</B> after
|
||||
iocInit() will produce a report which shows the current state of the driver.
|
||||
<H2>
|
||||
Event System interface</H2>
|
||||
The event system interface consists of seven function which can be provided
|
||||
by an event system. The synchronous time stamp support software uses a
|
||||
card number of zero on all functions that require a card number. The functions
|
||||
are as follows:
|
||||
<UL>
|
||||
<LI>
|
||||
long ErHaveReceiver(int event_card_number)</LI>
|
||||
|
||||
<LI>
|
||||
long ErGetTicks(int event_card_number, unsigned long* ticks)</LI>
|
||||
|
||||
<LI>
|
||||
long ErRegisterEventHandler(int event_card_num,EVENT_FUNC event_func)</LI>
|
||||
|
||||
<LI>
|
||||
long ErRegisterErrorHandler(int event_card_num,ERROR_FUNC error_func)</LI>
|
||||
|
||||
<LI>
|
||||
long ErForceSync(int event_card_number)</LI>
|
||||
|
||||
<LI>
|
||||
long ErGetTime(struct timespec* time_stamp)</LI>
|
||||
|
||||
<LI>
|
||||
long ErSyncEvent()</LI>
|
||||
|
||||
<LI>
|
||||
long ErDirectTime()</LI>
|
||||
|
||||
<LI>
|
||||
long ErDriverInit()</LI>
|
||||
</UL>
|
||||
The definition are as follows:
|
||||
<UL>
|
||||
<LI>
|
||||
<B>ErHaveReceiver()</B>: Returns -1 if no event (timing) hardware present,
|
||||
else returns the number of supported events.</LI>
|
||||
|
||||
<LI>
|
||||
<B>ErGetTicks()</B>: Returns the number of ticks since the last hardware
|
||||
tick counter reset.</LI>
|
||||
|
||||
<LI>
|
||||
<B>ErRegisterEventHandler()</B>: Informs the event system of a function
|
||||
to call when an event occurs, the format of the function will be defined
|
||||
below.</LI>
|
||||
|
||||
<LI>
|
||||
<B>ErRegisterErrorHandler()</B>: Informs the event system of a function
|
||||
to call when an error occurs, the format of the function will be defined
|
||||
below.</LI>
|
||||
|
||||
<LI>
|
||||
<B>ErForceSync()</B>: This function will force an event generator to generate
|
||||
a tick reset event and send it.</LI>
|
||||
|
||||
<LI>
|
||||
<B>ErGetTime()</B>: This function returns the actual time. The intention
|
||||
here is that this function will retrieve the actual time from GPS system
|
||||
or equivalent and return is in time stamp format.</LI>
|
||||
|
||||
<LI>
|
||||
<B>ErSyncEvent()</B>: Return the event number for the tick reset event.</LI>
|
||||
|
||||
<LI>
|
||||
<B>ErDirectTime()</B>: Return 0 for normal operation, return value not
|
||||
= 0 for systems that has direct time access, such as a GPS.</LI>
|
||||
|
||||
<LI>
|
||||
<B>ErDriverInit()</B>: The time stamp driver initialization function will
|
||||
call this user supplied function before it returns and after it sets up
|
||||
the vxWorks clock and attempts to set up the TIMEZONE variable. This can
|
||||
be useful to initialize a system such as a GPS (the year can be determined
|
||||
using the vxWorks ansiTime library).</LI>
|
||||
</UL>
|
||||
All of these routines are checked to exist when the time stamp support
|
||||
code initializes. All have some kind of default routine provided if they
|
||||
are not found, most of which just return an error condition. The functions
|
||||
which the time stamp support software registers (event and error) have
|
||||
the following format:
|
||||
<UL>
|
||||
<LI>
|
||||
TSeventHandler(int Card,int EventNum,unsigned long Ticks)</LI>
|
||||
|
||||
<LI>
|
||||
TSerrorHandler(int Card, int ErrorNum)</LI>
|
||||
</UL>
|
||||
Here the Card is the event system board of interest (always zero), the
|
||||
EventNum is the event that occurred, and the Ticks is the number of ticks
|
||||
since the last board tick counter reset.
|
||||
<P>In addition to the above functions, a global variable exists on the
|
||||
IOC which can be used to indicate that direct time is available. Setting
|
||||
the variable <B>TSdirectTimeVar</B> to a nonzero value has the same effect
|
||||
as providing the ErDirectTime() function.
|
||||
<H3>
|
||||
Creating Direct Time Support</H3>
|
||||
Most of the above interface functions apply only when special event hardware
|
||||
is present. A much simpler configuration is when a GPS is present and time
|
||||
stamps are distributed using IRIG-B to all or most of the IOCs. The easiest
|
||||
way to implement this scenario is to define ErDirectTime() to return the
|
||||
value one and define ErGetTime(). The job of ErGetTime() will be to actually
|
||||
be to generate and return the time stamp representing the current time
|
||||
(from the EPICS epoch). At system initialization, the actual time is retrieved
|
||||
from a Unix server through NTP or the Unix time protocol, so that year
|
||||
will be valid in the vxWorks time clock. At the GPS driver initialization,
|
||||
the vxWorks function clock_gettime() can be used to calculate the year.
|
||||
Record support will internally eventually call ErGetTime() each time the
|
||||
record is processed. The GPS driver should be included as part of drvSup.ascii,
|
||||
so it initialized in the proper order.
|
||||
<H2>
|
||||
Operation</H2>
|
||||
An IOC can be configured to run in one of four ways: synchronous-master,
|
||||
soft-master, synchronous-slave, soft-slave. Each mode maintains time differently.
|
||||
When the time stamp support code initializes, it determines the mode which
|
||||
it will operate in based on configuration parameters and event system function
|
||||
information.
|
||||
<H3>
|
||||
Synchronous Time</H3>
|
||||
Synchronous timing is determined by the presence of event system hardware.
|
||||
The function ErHaveReceiver() gives this information. All IOCs using synchronous
|
||||
time will have the exact same time stamps. The "tick" event increments
|
||||
all IOC's event system tick counters, the "reset tick counter" resets the
|
||||
counter to zero and posts the event to the time stamp support software.
|
||||
The time stamp support software system knows the current time by looking
|
||||
at the last "tick reset event" time and querying the event system with
|
||||
ErGetTicks() for the number of ticks which have elapsed since the last
|
||||
reset. Since the event handler function gets called with the "ticks since
|
||||
last reset", an event time is the last "tick reset event" time plus the
|
||||
ticks count in the call.
|
||||
<H4>
|
||||
Master</H4>
|
||||
A synchronous master is determined by the first parameter to TSconfigure()
|
||||
and the presence of event hardware. A master must have an event generator
|
||||
and an event receiver. Since the event system is configured from EPICS
|
||||
database records, the database must have records in it to initialize the
|
||||
event system. The master is responsible for providing the "tick" event
|
||||
and the "reset tick counter" event.
|
||||
<P>When the time stamp support software's event handler function on a master
|
||||
timing IOC receives a "reset tick counter" event, a time stamp message
|
||||
is broadcast out on the slave_port (configured by TSconfigure()). The master
|
||||
timing IOC is also listening on the master_port (also configured by TSconfigure())
|
||||
for incoming requests for time stamp information.
|
||||
<P>At boot time, a master will set the vxWorks clock from the Unix boot
|
||||
server time. The time is retrieved from the boot server using NTP or the
|
||||
time protocol, or the server pointed to by the EPICS environment variable
|
||||
EPICS_TS_NTP_INET using NTP. The GPS module takes an unknown period of
|
||||
time to sync to the correct time, so it can not be used until it's time
|
||||
is valid. The event system is not up and running until record support initialization
|
||||
is complete, therefore the event system time stamps are not ticking until
|
||||
the event system initializes. At the time of the first sync, the event
|
||||
system is known to be up, and the "reset tick counter" or "sync" event
|
||||
is set to the current time (vxWorks clock).
|
||||
<H4>
|
||||
Slave</H4>
|
||||
A synchronous slave is determined by the first parameter to TSconfigure()
|
||||
and the presence of event hardware. This mode is automatically selected
|
||||
if no TSconfigure() call is used in the "startup.cmd" file. This type of
|
||||
slave must have an event receiver. The EPICS database must be configured
|
||||
to initialize the event system.
|
||||
<P>When a synchronous slave configuration is determined, the IOC broadcasts
|
||||
a request for master on the master_port port. If a master is found, then
|
||||
all current time, sync rate, and clock are extracted from the master's
|
||||
response (the sync rate and clock rate from the TSconfigure() are overwritten
|
||||
to match the master's configuration). If a master is not found, the slave
|
||||
IOC goes into a polling mode to try to find a master every two minutes.
|
||||
While a slave has no master, The IOC's clock is initialized from the Unix
|
||||
boot server and TSgetTimeStamp() returns the vxWorks time clock value.
|
||||
<P>The slave experiences the same problems as the master upon boot.
|
||||
<H3>
|
||||
Soft Time</H3>
|
||||
Soft time IOCs use the 60 hertz clock available from vxWorks to maintain
|
||||
a time stamp. The IOC will increment a time stamp at a 60 hertz rate. Soft
|
||||
time is determined by the absence of event system hardware. All soft timing
|
||||
IOC's will not have the same time stamps.
|
||||
<H4>
|
||||
Master</H4>
|
||||
A soft master is determined by the first parameter of TSconfigure() and
|
||||
the absence of event hardware. Upon boot, the master soft timing IOC retrieves
|
||||
the current time from the Unix boot server. The IOC sets up a soft time-stamp
|
||||
counter using a one tick watch dog and sets the vxWorks clock. From this
|
||||
point on, the master runs using the soft time-stamp counter. The master
|
||||
listens on the master_port port for requests for the master's current time.
|
||||
<H4>
|
||||
Slave</H4>
|
||||
A soft slave is determined by the first parameter of TSconfigure() and
|
||||
the absence of the event hardware. This mode is automatically selected
|
||||
if no TSconfigure() is present in the "startup.cmd" file. The basic operation
|
||||
of a soft slave is to synchronize the time stamp with a master when possible
|
||||
or to the Unix boot server if no master is available. Upon initialization
|
||||
the time stamp support code determines if a master is present on the network,
|
||||
and if NTP support is available from the Unix boot server or the server
|
||||
pointed to by the EPICS environment variable EPICS_TS_NTP_INET. The slave
|
||||
will request time stamps from a master or unix server at sync_rate_in_seconds
|
||||
rate from TSconfigure(). If the time stamp on the slave is found to be
|
||||
off, the clock will be incrementally adjusted so that by the next sync,
|
||||
the clock will be corrected to match the master's time stamp. A soft slave
|
||||
will automatically switch between a master and the unix boot server depending
|
||||
on if the master is available or not. In order to sync with the unix boot
|
||||
server, NTP must be available there for query only.
|
||||
<HR>
|
||||
<P>Home page for <A HREF="http://www.aps.anl.gov/asd/controls/hideos/jimk.html">Jim
|
||||
Kowalkowski</A> .
|
||||
<BR>Argonne National Laboratory <A HREF="http://www.aps.anl.gov/asd/controls/epics_copyright.html">Copyright</A>
|
||||
Information
|
||||
<ADDRESS>
|
||||
jbk@aps.anl.gov (Jim Kowalkowski)</ADDRESS>
|
||||
|
||||
<BR>updated 8/10/95
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -73,7 +73,7 @@ DIRS += RTEMS
|
||||
RTEMS_DEPEND_DIRS = libCom
|
||||
|
||||
DIRS += libCom/test
|
||||
libCom/test_DEPEND_DIRS = libCom RTEMS
|
||||
libCom/test_DEPEND_DIRS = ca RTEMS
|
||||
|
||||
DIRS += db/test
|
||||
db/test_DEPEND_DIRS = db RTEMS
|
||||
@@ -90,7 +90,7 @@ cas_DEPEND_DIRS = ca gdd
|
||||
DIRS += excas
|
||||
excas_DEPEND_DIRS = cas as registry
|
||||
|
||||
#DIRS += cap5
|
||||
DIRS += cap5
|
||||
cap5_DEPEND_DIRS = ca dbStatic
|
||||
|
||||
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
<title>EPICS R3.14 Channel Access Reference Manual</title>
|
||||
<style type="text/css">
|
||||
<!--
|
||||
h3 code {
|
||||
background-color: #ddf;
|
||||
}
|
||||
-->
|
||||
h3 code {
|
||||
background-color: #ddf;
|
||||
}
|
||||
-->
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -411,7 +412,8 @@ other facility is already using the default port numbers. The default Channel
|
||||
Access port numbers have been registered with IANA.</p>
|
||||
|
||||
<table cellspacing="1" cellpadding="1" width="80%" border="1">
|
||||
<col><tbody>
|
||||
<col>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Purpose</th>
|
||||
<th>Default</th>
|
||||
@@ -1330,19 +1332,18 @@ the output.</p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Default:</td>
|
||||
<td>Print absolute timestamps (as reported by CA)</td>
|
||||
<td>Print absolute timestamps (as reported by CA server)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>-r</td>
|
||||
<td>Relative timestamps (time elapsed since start of program)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>-i</td>
|
||||
<td>Incremental timestamps (time elapsed since last update)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>-I</td>
|
||||
<td>Incremental timestamps (time elapsed since last update for this
|
||||
<td>-t <key></td>
|
||||
<td>Specify timestamp source(s) and type, with <key>
|
||||
containing<br>
|
||||
's' = CA server (remote) timestamps<br>
|
||||
'c' = CA client (local) timestamps (shown in '()'s)<br>
|
||||
'n' = no timestamps<br>
|
||||
'r' = relative timestamps (time elapsed since start of program)<br>
|
||||
'i' = incremental timestamps (time elapsed since last update)<br>
|
||||
'I' = incremental timestamps (time elapsed since last update, by
|
||||
channel)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -23,7 +23,8 @@ epicsShareFunc void epicsShareAPI configureChannelAccessAddressList
|
||||
( struct ELLLIST *pList, SOCKET sock, unsigned short port );
|
||||
|
||||
epicsShareFunc void epicsShareAPI addAddrToChannelAccessAddressList
|
||||
( struct ELLLIST *pList, const ENV_PARAM *pEnv, unsigned short port );
|
||||
( struct ELLLIST *pList, const ENV_PARAM *pEnv,
|
||||
unsigned short port, int ignoreNonDefaultPort );
|
||||
|
||||
epicsShareFunc void epicsShareAPI printChannelAccessAddressList
|
||||
( const struct ELLLIST *pList );
|
||||
|
||||
@@ -50,10 +50,12 @@ void disconnectGovernorTimer::shutdown (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
{
|
||||
epicsGuardRelease < epicsMutex > cbUnguard ( cbGuard );
|
||||
this->timer.cancel ();
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
{
|
||||
epicsGuardRelease < epicsMutex > cbUnguard ( cbGuard );
|
||||
this->timer.cancel ();
|
||||
}
|
||||
}
|
||||
while ( nciu * pChan = this->chanList.get () ) {
|
||||
pChan->channelNode::listMember =
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "hostNameCache.h"
|
||||
#include "epicsGuard.h"
|
||||
|
||||
@@ -33,6 +33,9 @@ hostNameCache::hostNameCache (
|
||||
const osiSockAddr & addr, ipAddrToAsciiEngine & engine ) :
|
||||
dnsTransaction ( engine.createTransaction() ), nameLength ( 0 )
|
||||
{
|
||||
sockAddrToDottedIP ( &addr.sa, hostNameBuf, sizeof ( hostNameBuf ) );
|
||||
hostNameBuf[ sizeof ( hostNameBuf ) - 1 ] = '\0';
|
||||
nameLength = strlen ( hostNameBuf );
|
||||
this->dnsTransaction.ipAddrToAscii ( addr, *this );
|
||||
}
|
||||
|
||||
@@ -49,11 +52,17 @@ hostNameCache::~hostNameCache ()
|
||||
void hostNameCache::transactionComplete ( const char * pHostNameIn )
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
if ( this->nameLength == 0u ) {
|
||||
strncpy ( this->hostNameBuf, pHostNameIn, sizeof ( this->hostNameBuf ) );
|
||||
this->hostNameBuf[ sizeof ( this->hostNameBuf ) - 1 ] = '\0';
|
||||
this->nameLength = strlen ( this->hostNameBuf );
|
||||
// a few legacy clients have a direct pointer to this buffer so we
|
||||
// set the entrire string to nill terminators before we start copying
|
||||
// in the name (this reduces the chance that another thread will see
|
||||
// garbage characters).
|
||||
size_t newNameLen = strlen ( pHostNameIn );
|
||||
if ( newNameLen > sizeof ( this->hostNameBuf ) - 1u ) {
|
||||
newNameLen = sizeof ( this->hostNameBuf ) - 1u;
|
||||
}
|
||||
strncpy ( this->hostNameBuf, "", sizeof ( this->hostNameBuf ) );
|
||||
strncpy ( this->hostNameBuf, pHostNameIn, sizeof ( this->hostNameBuf ) - 1 );
|
||||
this->nameLength = newNameLen;
|
||||
}
|
||||
|
||||
unsigned hostNameCache::getName (
|
||||
|
||||
@@ -74,7 +74,8 @@ static char *getToken ( const char **ppString, char *pBuf, unsigned bufSIze )
|
||||
* addAddrToChannelAccessAddressList ()
|
||||
*/
|
||||
extern "C" void epicsShareAPI addAddrToChannelAccessAddressList
|
||||
( ELLLIST *pList, const ENV_PARAM *pEnv, unsigned short port )
|
||||
( ELLLIST *pList, const ENV_PARAM *pEnv,
|
||||
unsigned short port, int ignoreNonDefaultPort )
|
||||
{
|
||||
osiSockAddrNode *pNewNode;
|
||||
const char *pStr;
|
||||
@@ -96,6 +97,10 @@ extern "C" void epicsShareAPI addAddrToChannelAccessAddressList
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ignoreNonDefaultPort && addr.sin_port != port ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode));
|
||||
if (pNewNode==NULL) {
|
||||
fprintf ( stderr, "addAddrToChannelAccessAddressList(): no memory available for configuration\n");
|
||||
@@ -235,7 +240,7 @@ extern "C" void epicsShareAPI configureChannelAccessAddressList
|
||||
}
|
||||
}
|
||||
}
|
||||
addAddrToChannelAccessAddressList ( &tmpList, &EPICS_CA_ADDR_LIST, port );
|
||||
addAddrToChannelAccessAddressList ( &tmpList, &EPICS_CA_ADDR_LIST, port, false );
|
||||
|
||||
removeDuplicateAddresses ( pList, &tmpList, 0 );
|
||||
}
|
||||
|
||||
@@ -28,8 +28,10 @@ our @ISA = qw(DynaLoader);
|
||||
|
||||
require DynaLoader;
|
||||
|
||||
# Add our lib/<arch> directory to the library search path
|
||||
push @DynaLoader::dl_library_path, '@TOP@/lib/'.$ENV{EPICS_HOST_ARCH};
|
||||
# Add our lib/<arch> directory to the shared library search path
|
||||
use File::Basename;
|
||||
my $Lib = dirname(__FILE__);
|
||||
push @DynaLoader::dl_library_path, "$Lib/../$ENV{EPICS_HOST_ARCH}";
|
||||
|
||||
bootstrap Cap5 $VERSION;
|
||||
|
||||
@@ -17,18 +17,16 @@ ifneq ($(findstring win32,$(T_A)),)
|
||||
BAT = .bat
|
||||
endif
|
||||
|
||||
EXPAND += cainfo.pl@ caput.pl@ caget.pl@ camonitor.pl@ CA.pm@
|
||||
ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),)
|
||||
# Doesn't build on WIN32
|
||||
LOADABLE_LIBRARY_HOST = Cap5
|
||||
|
||||
PERL_SCRIPTS += cainfo.pl
|
||||
PERL_SCRIPTS += caput.pl
|
||||
PERL_SCRIPTS += caget.pl
|
||||
PERL_SCRIPTS += camonitor.pl
|
||||
PERL_SCRIPTS += cainfo.pl
|
||||
PERL_SCRIPTS += caput.pl
|
||||
PERL_SCRIPTS += caget.pl
|
||||
PERL_SCRIPTS += camonitor.pl
|
||||
|
||||
PERL_MODULES += CA.pm
|
||||
|
||||
ifeq ($(findstring win32,$(T_A)),)
|
||||
# Doesn't build on WIN32 yet...
|
||||
LOADABLE_LIBRARY_HOST = Cap5
|
||||
PERL_MODULES += CA.pm
|
||||
endif
|
||||
|
||||
Cap5_SRCS = Cap5.xs
|
||||
@@ -46,8 +44,8 @@ include $(TOP)/configure/RULES
|
||||
|
||||
ifdef T_A
|
||||
PERL5_DIR = $(dir $(shell $(PERL) ../perlConfig.pl perl5))
|
||||
XSUBPP = $(PERL) $(PERL5_DIR)xsubpp$(BAT)
|
||||
PODCHECKER = $(PERL) $(PERL5_DIR)podchecker$(BAT)
|
||||
XSUBPP = $(PERL5_DIR)xsubpp$(BAT)
|
||||
PODCHECKER = $(PERL5_DIR)podchecker$(BAT)
|
||||
TYPEMAP = $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils/typemap
|
||||
|
||||
%.c: ../%.xs
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use lib '@TOP@/lib/perl';
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../../lib/perl";
|
||||
|
||||
use Getopt::Std;
|
||||
use CA;
|
||||
|
||||
@@ -16,7 +19,7 @@ HELP_MESSAGE() if $opt_h;
|
||||
|
||||
$opt_d = "DBR_$opt_d" if $opt_d && $opt_d !~ m/^DBR_/;
|
||||
|
||||
die "No pv name specified. ('caget -h' for help.)\n"
|
||||
die "No pv name specified. ('caget -h' gives help.)\n"
|
||||
unless @ARGV;
|
||||
|
||||
my @chans = map { CA->new($_); } @ARGV;
|
||||
@@ -1,7 +1,10 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use lib '@TOP@/lib/perl';
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../../lib/perl";
|
||||
|
||||
use Getopt::Std;
|
||||
use CA;
|
||||
|
||||
@@ -13,7 +16,7 @@ $Getopt::Std::OUTPUT_HELP_VERSION = 1;
|
||||
HELP_MESSAGE() unless getopts('hw:');
|
||||
HELP_MESSAGE() if $opt_h;
|
||||
|
||||
die "No pv name specified. ('cainfo -h' for help.)\n"
|
||||
die "No pv name specified. ('cainfo -h' gives help.)\n"
|
||||
unless @ARGV;
|
||||
|
||||
my @chans = map { CA->new($_); } @ARGV;
|
||||
@@ -1,7 +1,10 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use lib '@TOP@/lib/perl';
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../../lib/perl";
|
||||
|
||||
use Getopt::Std;
|
||||
use CA;
|
||||
|
||||
@@ -14,7 +17,7 @@ $Getopt::Std::OUTPUT_HELP_VERSION = 1;
|
||||
HELP_MESSAGE() unless getopts('0:C:e:f:g:hm:nsw:');
|
||||
HELP_MESSAGE() if $opt_h;
|
||||
|
||||
die "No pv name specified. ('camonitor -h' for help.)\n"
|
||||
die "No pv name specified. ('camonitor -h' gives help.)\n"
|
||||
unless @ARGV;
|
||||
|
||||
my %monitors;
|
||||
@@ -107,11 +110,11 @@ sub HELP_MESSAGE {
|
||||
" -w <sec>: Wait time, specifies longer CA timeout, default is $opt_w second\n",
|
||||
" -m <mask>: Specify CA event mask to use, with <mask> being any combination of\n",
|
||||
" 'v' (value), 'a' (alarm), 'l' (log). Default: '$opt_m'\n",
|
||||
"Timestamps:\n",
|
||||
" Default: Print absolute timestamps (as reported by CA)\n",
|
||||
" -r: Relative timestamps (time elapsed since start of program)\n",
|
||||
" -i: Incremental timestamps (time elapsed since last update)\n",
|
||||
" -I: Incremental timestamps (time elapsed since last update for this channel)\n",
|
||||
# "Timestamps:\n",
|
||||
# " Default: Print absolute timestamps (as reported by CA)\n",
|
||||
# " -r: Relative timestamps (time elapsed since start of program)\n",
|
||||
# " -i: Incremental timestamps (time elapsed since last update)\n",
|
||||
# " -I: Incremental timestamps (time elapsed since last update for this channel)\n",
|
||||
"Enum format:\n",
|
||||
" -n: Print DBF_ENUM values as number (default are enum string values)\n",
|
||||
"Arrays: Value format: print number of values, then list of values\n",
|
||||
@@ -1,7 +1,10 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use lib '@TOP@/lib/perl';
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../../lib/perl";
|
||||
|
||||
use Getopt::Std;
|
||||
use CA;
|
||||
|
||||
@@ -14,11 +17,11 @@ $Getopt::Std::OUTPUT_HELP_VERSION = 1;
|
||||
HELP_MESSAGE() unless getopts('achlnstw:');
|
||||
HELP_MESSAGE() if $opt_h;
|
||||
|
||||
die "No pv name specified. ('caput -h' for help.)\n"
|
||||
die "No pv name specified. ('caput -h' gives help.)\n"
|
||||
unless @ARGV;
|
||||
my $pv = shift;
|
||||
|
||||
die "No value specified. ('caput -h' for help.)\n"
|
||||
die "No value specified. ('caput -h' gives help.)\n"
|
||||
unless @ARGV;
|
||||
|
||||
my $chan = CA->new($pv);
|
||||
@@ -831,6 +831,7 @@ caStatus casDGClient::processMsg ()
|
||||
}
|
||||
status = ( this->*pHandler ) ();
|
||||
if ( status ) {
|
||||
this->in.removeMsg ( this->in.bytesPresent() );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ casDGIntfIO::casDGIntfIO ( caServerI & serverIn, clientBufMemoryManager & memMgr
|
||||
// add in the configured addresses
|
||||
//
|
||||
addAddrToChannelAccessAddressList (
|
||||
& BCastAddrList, pParam, beaconPort );
|
||||
& BCastAddrList, pParam, beaconPort, pParam == & EPICS_CA_ADDR_LIST );
|
||||
}
|
||||
|
||||
removeDuplicateAddresses ( & this->beaconAddrList, & BCastAddrList, 0 );
|
||||
@@ -177,7 +177,7 @@ casDGIntfIO::casDGIntfIO ( caServerI & serverIn, clientBufMemoryManager & memMgr
|
||||
ellInit ( & parsed );
|
||||
ellInit ( & filtered );
|
||||
// we dont care what port they are coming from
|
||||
addAddrToChannelAccessAddressList ( & parsed, & EPICS_CAS_IGNORE_ADDR_LIST, 0 );
|
||||
addAddrToChannelAccessAddressList ( & parsed, & EPICS_CAS_IGNORE_ADDR_LIST, 0, false );
|
||||
removeDuplicateAddresses ( & filtered, & parsed, true );
|
||||
|
||||
while ( ELLNODE * pRawNode = ellGet ( & filtered ) ) {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
|
||||
# Synchrotronstrahlung.
|
||||
# EPICS BASE Versions 3.13.7
|
||||
# and higher are distributed subject to a Software License Agreement found
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
TOP=../..
|
||||
@@ -14,21 +13,18 @@ TOP=../..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
SHARED_LIBRARIES = NO
|
||||
#STATIC_BUILD=YES
|
||||
|
||||
# Build but don't install catools as a static library
|
||||
LIBRARY_HOST += catools
|
||||
INSTALL_LIBS =
|
||||
|
||||
catools_SRCS += tool_lib.c
|
||||
|
||||
catools_LIBS += ca Com
|
||||
|
||||
#Remove LIBNAME from the library names to be installed (make it a local library)
|
||||
INSTALL_LIBS= $(addprefix $(INSTALL_LIB)/,$(filterout $(TESTLIBNAME),$(LIBNAME)))
|
||||
|
||||
# Build and link programs against the catools library
|
||||
PROD_HOST += caget camonitor cainfo caput
|
||||
|
||||
PROD_LIBS += catools ca Com
|
||||
|
||||
catools_DIR=.
|
||||
catools_DIR = .
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
@@ -45,10 +45,14 @@ void usage (void)
|
||||
" -m <mask>: Specify CA event mask to use, with <mask> being any combination of\n"
|
||||
" 'v' (value), 'a' (alarm), 'l' (log). Default: va\n"
|
||||
"Timestamps:\n"
|
||||
" Default: Print absolute timestamps (as reported by CA)\n"
|
||||
" -r: Relative timestamps (time elapsed since start of program)\n"
|
||||
" -i: Incremental timestamps (time elapsed since last update)\n"
|
||||
" -I: Incremental timestamps (time elapsed since last update for this channel)\n"
|
||||
" Default: Print absolute timestamps (as reported by CA server)\n"
|
||||
" -t <key>: Specify timestamp source(s) and type, with <key> containing\n"
|
||||
" 's' = CA server (remote) timestamps\n"
|
||||
" 'c' = CA client (local) timestamps (shown in '()'s)\n"
|
||||
" 'n' = no timestamps\n"
|
||||
" 'r' = relative timestamps (time elapsed since start of program)\n"
|
||||
" 'i' = incremental timestamps (time elapsed since last update)\n"
|
||||
" 'I' = incremental timestamps (time elapsed since last update, by channel)\n"
|
||||
"Enum format:\n"
|
||||
" -n: Print DBF_ENUM values as number (default are enum string values)\n"
|
||||
"Arrays: Value format: print number of requested values, then list of values\n"
|
||||
@@ -204,7 +208,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */
|
||||
|
||||
while ((opt = getopt(argc, argv, ":nhriIm:se:f:g:#:d:0:w:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, ":nhm:se:f:g:#:d:0:w:t:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h': /* Print usage */
|
||||
usage();
|
||||
@@ -212,14 +216,25 @@ int main (int argc, char *argv[])
|
||||
case 'n': /* Print ENUM as index numbers */
|
||||
enumAsNr=1;
|
||||
break;
|
||||
case 'r': /* Select relative timestamps */
|
||||
tsType = relative;
|
||||
break;
|
||||
case 'i': /* Select incremental timestamps */
|
||||
tsType = incremental;
|
||||
break;
|
||||
case 'I': /* Select incremental timestamps (by channel) */
|
||||
tsType = incrementalByChan;
|
||||
case 't': /* Select timestamp source(s) and type */
|
||||
tsSrcServer = 0;
|
||||
tsSrcClient = 0;
|
||||
{
|
||||
int i = 0;
|
||||
char c;
|
||||
while ((c = optarg[i++]))
|
||||
switch (c) {
|
||||
case 's': tsSrcServer = 1; break;
|
||||
case 'c': tsSrcClient = 1; break;
|
||||
case 'n': break;
|
||||
case 'r': tsType = relative; break;
|
||||
case 'i': tsType = incremental; break;
|
||||
case 'I': tsType = incrementalByChan; break;
|
||||
default :
|
||||
fprintf(stderr, "Invalid argument '%c' "
|
||||
"for option '-t' - ignored.\n", c);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'w': /* Set CA timeout value */
|
||||
if(epicsScanDouble(optarg, &caTimeout) != 1)
|
||||
|
||||
@@ -28,13 +28,17 @@
|
||||
|
||||
#include "tool_lib.h"
|
||||
|
||||
/* Time stamps for program start, previous value (used for relative resp.
|
||||
* incremental times with monitors) */
|
||||
static epicsTimeStamp tsStart, tsPrevious;
|
||||
/* Time stamps for program start, first incoming monitor,
|
||||
previous value (client and server stamp):
|
||||
used for relative resp. incremental timestamps with monitors */
|
||||
static epicsTimeStamp tsStart, tsFirst, tsPreviousC, tsPreviousS;
|
||||
|
||||
static int tsInit = 0; /* Flag: Timestamps init'd */
|
||||
static int tsInitS = 0; /* Flag: Server timestamps init'd */
|
||||
static int tsInitC = 0; /* Flag: Client timestamps init'd */
|
||||
|
||||
TimeT tsType = absolute; /* Timestamp type flag (-riI options) */
|
||||
TimeT tsType = absolute; /* Timestamp type flag (-t option) */
|
||||
int tsSrcServer = 1; /* Timestamp source flag (-t option) */
|
||||
int tsSrcClient = 0; /* Timestamp source flag (-t option) */
|
||||
IntFormatT outType = dec; /* For -0.. output format option */
|
||||
|
||||
char dblFormatStr[30] = "%g"; /* Format string to print doubles (-efg options) */
|
||||
@@ -366,80 +370,91 @@ char *dbr2str (const void *value, unsigned type)
|
||||
*
|
||||
**************************************************************************-*/
|
||||
|
||||
#define PRN_TIME_VAL_STS(TYPE,TYPE_ENUM) \
|
||||
printAbs = 0; \
|
||||
\
|
||||
switch (tsType) { \
|
||||
case relative: \
|
||||
ptsRef = &tsStart; \
|
||||
break; \
|
||||
case incremental: \
|
||||
ptsRef = &tsPrevious; \
|
||||
break; \
|
||||
case incrementalByChan: \
|
||||
ptsRef = &pv->tsPrevious; \
|
||||
break; \
|
||||
default : \
|
||||
printAbs = 1; \
|
||||
} \
|
||||
\
|
||||
if (!printAbs) { \
|
||||
if (pv->firstStampPrinted) \
|
||||
{ \
|
||||
printf("%10.4fs ", epicsTimeDiffInSeconds( \
|
||||
&(((struct TYPE *)value)->stamp), ptsRef) ); \
|
||||
} else { /* First stamp is always absolute */ \
|
||||
printAbs = 1; \
|
||||
pv->firstStampPrinted = 1; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (tsType == incrementalByChan) \
|
||||
pv->tsPrevious = ((struct TYPE *)value)->stamp; \
|
||||
\
|
||||
if (printAbs) { \
|
||||
epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, \
|
||||
&(((struct TYPE *)value)->stamp)); \
|
||||
printf("%s ", timeText); \
|
||||
} \
|
||||
\
|
||||
tsPrevious = ((struct TYPE *)value)->stamp; \
|
||||
\
|
||||
/* Print count if array */ \
|
||||
if ( nElems > 1 ) printf("%lu ", nElems); \
|
||||
/* Print Values */ \
|
||||
for (i=0; i<nElems; ++i) { \
|
||||
printf ("%s ", val2str(value, TYPE_ENUM, i)); \
|
||||
} \
|
||||
/* Print Status, Severity - if not NO_ALARM */ \
|
||||
if ( ((struct TYPE *)value)->status || ((struct TYPE *)value)->severity ) \
|
||||
{ \
|
||||
printf("%s %s\n", \
|
||||
stat_to_str(((struct TYPE *)value)->status), \
|
||||
sevr_to_str(((struct TYPE *)value)->severity)); \
|
||||
} else { \
|
||||
printf("\n"); \
|
||||
#define PRN_TIME_VAL_STS(TYPE,TYPE_ENUM) \
|
||||
printAbs = !pv->firstStampPrinted; \
|
||||
\
|
||||
ptsNewS = &((struct TYPE *)value)->stamp; \
|
||||
ptsNewC = &tsNow; \
|
||||
\
|
||||
switch (tsType) { \
|
||||
case relative: \
|
||||
ptsRefC = &tsStart; \
|
||||
ptsRefS = &tsFirst; \
|
||||
break; \
|
||||
case incremental: \
|
||||
ptsRefC = &tsPreviousC; \
|
||||
ptsRefS = &tsPreviousS; \
|
||||
break; \
|
||||
case incrementalByChan: \
|
||||
ptsRefC = &pv->tsPreviousC; \
|
||||
ptsRefS = &pv->tsPreviousS; \
|
||||
break; \
|
||||
default : \
|
||||
printAbs = 1; \
|
||||
} \
|
||||
\
|
||||
if (printAbs) { \
|
||||
if (tsSrcServer) { \
|
||||
epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, ptsNewS); \
|
||||
printf("%s ", timeText); \
|
||||
} \
|
||||
if (tsSrcClient) { \
|
||||
epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, ptsNewC); \
|
||||
printf("(%s) ", timeText); \
|
||||
} \
|
||||
pv->firstStampPrinted = 1; \
|
||||
} else { \
|
||||
if (tsSrcServer) { \
|
||||
printf(" %+12.6f ", epicsTimeDiffInSeconds(ptsNewS, ptsRefS) ); \
|
||||
} \
|
||||
if (tsSrcClient) { \
|
||||
printf(" (%+12.6f) ", epicsTimeDiffInSeconds(ptsNewC, ptsRefC) ); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (tsType == incrementalByChan) { \
|
||||
pv->tsPreviousC = *ptsNewC; \
|
||||
pv->tsPreviousS = *ptsNewS; \
|
||||
} \
|
||||
\
|
||||
tsPreviousC = *ptsNewC; \
|
||||
tsPreviousS = *ptsNewS; \
|
||||
\
|
||||
/* Print count if array */ \
|
||||
if ( nElems > 1 ) printf("%lu ", nElems); \
|
||||
/* Print Values */ \
|
||||
for (i=0; i<nElems; ++i) { \
|
||||
printf ("%s ", val2str(value, TYPE_ENUM, i)); \
|
||||
} \
|
||||
/* Print Status, Severity - if not NO_ALARM */ \
|
||||
if ( ((struct TYPE *)value)->status || ((struct TYPE *)value)->severity ) \
|
||||
{ \
|
||||
printf("%s %s\n", \
|
||||
stat_to_str(((struct TYPE *)value)->status), \
|
||||
sevr_to_str(((struct TYPE *)value)->severity)); \
|
||||
} else { \
|
||||
printf("\n"); \
|
||||
}
|
||||
|
||||
|
||||
void print_time_val_sts (pv* pv, unsigned long nElems)
|
||||
{
|
||||
char timeText[TIMETEXTLEN];
|
||||
char timeText[2*TIMETEXTLEN+2];
|
||||
int i, printAbs;
|
||||
void* value = pv->value;
|
||||
epicsTimeStamp *ptsRef = &tsStart;
|
||||
epicsTimeStamp *ptsRefC, *ptsRefS; /* Reference timestamps (client, server) */
|
||||
epicsTimeStamp *ptsNewC, *ptsNewS; /* Update timestamps (client, server) */
|
||||
epicsTimeStamp tsNow;
|
||||
|
||||
if (!tsInit) /* Initialize start timestamp */
|
||||
{
|
||||
epicsTimeGetCurrent(&tsStart);
|
||||
tsPrevious = tsStart;
|
||||
tsInit = 1;
|
||||
}
|
||||
|
||||
epicsTimeGetCurrent(&tsNow);
|
||||
epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, &tsNow);
|
||||
|
||||
if (!tsInitS)
|
||||
{
|
||||
tsFirst = tsNow;
|
||||
tsInitS = 1;
|
||||
}
|
||||
|
||||
printf("%-30s ", pv->name);
|
||||
if (!pv->onceConnected)
|
||||
printf("*** Not connected (PV not found)\n");
|
||||
@@ -502,6 +517,12 @@ int create_pvs (pv* pvs, int nPvs, caCh *pCB)
|
||||
int n;
|
||||
int result;
|
||||
int returncode = 0;
|
||||
|
||||
if (!tsInitC) /* Initialize start timestamp */
|
||||
{
|
||||
epicsTimeGetCurrent(&tsStart);
|
||||
tsInitC = 1;
|
||||
}
|
||||
/* Issue channel connections */
|
||||
for (n = 0; n < nPvs; n++) {
|
||||
result = ca_create_channel (pvs[n].name,
|
||||
|
||||
@@ -65,13 +65,16 @@ typedef struct
|
||||
unsigned long reqElems;
|
||||
int status;
|
||||
void* value;
|
||||
epicsTimeStamp tsPrevious;
|
||||
epicsTimeStamp tsPreviousC;
|
||||
epicsTimeStamp tsPreviousS;
|
||||
char firstStampPrinted;
|
||||
char onceConnected;
|
||||
} pv;
|
||||
|
||||
|
||||
extern TimeT tsType; /* Timestamp type flag (-r -i -I options) */
|
||||
extern TimeT tsType; /* Timestamp type flag (-t option) */
|
||||
extern int tsSrcServer; /* Timestamp source flag (-t option) */
|
||||
extern int tsSrcClient; /* Timestamp source flag (-t option) */
|
||||
extern IntFormatT outType; /* Flag used for -0.. output format option */
|
||||
extern int enumAsNr; /* Used for -n option (get DBF_ENUM as number) */
|
||||
extern double caTimeout; /* Wait time default (see -w option) */
|
||||
|
||||
@@ -338,6 +338,7 @@ static void getOptions(DBADDR *paddr,char **poriginal,long *options,void *pflin)
|
||||
pbuffer += dbr_units_size;
|
||||
}
|
||||
if( (*options) & DBR_PRECISION ) {
|
||||
memset(pbuffer, '\0', dbr_precision_size);
|
||||
if((field_type==DBF_FLOAT || field_type==DBF_DOUBLE)
|
||||
&& prset && prset->get_precision ){
|
||||
(*prset->get_precision)(paddr,pbuffer);
|
||||
|
||||
@@ -111,7 +111,7 @@ epicsShareExtern volatile int interruptAccept;
|
||||
long dp; /* number of decimal places*/\
|
||||
double unused; /* for alignment */\
|
||||
} precision;
|
||||
/* precision must be long to match the pointer arguments to
|
||||
/* precision.dp must be long to match the pointer arguments to
|
||||
* RSET->get_precision() and recGblGetPrec(), which it's
|
||||
* too late to change now. DBRprecision must be padded to
|
||||
* maintain 8-byte alignment. */
|
||||
|
||||
@@ -48,6 +48,7 @@ LIBSRCS += devMbboDirectSoftCallback.c
|
||||
LIBSRCS += devSoSoftCallback.c
|
||||
|
||||
LIBSRCS += devTimestamp.c
|
||||
LIBSRCS += devSoStdio.c
|
||||
|
||||
LIBRARY_IOC += softDevIoc
|
||||
softDevIoc_LIBS += miscIoc recIoc asIoc dbIoc registryIoc dbStaticIoc ca Com
|
||||
|
||||
109
src/dev/softDev/devSoStdio.c
Normal file
109
src/dev/softDev/devSoStdio.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dbCommon.h"
|
||||
#include "devSup.h"
|
||||
#include "errlog.h"
|
||||
#include "recGbl.h"
|
||||
#include "recSup.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
#include "stringoutRecord.h"
|
||||
|
||||
typedef int (*PRINTFFUNC)(const char *fmt, ...);
|
||||
|
||||
static int stderrPrintf(const char *fmt, ...);
|
||||
static int logPrintf(const char *fmt, ...);
|
||||
|
||||
|
||||
static struct outStream {
|
||||
const char *name;
|
||||
PRINTFFUNC print;
|
||||
} outStreams[] = {
|
||||
{"stdout", printf},
|
||||
{"stderr", stderrPrintf},
|
||||
{"errlog", logPrintf},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static int stderrPrintf(const char *fmt, ...) {
|
||||
va_list pvar;
|
||||
int retval;
|
||||
|
||||
va_start(pvar, fmt);
|
||||
retval = vfprintf(stderr, fmt, pvar);
|
||||
va_end (pvar);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int logPrintf(const char *fmt, ...) {
|
||||
va_list pvar;
|
||||
int retval;
|
||||
|
||||
va_start(pvar, fmt);
|
||||
retval = errlogVprintf(fmt, pvar);
|
||||
va_end (pvar);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static long add(dbCommon *pcommon) {
|
||||
stringoutRecord *prec = (stringoutRecord *) pcommon;
|
||||
struct outStream *pstream;
|
||||
|
||||
if (prec->out.type != INST_IO)
|
||||
return S_dev_badOutType;
|
||||
|
||||
for (pstream = outStreams; pstream->name; ++pstream) {
|
||||
if (strcmp(prec->out.value.instio.string, pstream->name) == 0) {
|
||||
prec->dpvt = pstream;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
prec->dpvt = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static long del(dbCommon *pcommon) {
|
||||
stringoutRecord *prec = (stringoutRecord *) pcommon;
|
||||
|
||||
prec->dpvt = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dsxt dsxtSoStdio = {
|
||||
add, del
|
||||
};
|
||||
|
||||
static long init(int pass)
|
||||
{
|
||||
if (pass == 0) devExtend(&dsxtSoStdio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long write_string(stringoutRecord *prec)
|
||||
{
|
||||
struct outStream *pstream = (struct outStream *)prec->dpvt;
|
||||
if (pstream)
|
||||
pstream->print("%s\n", prec->val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create the dset for devSoStdio */
|
||||
static struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devSoStdio = {
|
||||
{5, NULL, init, NULL, NULL}, write_string
|
||||
};
|
||||
epicsExportAddress(dset, devSoStdio);
|
||||
@@ -39,3 +39,5 @@ device(ai, INST_IO,devAiGeneralTime,"General Time")
|
||||
device(bo, INST_IO,devBoGeneralTime,"General Time")
|
||||
device(longin, INST_IO,devLiGeneralTime,"General Time")
|
||||
device(stringin,INST_IO,devSiGeneralTime,"General Time")
|
||||
|
||||
device(stringout,INST_IO,devSoStdio,"stdio")
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
@@ -93,4 +92,13 @@
|
||||
# define EPICS_PRINTF_STYLE(f,a)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Deprecation marker
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
# define EPICS_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
# define EPICS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#endif /* ifndef compilerDependencies_h */
|
||||
|
||||
@@ -82,7 +82,7 @@ template class tsFreeList
|
||||
|
||||
extern "C" {
|
||||
static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * );
|
||||
static void ipAddrToAsciiEngineGlobalMutexDestruct ( void * );
|
||||
static void ipAddrToAsciiEngineShutdownRequest ( void * );
|
||||
}
|
||||
|
||||
// - this class executes the synchronous DNS query
|
||||
@@ -111,6 +111,7 @@ private:
|
||||
static epicsMutex * pGlobalMutex;
|
||||
static ipAddrToAsciiEnginePrivate * pEngine;
|
||||
static unsigned numberOfReferences;
|
||||
static bool shutdownRequest;
|
||||
ipAddrToAsciiTransaction & createTransaction ();
|
||||
void release ();
|
||||
void run ();
|
||||
@@ -118,13 +119,14 @@ private:
|
||||
ipAddrToAsciiEnginePrivate & operator = ( const ipAddrToAsciiEngine & );
|
||||
friend class ipAddrToAsciiEngine;
|
||||
friend class ipAddrToAsciiTransactionPrivate;
|
||||
friend void ipAddrToAsciiEngineGlobalMutexDestruct ( void * );
|
||||
friend void ipAddrToAsciiEngineShutdownRequest ( void * );
|
||||
friend void ipAddrToAsciiEngineGlobalMutexConstruct ( void * );
|
||||
};
|
||||
|
||||
epicsMutex * ipAddrToAsciiEnginePrivate :: pGlobalMutex = 0;
|
||||
ipAddrToAsciiEnginePrivate * ipAddrToAsciiEnginePrivate :: pEngine = 0;
|
||||
unsigned ipAddrToAsciiEnginePrivate :: numberOfReferences = 0u;
|
||||
bool ipAddrToAsciiEnginePrivate :: shutdownRequest = false;
|
||||
static epicsThreadOnceId ipAddrToAsciiEngineGlobalMutexOnceFlag = 0;
|
||||
|
||||
// the users are not required to supply a show routine
|
||||
@@ -136,15 +138,26 @@ ipAddrToAsciiCallBack::~ipAddrToAsciiCallBack () {}
|
||||
ipAddrToAsciiTransaction::~ipAddrToAsciiTransaction () {}
|
||||
ipAddrToAsciiEngine::~ipAddrToAsciiEngine () {}
|
||||
|
||||
static void ipAddrToAsciiEngineGlobalMutexDestruct ( void * )
|
||||
static void ipAddrToAsciiEngineShutdownRequest ( void * )
|
||||
{
|
||||
delete ipAddrToAsciiEnginePrivate :: pGlobalMutex;
|
||||
bool deleteGlobalMutexCondDetected = false;
|
||||
{
|
||||
epicsGuard < epicsMutex >
|
||||
guard ( * ipAddrToAsciiEnginePrivate :: pGlobalMutex );
|
||||
ipAddrToAsciiEnginePrivate :: shutdownRequest = true;
|
||||
deleteGlobalMutexCondDetected =
|
||||
( ipAddrToAsciiEnginePrivate :: numberOfReferences == 0 );
|
||||
}
|
||||
if ( deleteGlobalMutexCondDetected ) {
|
||||
delete ipAddrToAsciiEnginePrivate :: pGlobalMutex;
|
||||
ipAddrToAsciiEnginePrivate :: pEngine = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * )
|
||||
{
|
||||
ipAddrToAsciiEnginePrivate :: pGlobalMutex = new epicsMutex ();
|
||||
epicsAtExit ( ipAddrToAsciiEngineGlobalMutexDestruct, 0 );
|
||||
epicsAtExit ( ipAddrToAsciiEngineShutdownRequest, 0 );
|
||||
}
|
||||
|
||||
// for now its probably sufficent to allocate one
|
||||
@@ -156,6 +169,16 @@ ipAddrToAsciiEngine & ipAddrToAsciiEngine::allocate ()
|
||||
epicsThreadOnce (
|
||||
& ipAddrToAsciiEngineGlobalMutexOnceFlag,
|
||||
ipAddrToAsciiEngineGlobalMutexConstruct, 0 );
|
||||
// since we must not own lock when checking this flag
|
||||
// this diagnostic has imperfect detection, but never
|
||||
// incorrect detection
|
||||
if ( ipAddrToAsciiEnginePrivate :: shutdownRequest ) {
|
||||
throw std :: runtime_error (
|
||||
"ipAddrToAsciiEngine::allocate (): "
|
||||
"attempts to create an "
|
||||
"ipAddrToAsciiEngine while the exit "
|
||||
"handlers are running are rejected");
|
||||
}
|
||||
epicsGuard < epicsMutex > guard ( * ipAddrToAsciiEnginePrivate::pGlobalMutex );
|
||||
if ( ! ipAddrToAsciiEnginePrivate::pEngine ) {
|
||||
ipAddrToAsciiEnginePrivate::pEngine = new ipAddrToAsciiEnginePrivate ();
|
||||
@@ -190,15 +213,23 @@ ipAddrToAsciiEnginePrivate::~ipAddrToAsciiEnginePrivate ()
|
||||
// leave our options open for the future
|
||||
void ipAddrToAsciiEnginePrivate::release ()
|
||||
{
|
||||
bool deleteGlobalMutexCondDetected = false;
|
||||
epicsThreadOnce (
|
||||
& ipAddrToAsciiEngineGlobalMutexOnceFlag,
|
||||
ipAddrToAsciiEngineGlobalMutexConstruct, 0 );
|
||||
epicsGuard < epicsMutex > guard ( * ipAddrToAsciiEnginePrivate::pGlobalMutex );
|
||||
assert ( ipAddrToAsciiEnginePrivate::numberOfReferences > 0u );
|
||||
ipAddrToAsciiEnginePrivate::numberOfReferences--;
|
||||
if ( ipAddrToAsciiEnginePrivate::numberOfReferences == 0u ) {
|
||||
delete ipAddrToAsciiEnginePrivate::pEngine;
|
||||
ipAddrToAsciiEnginePrivate::pEngine = 0;
|
||||
{
|
||||
epicsGuard < epicsMutex >
|
||||
guard ( * ipAddrToAsciiEnginePrivate::pGlobalMutex );
|
||||
assert ( ipAddrToAsciiEnginePrivate::numberOfReferences > 0u );
|
||||
ipAddrToAsciiEnginePrivate::numberOfReferences--;
|
||||
if ( ipAddrToAsciiEnginePrivate::numberOfReferences == 0u ) {
|
||||
deleteGlobalMutexCondDetected =
|
||||
ipAddrToAsciiEnginePrivate :: shutdownRequest;
|
||||
}
|
||||
}
|
||||
if ( deleteGlobalMutexCondDetected ) {
|
||||
delete ipAddrToAsciiEnginePrivate :: pGlobalMutex;
|
||||
ipAddrToAsciiEnginePrivate :: pEngine = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <exception>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
@@ -126,28 +127,40 @@ void epicsThread::exitWait () throw ()
|
||||
|
||||
bool epicsThread::exitWait ( const double delay ) throw ()
|
||||
{
|
||||
// if destructor is running in managed thread then of
|
||||
// course we will not wait for the managed thread to
|
||||
// exit
|
||||
if ( this->isCurrentThread() ) {
|
||||
if ( this->pWaitReleaseFlag ) {
|
||||
*this->pWaitReleaseFlag = true;
|
||||
try {
|
||||
// if destructor is running in managed thread then of
|
||||
// course we will not wait for the managed thread to
|
||||
// exit
|
||||
if ( this->isCurrentThread() ) {
|
||||
if ( this->pWaitReleaseFlag ) {
|
||||
*this->pWaitReleaseFlag = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
epicsTime exitWaitBegin = epicsTime::getCurrent ();
|
||||
double exitWaitElapsed = 0.0;
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
this->cancel = true;
|
||||
while ( ! this->terminated && exitWaitElapsed < delay ) {
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
this->event.signal ();
|
||||
this->exitEvent.wait ( delay - exitWaitElapsed );
|
||||
epicsTime current = epicsTime::getCurrent ();
|
||||
exitWaitElapsed = current - exitWaitBegin;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
epicsTime exitWaitBegin = epicsTime::getCurrent ();
|
||||
double exitWaitElapsed = 0.0;
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
this->cancel = true;
|
||||
while ( ! this->terminated ) {
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
this->event.signal ();
|
||||
this->exitEvent.wait ( delay - exitWaitElapsed );
|
||||
epicsTime current = epicsTime::getCurrent ();
|
||||
exitWaitElapsed = current - exitWaitBegin;
|
||||
if ( exitWaitElapsed >= delay ) {
|
||||
break;
|
||||
}
|
||||
catch ( std :: exception & except ) {
|
||||
errlogPrintf (
|
||||
"epicsThread::exitWait(): Unexpected exception "
|
||||
" \"%s\"\n",
|
||||
except.what () );
|
||||
epicsThreadSleep ( std :: min ( delay, 5.0 ) );
|
||||
}
|
||||
catch ( ... ) {
|
||||
errlogPrintf (
|
||||
"Non-standard unexpected exception in "
|
||||
"epicsThread::exitWait()\n" );
|
||||
epicsThreadSleep ( std :: min ( delay, 5.0 ) );
|
||||
}
|
||||
return this->terminated;
|
||||
}
|
||||
|
||||
45
src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp
Normal file
45
src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
* Author: Jeff Hill
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "osiSock.h"
|
||||
#include "errlog.h"
|
||||
|
||||
/*
|
||||
* Note: WINSOCK appears to assign a different functionality for
|
||||
* SO_REUSEADDR compared to other OS. With WINSOCK SO_REUSEADDR indicates
|
||||
* that simultaneously servers can bind to the same TCP port on the same host!
|
||||
* Also, servers are always enabled to reuse a port immediately after
|
||||
* they exit ( even if SO_REUSEADDR isnt set ).
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI
|
||||
epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s )
|
||||
{
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI
|
||||
epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s )
|
||||
{
|
||||
int yes = true;
|
||||
int status;
|
||||
status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *) & yes, sizeof ( yes ) );
|
||||
if ( status < 0 ) {
|
||||
errlogPrintf (
|
||||
"epicsSocketEnablePortUseForDatagramFanout: "
|
||||
"unable to set SO_REUSEADDR?\n");
|
||||
}
|
||||
}
|
||||
@@ -18,21 +18,21 @@
|
||||
#include <sysLib.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* The following not defined in an vxWorks header */
|
||||
#include "epicsEvent.h"
|
||||
|
||||
/* The following not defined in any vxWorks header */
|
||||
int sysClkRateGet(void);
|
||||
|
||||
#include "epicsEvent.h"
|
||||
|
||||
epicsEventId epicsEventCreate(epicsEventInitialState initialState)
|
||||
{
|
||||
return((epicsEventId)semBCreate(
|
||||
SEM_Q_FIFO,((initialState==epicsEventEmpty) ? SEM_EMPTY : SEM_FULL)));
|
||||
return (epicsEventId) semBCreate(SEM_Q_FIFO,
|
||||
(initialState == epicsEventEmpty) ? SEM_EMPTY : SEM_FULL);
|
||||
}
|
||||
|
||||
epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
|
||||
{
|
||||
epicsEventId id = epicsEventCreate (initialState);
|
||||
assert (id);
|
||||
epicsEventId id = epicsEventCreate(initialState);
|
||||
assert(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -41,8 +41,7 @@ void epicsEventDestroy(epicsEventId id)
|
||||
semDelete((SEM_ID)id);
|
||||
}
|
||||
|
||||
epicsEventWaitStatus epicsEventWaitWithTimeout(
|
||||
epicsEventId id, double timeOut)
|
||||
epicsEventWaitStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
|
||||
{
|
||||
int rate = sysClkRateGet();
|
||||
int status;
|
||||
@@ -54,24 +53,30 @@ epicsEventWaitStatus epicsEventWaitWithTimeout(
|
||||
ticks = WAIT_FOREVER;
|
||||
} else {
|
||||
ticks = timeOut * rate;
|
||||
if (ticks<=0) ticks = 1;
|
||||
if (ticks <= 0)
|
||||
ticks = 1;
|
||||
}
|
||||
status = semTake((SEM_ID)id,ticks);
|
||||
if(status==OK) return(epicsEventWaitOK);
|
||||
if(errno==S_objLib_OBJ_TIMEOUT) return(epicsEventWaitTimeout);
|
||||
return(epicsEventWaitError);
|
||||
status = semTake((SEM_ID)id, ticks);
|
||||
if (status == OK)
|
||||
return epicsEventWaitOK;
|
||||
if (errno == S_objLib_OBJ_TIMEOUT ||
|
||||
(errno == S_objLib_OBJ_UNAVAILABLE && ticks == 0))
|
||||
return epicsEventWaitTimeout;
|
||||
return epicsEventWaitError;
|
||||
}
|
||||
|
||||
epicsEventWaitStatus epicsEventTryWait(epicsEventId id)
|
||||
{
|
||||
int status;
|
||||
status = semTake((SEM_ID)id,NO_WAIT);
|
||||
if(status==OK) return(epicsEventWaitOK);
|
||||
if(errno==S_objLib_OBJ_UNAVAILABLE) return(epicsEventWaitTimeout);
|
||||
return(epicsEventWaitError);
|
||||
int status = semTake((SEM_ID)id, NO_WAIT);
|
||||
|
||||
if (status == OK)
|
||||
return epicsEventWaitOK;
|
||||
if (errno == S_objLib_OBJ_UNAVAILABLE)
|
||||
return epicsEventWaitTimeout;
|
||||
return epicsEventWaitError;
|
||||
}
|
||||
|
||||
void epicsEventShow(epicsEventId id,unsigned int level)
|
||||
void epicsEventShow(epicsEventId id, unsigned int level)
|
||||
{
|
||||
semShow((SEM_ID)id,level);
|
||||
}
|
||||
|
||||
@@ -144,31 +144,35 @@ MAIN(epicsEventTest)
|
||||
epicsEventId event;
|
||||
int status;
|
||||
|
||||
testPlan(10);
|
||||
testPlan(11);
|
||||
|
||||
event = epicsEventMustCreate(epicsEventEmpty);
|
||||
|
||||
status = epicsEventWaitWithTimeout(event, 2.0);
|
||||
status = epicsEventWaitWithTimeout(event, 0.0);
|
||||
testOk(status == epicsEventWaitTimeout,
|
||||
"epicsEventWaitWithTimeout(event, 2.0) = %d", status);
|
||||
"epicsEventWaitWithTimeout(event, 0.0) = %d", status);
|
||||
|
||||
status = epicsEventWaitWithTimeout(event, 1.0);
|
||||
testOk(status == epicsEventWaitTimeout,
|
||||
"epicsEventWaitWithTimeout(event, 1.0) = %d", status);
|
||||
|
||||
status = epicsEventTryWait(event);
|
||||
testOk(status == epicsEventWaitTimeout,
|
||||
"epicsEventTryWait(event) = %d", status);
|
||||
|
||||
epicsEventSignal(event);
|
||||
status = epicsEventWaitWithTimeout(event,2.0);
|
||||
testOk(status == 0,
|
||||
"epicsEventWaitWithTimeout(event, 2.0) = %d", status);
|
||||
status = epicsEventWaitWithTimeout(event, 1.0);
|
||||
testOk(status == epicsEventWaitOK,
|
||||
"epicsEventWaitWithTimeout(event, 1.0) = %d", status);
|
||||
|
||||
epicsEventSignal(event);
|
||||
status = epicsEventWaitWithTimeout(event,DBL_MAX);
|
||||
testOk(status == 0,
|
||||
testOk(status == epicsEventWaitOK,
|
||||
"epicsEventWaitWithTimeout(event, DBL_MAX) = %d", status);
|
||||
|
||||
epicsEventSignal(event);
|
||||
status = epicsEventTryWait(event);
|
||||
testOk(status == 0,
|
||||
testOk(status == epicsEventWaitOK,
|
||||
"epicsEventTryWait(event) = %d", status);
|
||||
|
||||
info *pinfo = (info *)calloc(1,sizeof(info));
|
||||
|
||||
@@ -36,7 +36,7 @@ static void testEpicsSnprintf() {
|
||||
const char *svalue = "OneTwoThreeFour";
|
||||
const char *format = "int %d float %8.2e string %s";
|
||||
const char *expected = exbuffer;
|
||||
size_t size;
|
||||
int size;
|
||||
int rtn, rlen;
|
||||
|
||||
sprintf(exbuffer, format, ivalue, fvalue, svalue);
|
||||
|
||||
@@ -205,7 +205,7 @@ void rsrv_online_notify_task(void *pParm)
|
||||
* add in the configured addresses
|
||||
*/
|
||||
addAddrToChannelAccessAddressList (
|
||||
&autoAddrList, pParam, port);
|
||||
&autoAddrList, pParam, port, pParam == &EPICS_CA_ADDR_LIST );
|
||||
}
|
||||
|
||||
removeDuplicateAddresses ( &beaconAddrList, &autoAddrList, 0 );
|
||||
|
||||
@@ -11,13 +11,6 @@ include $(TOP)/configure/CONFIG
|
||||
# Bootstrap resolution: tools not installed yet
|
||||
TOOLS = $(TOP)/src/tools
|
||||
|
||||
# Bootstrap resolution: expandVars.pl needs to be run on itself!
|
||||
EXPAND_TOOL = $(PERL) $(TOOLS)/expandVars.pl@
|
||||
|
||||
EXPAND += convertRelease.pl@
|
||||
EXPAND += expandVars.pl@
|
||||
EXPAND += fullPathName.pl@
|
||||
|
||||
PERL_MODULES += EPICS/Copy.pm
|
||||
PERL_MODULES += EPICS/Path.pm
|
||||
PERL_MODULES += EPICS/Release.pm
|
||||
|
||||
@@ -15,7 +15,9 @@ eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
#
|
||||
|
||||
use strict;
|
||||
use lib '@TOP@/lib/perl';
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../../lib/perl";
|
||||
|
||||
use Cwd qw(cwd abs_path);
|
||||
use Getopt::Std;
|
||||
@@ -9,16 +9,11 @@
|
||||
# $Id$
|
||||
#
|
||||
|
||||
BEGIN {
|
||||
# Do not copy this BEGIN code for other tools,
|
||||
# it's only needed so expandVars can bootstrap itself.
|
||||
our $libperl = '@TOP@/lib/perl';
|
||||
$libperl = '..' if ($libperl =~ m/^[@]TOP[@]/);
|
||||
}
|
||||
use lib $libperl;
|
||||
|
||||
use strict;
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../../lib/perl";
|
||||
|
||||
use EPICS::Getopts;
|
||||
use EPICS::Path;
|
||||
use EPICS::Release;
|
||||
@@ -15,7 +15,9 @@ eval 'exec perl -S -w $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
|
||||
use strict;
|
||||
|
||||
use lib '@TOP@/lib/perl';
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../../lib/perl";
|
||||
|
||||
use EPICS::Path;
|
||||
|
||||
print AbsPath(shift), "\n";
|
||||
Reference in New Issue
Block a user