Compare commits
99 Commits
R3.14.10-p
...
R3.14.10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4f741f97c | ||
|
|
0e08b62f34 | ||
|
|
2b37a8f746 | ||
|
|
f5967d268c | ||
|
|
078e30b7b9 | ||
|
|
01349a9448 | ||
|
|
dd2ef6d47a | ||
|
|
2d51fbc3c7 | ||
|
|
c5f15a3e17 | ||
|
|
cdd2748c98 | ||
|
|
6789814826 | ||
|
|
b3abcbb52e | ||
|
|
3274519a82 | ||
|
|
95b708a40b | ||
|
|
3b2bbd50e5 | ||
|
|
ab765613ec | ||
|
|
ba5080d6f4 | ||
|
|
a6ed0d3a53 | ||
|
|
edc141f98a | ||
|
|
7245f8127c | ||
|
|
ba37f17c89 | ||
|
|
e6e9b9a266 | ||
|
|
570825f693 | ||
|
|
2c020ffac4 | ||
|
|
bf829e0f48 | ||
|
|
9239b50615 | ||
|
|
2eb849b91c | ||
|
|
0fff507aea | ||
|
|
49687e27b2 | ||
|
|
98e09831fa | ||
|
|
36af6418db | ||
|
|
cd84a4cfd0 | ||
|
|
76af265f0d | ||
|
|
7558e0a468 | ||
|
|
925dcfd634 | ||
|
|
1d6bea83de | ||
|
|
2dad57f1da | ||
|
|
2e4d1f0d60 | ||
|
|
708b0be486 | ||
|
|
f58002e1fd | ||
|
|
980d790638 | ||
|
|
d579e30210 | ||
|
|
48257aec7c | ||
|
|
af2b7a3ef2 | ||
|
|
fd9867e973 | ||
|
|
e97439c7df | ||
|
|
150c4ff002 | ||
|
|
86740c98d7 | ||
|
|
d14713d675 | ||
|
|
11180d0c9c | ||
|
|
ec8761185d | ||
|
|
67e9d89ebd | ||
|
|
d3eb8170ff | ||
|
|
80eca1fafa | ||
|
|
3947594fe3 | ||
|
|
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,18 +19,28 @@
|
||||
|
||||
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
|
||||
# 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=-RC2
|
||||
#EPICS_CVS_SNAPSHOT=-RC2-CVS
|
||||
EPICS_CVS_SNAPSHOT=
|
||||
#EPICS_CVS_SNAPSHOT=
|
||||
|
||||
# No changes should be needed below here
|
||||
|
||||
|
||||
@@ -231,10 +231,12 @@ CONFORM_CFLAGS = $(CONFORM_CFLAGS_$(CMPLR))
|
||||
CONFORM_CXXFLAGS = $(CONFORM_CXXFLAGS_$(CXXCMPLR))
|
||||
|
||||
# Warnings flags
|
||||
WARN_CPPFLAGS = $(WARN_CPPFLAGS_$($(BUILD_CLASS)_WARN))
|
||||
WARN_CFLAGS = $(WARN_CFLAGS_$($(BUILD_CLASS)_WARN))
|
||||
WARN_CXXFLAGS = $(WARN_CXXFLAGS_$($(BUILD_CLASS)_WARN))
|
||||
|
||||
# Optimization flags
|
||||
OPT_CPPFLAGS = $(OPT_CPPFLAGS_$($(BUILD_CLASS)_OPT))
|
||||
OPT_CFLAGS = $(OPT_CFLAGS_$($(BUILD_CLASS)_OPT))
|
||||
OPT_CXXFLAGS = $(OPT_CXXFLAGS_$($(BUILD_CLASS)_OPT))
|
||||
|
||||
@@ -267,15 +269,15 @@ OP_SYS_LDFLAGS += $(LDFLAGS_$(COMMANDLINE_LIBRARY))
|
||||
INCLUDES = -I. $(SRC_INCLUDES) $(INSTALL_INCLUDES) $(RELEASE_INCLUDES)\
|
||||
$(TARGET_INCLUDES) $(USR_INCLUDES) $(OP_SYS_INCLUDES) $($(BUILD_CLASS)_INCLUDES)
|
||||
|
||||
CFLAGS = $(CONFORM_CFLAGS) $($(BUILD_CLASS)_CFLAGS) $(OPT_CFLAGS) $(DEBUG_CFLAGS)\
|
||||
CFLAGS = $(CONFORM_CFLAGS) $($(BUILD_CLASS)_CFLAGS) $(POSIX_CFLAGS) $(OPT_CFLAGS) $(DEBUG_CFLAGS)\
|
||||
$(PIPE_CFLAGS) $(WARN_CFLAGS) $(TARGET_CFLAGS) $(USR_CFLAGS) $(ARCH_DEP_CFLAGS)\
|
||||
$(CODE_CFLAGS) $(STATIC_CFLAGS) $(OP_SYS_CFLAGS) $(LIBRARY_SRC_CFLAGS)
|
||||
|
||||
CXXFLAGS = $(CONFORM_CXXFLAGS) $($(BUILD_CLASS)_CXXFLAGS) $(OPT_CXXFLAGS) $(DEBUG_CXXFLAGS)\
|
||||
CXXFLAGS = $(CONFORM_CXXFLAGS) $($(BUILD_CLASS)_CXXFLAGS) $(POSIX_CXXFLAGS) $(OPT_CXXFLAGS) $(DEBUG_CXXFLAGS)\
|
||||
$(PIPE_CFLAGS) $(WARN_CXXFLAGS) $(TARGET_CXXFLAGS) $(USR_CXXFLAGS) $(ARCH_DEP_CXXFLAGS)\
|
||||
$(CODE_CXXFLAGS) $(STATIC_CXXCFLAGS) $(OP_SYS_CXXFLAGS) $(LIBRARY_SRC_CFLAGS)
|
||||
|
||||
LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) \
|
||||
LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(POSIX_LDFLAGS) \
|
||||
$(ARCH_DEP_LDFLAGS) $(DEBUG_LDFLAGS) $(OP_SYS_LDFLAGS) $($(BUILD_CLASS)_LDFLAGS)\
|
||||
$(RUNTIME_LDFLAGS) $(CODE_LDFLAGS)
|
||||
|
||||
@@ -283,6 +285,7 @@ LDLIBS = $(STATIC_LDLIBS)\
|
||||
$(POSIX_LDLIBS) $(ARCH_DEP_LDLIBS) $(DEBUG_LDLIBS) $(OP_SYS_LDLIBS) $(GNU_LDLIBS_$(GNU))
|
||||
|
||||
CPPFLAGS += $(CONFORM_CPPFLAGS) $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS)\
|
||||
$(OPT_CPPFLAGS) $(DEBUG_CPPFLAGS) $(WARN_CPPFLAGS)\
|
||||
$(BASE_CPPFLAGS) $(TARGET_CPPFLAGS) $(USR_CPPFLAGS) $(ARCH_DEP_CPPFLAGS)\
|
||||
$(OP_SYS_CPPFLAGS) $(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS)
|
||||
|
||||
@@ -296,10 +299,12 @@ ARCMD = $(AR) $(ARFLAGS) $(USR_ARFLAGS) $@ $(LIBRARY_LD_OBJS)
|
||||
MUNCH_CMD = $(LD) -o $@ $^
|
||||
|
||||
#--------------------------------------------------
|
||||
# LEX default option (valid for EPICS base 3.13.0.beta12 and later)
|
||||
# LEX default options
|
||||
#
|
||||
# to allow characters that are not plain 7bit standard ASCII
|
||||
LEXOPT += -8
|
||||
# Allow 8-bit characters
|
||||
LEXOPT += -8
|
||||
# Generate an "interactive" scanner, solves problems at EOF.
|
||||
LEXOPT += -I
|
||||
|
||||
#--------------------------------------------------
|
||||
# Build compile line here
|
||||
|
||||
@@ -56,9 +56,6 @@ INSTALL_CFG = $(INSTALL_LOCATION)/cfg
|
||||
FILE_TYPE += EDL
|
||||
INSTALL_EDL = $(INSTALL_LOCATION)/edl
|
||||
|
||||
FILE_TYPE += IDL
|
||||
INSTALL_IDL = $(INSTALL_LOCATION_LIB)/idl
|
||||
|
||||
FILE_TYPE += PERL_MODULES
|
||||
INSTALL_PERL_MODULES = $(INSTALL_LOCATION_LIB)/perl
|
||||
|
||||
|
||||
@@ -30,15 +30,14 @@
|
||||
# linux-x86 (GNU compiler used for host builds)
|
||||
# linux-x86_64 (GNU compiler used for host builds)
|
||||
# linux-x86-borland (Borland C++ compiler used for host builds)
|
||||
# solaris-sparc (sun compiler used for host builds)
|
||||
# solaris-sparc (Sun compiler used for host builds)
|
||||
# solaris-sparc-gnu (GNU compiler used for host builds)
|
||||
# solaris-sparc64 (sun compiler used for host builds)
|
||||
# solaris-sparc64 (Sun compiler used for host builds)
|
||||
# solaris-sparc64-gnu (GNU compiler used for host builds)
|
||||
# solaris-x86 (sun compiler used for host builds)
|
||||
# solaris-x86 (Sun compiler used for host builds)
|
||||
# solaris-x86-gnu (GNU compiler used for host builds)
|
||||
# win32-x86 (MS Visual C++ compiler used for host builds)
|
||||
# win32-x86-mingw (MinGW compiler used for host builds)
|
||||
# win32-x86-borland (Borland C++ compiler used for host builds)
|
||||
# win32-x86-cygwin (WIN32 API with cygwin GNU compiler used for host builds)
|
||||
|
||||
# Debugging builds
|
||||
@@ -56,15 +55,18 @@
|
||||
# The cross-compiler architectures to build EPICS for
|
||||
#
|
||||
# Currently Supporting:
|
||||
# linux-386 (linux-x86 host)
|
||||
# linux-486 (linux-x86 host)
|
||||
# linux-586 (linux-x86 host)
|
||||
# linux-686 (linux-x86 host)
|
||||
# linux-athlon (linux-x86 host)
|
||||
# linux-cris (Axis GNU crosscompiler on linux-x86 host)
|
||||
# linux-cris_v10 (Axis GNU crosscompiler on linux-x86 host)
|
||||
# linux-cris_v32 (Axis GNU crosscompiler on linux-x86 host)
|
||||
# linux-386 (linux-x86 host)
|
||||
# linux-486 (linux-x86 host)
|
||||
# linux-586 (linux-x86 host)
|
||||
# linux-686 (linux-x86 host)
|
||||
# linux-arm
|
||||
# linux-arm_eb
|
||||
# linux-arm_el
|
||||
# linux-athlon (linux-x86 host)
|
||||
# linux-cris (Axis GNU crosscompiler on linux-x86 host)
|
||||
# linux-cris_v10 (Axis GNU crosscompiler on linux-x86 host)
|
||||
# linux-cris_v32 (Axis GNU crosscompiler on linux-x86 host)
|
||||
# linux-xscale_be
|
||||
# vxWorks-486
|
||||
# vxWorks-68040
|
||||
# vxWorks-68040lc
|
||||
@@ -76,10 +78,13 @@
|
||||
# vxWorks-ppc604_long
|
||||
# vxWorks-ppc604_altivec
|
||||
# vxWorks-mpc8540
|
||||
# RTEMS-at91rm9200ek
|
||||
# RTEMS-beatnik
|
||||
# RTEMS-gen68360
|
||||
# RTEMS-mcp750
|
||||
# RTEMS-mvme167
|
||||
# RTEMS-mvme2100
|
||||
# RTEMS-mvme3100
|
||||
# RTEMS-mvme5500
|
||||
# RTEMS-pc386
|
||||
# RTEMS-psim
|
||||
|
||||
@@ -33,15 +33,15 @@
|
||||
# where the start and end are mmddhh - that is month,day,hour
|
||||
# eg EPICS_TIMEZONE=CUS::360:033102:102802
|
||||
#
|
||||
# DST for 2007 US: Mar 11 - Nov 04
|
||||
# EU: Mar 25 - Oct 28
|
||||
# DST for 2008 US: Mar 09 - Nov 02
|
||||
# EU: Mar 30 - Oct 26
|
||||
# (see: http://www.worldtimezone.org/daylight.html)
|
||||
#
|
||||
# EPICS_TS_NTP_INET
|
||||
# NTP or Unix time server ip address. Uses boot host if not set.
|
||||
|
||||
EPICS_TIMEZONE=CUS::360:031102:110402
|
||||
#EPICS_TIMEZONE=MET::-60:032502:102802
|
||||
EPICS_TIMEZONE=CUS::360:030902:110202
|
||||
#EPICS_TIMEZONE=MET::-60:033002:102602
|
||||
EPICS_TS_NTP_INET=
|
||||
|
||||
# IOC Shell:
|
||||
|
||||
@@ -42,6 +42,8 @@ buildDirs = $(addprefix O.,$(BUILD_ARCHS))
|
||||
|
||||
CROSS_ARCHS += $(CROSS1) $(CROSS2)
|
||||
|
||||
ifeq ($(findstring j,$(MAKEFLAGS)),j)
|
||||
|
||||
define DEP_template
|
||||
$(2): $$(EPICS_HOST_ARCH)
|
||||
$(1)$$(DIVIDER)$(2): $(1)$$(DIVIDER)$$(EPICS_HOST_ARCH)
|
||||
@@ -50,6 +52,8 @@ endef
|
||||
$(foreach action, $(ACTIONS), $(foreach arch,\
|
||||
$(CROSS_ARCHS),$(eval $(call DEP_template,$(action),$(arch)))))
|
||||
|
||||
endif
|
||||
|
||||
#*************************************************************************
|
||||
|
||||
$(actionArchTargets) : $(buildDirs) O.Common
|
||||
|
||||
@@ -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
|
||||
@@ -16,7 +16,8 @@ ARCH_CLASS = alpha
|
||||
CODE_CPPFLAGS =
|
||||
|
||||
POSIX_CPPFLAGS += -pthread -ieee
|
||||
POSIX_LDFLAGS += -pthread -ieee
|
||||
# Unknown reason why this doesn't work in POSIX_LDFLAGS:
|
||||
POSIX_LDLIBS += -pthread -ieee
|
||||
|
||||
OP_SYS_CPPFLAGS += -D_OSF_SOURCE
|
||||
OP_SYS_LDLIBS += -lrt
|
||||
|
||||
@@ -48,10 +48,11 @@ USE_STLPORT=NO
|
||||
OP_SYS_CFLAGS+=$(STLPORT_CFLAGS_$(USE_STLPORT))
|
||||
OP_SYS_LDFLAGS+=$(STLPORT_CFLAGS_$(USE_STLPORT))
|
||||
|
||||
# OS libraries used when generating shared libraries or static binaries
|
||||
OP_SYS_LDLIBS += -lsocket -lnsl
|
||||
OP_SYS_LDLIBS_8 += -lCrun -lc
|
||||
OP_SYS_LDLIBS_9 += -lCrun -lc
|
||||
OP_SYS_LDLIBS_10 += -lCrun -lc
|
||||
OP_SYS_LDLIBS_9 += -lumem -lCrun -lc
|
||||
OP_SYS_LDLIBS_10 += -lumem -lCrun -lc
|
||||
OP_SYS_LDLIBS += $(OP_SYS_LDLIBS_$(SOLARIS_VERSION))
|
||||
OP_SYS_LDLIBS += $(STLPORT_LDLIBS_$(USE_STLPORT))
|
||||
|
||||
|
||||
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/CONFIG.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
|
||||
@@ -1,10 +1,10 @@
|
||||
# CONFIG.solaris-x86-debug.solaris-x86-debug
|
||||
# CONFIG.win32-x86-debug.win32-x86-debug
|
||||
#
|
||||
# $Id$
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for solaris-x86 debug compiler host - solaris-x86 debug compiler target builds
|
||||
# Sites may override these definitions in CONFIG_SITE.solaris-x86-debug.solaris-x86-debug
|
||||
# Definitions for win32-x86 debug compiler host - win32-x86 debug compiler target builds
|
||||
# Sites may override these definitions in CONFIG_SITE.win32-x86-debug.win32-x86-debug
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.win32-x86.win32-x86
|
||||
|
||||
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
|
||||
|
||||
@@ -6,16 +6,3 @@
|
||||
# Only the local epics system manager should modify this file
|
||||
#-------------------------------------------------------
|
||||
|
||||
# JBA test override values
|
||||
#CMPLR_SUFFIX=
|
||||
#GNU_TARGET=m68k-wrs-vxworks
|
||||
#CMPLR_PREFIX=$(addsuffix -,$(GNU_TARGET))
|
||||
|
||||
# ORNL SNS overrides for cross compilers
|
||||
#VX_DIR_YES = /opt/tornado20/
|
||||
#VX_CONFIG_DIR_YES = $(VX_DIR)/target/config
|
||||
#VX_INCLUDE_YES = /usr/local/crossgcc/m68k/m68k-wrs-vxworks/sys-include
|
||||
#VX_GNU_YES = /usr/local/crossgcc/m68k/
|
||||
#VX_GNU_BIN_YES = $(VX_GNU)/bin
|
||||
#VX_GNU_LIB_YES = /usr/local/crossgcc/m68k/lib/gcc-lib/m68k-wrs-vxworks/2.95.2
|
||||
|
||||
|
||||
@@ -6,9 +6,4 @@
|
||||
# Definitions for linux-x86 host - vxWorks target builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Example override lines for user built cross-compiler
|
||||
#GNU_DIR=/home/phoebus/JBA/gnu
|
||||
#GNU_TARGET_INCLUDE_DIR=$(GNU_DIR)/$(GNU_TARGET)/include
|
||||
#CMPLR_SUFFIX=
|
||||
#CMPLR_PREFIX=$(addsuffix -,$(GNU_TARGET))
|
||||
|
||||
|
||||
@@ -6,16 +6,3 @@
|
||||
# Only the local epics system manager should modify this file
|
||||
#-------------------------------------------------------
|
||||
|
||||
# JBA test override values
|
||||
#CMPLR_SUFFIX=
|
||||
#GNU_TARGET=m68k-wrs-vxworks
|
||||
#CMPLR_PREFIX=$(addsuffix -,$(GNU_TARGET))
|
||||
|
||||
# ORNL SNS overrides for cross compilers
|
||||
#VX_DIR = /opt/tornado20/
|
||||
#VX_CONFIG_DIR_YES = $(VX_DIR)/target/config
|
||||
#VX_INCLUDE_YES = /usr/local/crossgcc/m68k/m68k-wrs-vxworks/sys-include
|
||||
#VX_GNU_YES = /usr/local/crossgcc/m68k/
|
||||
#VX_GNU_BIN_YES = $(VX_GNU)/bin
|
||||
#VX_GNU_LIB_YES = /usr/local/crossgcc/m68k/lib/gcc-lib/m68k-wrs-vxworks/2.95.2
|
||||
|
||||
|
||||
@@ -4,33 +4,35 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>Known Problems R3.14.x</title>
|
||||
<meta name="GENERATOR" content="amaya 5.1" />
|
||||
<title>Known Problems R3.14.10-RC1</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 style="text-align: center">EPICS Base R3.14.9: Known Problems</h1>
|
||||
<h1 style="text-align: center">EPICS Base R3.14.10: Known Problems</h1>
|
||||
|
||||
<ul>
|
||||
<li>It is not possible to build this version of base on HP-UX due to C++
|
||||
issues which appear to be bugs in the HP-UX compiler.</li>
|
||||
<li>Parallel make (<tt>make -j</tt>) does not work on cygwin-x86 targets,
|
||||
probably due to a missing dependency in the EPICS build rules.</li>
|
||||
|
||||
<li>When shutting down an IOC on a recent version of GNU/Linux (one that
|
||||
includes the NPTL threading library) various messages may appear, such as:
|
||||
<li>Some older Perl versions do not properly install the xsubpp program. This
|
||||
will prevent the build in src/cap5 from completing — the build will
|
||||
finish with an error like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>FATAL: exception not rethrown</pre></blockquote>
|
||||
<blockquote><pre>/bin/sh: /bin/xsubpp: not found
|
||||
make[3]: *** [Cap5.c] Error 1
|
||||
make[3]: Leaving directory `/home/phoebus3/ANJ/epics/base/3-14-dev/src/cap5/O.solaris-x86'
|
||||
make[2]: *** [install.solaris-x86] Error 2
|
||||
make[2]: Leaving directory `/home/phoebus3/ANJ/epics/base/3-14-dev/src/cap5'
|
||||
make[1]: *** [cap5.install] Error 2
|
||||
make[1]: Leaving directory `/home/phoebus3/ANJ/epics/base/3-14-dev/src'
|
||||
make: *** [src.install] Error 2</pre></blockquote>
|
||||
|
||||
<blockquote>
|
||||
<pre>epicsThread: Unknown C++ exception in thread "CAC-UDP" at ...</pre>
|
||||
<pre>terminate called after throwing an instance of ''</pre>
|
||||
</blockquote>
|
||||
As long as you don't intend to use the Perl5 CA interface this error is
|
||||
harmless, as cap5 is the last directory to be compiled in Base. If you need
|
||||
the Perl5 CA inteface, fix your Perl installation so that the perl binary
|
||||
and the xsubpp program (or soft links to them) are both found in the same
|
||||
directory.</li>
|
||||
|
||||
These errors are caused by the implementation of the pthread_cancel()
|
||||
mechanism in NPTL, which uses the C++ exception mechanism without providing
|
||||
any means to distinguish the cancel exception to regular C++ exception
|
||||
handlers. It is possible that they might also occur when a CA client
|
||||
application exits (or closes its connection to the CA library).</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -39,16 +39,19 @@ Supported platforms
|
||||
configuration files in the configure/os directory and then make changes
|
||||
for your new platforms.
|
||||
|
||||
Host platforms (operating system - architecture - <alternate c++ compiler>)
|
||||
Host platforms (operating system - architecture [- alternate toolset])
|
||||
|
||||
aix-ppc
|
||||
aix-ppc-gnu
|
||||
cygwin-x86
|
||||
darwin-ppc (Mac OS X)
|
||||
darwin-ppc
|
||||
darwin-x86
|
||||
darwin-ppcx86
|
||||
freebsd-x86
|
||||
freebsd-x86_64
|
||||
hpux-parisc
|
||||
hpux-parisc-gnu
|
||||
linux-ppc
|
||||
linux-ppc-bgl
|
||||
linux-x86
|
||||
linux-x86_64
|
||||
linux-x86-borland
|
||||
@@ -59,25 +62,23 @@ Supported platforms
|
||||
solaris-x86
|
||||
solaris-x86-gnu
|
||||
win32-x86
|
||||
win32-x86-borland
|
||||
win32-x86-cygwin
|
||||
win32-x86-mingw
|
||||
|
||||
Debugging builds
|
||||
|
||||
linux-x86-debug
|
||||
linux-x86_64-debug
|
||||
solaris-sparc-debug
|
||||
win32-x86-debug
|
||||
win32-x86-cygwin
|
||||
|
||||
Cross compile target platforms (operating system - architecture)
|
||||
|
||||
linux-386 (linux-x86 host)
|
||||
linux-486 (linux-x86 host)
|
||||
linux-586 (linux-x86 host)
|
||||
linux-686 (linux-x86 host)
|
||||
linux-althon (linux-x86 host)
|
||||
linuxRT-mvme2100
|
||||
linux-386
|
||||
linux-486
|
||||
linux-586
|
||||
linux-686
|
||||
linux-arm
|
||||
linux-arm_eb
|
||||
linux-arm_el
|
||||
linux-athlon
|
||||
linux-cris
|
||||
linux-cris_v10
|
||||
linux-cris_v32
|
||||
linux-xscale_be
|
||||
vxWorks-486
|
||||
vxWorks-68040
|
||||
vxWorks-68040lc
|
||||
@@ -87,19 +88,20 @@ Supported platforms
|
||||
vxWorks-ppc603_long
|
||||
vxWorks-ppc604
|
||||
vxWorks-ppc604_long
|
||||
vxWorks6-mv2100
|
||||
vxWorks6-mv5100
|
||||
vxWorks-ppc604_altivec
|
||||
vxWorks-mpc8540
|
||||
RTEMS-at91rm9200ek
|
||||
RTEMS-beatnik
|
||||
RTEMS-gen68360
|
||||
RTEMS-mcp750
|
||||
RTEMS-mvme167
|
||||
RTEMS-mvme2100
|
||||
RTEMS-mvme3100
|
||||
RTEMS-mvme5500
|
||||
RTEMS-pc386
|
||||
RTEMS-psim
|
||||
RTEMS-uC5282
|
||||
|
||||
Debugging builds
|
||||
|
||||
vxWorks-68040-debug
|
||||
|
||||
Supported compilers
|
||||
|
||||
This version of EPICS base has been built and tested using the host
|
||||
@@ -116,7 +118,7 @@ Software requirements
|
||||
path so that a gnumake version 3.81 or later is available.
|
||||
|
||||
Perl
|
||||
You must have perl version 5.6 or later installed. The configure files do
|
||||
You must have perl version 5.8 or later installed. The configure files do
|
||||
not specify the perl full pathname. You need the perl executable in
|
||||
your search path.
|
||||
|
||||
|
||||
@@ -55,86 +55,73 @@ to create and add the appropriate new configure files to the base/configure/os/d
|
||||
You can start by copying existing configuration files in the configure/os
|
||||
directory and then make changes for your new platforms.</blockquote>
|
||||
|
||||
<blockquote><b>Host platforms (operating system - architecture - <alternate
|
||||
c++ compiler>)</b>
|
||||
<blockquote>
|
||||
<h4>Host platforms (operating system - architecture [- alternate toolset])</h4>
|
||||
|
||||
<blockquote>
|
||||
<tt>aix-ppc</tt>
|
||||
<br><tt>aix-ppc-gnu</tt>
|
||||
<br><tt>cygwin-x86</tt>
|
||||
<br><tt>darwin-ppc (Mac OS X)</tt>
|
||||
<br><tt>hpux-parisc</tt>
|
||||
<br><tt>hpux-parisc-gnu</tt>
|
||||
<br><tt>linux-ppc</tt>
|
||||
<br><tt>linux-ppc-bgl</tt>
|
||||
<br><tt>linux-x86</tt>
|
||||
<br><tt>linux-x86_64</tt>
|
||||
<br><tt>linux-x86-borland</tt>
|
||||
<br><tt>solaris-sparc</tt>
|
||||
<br><tt>solaris-sparc-gnu</tt>
|
||||
<br><tt>solaris-sparc64</tt>
|
||||
<br><tt>solaris-sparc64-gnu</tt>
|
||||
<br><tt>solaris-x86</tt>
|
||||
<br><tt>solaris-x86-gnu</tt>
|
||||
<br><tt>win32-x86</tt>
|
||||
<br><tt>win32-x86-borland</tt>
|
||||
<br><tt>win32-x86-cygwin</tt>
|
||||
<br><tt>win32-x86-mingw</tt>
|
||||
</blockquote>
|
||||
<pre>aix-ppc
|
||||
aix-ppc-gnu
|
||||
cygwin-x86
|
||||
darwin-ppc
|
||||
darwin-x86
|
||||
darwin-ppcx86
|
||||
freebsd-x86
|
||||
freebsd-x86_64
|
||||
hpux-parisc
|
||||
hpux-parisc-gnu
|
||||
linux-ppc
|
||||
linux-x86
|
||||
linux-x86_64
|
||||
linux-x86-borland
|
||||
solaris-sparc
|
||||
solaris-sparc-gnu
|
||||
solaris-sparc64
|
||||
solaris-sparc64-gnu
|
||||
solaris-x86
|
||||
solaris-x86-gnu
|
||||
win32-x86
|
||||
win32-x86-mingw
|
||||
win32-x86-cygwin
|
||||
</pre></blockquote>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<blockquote><b>Debugging builds</b>
|
||||
|
||||
<blockquote>
|
||||
<tt>linux-x86-debug</tt>
|
||||
<br><tt>linux-x86_64-debug</tt>
|
||||
<br><tt>solaris-sparc-debug</tt>
|
||||
<br><tt>win32-x86-debug</tt>
|
||||
</blockquote>
|
||||
|
||||
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<blockquote>
|
||||
<h4>
|
||||
Cross compile target platforms (operating system - architecture)</h4>
|
||||
</blockquote>
|
||||
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<tt>linux-386 (linux-x86 host)</tt>
|
||||
<br><tt>linux-486 (linux-x86 host)</tt>
|
||||
<br><tt>linux-586 (linux-x86 host)</tt>
|
||||
<br><tt>linux-686 (linux-x86 host)</tt>
|
||||
<br><tt>linux-althon (linux-x86 host)</tt>
|
||||
<br><tt>linuxRT-mvme2100</tt>
|
||||
<br><tt>vxWorks-486</tt>
|
||||
<br><tt>vxWorks-68040</tt>
|
||||
<br><tt>vxWorks-68040lc</tt>
|
||||
<br><tt>vxWorks-68060</tt>
|
||||
<br><tt>vxWorks-pentium</tt>
|
||||
<br><tt>vxWorks-ppc603</tt>
|
||||
<br><tt>vxWorks-ppc603_long</tt>
|
||||
<br><tt>vxWorks-ppc604</tt>
|
||||
<br><tt>vxWorks-ppc604_long</tt>
|
||||
<br><tt>vxWorks6-mv2100</tt>
|
||||
<br><tt>vxWorks6-mv5100</tt>
|
||||
<br><tt>RTEMS-gen68360</tt>
|
||||
<br><tt>RTEMS-mcp750</tt>
|
||||
<br><tt>RTEMS-mvme167</tt>
|
||||
<br><tt>RTEMS-pc386</tt>
|
||||
<br><tt>RTEMS-psim</tt>
|
||||
<br><tt>RTEMS-uC5282</tt>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<blockquote><b>Debugging builds</b>
|
||||
<blockquote>
|
||||
<tt>vxWorks-68040-debug</tt>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>linux-386
|
||||
linux-486
|
||||
linux-586
|
||||
linux-686
|
||||
linux-arm
|
||||
linux-arm_eb
|
||||
linux-arm_el
|
||||
linux-athlon
|
||||
linux-cris
|
||||
linux-cris_v10
|
||||
linux-cris_v32
|
||||
linux-xscale_be
|
||||
vxWorks-486
|
||||
vxWorks-68040
|
||||
vxWorks-68040lc
|
||||
vxWorks-68060
|
||||
vxWorks-pentium
|
||||
vxWorks-ppc603
|
||||
vxWorks-ppc603_long
|
||||
vxWorks-ppc604
|
||||
vxWorks-ppc604_long
|
||||
vxWorks-ppc604_altivec
|
||||
vxWorks-mpc8540
|
||||
RTEMS-at91rm9200ek
|
||||
RTEMS-beatnik
|
||||
RTEMS-gen68360
|
||||
RTEMS-mcp750
|
||||
RTEMS-mvme167
|
||||
RTEMS-mvme2100
|
||||
RTEMS-mvme3100
|
||||
RTEMS-mvme5500
|
||||
RTEMS-pc386
|
||||
RTEMS-psim
|
||||
RTEMS-uC5282
|
||||
</pre></blockquote>
|
||||
|
||||
<h3>
|
||||
Supported compilers</h3>
|
||||
@@ -155,7 +142,7 @@ path so that a gnumake version 3.81 or later is available.
|
||||
<p><b>gcc</b>
|
||||
<br>You must have gcc version 3.4.2 or later.
|
||||
<p><b>Perl</b>
|
||||
<br>You must have perl version 5.6 or later installed. The configure files
|
||||
<br>You must have perl version 5.8 or later installed. The configure files
|
||||
do not specify the perl full pathname. You need the perl executable
|
||||
in your search path.
|
||||
<p><b>Unzip and tar (Winzip on WIN32 systems)</b>
|
||||
|
||||
@@ -7,11 +7,44 @@
|
||||
</head>
|
||||
|
||||
<body lang="en">
|
||||
<h1 align="center">EPICS Base Release 3.14.x</h1>
|
||||
<h1 align="center">EPICS Base Release 3.14.10</h1>
|
||||
|
||||
<h2 align="center">Changes between 3.14.9 and 3.14.10</h2>
|
||||
<!-- Insert new items below here ... -->
|
||||
|
||||
<h4>RTEMS Release</h4>
|
||||
|
||||
<p>RTEMS release 4.9 or newer is required. If you are using the RTEMS NFS time provider you need to use RTEMS 4.9.1 or newer.</p>
|
||||
|
||||
<h4>RTEMS epicsEventWaitWithTimeout</h4>
|
||||
|
||||
<p>Correctly return epicsEventWaitTimeout when event is not pending and timeout value is 0.0 secondsmore agressive.</p>
|
||||
|
||||
<h4>epicsRingPointer, epicsRingBytes</h4>
|
||||
|
||||
<p>Fixed a race condition exposed by compilers with more agressive
|
||||
optimization.</p>
|
||||
|
||||
<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
|
||||
@@ -35,11 +68,11 @@ have their own separate report commands.</p>
|
||||
providers in Base. The Unix-like architectures rely on the underlying operating
|
||||
system clock, which normally involves running something like ntpd as a separate
|
||||
process. The real-time operating systems vxWorks and RTEMS install two Current
|
||||
Time providers; the native OS Clock at the lowest priority (this provider
|
||||
includes a task to periodically reset the OS Clock from a higher priority time
|
||||
provider), and an NTP time provider which synchronizes the underlying OS' tick
|
||||
Time providers; the native operating system clock at the lowest priority (this provider
|
||||
includes a task to periodically reset the operating system clock from a higher priority time
|
||||
provider), and an NTP time provider which synchronizes the underlying operating sytem tick
|
||||
timer with an NTP server. Microsoft Windows targets using the Win32 API use a
|
||||
Windows-specific time provider which contains a built-in PLL</p>
|
||||
Windows-specific time provider which contains a built-in PLL.</p>
|
||||
|
||||
<p>There are no Event Time providers included with Base except for an optional
|
||||
"Last Resort" Event provider which can be installed if a site wants to be sure
|
||||
@@ -106,7 +139,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>
|
||||
|
||||
@@ -198,7 +230,7 @@ noticed that an empty string converts to the value 0 for all types other than
|
||||
character <tt>'0'</tt>, value 0x30. Since these types are usually used for
|
||||
storing small integers or boolean values rather than ASCII characters, it was
|
||||
decided that this conversion is wrong so it has been changed to match the other
|
||||
nmeric conversions.</p>
|
||||
numeric conversions.</p>
|
||||
|
||||
<h4>epicsShareAPI deprecated inside IOC</h4>
|
||||
|
||||
@@ -217,10 +249,10 @@ implementations have been converted from K&R to ANSI C prototypes.</p>
|
||||
<h4>Added Perl5 CA library</h4>
|
||||
|
||||
<p>Base now provides a CA client library interface for Perl5 scripts in
|
||||
<tt>src/cap5</tt> and includes some alternative implementations of the catools
|
||||
programs written in Perl (for demonstration purposes mainly). Documentation on
|
||||
how to use the library is available in html/CA.html after the build
|
||||
completes.</p>
|
||||
<tt>src/cap5</tt> and includes as examples some implementations of the catools
|
||||
programs written in Perl. Documentation on how to use the Perl library is
|
||||
available in <tt>base/html/CA.html</tt> after the build completes. This library
|
||||
cannot currently be built on Windows targets.</p>
|
||||
|
||||
<h4>IOC ignores SIGHUP</h4>
|
||||
|
||||
@@ -236,14 +268,18 @@ should not affect the contents of <tt>Makefile</tt>s or any applications
|
||||
using Base. They do however require that the version of GNU Make used be 3.81
|
||||
or later. These changes are briefly:</p>
|
||||
<ul>
|
||||
|
||||
<li><p>A new tool is provided that expands out <tt>@VAR@</tt> macros. By
|
||||
default it knows the value of <tt>@TOP@</tt>, <tt>@ARCH@</tt> and any
|
||||
paths defined in the application's <tt>configure/RELEASE</tt> file, but
|
||||
additional macros can be defined in the <tt>Makefile</tt> that uses it by
|
||||
adding to the <tt>EXPAND_VARS</tt> macro like the example following,
|
||||
which creates an <tt>@EXE@</tt> macro that expands out to <tt>.exe</tt>
|
||||
on windows and to nothing on other platforms:</p>
|
||||
paths defined in the application's <tt>configure/RELEASE</tt> file such
|
||||
as @EPICS_BASE@, but additional macros can be defined in the
|
||||
<tt>Makefile</tt> that uses it by adding to the <tt>EXPAND_VARS</tt>
|
||||
variable like the example following, which creates an <tt>@EXE@</tt>
|
||||
macro that expands out to <tt>.exe</tt> on windows targets and to
|
||||
nothing on other platforms:</p>
|
||||
|
||||
<pre> EXPAND_VARS += EXE=$(EXE)</pre>
|
||||
|
||||
<p>Files that contain <tt>@VAR@</tt> macros to be substituted must have
|
||||
an at sign <tt><b>@</b></tt> as the last character of their name and be
|
||||
listed in the <tt>EXPAND</tt> variable of their <tt>Makefile</tt>. The
|
||||
@@ -251,24 +287,29 @@ or later. These changes are briefly:</p>
|
||||
<tt><b>@</b></tt> suffix removed, and is then available for compiling or
|
||||
installing using any other build mechanism.</p>
|
||||
</li>
|
||||
|
||||
<li><p>Support has been added for installing Perl library modules. The
|
||||
<tt>Makefile</tt> variable <tt>PERL_MODULES</tt> can be set to a list of
|
||||
names of files to be installed into the <tt>$(TOP)/lib/perl</tt>
|
||||
directory. The above macro expansion facility can then be used in perl
|
||||
programs that use these libraries to set the perl search path to include
|
||||
that directory. The syntax for this is as follows:</p>
|
||||
|
||||
<pre> use lib '@TOP@/lib/perl';
|
||||
use MyModule;</pre>
|
||||
|
||||
<p>The filenames listed in <tt>PERL_MODULES</tt> can include subdirectory
|
||||
path components and the build system will preserve these in the installed
|
||||
result.</p>
|
||||
</li>
|
||||
|
||||
<li>The Perl scripts that were in <tt>configure/tools</tt> are now found in
|
||||
the new <tt>src/tools</tt> directory, and get installed into the
|
||||
appropriate <tt>bin/<i>hostarch</i></tt> directory at build time. Some of
|
||||
these scripts are no longer required and have been removed, and others
|
||||
are being modified to make them more modular, extracting common routines
|
||||
into perl library modules.</li>
|
||||
|
||||
<li>The generated files that were created by running make in the
|
||||
<tt>configure</tt> directory are no longer required, having been replaced
|
||||
by additional mechanisms inside the build system files. This removes a
|
||||
@@ -314,6 +355,7 @@ although the core developers lack the ability to test all of them:</p>
|
||||
<li>linux-cris_v32</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>linux-xscale_be (tested with MOXA UC-7408 Plus)
|
||||
</ul>
|
||||
|
||||
<h4>Added compile line header search directories</h4>
|
||||
@@ -383,7 +425,7 @@ settting.</p>
|
||||
|
||||
<p>The -ansi flag has been removed from CONFORM_FLAGS_STRICT and
|
||||
CONFORM_CXXFLAGS_STRICT -- there are many useful library functions whose
|
||||
prototypes are disabled when -ansi is used..</p>
|
||||
prototypes are disabled when -ansi is used.</p>
|
||||
|
||||
<h4>SEL record (Mantis #295)</h4>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -51,9 +51,6 @@ void tzset(void);
|
||||
int fileno(FILE *);
|
||||
int main(int argc, char **argv);
|
||||
|
||||
rtems_interval rtemsTicksPerSecond;
|
||||
double rtemsTicksPerSecond_double, rtemsTicksPerTwoSeconds_double;
|
||||
|
||||
static void
|
||||
logReset (void)
|
||||
{
|
||||
@@ -81,6 +78,8 @@ logReset (void)
|
||||
static void
|
||||
delayedPanic (const char *msg)
|
||||
{
|
||||
extern rtems_interval rtemsTicksPerSecond;
|
||||
|
||||
rtems_task_wake_after (rtemsTicksPerSecond);
|
||||
rtems_panic (msg);
|
||||
}
|
||||
@@ -421,13 +420,6 @@ Init (rtems_task_argument ignored)
|
||||
rtems_status_code sc;
|
||||
rtems_time_of_day now;
|
||||
|
||||
/*
|
||||
* Get configuration
|
||||
*/
|
||||
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &rtemsTicksPerSecond);
|
||||
rtemsTicksPerSecond_double = rtemsTicksPerSecond;
|
||||
rtemsTicksPerTwoSeconds_double = rtemsTicksPerSecond_double * 2.0;
|
||||
|
||||
/*
|
||||
* Explain why we're here
|
||||
*/
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -116,6 +116,8 @@ private:
|
||||
epicsUInt8 buf [ comBufSize ];
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void * );
|
||||
template < class T >
|
||||
bool push ( const T * ); // disabled
|
||||
};
|
||||
|
||||
inline void * comBuf::operator new ( size_t size,
|
||||
|
||||
@@ -106,10 +106,7 @@ void comQueSend::clear ()
|
||||
|
||||
void comQueSend::copy_dbr_string ( const void * pValue )
|
||||
{
|
||||
// this extra step is required by Borland BCC 5.5
|
||||
const dbr_string_t & str =
|
||||
* static_cast <const dbr_string_t *> ( pValue );
|
||||
this->push ( str );
|
||||
this->push ( static_cast < const char * > ( pValue ), MAX_STRING_SIZE );
|
||||
}
|
||||
|
||||
void comQueSend::copy_dbr_short ( const void * pValue )
|
||||
@@ -186,7 +183,7 @@ const comQueSend::copyScalarFunc_t comQueSend::dbrCopyScalar [39] = {
|
||||
|
||||
void comQueSend::copy_dbr_string ( const void *pValue, unsigned nElem )
|
||||
{
|
||||
this->push ( static_cast <const dbr_string_t *> ( pValue ), nElem );
|
||||
this->push ( static_cast < const char * > ( pValue ), nElem * MAX_STRING_SIZE );
|
||||
}
|
||||
|
||||
void comQueSend::copy_dbr_short ( const void *pValue, unsigned nElem )
|
||||
|
||||
@@ -149,6 +149,9 @@ private:
|
||||
this->pushComBuf ( *pComBuf );
|
||||
}
|
||||
|
||||
template < class T >
|
||||
inline void push ( const T * ); // disabled
|
||||
|
||||
comQueSend ( const comQueSend & );
|
||||
comQueSend & operator = ( const comQueSend & );
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -13,27 +13,22 @@ ifneq ($(findstring darwin,$(T_A)),)
|
||||
LOADABLE_SHRLIB_PREFIX =
|
||||
LOADABLE_SHRLIB_SUFFIX = .bundle
|
||||
endif
|
||||
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
|
||||
Cap5_LIBS = ca Com
|
||||
Cap5_INCLUDES = -I $(shell $(PERL) ../perlConfig.pl archlib)/CORE
|
||||
Cap5_INCLUDES = -I$(shell $(PERL) ../perlConfig.pl archlib)/CORE
|
||||
Cap5_CFLAGS = $(shell $(PERL) ../perlConfig.pl ccflags)
|
||||
|
||||
ifeq ($(findstring Host,$(VALID_BUILDS)),Host)
|
||||
@@ -45,18 +40,15 @@ endif
|
||||
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)
|
||||
TYPEMAP = $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils/typemap
|
||||
EXTUTILS = $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils
|
||||
|
||||
%.c: ../%.xs
|
||||
$(RM) $@ $@_new
|
||||
$(XSUBPP) -typemap $(TYPEMAP) $< > $@_new && $(MV) $@_new $@
|
||||
$(PERL) $(EXTUTILS)/xsubpp -typemap $(EXTUTILS)/typemap $< > $@_new && $(MV) $@_new $@
|
||||
|
||||
%.html: %.pm
|
||||
%.html: ../%.pm
|
||||
$(RM) $@
|
||||
$(PODCHECKER) $< && pod2html --infile=$< --outfile=$@
|
||||
podchecker $< && pod2html --infile=$< --outfile=$@
|
||||
|
||||
clean::
|
||||
$(RM) Cap5.c
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1413,8 +1413,9 @@ caStatus casStrmClient::createChanResponse (
|
||||
this->chanTable.remove ( *pChan->pChanI );
|
||||
this->chanList.remove ( *pChan->pChanI );
|
||||
pChan->pChanI->uninstallFromPV ( this->eventSys );
|
||||
pChan->getPV()->pPVI->deleteSignal ();
|
||||
casPVI * pPVI = pChan->getPV()->pPVI;
|
||||
delete pChan->pChanI;
|
||||
pPVI->deleteSignal ();
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -256,8 +256,10 @@ int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
else
|
||||
{
|
||||
if (reqElems > 1) printf(" %lu ", reqElems);
|
||||
for (i=0; i<reqElems; ++i)
|
||||
printf("%s ", val2str(pvs[n].value, pvs[n].dbrType, i));
|
||||
for (i=0; i<reqElems; ++i) {
|
||||
if (i) printf (" ");
|
||||
printf("%s", val2str(pvs[n].value, pvs[n].dbrType, i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
break;
|
||||
@@ -285,8 +287,10 @@ int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
printf(" Element count: %lu\n"
|
||||
" Value: ",
|
||||
reqElems);
|
||||
for (i=0; i<reqElems; ++i) /* Print value(s) */
|
||||
printf("%s ", val2str(pvs[n].value, pvs[n].dbrType, i));
|
||||
for (i=0; i<reqElems; ++i) { /* Print value(s) */
|
||||
if (i) printf (" ");
|
||||
printf(" %s", val2str(pvs[n].value, pvs[n].dbrType, i));
|
||||
}
|
||||
printf("\n");
|
||||
if (pvs[n].dbrType > DBR_DOUBLE) /* Extended type extra info */
|
||||
printf("%s\n", dbr2str(pvs[n].value, pvs[n].dbrType));
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -147,10 +147,15 @@ void callbackInit(void)
|
||||
/* This routine can be called from interrupt context */
|
||||
void callbackRequest(CALLBACK *pcallback)
|
||||
{
|
||||
int priority = pcallback->priority;
|
||||
int priority;
|
||||
int pushOK;
|
||||
int lockKey;
|
||||
|
||||
if (!pcallback) {
|
||||
epicsPrintf("callbackRequest called with NULL pcallback\n");
|
||||
return;
|
||||
}
|
||||
priority = pcallback->priority;
|
||||
if (priority < 0 || priority >= NUM_CALLBACK_PRIORITIES) {
|
||||
epicsPrintf("callbackRequest called with invalid priority\n");
|
||||
return;
|
||||
@@ -174,6 +179,7 @@ static void ProcessCallback(CALLBACK *pcallback)
|
||||
dbCommon *pRec;
|
||||
|
||||
callbackGetUser(pRec, pcallback);
|
||||
if (!pRec) return;
|
||||
dbScanLock(pRec);
|
||||
(*pRec->rset->process)(pRec);
|
||||
dbScanUnlock(pRec);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -234,7 +234,7 @@ void epicsShareAPI dbCaRemoveLink(struct link *plink)
|
||||
{
|
||||
caLink *pca = (caLink *)plink->value.pv_link.pvt;
|
||||
|
||||
assert(pca);
|
||||
if (!pca) return;
|
||||
epicsMutexMustLock(pca->lock);
|
||||
pca->plink = 0;
|
||||
plink->value.pv_link.pvt = 0;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
/*************************************************************************\
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/* callbackTest.c */
|
||||
/* $Id$ */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
@@ -18,66 +17,107 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "epicsThread.h"
|
||||
#include "errlog.h"
|
||||
#include "callback.h"
|
||||
#include "taskwd.h"
|
||||
#include "cantProceed.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsTime.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
|
||||
#define NCALLBACKS 168
|
||||
#define DELAY_QUANTUM 0.25
|
||||
|
||||
#define TEST_DELAY(i) ((i / NUM_CALLBACK_PRIORITIES) * DELAY_QUANTUM)
|
||||
|
||||
typedef struct myPvt {
|
||||
CALLBACK callback;
|
||||
double requestedDiff;
|
||||
CALLBACK cb1;
|
||||
CALLBACK cb2;
|
||||
epicsTimeStamp start;
|
||||
}myPvt;
|
||||
double delay;
|
||||
int pass;
|
||||
} myPvt;
|
||||
|
||||
epicsEventId finished;
|
||||
|
||||
|
||||
static void myCallback(CALLBACK *pCallback)
|
||||
{
|
||||
myPvt *pmyPvt;
|
||||
epicsTimeStamp end;
|
||||
double diff, error;
|
||||
epicsTimeStamp now;
|
||||
double delay, error;
|
||||
|
||||
callbackGetUser(pmyPvt,pCallback);
|
||||
epicsTimeGetCurrent(&end);
|
||||
diff = epicsTimeDiffInSeconds(&end,&pmyPvt->start);
|
||||
error = fabs(pmyPvt->requestedDiff - diff);
|
||||
testOk(error < 0.05, "callback time error %f", error);
|
||||
epicsTimeGetCurrent(&now);
|
||||
callbackGetUser(pmyPvt, pCallback);
|
||||
|
||||
if (pmyPvt->pass++ == 0) {
|
||||
delay = 0.0;
|
||||
error = epicsTimeDiffInSeconds(&now, &pmyPvt->start);
|
||||
pmyPvt->start = now;
|
||||
callbackRequestDelayed(&pmyPvt->cb2, pmyPvt->delay);
|
||||
} else if (pmyPvt->pass == 2) {
|
||||
double diff = epicsTimeDiffInSeconds(&now, &pmyPvt->start);
|
||||
delay = pmyPvt->delay;
|
||||
error = fabs(delay - diff);
|
||||
} else {
|
||||
testFail("pass = %d for delay = %f", pmyPvt->pass, pmyPvt->delay);
|
||||
return;
|
||||
}
|
||||
testOk(error < 0.05, "delay %f seconds, callback time error %f",
|
||||
delay, error);
|
||||
}
|
||||
|
||||
static void finalCallback(CALLBACK *pCallback)
|
||||
{
|
||||
myCallback(pCallback);
|
||||
epicsEventSignal(finished);
|
||||
}
|
||||
|
||||
#define ncallbacks 5
|
||||
|
||||
MAIN(callbackTest)
|
||||
{
|
||||
myPvt *nowait[ncallbacks];
|
||||
myPvt *wait[ncallbacks];
|
||||
epicsTimeStamp start;
|
||||
myPvt *pcbt[NCALLBACKS];
|
||||
myPvt *pfinal;
|
||||
int i;
|
||||
|
||||
testPlan(ncallbacks * 2);
|
||||
testPlan(NCALLBACKS * 2 + 2);
|
||||
|
||||
taskwdInit();
|
||||
errlogInit(4096);
|
||||
callbackInit();
|
||||
epicsThreadSleep(1.0);
|
||||
for(i=0; i<ncallbacks ; i++) {
|
||||
nowait[i] = calloc(1,sizeof(myPvt));
|
||||
callbackSetCallback(myCallback,&nowait[i]->callback);
|
||||
callbackSetUser(nowait[i],&nowait[i]->callback);
|
||||
callbackSetPriority(i%3,&nowait[i]->callback);
|
||||
epicsTimeGetCurrent(&start);
|
||||
nowait[i]->start = start;
|
||||
nowait[i]->requestedDiff = 0.0;
|
||||
callbackRequest(&nowait[i]->callback);
|
||||
wait[i] = calloc(1,sizeof(myPvt));
|
||||
callbackSetCallback(myCallback,&wait[i]->callback);
|
||||
callbackSetUser(wait[i],&wait[i]->callback);
|
||||
callbackSetPriority(i%3,&wait[i]->callback);
|
||||
epicsTimeGetCurrent(&start);
|
||||
wait[i]->start = start;
|
||||
wait[i]->requestedDiff = (double)i;
|
||||
callbackRequestDelayed(&wait[i]->callback,wait[i]->requestedDiff);
|
||||
|
||||
finished = epicsEventMustCreate(epicsEventEmpty);
|
||||
|
||||
for (i = 0; i < NCALLBACKS ; i++) {
|
||||
pcbt[i] = callocMustSucceed(1, sizeof(myPvt), "pcbt");
|
||||
callbackSetCallback(myCallback, &pcbt[i]->cb1);
|
||||
callbackSetCallback(myCallback, &pcbt[i]->cb2);
|
||||
callbackSetUser(pcbt[i], &pcbt[i]->cb1);
|
||||
callbackSetUser(pcbt[i], &pcbt[i]->cb2);
|
||||
callbackSetPriority(i % NUM_CALLBACK_PRIORITIES, &pcbt[i]->cb1);
|
||||
callbackSetPriority(i % NUM_CALLBACK_PRIORITIES, &pcbt[i]->cb2);
|
||||
pcbt[i]->delay = TEST_DELAY(i);
|
||||
pcbt[i]->pass = 0;
|
||||
}
|
||||
epicsThreadSleep((double)(ncallbacks + 2));
|
||||
|
||||
for (i = 0; i < NCALLBACKS ; i++) {
|
||||
epicsTimeGetCurrent(&pcbt[i]->start);
|
||||
callbackRequest(&pcbt[i]->cb1);
|
||||
}
|
||||
|
||||
pfinal = callocMustSucceed(1, sizeof(myPvt), "final");
|
||||
callbackSetCallback(myCallback, &pfinal->cb1);
|
||||
callbackSetCallback(finalCallback, &pfinal->cb2);
|
||||
callbackSetUser(pfinal, &pfinal->cb1);
|
||||
callbackSetUser(pfinal, &pfinal->cb2);
|
||||
callbackSetPriority(0, &pfinal->cb1);
|
||||
callbackSetPriority(0, &pfinal->cb2);
|
||||
pfinal->delay = TEST_DELAY(NCALLBACKS) + 1.0;
|
||||
pfinal->pass = 0;
|
||||
|
||||
epicsTimeGetCurrent(&pfinal->start);
|
||||
callbackRequest(&pfinal->cb1);
|
||||
|
||||
epicsEventWait(finished);
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -77,26 +77,21 @@ include $(TOP)/configure/RULES
|
||||
# not have been installed if we are building for
|
||||
# the first time
|
||||
# -> use explicit reference to the uninstalled files in '..'
|
||||
aitConvert$(OBJ): ../aitConvert.cc aitConvertGenerated.cc\
|
||||
../aitConvert.h ../aitTypes.h
|
||||
|
||||
aitConvert$(OBJ): $(COMMON_DIR)/aitConvertGenerated.cc
|
||||
|
||||
dbMapper$(OBJ): ../gdd.h ../gddI.h ../gddContainer.h ../gddContainerI.h \
|
||||
../gddArray.h ../gddScalar.h ../gddAppTable.h ../dbMapper.h \
|
||||
$(INSTALL_INCLUDE)/gddApps.h ../aitTypes.h ../gddUtils.h ../gddUtilsI.h
|
||||
dbMapper$(OBJ): $(COMMON_DIR)/gddApps.h
|
||||
|
||||
# Rules for generated files
|
||||
#
|
||||
aitConvertGenerated.cc: $(INSTALL_HOST_BIN)/aitGen$(HOSTEXE) aitTypes.h
|
||||
$(INSTALL_HOST_BIN)/aitGen$(HOSTEXE)
|
||||
|
||||
$(COMMON_DIR)/aitConvertGenerated.cc: $(INSTALL_HOST_BIN)/aitGen$(HOSTEXE)
|
||||
$(INSTALL_HOST_BIN)/aitGen$(HOSTEXE) $@
|
||||
|
||||
$(COMMON_DIR)/gddApps.h : $(INSTALL_HOST_BIN)/genApps$(HOSTEXE)
|
||||
$(INSTALL_HOST_BIN)/genApps$(HOSTEXE) $@
|
||||
|
||||
clean::
|
||||
$(RM) aitConvertGenerated.cc gddApps.h
|
||||
|
||||
aitConvert$(OBJ): aitConvertGenerated.cc
|
||||
@$(RM) $(COMMON_DIR)/aitConvertGenerated.cc
|
||||
|
||||
# EOF base/src/gdd/Makefile
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ void MakeStringFuncTo(int i,int j,int k);
|
||||
void MakeFStringFuncFrom(int i,int j,int k);
|
||||
void MakeFStringFuncTo(int i,int j,int k);
|
||||
|
||||
#define FILE_NAME "aitConvertGenerated.cc"
|
||||
#define pr fprintf
|
||||
|
||||
#define AIT_TO_NET 0
|
||||
@@ -116,9 +115,15 @@ int main(int argc,char* argv[])
|
||||
|
||||
initMinMaxAIT ();
|
||||
|
||||
if((dfd=fopen(FILE_NAME,"w"))==NULL)
|
||||
if(argc<2)
|
||||
{
|
||||
pr(stderr,"file %s failed to open\n",FILE_NAME);
|
||||
fprintf(stderr,"You must enter a file name on command line\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((dfd=fopen(argv[1],"w"))==NULL)
|
||||
{
|
||||
pr(stderr,"file %s failed to open\n",argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 :: pGlobalMutex = 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,25 @@ 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;
|
||||
delete ipAddrToAsciiEnginePrivate :: pEngine;
|
||||
ipAddrToAsciiEnginePrivate :: pEngine = 0;
|
||||
}
|
||||
}
|
||||
if ( deleteGlobalMutexCondDetected ) {
|
||||
delete ipAddrToAsciiEnginePrivate :: pGlobalMutex;
|
||||
ipAddrToAsciiEnginePrivate :: pGlobalMutex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
#ifndef INCdevLibh
|
||||
#define INCdevLibh 1
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <osdVME.h>
|
||||
#include "dbDefs.h"
|
||||
#include "osdVME.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -44,14 +45,14 @@ typedef enum {
|
||||
*/
|
||||
extern const char *epicsAddressTypeName[];
|
||||
|
||||
long devAddressMap(void); /* print an address map */
|
||||
epicsShareFunc long devAddressMap(void); /* print an address map */
|
||||
|
||||
/*
|
||||
* devBusToLocalAddr()
|
||||
*
|
||||
* OSI routine to translate bus addresses their local CPU address mapping
|
||||
*/
|
||||
long devBusToLocalAddr (
|
||||
epicsShareFunc long devBusToLocalAddr (
|
||||
epicsAddressType addrType,
|
||||
size_t busAddr,
|
||||
volatile void **ppLocalAddr);
|
||||
@@ -61,7 +62,8 @@ long devBusToLocalAddr (
|
||||
* a bus error safe "wordSize" read at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long devReadProbe (unsigned wordSize, volatile const void *ptr, void *pValueRead);
|
||||
epicsShareFunc long devReadProbe (
|
||||
unsigned wordSize, volatile const void *ptr, void *pValueRead);
|
||||
|
||||
/*
|
||||
* devNoResponseProbe()
|
||||
@@ -73,7 +75,7 @@ long devReadProbe (unsigned wordSize, volatile const void *ptr, void *pValueRead
|
||||
* Checks all naturally aligned word sizes between char and long for
|
||||
* the entire specified range of bytes.
|
||||
*/
|
||||
long devNoResponseProbe(
|
||||
epicsShareFunc long devNoResponseProbe(
|
||||
epicsAddressType addrType,
|
||||
size_t base,
|
||||
size_t size
|
||||
@@ -85,16 +87,17 @@ long devNoResponseProbe(
|
||||
* a bus error safe "wordSize" write at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long devWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValueWritten);
|
||||
epicsShareFunc long devWriteProbe (
|
||||
unsigned wordSize, volatile void *ptr, const void *pValueWritten);
|
||||
|
||||
long devRegisterAddress(
|
||||
epicsShareFunc long devRegisterAddress(
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
size_t logicalBaseAddress,
|
||||
size_t size, /* bytes */
|
||||
volatile void **pPhysicalAddress);
|
||||
|
||||
long devUnregisterAddress(
|
||||
epicsShareFunc long devUnregisterAddress(
|
||||
epicsAddressType addrType,
|
||||
size_t logicalBaseAddress,
|
||||
const char *pOwnerName);
|
||||
@@ -102,7 +105,7 @@ long devUnregisterAddress(
|
||||
/*
|
||||
* allocate and register an unoccupied address block
|
||||
*/
|
||||
long devAllocAddress(
|
||||
epicsShareFunc long devAllocAddress(
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
size_t size,
|
||||
@@ -112,7 +115,7 @@ long devAllocAddress(
|
||||
/*
|
||||
* connect ISR to a VME interrupt vector
|
||||
*/
|
||||
long devConnectInterruptVME(
|
||||
epicsShareFunc long devConnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
@@ -122,7 +125,7 @@ long devConnectInterruptVME(
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
*/
|
||||
long devConnectInterruptISA(
|
||||
epicsShareFunc long devConnectInterruptISA(
|
||||
unsigned interruptLevel,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
@@ -132,7 +135,7 @@ long devConnectInterruptISA(
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
*/
|
||||
long devConnectInterruptPCI(
|
||||
epicsShareFunc long devConnectInterruptPCI(
|
||||
unsigned bus,
|
||||
unsigned device,
|
||||
unsigned function,
|
||||
@@ -146,7 +149,7 @@ long devConnectInterruptPCI(
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
*/
|
||||
long devDisconnectInterruptVME(
|
||||
epicsShareFunc long devDisconnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
@@ -159,7 +162,7 @@ long devDisconnectInterruptVME(
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
*/
|
||||
long devDisconnectInterruptISA(
|
||||
epicsShareFunc long devDisconnectInterruptISA(
|
||||
unsigned interruptLevel,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
@@ -172,7 +175,7 @@ long devDisconnectInterruptISA(
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
*/
|
||||
long devDisconnectInterruptPCI(
|
||||
epicsShareFunc long devDisconnectInterruptPCI(
|
||||
unsigned bus,
|
||||
unsigned device,
|
||||
unsigned function,
|
||||
@@ -183,7 +186,7 @@ long devDisconnectInterruptPCI(
|
||||
*
|
||||
* returns boolean
|
||||
*/
|
||||
int devInterruptInUseVME (unsigned vectorNumber);
|
||||
epicsShareFunc int devInterruptInUseVME (unsigned vectorNumber);
|
||||
|
||||
/*
|
||||
* determine if an ISA interrupt level is in use
|
||||
@@ -191,7 +194,7 @@ int devInterruptInUseVME (unsigned vectorNumber);
|
||||
*
|
||||
* returns boolean
|
||||
*/
|
||||
int devInterruptLevelInUseISA (unsigned interruptLevel);
|
||||
epicsShareFunc int devInterruptLevelInUseISA (unsigned interruptLevel);
|
||||
|
||||
/*
|
||||
* determine if a PCI interrupt is in use
|
||||
@@ -199,7 +202,7 @@ int devInterruptLevelInUseISA (unsigned interruptLevel);
|
||||
*
|
||||
* returns boolean
|
||||
*/
|
||||
int devInterruptInUsePCI (unsigned bus, unsigned device,
|
||||
epicsShareFunc int devInterruptInUsePCI (unsigned bus, unsigned device,
|
||||
unsigned function);
|
||||
|
||||
typedef enum {intVME, intVXI, intISA} epicsInterruptType;
|
||||
@@ -207,42 +210,42 @@ typedef enum {intVME, intVXI, intISA} epicsInterruptType;
|
||||
/*
|
||||
* enable VME interrupt level
|
||||
*/
|
||||
long devEnableInterruptLevelVME (unsigned level);
|
||||
epicsShareFunc long devEnableInterruptLevelVME (unsigned level);
|
||||
|
||||
/*
|
||||
* enable ISA interrupt level
|
||||
*/
|
||||
long devEnableInterruptLevelISA (unsigned level);
|
||||
epicsShareFunc long devEnableInterruptLevelISA (unsigned level);
|
||||
|
||||
/*
|
||||
* not implemented - API needs to be reviewed
|
||||
*/
|
||||
long devEnableInterruptLevelPCI (unsigned level,
|
||||
epicsShareFunc long devEnableInterruptLevelPCI (unsigned level,
|
||||
unsigned bus, unsigned device, unsigned function);
|
||||
|
||||
/*
|
||||
* disable VME interrupt level
|
||||
*/
|
||||
long devDisableInterruptLevelVME (unsigned level);
|
||||
epicsShareFunc long devDisableInterruptLevelVME (unsigned level);
|
||||
|
||||
/*
|
||||
* disable ISA interrupt level
|
||||
*/
|
||||
long devDisableInterruptLevelISA (unsigned level);
|
||||
epicsShareFunc long devDisableInterruptLevelISA (unsigned level);
|
||||
|
||||
/*
|
||||
* not implemented - API needs to be reviewed
|
||||
*/
|
||||
long devDisableInterruptLevelPCI (unsigned level,
|
||||
epicsShareFunc long devDisableInterruptLevelPCI (unsigned level,
|
||||
unsigned bus, unsigned device, unsigned function);
|
||||
|
||||
/*
|
||||
* Routines to allocate and free memory in the A24 memory region.
|
||||
*
|
||||
*/
|
||||
void *devLibA24Malloc(size_t);
|
||||
void *devLibA24Calloc(size_t);
|
||||
void devLibA24Free(void *pBlock);
|
||||
epicsShareFunc void *devLibA24Malloc(size_t);
|
||||
epicsShareFunc void *devLibA24Calloc(size_t);
|
||||
epicsShareFunc void devLibA24Free(void *pBlock);
|
||||
|
||||
/*
|
||||
* Normalize a digital value and convert it to type TYPE
|
||||
@@ -327,7 +330,7 @@ typedef struct devLibVirtualOS {
|
||||
void (*pDevA24Free)(void *pBlock);
|
||||
long (*pDevInit)(void);
|
||||
}devLibVirtualOS;
|
||||
extern devLibVirtualOS *pdevLibVirtualOS;
|
||||
epicsShareExtern devLibVirtualOS *pdevLibVirtualOS;
|
||||
|
||||
/*
|
||||
* error codes (and messages) associated with devLib.c
|
||||
@@ -378,7 +381,7 @@ extern devLibVirtualOS *pdevLibVirtualOS;
|
||||
* devConnectInterruptISA etc. devConnectInterrupt will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
long devConnectInterrupt(
|
||||
epicsShareFunc long devConnectInterrupt(
|
||||
epicsInterruptType intType,
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *),
|
||||
@@ -392,10 +395,10 @@ long devConnectInterrupt(
|
||||
* devDisconnectInterruptISA etc. devDisconnectInterrupt will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
long devDisconnectInterrupt(
|
||||
epicsShareFunc long devDisconnectInterrupt(
|
||||
epicsInterruptType intType,
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
@@ -405,7 +408,8 @@ long devDisconnectInterrupt(
|
||||
* devEnableInterruptLevelISA etc. devEnableInterruptLevel will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
long devEnableInterruptLevel(epicsInterruptType intType, unsigned level);
|
||||
epicsShareFunc long devEnableInterruptLevel(
|
||||
epicsInterruptType intType, unsigned level);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
@@ -415,7 +419,8 @@ long devEnableInterruptLevel(epicsInterruptType intType, unsigned level);
|
||||
* devDisableInterruptLevelPCI etc. devDisableInterruptLevel will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
long devDisableInterruptLevel (epicsInterruptType intType, unsigned level);
|
||||
epicsShareFunc long devDisableInterruptLevel (
|
||||
epicsInterruptType intType, unsigned level);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
@@ -424,7 +429,7 @@ long devDisableInterruptLevel (epicsInterruptType intType, unsigned level);
|
||||
* Please use devNoResponseProbe(). locationProbe() will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
long locationProbe (epicsAddressType addrType, char *pLocation);
|
||||
epicsShareFunc long locationProbe (epicsAddressType addrType, char *pLocation);
|
||||
|
||||
/*
|
||||
* Some vxWorks convenience routines
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <float.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsAlgorithm.h"
|
||||
#include "epicsTime.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsAssert.h"
|
||||
@@ -30,23 +31,6 @@ epicsThreadRunable::~epicsThreadRunable () {}
|
||||
void epicsThreadRunable::run () {}
|
||||
void epicsThreadRunable::show ( unsigned int ) const {}
|
||||
|
||||
// vxWorks 5.4 gcc fails during compile when I use std::exception
|
||||
using namespace std;
|
||||
|
||||
// exception payload
|
||||
class epicsThread::unableToCreateThread : public exception {
|
||||
const char * what () const throw () {
|
||||
return "epicsThread class was unable to create a new thread";
|
||||
}
|
||||
};
|
||||
|
||||
// exception payload
|
||||
class epicsThread::exitException : public exception {
|
||||
const char * what () const throw () {
|
||||
return "epicsThread class's private exit exception";
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" void epicsThreadCallEntryPoint ( void * pPvt )
|
||||
{
|
||||
epicsThread * pThread =
|
||||
@@ -76,7 +60,7 @@ extern "C" void epicsThreadCallEntryPoint ( void * pPvt )
|
||||
// this should behave as the C++ implementation intends when an
|
||||
// exception isnt handled. If users dont like this behavior, they
|
||||
// can install an application specific unexpected handler.
|
||||
unexpected ();
|
||||
std::unexpected ();
|
||||
}
|
||||
}
|
||||
catch ( ... ) {
|
||||
@@ -89,11 +73,14 @@ extern "C" void epicsThreadCallEntryPoint ( void * pPvt )
|
||||
errlogPrintf (
|
||||
"epicsThread: Unknown C++ exception in thread \"%s\" at %s\n",
|
||||
name, date );
|
||||
// this should behave as the C++ implementation intends when an
|
||||
// exception isnt handled. If users dont like this behavior, they
|
||||
// can install an application specific unexpected handler.
|
||||
unexpected ();
|
||||
errlogFlush ();
|
||||
}
|
||||
// The Linux NPTL library requires us to re-throw here; it uses
|
||||
// an untyped exception object to shut down threads when we call
|
||||
// pthread_cancel() in the os/posix/osdThread.c myAtExit()
|
||||
// handler, and aborts with "FATAL: exception not rethrown" if
|
||||
// we don't re-throw it. This solution is incomplete though...
|
||||
throw;
|
||||
}
|
||||
if ( ! waitRelease ) {
|
||||
epicsGuard < epicsMutex > guard ( pThread->mutex );
|
||||
@@ -126,28 +113,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 ( epicsMin ( delay, 5.0 ) );
|
||||
}
|
||||
catch ( ... ) {
|
||||
errlogPrintf (
|
||||
"Non-standard unexpected exception in "
|
||||
"epicsThread::exitWait()\n" );
|
||||
epicsThreadSleep ( epicsMin ( delay, 5.0 ) );
|
||||
}
|
||||
return this->terminated;
|
||||
}
|
||||
@@ -270,13 +269,6 @@ void epicsThread::setOkToBlock(bool isOkToBlock) throw ()
|
||||
epicsThreadSetOkToBlock(static_cast<int>(isOkToBlock));
|
||||
}
|
||||
|
||||
class epicsThreadPrivateBase::unableToCreateThreadPrivate : public exception {
|
||||
const char * what () const throw ()
|
||||
{
|
||||
return "epicsThreadPrivate:: unable to create thread private variable";
|
||||
}
|
||||
};
|
||||
|
||||
void epicsThreadPrivateBase::throwUnableToCreateThreadPrivate ()
|
||||
{
|
||||
throw epicsThreadPrivateBase::unableToCreateThreadPrivate ();
|
||||
@@ -321,4 +313,4 @@ extern "C" {
|
||||
} // extern "C"
|
||||
|
||||
// Ensure the main thread gets a unique ID
|
||||
static epicsThreadId epicsThreadMainId = epicsThreadGetIdSelf();
|
||||
epicsThreadId epicsThreadMainId = epicsThreadGetIdSelf();
|
||||
|
||||
@@ -156,7 +156,9 @@ public:
|
||||
static const char * getNameSelf () throw ();
|
||||
static bool isOkToBlock () throw ();
|
||||
static void setOkToBlock ( bool isOkToBlock ) throw ();
|
||||
class unableToCreateThread; /* exception payload */
|
||||
|
||||
/* exceptions */
|
||||
class unableToCreateThread {};
|
||||
private:
|
||||
epicsThreadRunable & runable;
|
||||
epicsThreadId id;
|
||||
@@ -173,12 +175,13 @@ private:
|
||||
epicsThread & operator = ( const epicsThread & );
|
||||
friend void epicsThreadCallEntryPoint ( void * );
|
||||
|
||||
class exitException; /* exception payload */
|
||||
/* exceptions */
|
||||
class exitException {};
|
||||
};
|
||||
|
||||
class epicsShareClass epicsThreadPrivateBase {
|
||||
public:
|
||||
class unableToCreateThreadPrivate; /* exception */
|
||||
class unableToCreateThreadPrivate {}; /* exception */
|
||||
protected:
|
||||
static void throwUnableToCreateThreadPrivate ();
|
||||
};
|
||||
|
||||
@@ -131,22 +131,16 @@ epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
rtems_status_code sc;
|
||||
uint32_t wait;
|
||||
rtems_interval delay;
|
||||
extern double rtemsTicksPerSecond_double;
|
||||
|
||||
if (timeOut <= 0.0)
|
||||
return epicsEventTryWait(id);
|
||||
SEMSTAT(1)
|
||||
if (timeOut <= 0.0) {
|
||||
wait = RTEMS_NO_WAIT;
|
||||
delay = 0;
|
||||
}
|
||||
else {
|
||||
wait = RTEMS_WAIT;
|
||||
delay = timeOut * rtemsTicksPerSecond_double;
|
||||
if (delay == 0)
|
||||
delay++;
|
||||
}
|
||||
sc = rtems_semaphore_obtain (sid, wait, delay);
|
||||
delay = timeOut * rtemsTicksPerSecond_double;
|
||||
if (delay == 0)
|
||||
delay++;
|
||||
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, delay);
|
||||
if (sc == RTEMS_SUCCESSFUL)
|
||||
return epicsEventWaitOK;
|
||||
else if (sc == RTEMS_TIMEOUT)
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* This header fragment is intended to be included as part of epicsString.h
|
||||
* epicsStrtod() for systems with working strtod() routine
|
||||
*/
|
||||
|
||||
/*
|
||||
* epicsStrtod() for systems with broken strtod() routine
|
||||
*/
|
||||
epicsShareFunc double epicsStrtod(const char *str, char **endp);
|
||||
#define epicsStrtod strtod
|
||||
|
||||
@@ -104,6 +104,9 @@ int epicsTime_localtime ( const time_t *clock, struct tm *result )
|
||||
}
|
||||
}
|
||||
|
||||
rtems_interval rtemsTicksPerSecond;
|
||||
double rtemsTicksPerSecond_double, rtemsTicksPerTwoSeconds_double;
|
||||
|
||||
} // extern "C"
|
||||
|
||||
/*
|
||||
@@ -119,6 +122,11 @@ static int staticTimeRegister(void)
|
||||
{
|
||||
if (rtemsTicksPerSecond != 0)
|
||||
osdTimeRegister();
|
||||
|
||||
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &rtemsTicksPerSecond);
|
||||
rtemsTicksPerSecond_double = rtemsTicksPerSecond;
|
||||
rtemsTicksPerTwoSeconds_double = rtemsTicksPerSecond_double * 2.0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
static int done = staticTimeRegister();
|
||||
|
||||
@@ -793,13 +793,17 @@ epicsShareFunc void epicsShareAPI epicsThreadSleep ( double seconds )
|
||||
* epicsThreadSleepQuantum ()
|
||||
*/
|
||||
double epicsShareAPI epicsThreadSleepQuantum ()
|
||||
{
|
||||
{
|
||||
/*
|
||||
* Its worth noting here that the sleep quantum on windows can
|
||||
* mysteriously get better. I eventually tracked this down to
|
||||
* codes that call timeBeginPeriod(1). Calling timeBeginPeriod()
|
||||
* specifying a better timer resolution also increases the interrupt
|
||||
* load. This appears to be related to java applet activity.
|
||||
* The function timeGetDevCaps can tell us the range of periods
|
||||
* that can be specified to timeBeginPeriod, but alas there
|
||||
* appears to be no way to find out what the value of the global
|
||||
* minimum of all timeBeginPeriod calls for all processes is.
|
||||
*/
|
||||
static const double secPerTick = 100e-9;
|
||||
DWORD adjustment;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,18 @@
|
||||
//
|
||||
// Default version of osdWireConfig.h that might
|
||||
// work on UNIX like systems that define <sys/param.h>
|
||||
//
|
||||
// Author Jeffrey O. Hill
|
||||
// johill@lanl.gov
|
||||
//
|
||||
/*
|
||||
* Default version of osdWireConfig.h that might
|
||||
* work on UNIX like systems that define <sys/param.h>
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef osdWireConfig_h
|
||||
#define osdWireConfig_h
|
||||
|
||||
// if compilation fails because this wasnt found then you may need to define an OS
|
||||
// specific osdWireConfig.h
|
||||
/* This file must be usable from both C and C++ */
|
||||
|
||||
/* if compilation fails because this wasnt found then you may need to define an OS
|
||||
specific osdWireConfig.h */
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifdef __BYTE_ORDER
|
||||
@@ -53,10 +55,10 @@
|
||||
# error EPICS hasnt been ported to <sys/param.h> specified FLOAT_WORD_ORDER
|
||||
# endif
|
||||
# else
|
||||
// assume that if neither __FLOAT_WORD_ORDER nor FLOAT_WORD_ORDER are
|
||||
// defined then weird fp ordered archs like arm nwfp aren't supported
|
||||
/* assume that if neither __FLOAT_WORD_ORDER nor FLOAT_WORD_ORDER are
|
||||
defined then weird fp ordered archs like arm nwfp aren't supported */
|
||||
# define EPICS_FLOAT_WORD_ORDER EPICS_BYTE_ORDER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // ifdef osdWireConfig_h
|
||||
#endif /* ifdef osdWireConfig_h */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -22,20 +22,28 @@
|
||||
#include "cantProceed.h"
|
||||
#include "epicsRingBytes.h"
|
||||
|
||||
/*
|
||||
* Need at least one extra byte to be able to distinguish a completely
|
||||
* full buffer from a completely empty one. Allow for a little extra
|
||||
* space to try and keep good alignment and avoid multiple calls to
|
||||
* memcpy for a single put/get operation.
|
||||
*/
|
||||
#define SLOP 16
|
||||
|
||||
typedef struct ringPvt {
|
||||
int nextPut;
|
||||
int nextGet;
|
||||
int size;
|
||||
char *buffer;
|
||||
volatile int nextPut;
|
||||
volatile int nextGet;
|
||||
int size;
|
||||
volatile char *buffer;
|
||||
}ringPvt;
|
||||
|
||||
|
||||
epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int size)
|
||||
{
|
||||
ringPvt *pring = mallocMustSucceed(sizeof(ringPvt),"epicsRingBytesCreate");
|
||||
pring->size = size + 1;
|
||||
pring->size = size + SLOP;
|
||||
pring->buffer = mallocMustSucceed(pring->size,"ringCreate");
|
||||
pring->nextGet = pring->nextPut = 0;
|
||||
pring->nextGet = 0;
|
||||
pring->nextPut = 0;
|
||||
return((void *)pring);
|
||||
}
|
||||
|
||||
@@ -45,7 +53,7 @@ epicsShareFunc void epicsShareAPI epicsRingBytesDelete(epicsRingBytesId id)
|
||||
free((void *)pring->buffer);
|
||||
free((void *)pring);
|
||||
}
|
||||
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesGet(
|
||||
epicsRingBytesId id, char *value,int nbytes)
|
||||
{
|
||||
@@ -59,19 +67,21 @@ epicsShareFunc int epicsShareAPI epicsRingBytesGet(
|
||||
count = nextPut - nextGet;
|
||||
if (count < nbytes)
|
||||
nbytes = count;
|
||||
memcpy (value, &pring->buffer[nextGet], nbytes);
|
||||
if (nbytes)
|
||||
memcpy (value, (void *)&pring->buffer[nextGet], nbytes);
|
||||
nextGet += nbytes;
|
||||
}
|
||||
else {
|
||||
count = size - nextGet;
|
||||
if (count > nbytes)
|
||||
count = nbytes;
|
||||
memcpy (value, &pring->buffer[nextGet], count);
|
||||
if ((nextGet = nextGet + count) == size) {
|
||||
memcpy (value, (void *)&pring->buffer[nextGet], count);
|
||||
nextGet += count;
|
||||
if (nextGet == size) {
|
||||
int nLeft = nbytes - count;
|
||||
if (nLeft > nextPut)
|
||||
nLeft = nextPut;
|
||||
memcpy (value+count, &pring->buffer[0], nLeft);
|
||||
memcpy (value+count, (void *)&pring->buffer[0], nLeft);
|
||||
nextGet = nLeft;
|
||||
nbytes = count + nLeft;
|
||||
}
|
||||
@@ -90,78 +100,68 @@ epicsShareFunc int epicsShareAPI epicsRingBytesPut(
|
||||
int nextGet = pring->nextGet;
|
||||
int nextPut = pring->nextPut;
|
||||
int size = pring->size;
|
||||
int count;
|
||||
int freeCount, copyCount, topCount;
|
||||
|
||||
if (nextPut < nextGet) {
|
||||
count = nextGet - nextPut - 1;
|
||||
if (nbytes > count)
|
||||
nbytes = count;
|
||||
memcpy (&pring->buffer[nextPut], value, nbytes);
|
||||
nextPut += nbytes;
|
||||
}
|
||||
else if (nextGet == 0) {
|
||||
count = size - nextPut - 1;
|
||||
if (nbytes > count)
|
||||
nbytes = count;
|
||||
memcpy (&pring->buffer[nextPut], value, nbytes);
|
||||
freeCount = nextGet - nextPut - SLOP;
|
||||
if (nbytes > freeCount)
|
||||
nbytes = freeCount;
|
||||
if (nbytes)
|
||||
memcpy ((void *)&pring->buffer[nextPut], value, nbytes);
|
||||
nextPut += nbytes;
|
||||
}
|
||||
else {
|
||||
count = size - nextPut;
|
||||
if (count > nbytes)
|
||||
count = nbytes;
|
||||
memcpy (&pring->buffer[nextPut], value, count);
|
||||
if ((nextPut = nextPut + count) == size) {
|
||||
int nLeft = nbytes - count;
|
||||
if (nLeft > (nextGet - 1))
|
||||
nLeft = nextGet - 1;
|
||||
memcpy (&pring->buffer[0], value+count, nLeft);
|
||||
freeCount = size - nextPut + nextGet - SLOP;
|
||||
if (nbytes > freeCount)
|
||||
nbytes = freeCount;
|
||||
topCount = size - nextPut;
|
||||
copyCount = (nbytes > topCount) ? topCount : nbytes;
|
||||
if (copyCount)
|
||||
memcpy ((void *)&pring->buffer[nextPut], value, copyCount);
|
||||
nextPut += copyCount;
|
||||
if (nextPut == size) {
|
||||
int nLeft = nbytes - copyCount;
|
||||
if (nLeft)
|
||||
memcpy ((void *)&pring->buffer[0], value+copyCount, nLeft);
|
||||
nextPut = nLeft;
|
||||
nbytes = count + nLeft;
|
||||
}
|
||||
else {
|
||||
nbytes = count;
|
||||
nextPut = nextPut;
|
||||
}
|
||||
}
|
||||
pring->nextPut = nextPut;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsRingBytesFlush(epicsRingBytesId id)
|
||||
{
|
||||
ringPvt *pring = (ringPvt *)id;
|
||||
|
||||
pring->nextGet = pring->nextPut = 0;
|
||||
pring->nextGet = 0;
|
||||
pring->nextPut = 0;
|
||||
}
|
||||
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesFreeBytes(epicsRingBytesId id)
|
||||
{
|
||||
ringPvt *pring = (ringPvt *)id;
|
||||
int n;
|
||||
int nextGet = pring->nextGet;
|
||||
int nextPut = pring->nextPut;
|
||||
|
||||
n = pring->nextGet - pring->nextPut - 1;
|
||||
if (n < 0)
|
||||
n += pring->size;
|
||||
return n;
|
||||
if (nextPut < nextGet)
|
||||
return nextGet - nextPut - SLOP;
|
||||
else
|
||||
return pring->size - nextPut + nextGet - SLOP;
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesUsedBytes(epicsRingBytesId id)
|
||||
{
|
||||
ringPvt *pring = (ringPvt *)id;
|
||||
int n;
|
||||
|
||||
n = pring->nextPut - pring->nextGet;
|
||||
if (n < 0)
|
||||
n += pring->size;
|
||||
return n;
|
||||
return pring->size - epicsRingBytesFreeBytes(id) - SLOP;
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesSize(epicsRingBytesId id)
|
||||
{
|
||||
ringPvt *pring = (ringPvt *)id;
|
||||
|
||||
return pring->size - 1;
|
||||
return pring->size - SLOP;
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesIsEmpty(epicsRingBytesId id)
|
||||
@@ -173,9 +173,5 @@ epicsShareFunc int epicsShareAPI epicsRingBytesIsEmpty(epicsRingBytesId id)
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesIsFull(epicsRingBytesId id)
|
||||
{
|
||||
ringPvt *pring = (ringPvt *)id;
|
||||
int count;
|
||||
|
||||
count = (pring->nextPut - pring->nextGet) + 1;
|
||||
return ((count == 0) || (count == pring->size));
|
||||
return (epicsRingBytesFreeBytes(id) <= 0);
|
||||
}
|
||||
|
||||
@@ -43,10 +43,10 @@ private: /* Prevent compiler-generated member functions */
|
||||
epicsRingPointer& operator=(const epicsRingPointer &);
|
||||
|
||||
private: /* Data */
|
||||
int nextPush;
|
||||
int nextPop;
|
||||
volatile int nextPush;
|
||||
volatile int nextPop;
|
||||
int size;
|
||||
T **buffer;
|
||||
T * volatile * buffer;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
@@ -93,10 +93,11 @@ inline epicsRingPointer<T>::~epicsRingPointer()
|
||||
template <class T>
|
||||
inline bool epicsRingPointer<T>::push(T *p)
|
||||
{
|
||||
int newNext = nextPush +1;
|
||||
int next = nextPush;
|
||||
int newNext = next + 1;
|
||||
if(newNext>=size) newNext=0;
|
||||
if(newNext==nextPop) return(false);
|
||||
buffer[nextPush] = p;
|
||||
buffer[next] = p;
|
||||
nextPush = newNext;
|
||||
return(true);
|
||||
}
|
||||
@@ -104,18 +105,21 @@ inline bool epicsRingPointer<T>::push(T *p)
|
||||
template <class T>
|
||||
inline T* epicsRingPointer<T>::pop()
|
||||
{
|
||||
if(nextPop == nextPush) return(0);
|
||||
T*p = buffer[nextPop];
|
||||
int newNext= nextPop;
|
||||
++newNext;
|
||||
if(newNext >=size) newNext = 0;
|
||||
nextPop = newNext;
|
||||
int next = nextPop;
|
||||
if(next == nextPush) return(0);
|
||||
T*p = buffer[next];
|
||||
++next;
|
||||
if(next >=size) next = 0;
|
||||
nextPop = next;
|
||||
return(p);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void epicsRingPointer<T>::flush()
|
||||
{ nextPop = nextPush = 0;}
|
||||
{
|
||||
nextPop = 0;
|
||||
nextPush = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline int epicsRingPointer<T>::getFree() const
|
||||
|
||||
@@ -77,6 +77,11 @@ ringPointerTest_SRCS += ringPointerTest.c
|
||||
testHarness_SRCS += ringPointerTest.c
|
||||
TESTS += ringPointerTest
|
||||
|
||||
TESTPROD_HOST += ringBytesTest
|
||||
ringBytesTest_SRCS += ringBytesTest.c
|
||||
testHarness_SRCS += ringBytesTest.c
|
||||
TESTS += ringBytesTest
|
||||
|
||||
TESTPROD_HOST += epicsEventTest
|
||||
epicsEventTest_SRCS += epicsEventTest.cpp
|
||||
testHarness_SRCS += epicsEventTest.cpp
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
#include "testMain.h"
|
||||
|
||||
static const char *msg1 = "1234567890This is a very long message.";
|
||||
static int testExit = 0;
|
||||
static volatile int testExit = 0;
|
||||
static epicsEventId finished;
|
||||
|
||||
/*
|
||||
* In Numerical Recipes in C: The Art of Scientific Computing (William H.
|
||||
@@ -105,6 +106,7 @@ receiver(void *arg)
|
||||
testDiag("Sender %d -- %d messages", sender, expectmsg[sender-1]-1);
|
||||
}
|
||||
testOk1(errors == 0);
|
||||
epicsEventSignal(finished);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
@@ -125,7 +127,6 @@ sender(void *arg)
|
||||
|
||||
extern "C" void messageQueueTest(void *parm)
|
||||
{
|
||||
epicsEventId *pfinished = (epicsEventId *) parm;
|
||||
unsigned int i;
|
||||
char cbuf[80];
|
||||
int len;
|
||||
@@ -278,19 +279,17 @@ extern "C" void messageQueueTest(void *parm)
|
||||
epicsThreadSleep(300.0);
|
||||
|
||||
testExit = 1;
|
||||
epicsThreadSleep(1.0);
|
||||
epicsEventSignal(*pfinished);
|
||||
}
|
||||
|
||||
MAIN(epicsMessageQueueTest)
|
||||
{
|
||||
testPlan(58);
|
||||
|
||||
epicsEventId finished = epicsEventMustCreate(epicsEventEmpty);
|
||||
finished = epicsEventMustCreate(epicsEventEmpty);
|
||||
|
||||
epicsThreadCreate("messageQueueTest", epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
messageQueueTest, (void *) &finished);
|
||||
messageQueueTest, NULL);
|
||||
|
||||
epicsEventWait(finished);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ int epicsTimeTest(void);
|
||||
int macLibTest(void);
|
||||
int macEnvExpandTest(void);
|
||||
int ringPointerTest(void);
|
||||
int ringBytesTest(void);
|
||||
int blockingSockTest(void);
|
||||
int taskwdTest(void);
|
||||
int epicsExitTest(void);
|
||||
@@ -80,6 +81,8 @@ void epicsRunLibComTests(void)
|
||||
|
||||
runTest(ringPointerTest);
|
||||
|
||||
runTest(ringBytesTest);
|
||||
|
||||
runTest(blockingSockTest);
|
||||
|
||||
runTest(taskwdTest);
|
||||
|
||||
@@ -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);
|
||||
@@ -46,7 +46,9 @@ static void testEpicsSnprintf() {
|
||||
|
||||
for (size = 1; size < strlen(expected) + 5; ++size) {
|
||||
rtn = epicsSnprintf(buffer, size, format, ivalue, fvalue, svalue);
|
||||
testOk(rtn == rlen-1, "epicsSnprintf(size=%d) = %d", size, rtn);
|
||||
testOk(rtn <= rlen-1, "epicsSnprintf(size=%d) = %d", size, rtn);
|
||||
if (rtn != rlen-1)
|
||||
testDiag("Return value does not indicate buffer size needed");
|
||||
testOk(strncmp(buffer, expected, size - 1) == 0,
|
||||
"buffer = '%s'", buffer);
|
||||
rtn = strlen(buffer);
|
||||
|
||||
142
src/libCom/test/ringBytesTest.c
Normal file
142
src/libCom/test/ringBytesTest.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*************************************************************************\
|
||||
* 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 is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* ringBytesTest.c */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "epicsThread.h"
|
||||
#include "epicsRingBytes.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
#define RINGSIZE 10
|
||||
|
||||
static char msg[] = "This is a very long string to be sent through the ring. "
|
||||
"It will take multiple transmissions, you know.";
|
||||
|
||||
typedef struct info {
|
||||
epicsEventId consumerEvent;
|
||||
epicsRingBytesId ring;
|
||||
}info;
|
||||
|
||||
static void check(epicsRingBytesId ring, int expectedFree)
|
||||
{
|
||||
int expectedUsed = RINGSIZE - expectedFree;
|
||||
int expectedEmpty = (expectedUsed == 0);
|
||||
int expectedFull = (expectedFree == 0);
|
||||
int nFree = epicsRingBytesFreeBytes(ring);
|
||||
int nUsed = epicsRingBytesUsedBytes(ring);
|
||||
int isEmpty = epicsRingBytesIsEmpty(ring);
|
||||
int isFull = epicsRingBytesIsFull(ring);
|
||||
|
||||
testOk(nFree == expectedFree, "Free: %d == %d", nFree, expectedFree);
|
||||
testOk(nUsed == expectedUsed, "Used: %d == %d", nUsed, expectedUsed);
|
||||
testOk(isEmpty == expectedEmpty, "Empty: %d == %d", isEmpty, expectedEmpty);
|
||||
testOk(isFull == expectedFull, "Full: %d == %d", isFull, expectedFull);
|
||||
}
|
||||
|
||||
static void consumer(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
char getMsg[sizeof(msg) + RINGSIZE];
|
||||
int i = 0;
|
||||
int n;
|
||||
|
||||
testDiag("Consumer starting");
|
||||
while(1) {
|
||||
epicsEventMustWait(pinfo->consumerEvent);
|
||||
n = epicsRingBytesGet(pinfo->ring, getMsg+i, RINGSIZE);
|
||||
testOk(n != 0, "Read from ring");
|
||||
i += n;
|
||||
if (i >= sizeof(msg))
|
||||
break;
|
||||
}
|
||||
testOk(i==sizeof(msg), "Correct number of bytes received %d==%d", i, (int)sizeof(msg));
|
||||
testOk(strcmp(msg, getMsg) == 0, "Message received");
|
||||
}
|
||||
|
||||
MAIN(ringBytesTest)
|
||||
{
|
||||
int i, n;
|
||||
info *pinfo;
|
||||
epicsEventId consumerEvent;
|
||||
char put[RINGSIZE+1];
|
||||
char get[RINGSIZE+1];
|
||||
epicsRingBytesId ring;
|
||||
|
||||
testPlan(242);
|
||||
|
||||
pinfo = calloc(1,sizeof(info));
|
||||
if (!pinfo) {
|
||||
testAbort("calloc failed");
|
||||
}
|
||||
pinfo->consumerEvent = consumerEvent = epicsEventCreate(epicsEventEmpty);
|
||||
if (!consumerEvent) {
|
||||
testAbort("epicsEventCreate failed");
|
||||
}
|
||||
|
||||
pinfo->ring = ring = epicsRingBytesCreate(RINGSIZE);
|
||||
if (!ring) {
|
||||
testAbort("epicsRingBytesCreate failed");
|
||||
}
|
||||
check(ring, RINGSIZE);
|
||||
|
||||
for (i = 0 ; i < sizeof(put) ; i++)
|
||||
put[i] = i;
|
||||
for(i = 0 ; i < RINGSIZE ; i++) {
|
||||
n = epicsRingBytesPut(ring, put, i);
|
||||
testOk(n==i, "ring put %d", i);
|
||||
check(ring, RINGSIZE-i);
|
||||
n = epicsRingBytesGet(ring, get, i);
|
||||
testOk(n==i, "ring get %d", i);
|
||||
check(ring, RINGSIZE);
|
||||
testOk(memcmp(put,get,i)==0, "get matches write");
|
||||
}
|
||||
|
||||
for(i = 0 ; i < RINGSIZE ; i++) {
|
||||
n = epicsRingBytesPut(ring, put+i, 1);
|
||||
testOk(n==1, "ring put 1, %d", i);
|
||||
check(ring, RINGSIZE-1-i);
|
||||
}
|
||||
n = epicsRingBytesPut(ring, put+RINGSIZE, 1);
|
||||
testOk(n==0, "put to full ring");
|
||||
check(ring, 0);
|
||||
for(i = 0 ; i < RINGSIZE ; i++) {
|
||||
n = epicsRingBytesGet(ring, get+i, 1);
|
||||
testOk(n==1, "ring get 1, %d", i);
|
||||
check(ring, 1+i);
|
||||
}
|
||||
testOk(memcmp(put,get,RINGSIZE)==0, "get matches write");
|
||||
n = epicsRingBytesGet(ring, get+RINGSIZE, 1);
|
||||
testOk(n==0, "get from empty ring");
|
||||
check(ring, RINGSIZE);
|
||||
|
||||
epicsThreadCreate("consumer", 50,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall), consumer, pinfo);
|
||||
epicsThreadSleep(0.1);
|
||||
|
||||
for (i = 0; i < sizeof(msg) ; ) {
|
||||
n = epicsRingBytesPut(ring, msg+i, sizeof(msg)-i);
|
||||
epicsEventSignal(consumerEvent);
|
||||
epicsThreadSleep(0.2);
|
||||
i += n;
|
||||
}
|
||||
epicsThreadSleep(0.2);
|
||||
check(ring, RINGSIZE);
|
||||
|
||||
return testDone();
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#define ringSize 10
|
||||
|
||||
static int testExit = 0;
|
||||
static volatile int testExit = 0;
|
||||
|
||||
typedef struct info {
|
||||
epicsEventId consumerEvent;
|
||||
|
||||
@@ -23,7 +23,6 @@ TEMPLATES += top/iocApp/Makefile
|
||||
TEMPLATES += top/iocApp/Db/Makefile
|
||||
TEMPLATES += top/iocApp/src/Makefile
|
||||
TEMPLATES += top/iocApp/src/_APPNAME_Main.cpp
|
||||
TEMPLATES += top/iocApp/src/sncExample.stt
|
||||
|
||||
TEMPLATES += top/exampleApp/Makefile
|
||||
TEMPLATES += top/exampleApp/Db/Makefile
|
||||
|
||||
@@ -48,7 +48,7 @@ _APPNAME__SRCS_DEFAULT += _APPNAME_Main.cpp
|
||||
_APPNAME__SRCS_vxWorks += -nil-
|
||||
|
||||
# Add support from base/src/vxWorks if needed
|
||||
_APPNAME__OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
|
||||
#_APPNAME__OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
|
||||
|
||||
# Link in the code from the support library
|
||||
_APPNAME__LIBS += _APPNAME_Support
|
||||
@@ -58,7 +58,7 @@ _APPNAME__LIBS += _APPNAME_Support
|
||||
|
||||
ifneq ($(SNCSEQ),)
|
||||
# Build sncExample into _APPNAME_Support
|
||||
_APPNAME__SNCFLAGS += +r
|
||||
sncExample_SNCFLAGS += +r
|
||||
_APPNAME__DBD += sncExample.dbd
|
||||
_APPNAME_Support_SRCS += sncExample.stt
|
||||
_APPNAME_Support_LIBS += seq pv
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user