Compare commits
79 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5b754d320f | |||
| 2be2658cfc | |||
| 2b157096e6 | |||
| 71eaddfd84 | |||
| 5589deb3ad | |||
| 0bb80e373b | |||
| 4acdd83984 | |||
| d12d38f970 | |||
| 74d9749255 | |||
| 3276ada78a | |||
| de378eec34 | |||
| dbb2d875fb | |||
| c7f966a1f5 | |||
|
|
2a14647eec | ||
|
|
597393a8ee | ||
|
|
bad8b25e4e | ||
|
|
7fe8373c32 | ||
|
|
72be690fec | ||
|
|
a5b3157ec1 | ||
|
|
9a062cd6a1 | ||
|
|
592b935146 | ||
|
|
638391249d | ||
|
|
cde682f7ba | ||
|
|
89da4130fc | ||
|
|
1d2637a04e | ||
|
|
a2123db9fb | ||
|
|
7f55bb0386 | ||
|
|
511a541f31 | ||
|
|
394c39da51 | ||
|
|
632d1f45c8 | ||
|
|
0f75e0aa7f | ||
|
|
c93ec231a2 | ||
|
|
d1149a0ba9 | ||
|
|
8c3c5a9731 | ||
|
|
44510f2fb2 | ||
| 7889dda6f8 | |||
|
|
933733465e | ||
|
|
688f32cff0 | ||
|
|
d3feb1e2f9 | ||
|
|
62c11c22c9 | ||
|
|
736075daf6 | ||
|
|
9ef3b77348 | ||
|
|
d15c8093ec | ||
|
|
0211698b69 | ||
|
|
e860617389 | ||
|
|
e918994704 | ||
|
|
5eb7da4595 | ||
|
|
2206934ae2 | ||
|
|
318fc96912 | ||
|
|
a58cc37a5e | ||
|
|
b5e041b991 | ||
|
|
5e1bad2b34 | ||
|
|
0ae50485cf | ||
|
|
bc7ee94e2c | ||
|
|
3fb10b6d59 | ||
|
|
a8fdf2efeb | ||
|
|
c9eda3ca48 | ||
| a2ccf3b631 | |||
| 57db34b303 | |||
| 4f790758af | |||
| ce9dfc6bb4 | |||
| 4f40ad1927 | |||
| a42a4010d6 | |||
| a2aa17fafc | |||
| 5bf2784db2 | |||
| 7a4e7b7600 | |||
| 70aa23513f | |||
| 71ded2f25f | |||
| 11103351b2 | |||
| 146a413977 | |||
| 4e44550f62 | |||
| 9952470486 | |||
| 02d30dedbc | |||
| 5ed0fe52a0 | |||
| 42b1f774da | |||
| 7738b68320 | |||
| 1199fabe90 | |||
| 1aefc5f2f0 | |||
| 6f666c6c22 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -22,3 +22,6 @@
|
||||
path = modules/pva2pva
|
||||
url = https://github.com/epics-base/pva2pva
|
||||
branch = master
|
||||
[submodule "modules/pcas"]
|
||||
path = modules/pcas
|
||||
url = https://github.com/epics-modules/pcas
|
||||
|
||||
@@ -36,7 +36,10 @@ case "$PREFIX" in
|
||||
esac
|
||||
|
||||
# Check for both <tag> and R<tag>
|
||||
if ! [ `git tag -l $TOPREV` ]
|
||||
if [ "$TOPREV" = "HEAD" ]
|
||||
then
|
||||
true
|
||||
elif ! [ `git tag -l $TOPREV` ]
|
||||
then
|
||||
if [ `git tag -l R$TOPREV` ]
|
||||
then
|
||||
|
||||
7
Makefile
7
Makefile
@@ -23,3 +23,10 @@ DIRS += modules
|
||||
modules_DEPEND_DIRS = src
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
||||
|
||||
UNINSTALL_DIRS += $(INSTALL_LOCATION)/src
|
||||
copysrc:
|
||||
tar cf - --exclude-vcs --exclude-backups --exclude=O.* modules/*/src | tar xf - -C $(INSTALL_LOCATION)
|
||||
|
||||
tar:
|
||||
tar cfjP epics_base-$(EPICS_VERSION_NUMBER).tar.bz2 $(INSTALL_LOCATION)
|
||||
|
||||
@@ -52,10 +52,12 @@ EPICS_MODIFICATION = 2
|
||||
|
||||
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
|
||||
# Not included if zero
|
||||
EPICS_PATCH_LEVEL = 0
|
||||
EPICS_PATCH_LEVEL = 2
|
||||
|
||||
# This will end in -DEV between official releases
|
||||
#EPICS_DEV_SNAPSHOT=-DEV
|
||||
# Between official releases, the EPICS_PATCH_LEVEL gets incremented
|
||||
# and a -DEV suffix is added (similar to the Maven -SNAPSHOT versions)
|
||||
#EPICS_DEV_SNAPSHOT=
|
||||
EPICS_DEV_SNAPSHOT=-DEV
|
||||
#EPICS_DEV_SNAPSHOT=-pre1
|
||||
#EPICS_DEV_SNAPSHOT=-pre1-DEV
|
||||
#EPICS_DEV_SNAPSHOT=-pre2
|
||||
@@ -64,7 +66,6 @@ EPICS_PATCH_LEVEL = 0
|
||||
#EPICS_DEV_SNAPSHOT=-rc1-DEV
|
||||
#EPICS_DEV_SNAPSHOT=-rc2
|
||||
#EPICS_DEV_SNAPSHOT=-rc2-DEV
|
||||
EPICS_DEV_SNAPSHOT=
|
||||
|
||||
# No changes should be needed below here
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES
|
||||
|
||||
# Site version number, if set will append '-' and this string to the
|
||||
# EPICS version number string that is reported by many tools.
|
||||
EPICS_SITE_VERSION =
|
||||
EPICS_SITE_VERSION:=$(shell date +%Y-%m)
|
||||
|
||||
# For GNU compiler, use pipes rather than temporary files for
|
||||
# communication between the various stages of compilation.
|
||||
|
||||
@@ -34,14 +34,9 @@
|
||||
# The future dates below assume the rules don't get changed;
|
||||
# see http://www.timeanddate.com/time/dst/2018.html to check.
|
||||
#
|
||||
# DST for 2018 US: Mar 11 - Nov 04
|
||||
# EU: Mar 25 - Oct 28
|
||||
EPICS_TIMEZONE = CUS::360:031102:110402
|
||||
#EPICS_TIMEZONE = MET::-60:032502:102803
|
||||
#
|
||||
# DST for 2019 US: Mar 10 - Nov 03
|
||||
# EU: Mar 31 - Oct 27
|
||||
#EPICS_TIMEZONE = CUS::360:031002:110302
|
||||
EPICS_TIMEZONE = CUS::360:031002:110302
|
||||
#EPICS_TIMEZONE = MET::-60:033102:102703
|
||||
#
|
||||
# DST for 2020 US: Mar 08 - Nov 01
|
||||
@@ -58,6 +53,11 @@ EPICS_TIMEZONE = CUS::360:031102:110402
|
||||
# EU: Mar 27 - Oct 30
|
||||
#EPICS_TIMEZONE = CUS::360:031302:110602
|
||||
#EPICS_TIMEZONE = MET::-60:032702:103003
|
||||
#
|
||||
# DST for 2023 US: Mar 13 - Nov 06
|
||||
# EU: Mar 27 - Oct 30
|
||||
#EPICS_TIMEZONE = CUS::360:031202:110502
|
||||
#EPICS_TIMEZONE = MET::-60:032602:102903
|
||||
|
||||
# EPICS_TS_NTP_INET
|
||||
# NTP time server ip address for VxWorks and RTEMS.
|
||||
|
||||
@@ -86,6 +86,23 @@ include $(CONFIG)/RULES_FILE_TYPE
|
||||
|
||||
include $(CONFIG)/RULES.Db
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Do not build anything if current path matches SKIP_BUILD
|
||||
|
||||
ifneq (,$(strip $(SKIP_BUILDS)))
|
||||
CURRENT_MODULE=$(subst $(realpath $(TOP)/..)/,,$(subst $(realpath $(dir $(lastword $(MAKEFILE_LIST)))..)/,,$(realpath ..)))
|
||||
ifneq ($(filter $(SKIP_BUILDS) $(addsuffix /%,$(SKIP_BUILDS)),$(CURRENT_MODULE)),)
|
||||
$(info Skipping $(CURRENT_MODULE) for $(T_A))
|
||||
PROD=
|
||||
TESTPROD=
|
||||
LIBRARY=
|
||||
TESTLIBRARY=
|
||||
LOADABLE_LIBRARY=
|
||||
TESTS=
|
||||
SRC_FILES=
|
||||
endif
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Include defines and rules for prod, library and test* targets
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@ realuninstall: uninstallDirs
|
||||
UNINSTALL_DIRS += $(INSTALL_DBD) $(INSTALL_INCLUDE) $(INSTALL_DOC) \
|
||||
$(INSTALL_HTML) $(INSTALL_TEMPLATES) $(INSTALL_DB) $(DIRECTORY_TARGETS)
|
||||
ifneq ($(INSTALL_LOCATION),$(TOP))
|
||||
ifneq ($(INSTALL_LOCATION),$(EPICS_BASE))
|
||||
UNINSTALL_DIRS += $(INSTALL_CONFIG)
|
||||
endif
|
||||
endif
|
||||
uninstallDirs:
|
||||
$(RMDIR) $(UNINSTALL_DIRS)
|
||||
|
||||
|
||||
4
configure/os/CONFIG.Common.RHEL7-x86_64
Normal file
4
configure/os/CONFIG.Common.RHEL7-x86_64
Normal file
@@ -0,0 +1,4 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
3
configure/os/CONFIG.Common.RHEL7-x86_64-clang
Normal file
3
configure/os/CONFIG.Common.RHEL7-x86_64-clang
Normal file
@@ -0,0 +1,3 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
6
configure/os/CONFIG.Common.SL5-x86
Normal file
6
configure/os/CONFIG.Common.SL5-x86
Normal file
@@ -0,0 +1,6 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
|
||||
ARCH_DEP_CFLAGS += -march=i686
|
||||
4
configure/os/CONFIG.Common.SL5-x86_64
Normal file
4
configure/os/CONFIG.Common.SL5-x86_64
Normal file
@@ -0,0 +1,4 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
9
configure/os/CONFIG.Common.SL6-x86
Normal file
9
configure/os/CONFIG.Common.SL6-x86
Normal file
@@ -0,0 +1,9 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_DEP_CFLAGS += -march=i686
|
||||
|
||||
# remove warning in anyscalar.h
|
||||
ARCH_DEP_CXXFLAGS += -fno-strict-aliasing
|
||||
7
configure/os/CONFIG.Common.SL6-x86_64
Normal file
7
configure/os/CONFIG.Common.SL6-x86_64
Normal file
@@ -0,0 +1,7 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
# remove warning in anyscalar.h
|
||||
ARCH_DEP_CXXFLAGS += -fno-strict-aliasing
|
||||
3
configure/os/CONFIG.Common.SL6-x86_64-clang
Normal file
3
configure/os/CONFIG.Common.SL6-x86_64-clang
Normal file
@@ -0,0 +1,3 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
8
configure/os/CONFIG.Common.T2-ppc604
Normal file
8
configure/os/CONFIG.Common.T2-ppc604
Normal file
@@ -0,0 +1,8 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 5.5.1
|
||||
WIND_BASE = /afs/psi.ch/project/vxworks/Tornado2.2.1
|
||||
|
||||
#there is a problem with our ccppc and optimization
|
||||
# -O0 works, -O and -O1 and higher are buggy
|
||||
OPT_CFLAGS_YES = -O0
|
||||
OPT_CXXFLAGS_YES = -O0
|
||||
@@ -18,8 +18,10 @@ OBJ = .o
|
||||
LIB_PREFIX = lib
|
||||
LIB_SUFFIX = .a
|
||||
SHRLIB_SUFFIX_BASE = .so
|
||||
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(SHRLIB_VERSION))
|
||||
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(LOADABLE_SHRLIB_VERSION))
|
||||
#SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(SHRLIB_VERSION))
|
||||
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
#LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(LOADABLE_SHRLIB_VERSION))
|
||||
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
LOADABLE_SHRLIB_PREFIX = lib
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
2
configure/os/CONFIG.Common.V62-ppc604
Normal file
2
configure/os/CONFIG.Common.V62-ppc604
Normal file
@@ -0,0 +1,2 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.2
|
||||
5
configure/os/CONFIG.Common.V63-ppc603
Normal file
5
configure/os/CONFIG.Common.V63-ppc603
Normal file
@@ -0,0 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603_long
|
||||
VXWORKS_VERSION = 6.3
|
||||
|
||||
# Buggy "uninitialized variable" warning produces many false positives
|
||||
ARCH_DEP_CXXFLAGS += -Wno-uninitialized
|
||||
5
configure/os/CONFIG.Common.V63-ppc604
Normal file
5
configure/os/CONFIG.Common.V63-ppc604
Normal file
@@ -0,0 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.3
|
||||
|
||||
# Buggy "uninitialized variable" warning produces many false positives
|
||||
ARCH_DEP_CXXFLAGS += -Wno-uninitialized
|
||||
2
configure/os/CONFIG.Common.V66-ppc603
Normal file
2
configure/os/CONFIG.Common.V66-ppc603
Normal file
@@ -0,0 +1,2 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603_long
|
||||
VXWORKS_VERSION = 6.6
|
||||
2
configure/os/CONFIG.Common.V66-ppc604
Normal file
2
configure/os/CONFIG.Common.V66-ppc604
Normal file
@@ -0,0 +1,2 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.6
|
||||
5
configure/os/CONFIG.Common.V67-ppc604
Normal file
5
configure/os/CONFIG.Common.V67-ppc604
Normal file
@@ -0,0 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.7
|
||||
|
||||
#needed when including memPartLib.h, e.g. through moduleLib.h or loadLib.h
|
||||
ARCH_DEP_CFLAGS += -D_VSB_CONFIG_FILE='<../lib/h/config/vsbConfig.h>'
|
||||
25
configure/os/CONFIG.Common.eldk42-ppc4xxFP
Normal file
25
configure/os/CONFIG.Common.eldk42-ppc4xxFP
Normal file
@@ -0,0 +1,25 @@
|
||||
# DeltaTau PowerPMAC with ELDK 4.2
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
ELDK=/opt/eldk-4.2
|
||||
GNU_TARGET=ppc_4xxFP
|
||||
GNU_DIR=$(ELDK)/usr
|
||||
|
||||
# This cross tool chain is installed in a somehow weired way
|
||||
# Without the following lines it does not work on RHEL7
|
||||
# but it worked on SL6
|
||||
ARCH_DEP_CXXFLAGS += -I $(ELDK)/$(GNU_TARGET)/usr/include/c++/4.2.2
|
||||
ARCH_DEP_CXXFLAGS += -I $(ELDK)/$(GNU_TARGET)/usr/include/c++/4.2.2/powerpc-linux
|
||||
ARCH_DEP_CXXFLAGS += -I $(ELDK)/$(GNU_TARGET)/usr/include/c++/4.2.2/backward
|
||||
|
||||
ARCH_DEP_LDFLAGS += -Wl,-rpath-link,$(ELDK)/$(GNU_TARGET)/lib
|
||||
ARCH_DEP_LDFLAGS += -Wl,-rpath-link,$(ELDK)/$(GNU_TARGET)/usr/lib
|
||||
|
||||
# Some drivers complain
|
||||
ARCH_DEP_CFLAGS += -fno-strict-aliasing
|
||||
16
configure/os/CONFIG.Common.eldk51-ppc4xxSF
Normal file
16
configure/os/CONFIG.Common.eldk51-ppc4xxSF
Normal file
@@ -0,0 +1,16 @@
|
||||
# Virtex FPGA embedded Processor with ELDK 5.1
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = eldk
|
||||
SDK_DIR = /opt/eldk-5.1
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH)-$(SDK)-$(GNU_HOST_OS)
|
||||
GNU_TARGET = powerpc-4xx-softfloat
|
||||
GNU_ARCH = ppc405-linux
|
||||
GNU_DIR = $(SDK_DIR)/$(GNU_TARGET)/sysroots/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_ARCH)
|
||||
17
configure/os/CONFIG.Common.eldk52-e500v2
Normal file
17
configure/os/CONFIG.Common.eldk52-e500v2
Normal file
@@ -0,0 +1,17 @@
|
||||
# IOxOS IFC1210 with ELDK 5.2
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = eldk
|
||||
SDK_DIR = /opt/eldk-5.2
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH)-$(SDK)-$(GNU_HOST_OS)
|
||||
GNU_TARGET = powerpc-e500v2
|
||||
GNU_ARCH = ppce500v2-linux-gnuspe
|
||||
GNU_DIR = $(SDK_DIR)/$(GNU_TARGET)/sysroots/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_ARCH)
|
||||
GNU_TARGET_INCLUDE_DIR =
|
||||
23
configure/os/CONFIG.Common.eldk53-ppc4xxFP
Normal file
23
configure/os/CONFIG.Common.eldk53-ppc4xxFP
Normal file
@@ -0,0 +1,23 @@
|
||||
# DeltaTau PowerPMAC with ELDK 5.2
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = eldk
|
||||
SDK_DIR = /opt/eldk-5.3
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH)-$(SDK)-$(GNU_HOST_OS)
|
||||
GNU_ARCH = ppc440e-linux
|
||||
SDKTARGETSYSROOT=$(SDK_DIR)/powerpc-4xx/sysroots
|
||||
GNU_DIR = $(SDKTARGETSYSROOT)/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_ARCH)
|
||||
GNU_TARGET_INCLUDE_DIR =
|
||||
GNU_TARGET=powerpc-linux
|
||||
|
||||
ARCH_DEP_CPPFLAGS = -m32 -mcpu=440fp -mhard-float
|
||||
ARCH_DEP_CPPFLAGS += --sysroot=$(SDKTARGETSYSROOT)/$(GNU_ARCH)
|
||||
ARCH_DEP_LDFLAGS = --sysroot=$(SDKTARGETSYSROOT)/$(GNU_ARCH)
|
||||
AS=$(GNU_BIN)/$(GNU_TARGET)-as
|
||||
25
configure/os/CONFIG.Common.fslqoriq20-e6500_64
Normal file
25
configure/os/CONFIG.Common.fslqoriq20-e6500_64
Normal file
@@ -0,0 +1,25 @@
|
||||
# IOxOS IFC1211 with Freescale QorIQ 2.0 toolchain
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = fslsdk
|
||||
SDK_DIR = /opt/fsl-qoriq/2.0
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH_64)-$(SDK)-$(GNU_HOST_OS)
|
||||
SDK_TARGET = ppc64e6500-fsl-linux
|
||||
GNU_TARGET = powerpc64-fsl-linux
|
||||
SDKTARGETSYSROOT = $(SDK_DIR)/sysroots/$(SDK_TARGET)
|
||||
GNU_DIR = $(SDK_DIR)/sysroots/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_TARGET)
|
||||
|
||||
ARCH_DEP_CPPFLAGS = --sysroot=$(SDKTARGETSYSROOT)
|
||||
ARCH_DEP_CFLAGS = -mcpu=e6500 -m64 -mhard-float
|
||||
ARCH_DEP_LDFLAGS = --sysroot=$(SDKTARGETSYSROOT)
|
||||
|
||||
# warning -O2 and higher are broken!
|
||||
#OPT_CFLAGS_YES = -O1
|
||||
#OPT_CXXFLAGS_YES = -O1
|
||||
5
configure/os/CONFIG.Common.linux-clang
Normal file
5
configure/os/CONFIG.Common.linux-clang
Normal file
@@ -0,0 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
GNU = NO
|
||||
CMPLR_CLASS = clang
|
||||
CC = clang
|
||||
CCC = clang++
|
||||
19
configure/os/CONFIG.Common.moxa42-armv6l
Normal file
19
configure/os/CONFIG.Common.moxa42-armv6l
Normal file
@@ -0,0 +1,19 @@
|
||||
# Moxa DA-66x with SDK 4.2 and ARM7 processor
|
||||
|
||||
# Include definitions common to all Linux ARM targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-arm
|
||||
|
||||
GNU_DIR=/afs/psi.ch/project/embeddedlinux/moxa/arm-linux-4.4.2-v4
|
||||
GNU_TARGET=arm
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(GNU_DIR)/arm-none-linux-gnueabi/lib
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(INSTALL_LIB)
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
|
||||
# suppress note "the mangling of 'va_list' has changed in GCC 4.4"
|
||||
ARCH_DEP_CXXFLAGS += -Wno-psabi
|
||||
|
||||
ARCH_DEP_CFLAGS += -funwind-tables
|
||||
|
||||
# remove warning in anyscalar.h
|
||||
ARCH_DEP_CXXFLAGS += -fno-strict-aliasing
|
||||
15
configure/os/CONFIG.Common.mvl40-xscale_be
Normal file
15
configure/os/CONFIG.Common.mvl40-xscale_be
Normal file
@@ -0,0 +1,15 @@
|
||||
# Moxa DA-66x with Montavista Linux 4.0
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_CURSES
|
||||
|
||||
ARCH_CLASS = xscale
|
||||
|
||||
GNU_DIR=/afs/psi.ch/project/embeddedlinux/moxa/xscale_be/armv5teb-montavista-linuxeabi
|
||||
|
||||
ARCH_DEP_CFLAGS += -funwind-tables
|
||||
|
||||
# Cannot build PVA because of missing boost support
|
||||
SKIP_BUILDS = pv% normativeTypes
|
||||
43
configure/os/CONFIG.Common.raspbian-arm
Normal file
43
configure/os/CONFIG.Common.raspbian-arm
Normal file
@@ -0,0 +1,43 @@
|
||||
# RaspberryPi with github.com/raspberrypi/tools toolchain
|
||||
# Tested on:
|
||||
# * Raspberry 3B+ Raspbian 9
|
||||
# * Raspberry 2 Raspbian 7
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
# Using readline:
|
||||
# Due to missing/messed up libs in the toolchain, readline needs copies of
|
||||
# libtinfo.so.5.9 and libreadline.so.6.2 from a Raspbian 7 rootfs
|
||||
# /lib/arm-linux-gnueabihf/ to the toolchain, e.g.
|
||||
# $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf/
|
||||
# and manually created links libtinfo.so.5 and libreadline.so.
|
||||
# For gcc-linaro-arm-linux-gnueabihf-raspbian, an existing incompatible
|
||||
# libtinfo.so.5 is in the way. Remove it.
|
||||
# (Built with glibc 2.16 like installed on Raspbian 9 but toolchain uses glibc 2.13.)
|
||||
# Also copy /usr/include/readline/ directory from some readline 6 installation
|
||||
# to $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/usr/include/
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = arm
|
||||
|
||||
SDK_DIR = /opt/raspberrypi/arm-bcm2708
|
||||
|
||||
# Available SDK_TARGETs:
|
||||
|
||||
# gcc 4.8.3 for 32 bit hosts with GLIBC 2.3 or higher
|
||||
SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian
|
||||
|
||||
# gcc 4.8.3 for 64 bit hosts with GLIBC 2.14 or higher
|
||||
# SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian-x64
|
||||
|
||||
# gcc 4.7.1 for 64 bit hosts with GLIBC 2.8 or higher
|
||||
# SDK_TARGET = arm-linux-gnueabihf
|
||||
|
||||
# gcc 4.7.1 for 32 bit hosts with GLIBC 2.4 or higher
|
||||
# SDK_TARGET = arm-bcm2708hardfp-linux-gnueabi
|
||||
# SDK_TARGET = arm-bcm2708-linux-gnueabi
|
||||
|
||||
GNU_DIR = $(SDK_DIR)/$(SDK_TARGET)
|
||||
GNU_TARGET = $(if $(filter arm-bcm2708%,SDK_TARGET),$(SDK_TARGET),arm-linux-gnueabihf)
|
||||
@@ -63,6 +63,7 @@ VXWORKS_MAJOR_VERSION = $(basename $(basename $(VXWORKS_VERSION)))
|
||||
|
||||
# These are needed for vxWorks 6.x; the GNU toolset version number
|
||||
# is in the path to the compiler tools:
|
||||
VX_GNU_VERSION_5 = 2.96
|
||||
VX_GNU_VERSION_6.0 = 3.3.2
|
||||
VX_GNU_VERSION_6.1 = 3.3.2
|
||||
VX_GNU_VERSION_6.2 = 3.3.2
|
||||
@@ -73,9 +74,17 @@ VX_GNU_VERSION_6.6 = 4.1.2
|
||||
VX_GNU_VERSION_6.7 = 4.1.2
|
||||
VX_GNU_VERSION_6.8 = 4.1.2
|
||||
VX_GNU_VERSION_6.9 = 4.3.3
|
||||
VX_GNU_VERSION = $(VX_GNU_VERSION_$(VXWORKS_VERSION))
|
||||
VX_GNU_VERSION_6 = $(VX_GNU_VERSION_$(VXWORKS_VERSION))
|
||||
VX_GNU_VERSION = $(VX_GNU_VERSION_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
VX_GNU_MAJOR_VERSION = $(basename $(basename $(VX_GNU_VERSION)))
|
||||
VX_GNU_MINOR_VERSION = $(basename $(patsubst $(VX_GNU_MAJOR_VERSION).%,%,$(VX_GNU_VERSION)))
|
||||
|
||||
# gcc version before 3.4 are "old" and need special treatment
|
||||
VX_OLD_GCC_2 = OLD
|
||||
VX_OLD_GCC_3.3 = OLD
|
||||
VX_OLD_GCC_3 = $(VX_OLD_GCC_3.$(VX_GNU_MINOR_VERSION))
|
||||
VX_OLD_GCC = $(VX_OLD_GCC_$(VX_GNU_MAJOR_VERSION))
|
||||
|
||||
#--------------------------------------------------
|
||||
# Fix old Linux WIND_HOST_TYPE
|
||||
@@ -85,14 +94,21 @@ endif
|
||||
|
||||
#--------------------------------------------------
|
||||
# vxWorks directory definitions
|
||||
VX_DIR = $(WIND_BASE)/vxworks-$(VXWORKS_VERSION)
|
||||
VX_DIR_5 = $(WIND_BASE)
|
||||
VX_DIR_6 = $(WIND_BASE)/vxworks-$(VXWORKS_VERSION)
|
||||
VX_DIR = $(VX_DIR_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
GNU_TARGET_INCLUDE_DIR = $(VX_DIR)/target/h $(VX_DIR)/target/h/wrn/coreip
|
||||
VX_INCLUDE_DIRS_5 = $(VX_DIR)/target/h
|
||||
VX_INCLUDE_DIRS_6 = $(VX_DIR)/target/h $(VX_DIR)/target/h/wrn/coreip
|
||||
GNU_TARGET_INCLUDE_DIR = $(VX_INCLUDE_DIRS_$(VXWORKS_MAJOR_VERSION))
|
||||
TARGET_CPPFLAGS = -isystem $(VX_DIR)/target/h
|
||||
|
||||
#--------------------------------------------------
|
||||
# vxWorks GNU directories
|
||||
|
||||
GNU_DIR = $(WIND_BASE)/gnu/$(VX_GNU_VERSION)-vxworks-$(VXWORKS_VERSION)/$(WIND_HOST_TYPE)
|
||||
GNU_DIR_5 = $(WIND_BASE)/host/$(WIND_HOST_TYPE)
|
||||
GNU_DIR_6 = $(WIND_BASE)/gnu/$(VX_GNU_VERSION)-vxworks-$(VXWORKS_VERSION)/$(WIND_HOST_TYPE)
|
||||
GNU_DIR = $(GNU_DIR_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
#--------------------------------------------------
|
||||
# This finds nm on any supported VxWorks version
|
||||
@@ -116,7 +132,7 @@ export TOOL_FAMILY = GNU
|
||||
#--------------------------------------------------
|
||||
# Operating system flags
|
||||
OP_SYS_CPPFLAGS += -DvxWorks=vxWorks
|
||||
OP_SYS_CFLAGS += -fno-builtin
|
||||
OP_SYS_CFLAGS += -fno-builtin -fno-strict-aliasing
|
||||
|
||||
# Fix for vxWorks headers that use macros defined in vxWorks.h but
|
||||
# which don't actually include vxWorks.h themselves, for example the
|
||||
@@ -133,12 +149,23 @@ OPT_CXXFLAGS_YES = -O2
|
||||
# code flags
|
||||
CODE_CFLAGS =
|
||||
#
|
||||
# For vxWorks versions before 6.3 we need this g++ compiler flag
|
||||
CODE_CXXFLAGS_6.0 = -fno-implicit-templates
|
||||
CODE_CXXFLAGS_6.1 = -fno-implicit-templates
|
||||
CODE_CXXFLAGS_6.2 = -fno-implicit-templates
|
||||
CODE_CXXFLAGS_6 = $(CODE_CXXFLAGS_$(VXWORKS_VERSION))
|
||||
CODE_CXXFLAGS = $(CODE_CXXFLAGS_$(VXWORKS_MAJOR_VERSION))
|
||||
# For gcc versions before 3.4 we need this g++ compiler flag
|
||||
# However WindRiver says gcc 3.3 does not need it any more
|
||||
# which would allow to build vxWorks 6 without this flag.
|
||||
# Maybe we can live without it at the penalty of larger code.
|
||||
# See vxWorks 5 docs/gnu2.96+ppc/gcc.html
|
||||
# chapter 4.5 "Where's the Template?"
|
||||
CODE_CXXFLAGS_OLD = -fno-implicit-templates
|
||||
CODE_CXXFLAGS = $(CODE_CXXFLAGS_$(VX_OLD_GCC))
|
||||
|
||||
#--------------------------------------------------
|
||||
# Modules we cannot build with old compiler
|
||||
|
||||
PV_MODULES = pv% normativeTypes
|
||||
SKIP_BUILDS_5 = $(PV_MODULES)
|
||||
SKIP_BUILDS_OLD = $(PV_MODULES)
|
||||
SKIP_BUILDS_6 = $(SKIP_BUILDS_$(VX_OLD_GCC))
|
||||
SKIP_BUILDS = $(SKIP_BUILDS_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
#--------------------------------------------------
|
||||
# no shared libs for vxWorks
|
||||
|
||||
20
configure/os/CONFIG.Common.yocto21-aarch64
Normal file
20
configure/os/CONFIG.Common.yocto21-aarch64
Normal file
@@ -0,0 +1,20 @@
|
||||
# XILINX Zynq with Yocto 2.1 / Petalinux toolchain
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = arm64
|
||||
|
||||
SDK = petalinux
|
||||
SDK_DIR = /opt/petalinux-gfa/2017.2
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH_64)-$(SDK)-$(GNU_HOST_OS)
|
||||
SDK_TARGET = aarch64-xilinx-linux
|
||||
GNU_TARGET = $(SDK_TARGET)
|
||||
SDKTARGETSYSROOT = $(SDK_DIR)/sysroots/$(SDK_TARGET)
|
||||
GNU_DIR = $(SDK_DIR)/sysroots/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_TARGET)
|
||||
|
||||
ARCH_DEP_CPPFLAGS = --sysroot=$(SDKTARGETSYSROOT)
|
||||
ARCH_DEP_LDFLAGS = --sysroot=$(SDKTARGETSYSROOT)
|
||||
3
configure/os/CONFIG.RHEL7-x86_64.Common
Normal file
3
configure/os/CONFIG.RHEL7-x86_64.Common
Normal file
@@ -0,0 +1,3 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
2
configure/os/CONFIG.RHEL7-x86_64.RHEL7-x86_64
Normal file
2
configure/os/CONFIG.RHEL7-x86_64.RHEL7-x86_64
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
16
configure/os/CONFIG.RHEL7-x86_64.SL6-x86
Normal file
16
configure/os/CONFIG.RHEL7-x86_64.SL6-x86
Normal file
@@ -0,0 +1,16 @@
|
||||
# "cross compile" for older Linux version
|
||||
# Use older compiler and older libraries
|
||||
# Used packages:
|
||||
# compat-gcc-44-c++-4.4
|
||||
# compat-gcc-44-4.4
|
||||
# compat-glibc-headers-2.12-4
|
||||
# It was neccessary to install 32 bit compatibility libraries manually
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
CC = $(GNU_BIN)/$(CMPLR_PREFIX)gcc44
|
||||
CCC = $(GNU_BIN)/$(CMPLR_PREFIX)g++44
|
||||
|
||||
TARGET_CPPFLAGS = -isystem /usr/lib/x86_64-redhat-linux6E/include
|
||||
TARGET_LDFLAGS = -L /usr/lib/x86_64-redhat-linux6E/lib
|
||||
LINK.cpp += --as-needed -lc -lm -lrt -lpthread -lreadline -ltinfo
|
||||
16
configure/os/CONFIG.RHEL7-x86_64.SL6-x86_64
Normal file
16
configure/os/CONFIG.RHEL7-x86_64.SL6-x86_64
Normal file
@@ -0,0 +1,16 @@
|
||||
# "cross compile" for older Linux version
|
||||
# Use older compiler and older libraries
|
||||
# Used packages:
|
||||
# compat-gcc-44-c++-4.4
|
||||
# compat-gcc-44-4.4
|
||||
# compat-glibc-headers-2.12-4
|
||||
# compat-glibc-2.12-4
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
CC = $(GNU_BIN)/$(CMPLR_PREFIX)gcc44
|
||||
CCC = $(GNU_BIN)/$(CMPLR_PREFIX)g++44
|
||||
|
||||
TARGET_CPPFLAGS = -isystem /usr/lib/x86_64-redhat-linux6E/include
|
||||
TARGET_LDFLAGS = -L /usr/lib/x86_64-redhat-linux6E/lib64
|
||||
LINK.cpp += --as-needed -lc -lm -lrt -lpthread -lreadline -ltinfo
|
||||
3
configure/os/CONFIG.SL5-x86.Common
Normal file
3
configure/os/CONFIG.SL5-x86.Common
Normal file
@@ -0,0 +1,3 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.Common
|
||||
2
configure/os/CONFIG.SL5-x86.SL5-x86
Normal file
2
configure/os/CONFIG.SL5-x86.SL5-x86
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
3
configure/os/CONFIG.SL5-x86_64.Common
Normal file
3
configure/os/CONFIG.SL5-x86_64.Common
Normal file
@@ -0,0 +1,3 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
2
configure/os/CONFIG.SL5-x86_64.SL5-x86_64
Normal file
2
configure/os/CONFIG.SL5-x86_64.SL5-x86_64
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
2
configure/os/CONFIG.SL6-x86.Common
Normal file
2
configure/os/CONFIG.SL6-x86.Common
Normal file
@@ -0,0 +1,2 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
2
configure/os/CONFIG.SL6-x86.SL6-x86
Normal file
2
configure/os/CONFIG.SL6-x86.SL6-x86
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
3
configure/os/CONFIG.SL6-x86_64.Common
Normal file
3
configure/os/CONFIG.SL6-x86_64.Common
Normal file
@@ -0,0 +1,3 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
2
configure/os/CONFIG.SL6-x86_64.SL6-x86
Normal file
2
configure/os/CONFIG.SL6-x86_64.SL6-x86
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
2
configure/os/CONFIG.SL6-x86_64.SL6-x86_64
Normal file
2
configure/os/CONFIG.SL6-x86_64.SL6-x86_64
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
@@ -65,7 +65,7 @@ GNU = NO
|
||||
#
|
||||
# Darwin shared libraries
|
||||
#
|
||||
SHRLIB_LDFLAGS = -dynamiclib -undefined dynamic_lookup \
|
||||
SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined dynamic_lookup \
|
||||
-install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \
|
||||
$(addprefix -compatibility_version , $(SHRLIB_VERSION)) \
|
||||
$(addprefix -current_version , $(SHRLIB_VERSION))
|
||||
|
||||
@@ -21,5 +21,6 @@ VXWORKS_VERSION = 6.9
|
||||
# WIND_BASE is where you installed the Wind River software.
|
||||
|
||||
#WIND_BASE = /usr/local/vw/tornado22-$(ARCH_CLASS)
|
||||
WIND_BASE = /usr/local/vw/vxWorks-$(VXWORKS_VERSION)
|
||||
#WIND_BASE = /usr/local/vw/vxWorks-$(VXWORKS_VERSION)
|
||||
#WIND_BASE = /ade/vxWorks/$(VXWORKS_VERSION)
|
||||
WIND_BASE = /afs/psi.ch/project/vxworks/VxWorks$(VXWORKS_VERSION)
|
||||
|
||||
13
configure/os/CONFIG_SITE.RHEL7-x86_64.Common
Normal file
13
configure/os/CONFIG_SITE.RHEL7-x86_64.Common
Normal file
@@ -0,0 +1,13 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
|
||||
# Build 32 bit version as a cross architecture
|
||||
#CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86
|
||||
|
||||
# Improved error checking with clang
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64-clang
|
||||
|
||||
# Build for old SL6 64 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL6-x86_64
|
||||
|
||||
# Build for old SL6 32 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL6-x86
|
||||
1
configure/os/CONFIG_SITE.SL5-x86.Common
Normal file
1
configure/os/CONFIG_SITE.SL5-x86.Common
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86.Common
|
||||
3
configure/os/CONFIG_SITE.SL5-x86_64.Common
Normal file
3
configure/os/CONFIG_SITE.SL5-x86_64.Common
Normal file
@@ -0,0 +1,3 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86.Common
|
||||
# Build 32 bit version as a cross architecture
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL5-x86
|
||||
1
configure/os/CONFIG_SITE.SL6-x86.Common
Normal file
1
configure/os/CONFIG_SITE.SL6-x86.Common
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86.Common
|
||||
7
configure/os/CONFIG_SITE.SL6-x86_64.Common
Normal file
7
configure/os/CONFIG_SITE.SL6-x86_64.Common
Normal file
@@ -0,0 +1,7 @@
|
||||
# Build 32 bit version as a cross architecture
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL6-x86
|
||||
|
||||
# Improved error checking with clang
|
||||
#CROSS_COMPILER_TARGET_ARCHS += SL6-x86_64-clang
|
||||
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
@@ -1,9 +1,43 @@
|
||||
# CONFIG_SITE.linux-x86.Common
|
||||
#
|
||||
# Site override definitions for linux-x86 host builds
|
||||
#-------------------------------------------------------
|
||||
INSTALL_LOCATION=/usr/local/epics/base-$(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)
|
||||
EPICS_SITE_VERSION:=$(shell date +%Y-%m-%d)
|
||||
|
||||
# JBA test override values
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040 solaris-sparc
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
|
||||
#CROSS_COMPILER_TARGET_ARCHS = RTEMS-mvme2100 RTEMS-pc386 # RTEMS-mvme5500 RTEMS-mvme167
|
||||
GNU_HOST_ARCH=i686
|
||||
GNU_HOST_OS=linux
|
||||
|
||||
# LD_LIBRARY_PATH may cause problems for eldk53-ppc4xxFP
|
||||
LD_LIBRARY_PATH=
|
||||
|
||||
# vxWorks 5.5 for MVxxxx boards
|
||||
CROSS_COMPILER_TARGET_ARCHS += T2-ppc604
|
||||
|
||||
# vxWorks 6.7 for MVxxxx boards
|
||||
CROSS_COMPILER_TARGET_ARCHS += V67-ppc604
|
||||
|
||||
# NI compact RIO
|
||||
CROSS_COMPILER_TARGET_ARCHS += V63-ppc603
|
||||
|
||||
# MOXA montavista linux (No PVA because of missing boost support)
|
||||
CROSS_COMPILER_TARGET_ARCHS += mvl40-xscale_be
|
||||
|
||||
# MOXA SDK 4.2
|
||||
CROSS_COMPILER_TARGET_ARCHS += moxa42-armv6l
|
||||
|
||||
# Virtex embedded PPC
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk51-ppc4xxSF
|
||||
|
||||
# IOxOS IFC1210
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk52-e500v2
|
||||
|
||||
# DeltaTau PowerPMAC
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk42-ppc4xxFP
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk53-ppc4xxFP
|
||||
|
||||
# Test other vxWorks versions
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V66-ppc603
|
||||
CROSS_COMPILER_TARGET_ARCHS += V66-ppc604
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V63-ppc604
|
||||
# (No PVA because of old compiler)
|
||||
CROSS_COMPILER_TARGET_ARCHS += V62-ppc604
|
||||
|
||||
# Raspberry Pi
|
||||
CROSS_COMPILER_TARGET_ARCHS += raspbian-arm
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# CONFIG_SITE.linux-x86_64.Common
|
||||
#
|
||||
# Site override definitions for linux-x86_64 host builds
|
||||
#-------------------------------------------------------
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86.Common
|
||||
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040 solaris-sparc
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
|
||||
#CROSS_COMPILER_TARGET_ARCHS = RTEMS-mvme2100
|
||||
GNU_HOST_ARCH_64=x86_64
|
||||
|
||||
# IOxOS IFC1211
|
||||
CROSS_COMPILER_TARGET_ARCHS += fslqoriq20-e6500_64
|
||||
|
||||
# Zynq
|
||||
CROSS_COMPILER_TARGET_ARCHS += yocto21-aarch64
|
||||
|
||||
@@ -20,8 +20,7 @@ release.</p>
|
||||
which should also be read to understand what has changed since an earlier
|
||||
release.</p>
|
||||
|
||||
|
||||
<h1 align="center">EPICS Release 7.0.2</h1>
|
||||
<h1 align="center">EPICS Release 7.0.2.2</h1>
|
||||
|
||||
<!-- Insert new items immediately below this template ...
|
||||
|
||||
@@ -31,6 +30,64 @@ release.</p>
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<h1 align="center">EPICS Release 7.0.2.1</h1>
|
||||
|
||||
<h3>Linking shared libraries on macOS</h3>
|
||||
|
||||
<p>The linker flag <tt>-flat_namespace</tt> has been restored for creating
|
||||
shared libraries, although not for loadable libraries (bundles). This was
|
||||
required for building using the latest versions of Apple XCode.</p>
|
||||
|
||||
<h3>Fix DB_LINK loop breaking</h3>
|
||||
|
||||
<p>A regression was introduced in 7.0.2 which caused record chains with loops to
|
||||
be incorrectly broken. Processing should be skipped when a DB_LINK with Process
|
||||
Passive (PP) closes a loop to a synchronous record.</p>
|
||||
|
||||
<p>Instead in 7.0.2 the targeted record would be processed if processing began
|
||||
with a remote action (or some other caller of <tt>dbPutField()</tt>). This would
|
||||
result in the loop running a second time. The loop would be broken on the second
|
||||
iteration.</p>
|
||||
|
||||
<p><a href="https://bugs.launchpad.net/epics-base/+bug/1809570">See lp:
|
||||
#1809570</a></p>
|
||||
|
||||
<h3>Old dbStaticLib APIs removed</h3>
|
||||
|
||||
<p>Support for some obsolete dbStaticLib Database Configuration Tool (DCT) APIs
|
||||
was removed some time ago, but vestiges of them still remained. The following
|
||||
routines and macros and have now finally been removed:</p>
|
||||
|
||||
<ul>
|
||||
<li>int dbGetFieldType(DBENTRY *pdbentry)</li>
|
||||
<li>int dbGetLinkType(DBENTRY *pdbentry)</li>
|
||||
<li>DCT_STRING</li>
|
||||
<li>DCT_INTEGER</li>
|
||||
<li>DCT_REAL</li>
|
||||
<li>DCT_MENU</li>
|
||||
<li>DCT_MENUFORM</li>
|
||||
<li>DCT_INLINK</li>
|
||||
<li>DCT_OUTLINK</li>
|
||||
<li>DCT_FWDLINK</li>
|
||||
<li>DCT_NOACCESS</li>
|
||||
<li>DCT_LINK_CONSTANT</li>
|
||||
<li>DCT_LINK_FORM</li>
|
||||
<li>DCT_LINK_PV</li>
|
||||
</ul>
|
||||
|
||||
<h3>Fix for <tt>dbhcr</tt> before <tt>iocInit</tt></h3>
|
||||
|
||||
<p>The <tt>dbhcr</tt> command used to work before <tt>iocInit</tt> as well as
|
||||
afterwards. It displays all records that have hardware addresses (VME_IO,
|
||||
CAMAC_IO, GPIB_IO, INST_IO etc.) but stopped working if run before iocInit due
|
||||
to the rewrite of the link address parser code in dbStaticLib. This release
|
||||
fixes that issue, although in some cases the output may be slightly different
|
||||
than it used to be.</p>
|
||||
|
||||
|
||||
<h1 align="center">EPICS Release 7.0.2</h1>
|
||||
|
||||
<h3>Launchpad Bugs</h3>
|
||||
|
||||
<p>The list of tracked bugs fixed in this release can be found on the
|
||||
@@ -920,6 +977,15 @@ of its CALLBACK objects.</p>
|
||||
|
||||
<!-- Insert inherited items immediately below here ... -->
|
||||
|
||||
<h3>Perl CA bindings fixed for macOS Mojave</h3>
|
||||
|
||||
<p>Apple removed some Perl header files from macOS Mojave that were available
|
||||
in their SDK, requiring a change to the include paths used when compiling the
|
||||
CA bindings. The new version should build on new and older macOS versions, and
|
||||
these changes may also help other targets that have an incomplete installation
|
||||
of Perl (the build will continue after printing a warning that the Perl CA
|
||||
bindings could not be built).</p>
|
||||
|
||||
<h3>Routine <tt>epicsTempName()</tt> removed from libCom</h3>
|
||||
|
||||
<p>This routine was a simple wrapper around the C89 function <tt>tmpnam()</tt>
|
||||
|
||||
@@ -37,6 +37,8 @@ that should be performed when creating production releases of EPICS Base.</p>
|
||||
|
||||
<h3>The Release Process</h3>
|
||||
|
||||
<h4>Full Process</h4>
|
||||
|
||||
<p>The version released on the Feature Freeze date is designated the first
|
||||
pre-release, <tt>-pre1</tt>. The first release candidate <tt>-rc1</tt> is the
|
||||
first version that has undergone testing by the developers and has shown no
|
||||
@@ -49,6 +51,12 @@ release candidate has been available for 2 weeks without any new problems being
|
||||
reported or major changes having to be committed, the final release can be
|
||||
made.</p>
|
||||
|
||||
<h4>Short Process for Patch Releases</h4>
|
||||
|
||||
<p>The Patch Release date and its scope are agreed upon about four weeks
|
||||
ahead of time. If no blocking issues are raised, the release is made by the
|
||||
release manager.</p>
|
||||
|
||||
<h3>Roles</h3>
|
||||
|
||||
<p>The following roles are used below:</p>
|
||||
@@ -322,6 +330,21 @@ made.</p>
|
||||
</tt></blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Release Manager</td>
|
||||
<td>Edit and commit changes to the EPICS Base version number file and
|
||||
the embedded module version files:
|
||||
<ul>
|
||||
<li>configure/CONFIG_BASE_VERSION </li>
|
||||
<li>modules/libcom/configure/CONFIG_LIBCOM_VERSION</li>
|
||||
<li>modules/ca/configure/CONFIG_CA_VERSION</li>
|
||||
<li>modules/database/configure/CONFIG_DATABASE_VERSION</li>
|
||||
</ul>
|
||||
Version numbers should be set to the next expected patch release,
|
||||
with a "-DEV" tag added (where applicable).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Release Manager</td>
|
||||
|
||||
@@ -36,6 +36,9 @@ pva2pva_DEPEND_DIRS = pvAccess
|
||||
SUBMODULES += example
|
||||
example_DEPEND_DIRS = pva2pva pvaClient
|
||||
|
||||
SUBMODULES += pcas
|
||||
pcas_DEPEND_DIRS = ca
|
||||
|
||||
# Allow sites to add extra submodules
|
||||
-include Makefile.local
|
||||
|
||||
@@ -55,4 +58,4 @@ $(RELEASE_LOCAL):
|
||||
$(ECHO) Creating $@, EPICS_BASE = $(INSTALL_LOCATION_ABS)
|
||||
@echo EPICS_BASE = $(INSTALL_LOCATION_ABS)> $@
|
||||
realclean:
|
||||
$(RM) $(RELEASE_LOCAL)
|
||||
$(RM) $(wildcard RELEASE.*.local)
|
||||
|
||||
@@ -72,6 +72,7 @@ LIBSRCS += comQueSend.cpp
|
||||
LIBSRCS += comBuf.cpp
|
||||
LIBSRCS += hostNameCache.cpp
|
||||
LIBSRCS += msgForMultiplyDefinedPV.cpp
|
||||
LIBSRCS_vxWorks += templateInstances.cpp
|
||||
|
||||
LIBRARY=ca
|
||||
|
||||
|
||||
66
modules/ca/src/client/templateInstances.cpp
Normal file
66
modules/ca/src/client/templateInstances.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*************************************************************************\
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
*
|
||||
* Copyright, 1986, The Regents of the University of California.
|
||||
*
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*/
|
||||
|
||||
#include "cac.h"
|
||||
#include "oldAccess.h"
|
||||
#include "repeaterClient.h"
|
||||
|
||||
template class chronIntIdResTable < nciu >;
|
||||
template class chronIntIdResTable < baseNMIU >;
|
||||
template class chronIntIdResTable < CASG >;
|
||||
template class resTable < nciu, chronIntId >;
|
||||
template class resTable < baseNMIU, chronIntId >;
|
||||
template class resTable < CASG, chronIntId >;
|
||||
template class resTable < bhe, inetAddrID >;
|
||||
template class resTable < tcpiiu, caServerID >;
|
||||
template class tsFreeList < bhe, 0x100 >;
|
||||
template class tsFreeList < tcpiiu, 32, epicsMutexNOOP >;
|
||||
template class tsFreeList < netReadNotifyIO, 1024, epicsMutexNOOP >;
|
||||
template class tsFreeList < netWriteNotifyIO, 1024, epicsMutexNOOP >;
|
||||
template class tsFreeList < netSubscription, 1024, epicsMutexNOOP >;
|
||||
template class tsFreeList < CASG, 128, epicsMutexNOOP >;
|
||||
template class tsFreeList < syncGroupReadNotify, 128, epicsMutexNOOP >;
|
||||
template class tsFreeList < syncGroupWriteNotify, 128, epicsMutexNOOP >;
|
||||
template class tsFreeList < comBuf, 0x20 >;
|
||||
template class tsFreeList < getCallback, 1024, epicsMutexNOOP >;
|
||||
template class tsFreeList < getCopy, 1024, epicsMutexNOOP >;
|
||||
template class tsFreeList < msgForMultiplyDefinedPV, 16 >;
|
||||
template class tsFreeList < nciu, 1024, epicsMutexNOOP>;
|
||||
template class tsFreeList < oldChannelNotify, 1024, epicsMutexNOOP >;
|
||||
template class tsFreeList < oldSubscription, 1024, epicsMutexNOOP >;
|
||||
template class tsFreeList < putCallback, 1024, epicsMutexNOOP >;
|
||||
template class tsFreeList < repeaterClient, 0x20 >;
|
||||
template class epicsSingleton < localHostName >;
|
||||
template unsigned comBuf :: push ( const double * pValue, unsigned nElem );
|
||||
template unsigned comBuf :: push ( const float * pValue, unsigned nElem );
|
||||
template unsigned comBuf :: push ( const int * pValue, unsigned nElem );
|
||||
template unsigned comBuf :: push ( const short * pValue, unsigned nElem );
|
||||
template comBuf :: popStatus comBuf :: pop ( unsigned int & returnVal );
|
||||
template comBuf :: popStatus comBuf :: pop ( unsigned short & returnVal );
|
||||
template comBuf :: popStatus comBuf :: pop ( unsigned char & returnVal );
|
||||
template void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO
|
||||
(epicsGuard < epicsMutex > &, syncGroupWriteNotify & );
|
||||
template void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO
|
||||
( epicsGuard < epicsMutex > &, syncGroupReadNotify & );
|
||||
@@ -8,6 +8,18 @@
|
||||
TOP = ../..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
ifdef T_A
|
||||
PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version)
|
||||
PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname)
|
||||
PERL_ARCHPATH := $(PERL_VERSION)/$(PERL_ARCHNAME)
|
||||
|
||||
PERL_ARCHLIB := $(shell $(PERL) ../perlConfig.pl archlib)
|
||||
PERL_h = $(PERL_ARCHLIB)/CORE/perl.h
|
||||
|
||||
EXTUTILS := $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils
|
||||
PERLBIN := $(shell $(PERL) ../perlConfig.pl bin)
|
||||
XSUBPP := $(firstword $(wildcard $(PERLBIN)/xsubpp $(EXTUTILS)/xsubpp))
|
||||
|
||||
# Special settings for Darwin:
|
||||
ifeq ($(OS_CLASS),Darwin)
|
||||
# Use hdepends command (not GNU compiler flags)
|
||||
@@ -18,22 +30,23 @@ ifeq ($(OS_CLASS),Darwin)
|
||||
# Perl loadable libraries on Darwin have funny names
|
||||
LOADABLE_SHRLIB_PREFIX =
|
||||
LOADABLE_SHRLIB_SUFFIX = .$(shell $(PERL) ../perlConfig.pl dlext)
|
||||
|
||||
ifeq ($(wildcard $(PERL_h)),)
|
||||
# Perl's headers moved in Mojave
|
||||
SDK_PATH := $(shell xcodebuild -version -sdk macosx Path)
|
||||
PERL_ARCHLIB := $(SDK_PATH)/$(PERL_ARCHLIB)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef T_A
|
||||
PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version)
|
||||
PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname)
|
||||
PERL_ARCHPATH := $(PERL_VERSION)/$(PERL_ARCHNAME)
|
||||
|
||||
EXTUTILS := $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils
|
||||
PERLBIN := $(shell $(PERL) ../perlConfig.pl bin)
|
||||
XSUBPP := $(firstword $(wildcard $(PERLBIN)/xsubpp $(EXTUTILS)/xsubpp))
|
||||
|
||||
ifeq ($(T_A),$(EPICS_HOST_ARCH)) # No cross-builds (wrong Perl!)
|
||||
ifeq ($(strip $(XSUBPP)),)
|
||||
$(warning Perl's xsubpp program was not found.)
|
||||
$(warning The Perl CA module will not be built.)
|
||||
else
|
||||
ifeq ($(T_A),$(EPICS_HOST_ARCH)) # No cross-builds (wrong Perl!)
|
||||
ifeq ($(wildcard $(PERL_h)),)
|
||||
$(warning Perl's C header files were not found.)
|
||||
$(warning The Perl CA module will not be built.)
|
||||
else
|
||||
ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),) # Doesn't build on WIN32
|
||||
LOADABLE_LIBRARY_HOST = Cap5
|
||||
|
||||
@@ -50,10 +63,11 @@ endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
Cap5_SRCS = Cap5.xs
|
||||
Cap5_LIBS = ca Com
|
||||
Cap5_INCLUDES = -I$(shell $(PERL) ../perlConfig.pl archlib)/CORE
|
||||
Cap5_INCLUDES = -I$(PERL_ARCHLIB)/CORE
|
||||
Cap5_CFLAGS = $(shell $(PERL) ../perlConfig.pl ccflags)
|
||||
|
||||
CLEANS += Cap5.c
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
EPICS_DATABASE_MAJOR_VERSION = 3
|
||||
EPICS_DATABASE_MINOR_VERSION = 17
|
||||
EPICS_DATABASE_MAINTENANCE_VERSION = 2
|
||||
EPICS_DATABASE_MAINTENANCE_VERSION = 3
|
||||
EPICS_DATABASE_DEVELOPMENT_FLAG = 0
|
||||
|
||||
@@ -42,6 +42,7 @@ INC += dbState.h
|
||||
INC += db_access_routines.h
|
||||
INC += db_convert.h
|
||||
INC += dbUnitTest.h
|
||||
INC += dbCaPvt.h
|
||||
|
||||
# Generate menuGlobal.dbd, not really by concatenation, see RULES
|
||||
DBDCAT += menuGlobal.dbd
|
||||
@@ -96,4 +97,5 @@ dbCore_SRCS += chfPlugin.c
|
||||
dbCore_SRCS += dbState.c
|
||||
dbCore_SRCS += dbUnitTest.c
|
||||
dbCore_SRCS += dbServer.c
|
||||
dbCore_SRCS_vxWorks += templateInstances.cpp
|
||||
|
||||
|
||||
@@ -601,6 +601,31 @@ all_done:
|
||||
return status;
|
||||
}
|
||||
|
||||
long dbEntryToAddr(const DBENTRY *pdbentry, DBADDR *paddr)
|
||||
{
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
short dbfType = pflddes->field_type;
|
||||
|
||||
paddr->precord = pdbentry->precnode->precord;
|
||||
paddr->pfield = pdbentry->pfield;
|
||||
paddr->pfldDes = pflddes;
|
||||
paddr->no_elements = 1;
|
||||
paddr->field_type = dbfType;
|
||||
paddr->field_size = pflddes->size;
|
||||
paddr->special = pflddes->special;
|
||||
paddr->dbr_field_type = mapDBFToDBR[dbfType];
|
||||
|
||||
if (paddr->special == SPC_DBADDR) {
|
||||
const rset *prset = dbGetRset(paddr);
|
||||
|
||||
/* Let record type modify paddr */
|
||||
if (prset && prset->cvt_dbaddr) {
|
||||
return prset->cvt_dbaddr(paddr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill out a database structure (*paddr) for
|
||||
* a record given by the name "pname."
|
||||
@@ -611,9 +636,7 @@ all_done:
|
||||
long dbNameToAddr(const char *pname, DBADDR *paddr)
|
||||
{
|
||||
DBENTRY dbEntry;
|
||||
dbFldDes *pflddes;
|
||||
long status = 0;
|
||||
short dbfType;
|
||||
|
||||
if (!pname || !*pname || !pdbbase)
|
||||
return S_db_notFound;
|
||||
@@ -628,46 +651,28 @@ long dbNameToAddr(const char *pname, DBADDR *paddr)
|
||||
status = dbGetAttributePart(&dbEntry, &pname);
|
||||
if (status) goto finish;
|
||||
|
||||
pflddes = dbEntry.pflddes;
|
||||
dbfType = pflddes->field_type;
|
||||
|
||||
paddr->precord = dbEntry.precnode->precord;
|
||||
paddr->pfield = dbEntry.pfield;
|
||||
paddr->pfldDes = pflddes;
|
||||
paddr->no_elements = 1;
|
||||
paddr->field_type = dbfType;
|
||||
paddr->field_size = pflddes->size;
|
||||
paddr->special = pflddes->special;
|
||||
paddr->dbr_field_type = mapDBFToDBR[dbfType];
|
||||
|
||||
if (paddr->special == SPC_DBADDR) {
|
||||
rset *prset = dbGetRset(paddr);
|
||||
|
||||
/* Let record type modify paddr */
|
||||
if (prset && prset->cvt_dbaddr) {
|
||||
status = prset->cvt_dbaddr(paddr);
|
||||
if (status)
|
||||
goto finish;
|
||||
dbfType = paddr->field_type;
|
||||
}
|
||||
}
|
||||
status = dbEntryToAddr(&dbEntry, paddr);
|
||||
if (status) goto finish;
|
||||
|
||||
/* Handle field modifiers */
|
||||
if (*pname++ == '$') {
|
||||
short dbfType = paddr->field_type;
|
||||
|
||||
/* Some field types can be accessed as char arrays */
|
||||
if (dbfType == DBF_STRING) {
|
||||
paddr->no_elements = paddr->field_size;
|
||||
paddr->field_type = DBF_CHAR;
|
||||
paddr->field_size = 1;
|
||||
paddr->dbr_field_type = DBR_CHAR;
|
||||
} else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
|
||||
}
|
||||
else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
|
||||
/* Clients see a char array, but keep original dbfType */
|
||||
paddr->no_elements = PVLINK_STRINGSZ;
|
||||
paddr->field_size = 1;
|
||||
paddr->dbr_field_type = DBR_CHAR;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
status = S_dbLib_fieldNotFound;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -679,7 +684,7 @@ finish:
|
||||
void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY *pdbentry)
|
||||
{
|
||||
struct dbCommon *prec = paddr->precord;
|
||||
dbCommonPvt *ppvt = CONTAINER(prec, dbCommonPvt, common);
|
||||
dbCommonPvt *ppvt = dbRec2Pvt(prec);
|
||||
|
||||
memset((char *)pdbentry,'\0',sizeof(DBENTRY));
|
||||
|
||||
@@ -693,7 +698,7 @@ void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY *pdbentry)
|
||||
|
||||
void dbInitEntryFromRecord(struct dbCommon *prec, DBENTRY *pdbentry)
|
||||
{
|
||||
dbCommonPvt *ppvt = CONTAINER(prec, dbCommonPvt, common);
|
||||
dbCommonPvt *ppvt = dbRec2Pvt(prec);
|
||||
|
||||
memset((char *)pdbentry,'\0',sizeof(DBENTRY));
|
||||
|
||||
|
||||
@@ -204,6 +204,8 @@ struct dbr_alDouble {DBRalDouble};
|
||||
#define S_db_notInit (M_dbAccess|67) /*Not initialized*/
|
||||
#define S_db_bufFull (M_dbAccess|68) /*Buffer full*/
|
||||
|
||||
struct dbEntry;
|
||||
|
||||
epicsShareFunc long dbPutSpecial(struct dbAddr *paddr,int pass);
|
||||
epicsShareFunc rset * dbGetRset(const struct dbAddr *paddr);
|
||||
epicsShareFunc long dbPutAttribute(
|
||||
@@ -213,8 +215,29 @@ epicsShareFunc int dbGetFieldIndex(const struct dbAddr *paddr);
|
||||
epicsShareFunc long dbScanPassive(
|
||||
struct dbCommon *pfrom,struct dbCommon *pto);
|
||||
epicsShareFunc long dbProcess(struct dbCommon *precord);
|
||||
epicsShareFunc long dbNameToAddr(
|
||||
const char *pname,struct dbAddr *);
|
||||
epicsShareFunc long dbNameToAddr(const char *pname, struct dbAddr *paddr);
|
||||
|
||||
/** Initialize DBADDR from a dbEntry
|
||||
* Also handles SPC_DBADDR processing. This is really an internal
|
||||
* routine for use by dbNameToAddr() and dbChannelCreate().
|
||||
*/
|
||||
epicsShareFunc long dbEntryToAddr(const struct dbEntry *pdbentry,
|
||||
struct dbAddr *paddr);
|
||||
|
||||
/** Initialize DBENTRY from a valid dbAddr*
|
||||
* Constant time equivalent of dbInitEntry() then dbFindRecord(),
|
||||
* and finally dbFollowAlias().
|
||||
*/
|
||||
epicsShareFunc void dbInitEntryFromAddr(struct dbAddr *paddr,
|
||||
struct dbEntry *pdbentry);
|
||||
|
||||
/** Initialize DBENTRY from a valid record (dbCommon*)
|
||||
* Constant time equivalent of dbInitEntry() then dbFindRecord(),
|
||||
* and finally dbFollowAlias() when no field is specified.
|
||||
*/
|
||||
epicsShareFunc void dbInitEntryFromRecord(struct dbCommon *prec,
|
||||
struct dbEntry *pdbentry);
|
||||
|
||||
epicsShareFunc devSup* dbDTYPtoDevSup(dbRecordType *prdes, int dtyp);
|
||||
epicsShareFunc devSup* dbDSETtoDevSup(dbRecordType *prdes, struct dset *pdset);
|
||||
epicsShareFunc long dbGetField(
|
||||
|
||||
@@ -473,9 +473,7 @@ dbChannel * dbChannelCreate(const char *name)
|
||||
dbChannel *chan = NULL;
|
||||
char *cname;
|
||||
dbAddr *paddr;
|
||||
dbFldDes *pflddes;
|
||||
long status;
|
||||
short dbfType;
|
||||
|
||||
if (!name || !*name || !pdbbase)
|
||||
return NULL;
|
||||
@@ -498,32 +496,14 @@ dbChannel * dbChannelCreate(const char *name)
|
||||
ellInit(&chan->post_chain);
|
||||
|
||||
paddr = &chan->addr;
|
||||
pflddes = dbEntry.pflddes;
|
||||
dbfType = pflddes->field_type;
|
||||
|
||||
paddr->precord = dbEntry.precnode->precord;
|
||||
paddr->pfield = dbEntry.pfield;
|
||||
paddr->pfldDes = pflddes;
|
||||
paddr->no_elements = 1;
|
||||
paddr->field_type = dbfType;
|
||||
paddr->field_size = pflddes->size;
|
||||
paddr->special = pflddes->special;
|
||||
paddr->dbr_field_type = mapDBFToDBR[dbfType];
|
||||
|
||||
if (paddr->special == SPC_DBADDR) {
|
||||
rset *prset = dbGetRset(paddr);
|
||||
|
||||
/* Let record type modify paddr */
|
||||
if (prset && prset->cvt_dbaddr) {
|
||||
status = prset->cvt_dbaddr(paddr);
|
||||
if (status)
|
||||
goto finish;
|
||||
dbfType = paddr->field_type;
|
||||
}
|
||||
}
|
||||
status = dbEntryToAddr(&dbEntry, paddr);
|
||||
if (status)
|
||||
goto finish;
|
||||
|
||||
/* Handle field modifiers */
|
||||
if (*pname) {
|
||||
short dbfType = paddr->field_type;
|
||||
|
||||
if (*pname == '$') {
|
||||
/* Some field types can be accessed as char arrays */
|
||||
if (dbfType == DBF_STRING) {
|
||||
@@ -531,12 +511,14 @@ dbChannel * dbChannelCreate(const char *name)
|
||||
paddr->field_type = DBF_CHAR;
|
||||
paddr->field_size = 1;
|
||||
paddr->dbr_field_type = DBR_CHAR;
|
||||
} else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
|
||||
}
|
||||
else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
|
||||
/* Clients see a char array, but keep original dbfType */
|
||||
paddr->no_elements = PVLINK_STRINGSZ;
|
||||
paddr->field_size = 1;
|
||||
paddr->dbr_field_type = DBR_CHAR;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
status = S_dbLib_fieldNotFound;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,27 @@
|
||||
#ifndef DBCOMMONPVT_H
|
||||
#define DBCOMMONPVT_H
|
||||
|
||||
#include <compilerDependencies.h>
|
||||
#include <dbDefs.h>
|
||||
#include "dbCommon.h"
|
||||
|
||||
struct epicsThreadOSD;
|
||||
|
||||
/** Base internal additional information for every record
|
||||
*/
|
||||
typedef struct dbCommonPvt {
|
||||
struct dbRecordNode *recnode;
|
||||
|
||||
/* Thread which is currently processing this record */
|
||||
struct epicsThreadOSD* procThread;
|
||||
|
||||
struct dbCommon common;
|
||||
} dbCommonPvt;
|
||||
|
||||
static EPICS_ALWAYS_INLINE
|
||||
dbCommonPvt* dbRec2Pvt(struct dbCommon *prec)
|
||||
{
|
||||
return CONTAINER(prec, dbCommonPvt, common);
|
||||
}
|
||||
|
||||
#endif // DBCOMMONPVT_H
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
#include "dbAddr.h"
|
||||
#include "dbBase.h"
|
||||
#include "dbBkpt.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbCommonPvt.h"
|
||||
#include "dbConvertFast.h"
|
||||
#include "dbConvert.h"
|
||||
#include "db_field_log.h"
|
||||
@@ -386,8 +386,11 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
|
||||
{
|
||||
char context[40] = "";
|
||||
int trace = dbAccessDebugPUTF && *dbLockSetAddrTrace(psrc);
|
||||
int claim_src = dbRec2Pvt(psrc)->procThread==NULL;
|
||||
int claim_dst = psrc!=pdst && dbRec2Pvt(pdst)->procThread==NULL;
|
||||
long status;
|
||||
epicsUInt8 pact = psrc->pact;
|
||||
epicsThreadId self = epicsThreadGetIdSelf();
|
||||
|
||||
psrc->pact = TRUE;
|
||||
|
||||
@@ -406,14 +409,11 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
|
||||
printf("%s: '%s' -> '%s' with PUTF=%u\n",
|
||||
context, psrc->name, pdst->name, psrc->putf);
|
||||
|
||||
if (pdst->putf)
|
||||
errlogPrintf("Warning: '%s.PUTF' found true with PACT false\n",
|
||||
pdst->name);
|
||||
|
||||
pdst->putf = psrc->putf;
|
||||
}
|
||||
else if (psrc->putf) {
|
||||
/* The dst record is busy (awaiting async reprocessing) and
|
||||
else if (psrc->putf && claim_dst) {
|
||||
/* The dst record is busy (awaiting async reprocessing),
|
||||
* not being processed recursively by us, and
|
||||
* we were originally triggered by a call to dbPutField(),
|
||||
* so we mark the dst record for reprocessing once the async
|
||||
* completion is over.
|
||||
@@ -426,17 +426,43 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
|
||||
pdst->rpro = TRUE;
|
||||
}
|
||||
else {
|
||||
/* The dst record is busy, but we weren't triggered by a call
|
||||
* to dbPutField(). Do nothing.
|
||||
/* The dst record is busy, but either is being processed recursively,
|
||||
* or wasn't triggered by a call to dbPutField(). Do nothing.
|
||||
*/
|
||||
if (trace)
|
||||
printf("%s: '%s' -> Active '%s', done\n",
|
||||
context, psrc->name, pdst->name);
|
||||
}
|
||||
|
||||
if(claim_src) {
|
||||
dbRec2Pvt(psrc)->procThread = self;
|
||||
}
|
||||
if(claim_dst) {
|
||||
dbRec2Pvt(pdst)->procThread = self;
|
||||
}
|
||||
|
||||
if(dbRec2Pvt(psrc)->procThread!=self ||
|
||||
dbRec2Pvt(pdst)->procThread!=self) {
|
||||
errlogPrintf("Logic Error: processTarget 1 from %p, %s(%p) -> %s(%p)\n",
|
||||
self, psrc->name, dbRec2Pvt(psrc), pdst->name, dbRec2Pvt(pdst));
|
||||
}
|
||||
|
||||
status = dbProcess(pdst);
|
||||
|
||||
psrc->pact = pact;
|
||||
|
||||
if(dbRec2Pvt(psrc)->procThread!=self ||
|
||||
dbRec2Pvt(pdst)->procThread!=self) {
|
||||
errlogPrintf("Logic Error: processTarget 2 from %p, %s(%p) -> %s(%p)\n",
|
||||
self, psrc->name, dbRec2Pvt(psrc), pdst->name, dbRec2Pvt(pdst));
|
||||
}
|
||||
|
||||
if(claim_src) {
|
||||
dbRec2Pvt(psrc)->procThread = NULL;
|
||||
}
|
||||
if(claim_dst) {
|
||||
dbRec2Pvt(pdst)->procThread = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -86,12 +86,6 @@ typedef struct notifyGlobal {
|
||||
|
||||
static notifyGlobal *pnotifyGlobal = 0;
|
||||
|
||||
/*Local routines*/
|
||||
static void notifyInit(processNotify *ppn);
|
||||
static void notifyCleanup(processNotify *ppn);
|
||||
static void restartCheck(processNotifyRecord *ppnr);
|
||||
static void callDone(dbCommon *precord,processNotify *ppn);
|
||||
static void processNotifyCommon(processNotify *ppn,dbCommon *precord);
|
||||
static void notifyCallback(CALLBACK *pcallback);
|
||||
|
||||
#define ellSafeAdd(list,listnode) \
|
||||
@@ -210,7 +204,7 @@ static void callDone(dbCommon *precord, processNotify *ppn)
|
||||
return;
|
||||
}
|
||||
|
||||
static void processNotifyCommon(processNotify *ppn,dbCommon *precord)
|
||||
static void processNotifyCommon(processNotify *ppn, dbCommon *precord, int first)
|
||||
{
|
||||
notifyPvt *pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
|
||||
int didPut = 0;
|
||||
@@ -256,6 +250,9 @@ static void processNotifyCommon(processNotify *ppn,dbCommon *precord)
|
||||
doProcess = 1;
|
||||
|
||||
if (doProcess) {
|
||||
if (first) {
|
||||
precord->putf = TRUE;
|
||||
}
|
||||
ppn->wasProcessed = 1;
|
||||
precord->ppn = ppn;
|
||||
ellSafeAdd(&pnotifyPvt->waitList, &precord->ppnr->waitNode);
|
||||
@@ -298,7 +295,7 @@ static void notifyCallback(CALLBACK *pcallback)
|
||||
return;
|
||||
}
|
||||
if(pnotifyPvt->state == notifyRestartCallbackRequested) {
|
||||
processNotifyCommon(ppn, precord);
|
||||
processNotifyCommon(ppn, precord, 0);
|
||||
return;
|
||||
}
|
||||
/* All done. Clean up and call userCallback */
|
||||
@@ -382,7 +379,7 @@ void dbProcessNotify(processNotify *ppn)
|
||||
precord->ppnr->precord = precord;
|
||||
ellInit(&precord->ppnr->restartList);
|
||||
}
|
||||
processNotifyCommon(ppn, precord);
|
||||
processNotifyCommon(ppn, precord, 1);
|
||||
}
|
||||
|
||||
void dbNotifyCancel(processNotify *ppn)
|
||||
@@ -582,7 +579,7 @@ static void tpnThread(void *pvt)
|
||||
processNotify *ppn = (processNotify *) ptpnInfo->ppn;
|
||||
|
||||
dbProcessNotify(ppn);
|
||||
epicsEventWait(ptpnInfo->callbackDone);
|
||||
epicsEventMustWait(ptpnInfo->callbackDone);
|
||||
dbNotifyCancel(ppn);
|
||||
epicsEventDestroy(ptpnInfo->callbackDone);
|
||||
dbChannelDelete(ppn->chan);
|
||||
|
||||
9
modules/database/src/ioc/db/templateInstances.cpp
Normal file
9
modules/database/src/ioc/db/templateInstances.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "dbCAC.h"
|
||||
#include "dbChannelIO.h"
|
||||
#include "dbPutNotifyBlocker.h"
|
||||
|
||||
template class tsFreeList < dbSubscriptionIO, 256, epicsMutexNOOP >;
|
||||
template class tsFreeList < dbChannelIO, 256, epicsMutexNOOP >;
|
||||
template class tsFreeList < dbPutNotifyBlocker, 64, epicsMutexNOOP >;
|
||||
template class resTable < dbBaseIO, chronIntId >;
|
||||
template class chronIntIdResTable < dbBaseIO >;
|
||||
@@ -434,6 +434,10 @@ static void dbMenuHead(char *name)
|
||||
dbMenu *pdbMenu;
|
||||
GPHENTRY *pgphentry;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbMenuHead: Menu name can't be empty");
|
||||
return;
|
||||
}
|
||||
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->menuList);
|
||||
if(pgphentry) {
|
||||
duplicate = TRUE;
|
||||
@@ -447,6 +451,10 @@ static void dbMenuHead(char *name)
|
||||
|
||||
static void dbMenuChoice(char *name,char *value)
|
||||
{
|
||||
if (!*name) {
|
||||
yyerror("dbMenuChoice: Menu choice name can't be empty");
|
||||
return;
|
||||
}
|
||||
if(duplicate) return;
|
||||
allocTemp(epicsStrDup(name));
|
||||
allocTemp(epicsStrDup(value));
|
||||
@@ -494,6 +502,10 @@ static void dbRecordtypeHead(char *name)
|
||||
dbRecordType *pdbRecordType;
|
||||
GPHENTRY *pgphentry;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbRecordtypeHead: Recordtype name can't be empty");
|
||||
return;
|
||||
}
|
||||
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->recordTypeList);
|
||||
if(pgphentry) {
|
||||
duplicate = TRUE;
|
||||
@@ -512,6 +524,10 @@ static void dbRecordtypeFieldHead(char *name,char *type)
|
||||
dbFldDes *pdbFldDes;
|
||||
int i;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbRecordtypeFieldHead: Field name can't be empty");
|
||||
return;
|
||||
}
|
||||
if(duplicate) return;
|
||||
pdbFldDes = dbCalloc(1,sizeof(dbFldDes));
|
||||
allocTemp(pdbFldDes);
|
||||
@@ -580,7 +596,7 @@ static void dbRecordtypeFieldItem(char *name,char *value)
|
||||
if(sscanf(value,"%hd",&pdbFldDes->special)==1) {
|
||||
return;
|
||||
}
|
||||
yyerror("Illegal special value.");
|
||||
yyerror("Illegal 'special' value.");
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"pp")==0) {
|
||||
@@ -589,13 +605,13 @@ static void dbRecordtypeFieldItem(char *name,char *value)
|
||||
} else if((strcmp(value,"NO")==0) || (strcmp(value,"FALSE")==0)) {
|
||||
pdbFldDes->process_passive = FALSE;
|
||||
} else {
|
||||
yyerror("Illegal value. Must be NO or YES");
|
||||
yyerror("Illegal 'pp' value, must be YES/NO/TRUE/FALSE");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"interest")==0) {
|
||||
if(sscanf(value,"%hd",&pdbFldDes->interest)!=1)
|
||||
yyerror("Illegal value. Must be integer");
|
||||
yyerror("Illegal 'interest' value, must be integer");
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"base")==0) {
|
||||
@@ -604,13 +620,13 @@ static void dbRecordtypeFieldItem(char *name,char *value)
|
||||
} else if(strcmp(value,"HEX")==0) {
|
||||
pdbFldDes->base = CT_HEX;
|
||||
} else {
|
||||
yyerror("Illegal value. Must be CT_DECIMAL or CT_HEX");
|
||||
yyerror("Illegal 'base' value, must be DECIMAL/HEX");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"size")==0) {
|
||||
if(sscanf(value,"%hd",&pdbFldDes->size)!=1)
|
||||
yyerror("Illegal value. Must be integer");
|
||||
yyerror("Illegal 'size' value, must be integer");
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"extra")==0) {
|
||||
@@ -802,6 +818,10 @@ static void dbDriver(char *name)
|
||||
drvSup *pdrvSup;
|
||||
GPHENTRY *pgphentry;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbDriver: Driver name can't be empty");
|
||||
return;
|
||||
}
|
||||
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->drvList);
|
||||
if(pgphentry) {
|
||||
return;
|
||||
@@ -841,6 +861,10 @@ static void dbRegistrar(char *name)
|
||||
dbText *ptext;
|
||||
GPHENTRY *pgphentry;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbRegistrar: Registrar name can't be empty");
|
||||
return;
|
||||
}
|
||||
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->registrarList);
|
||||
if(pgphentry) {
|
||||
return;
|
||||
@@ -860,6 +884,10 @@ static void dbFunction(char *name)
|
||||
dbText *ptext;
|
||||
GPHENTRY *pgphentry;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbFunction: Function name can't be empty");
|
||||
return;
|
||||
}
|
||||
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->functionList);
|
||||
if(pgphentry) {
|
||||
return;
|
||||
@@ -879,6 +907,10 @@ static void dbVariable(char *name, char *type)
|
||||
dbVariableDef *pvar;
|
||||
GPHENTRY *pgphentry;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbVariable: Variable name can't be empty");
|
||||
return;
|
||||
}
|
||||
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->variableList);
|
||||
if(pgphentry) {
|
||||
return;
|
||||
@@ -899,6 +931,10 @@ static void dbBreakHead(char *name)
|
||||
brkTable *pbrkTable;
|
||||
GPHENTRY *pgphentry;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbBreakHead: Breaktable name can't be empty");
|
||||
return;
|
||||
}
|
||||
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->bptList);
|
||||
if(pgphentry) {
|
||||
duplicate = TRUE;
|
||||
@@ -1001,6 +1037,10 @@ static void dbRecordHead(char *recordType, char *name, int visible)
|
||||
DBENTRY *pdbentry;
|
||||
long status;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbRecordHead: Record name can't be empty");
|
||||
return;
|
||||
}
|
||||
badch = strpbrk(name, " \"'.$");
|
||||
if (badch) {
|
||||
epicsPrintf("Bad character '%c' in record name \"%s\"\n",
|
||||
@@ -1108,6 +1148,10 @@ static void dbRecordInfo(char *name, char *value)
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbRecordInfo: Info item name can't be empty");
|
||||
return;
|
||||
}
|
||||
if (duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
@@ -1132,6 +1176,10 @@ static void dbRecordAlias(char *name)
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
|
||||
if (!*name) {
|
||||
yyerrorAbort("dbRecordAlias: Alias name can't be empty");
|
||||
return;
|
||||
}
|
||||
if (duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
@@ -1149,6 +1197,10 @@ static void dbAlias(char *name, char *alias)
|
||||
DBENTRY dbEntry;
|
||||
DBENTRY *pdbEntry = &dbEntry;
|
||||
|
||||
if (!*alias) {
|
||||
yyerrorAbort("dbAlias: Alias name can't be empty");
|
||||
return;
|
||||
}
|
||||
dbInitEntry(pdbbase, pdbEntry);
|
||||
if (dbFindRecord(pdbEntry, name)) {
|
||||
epicsPrintf("Alias \"%s\" refers to unknown record \"%s\"\n",
|
||||
|
||||
@@ -79,16 +79,6 @@ epicsShareDef maplinkType pamaplinkType[LINK_NTYPES] = {
|
||||
{"VXI_IO",VXI_IO}
|
||||
};
|
||||
|
||||
static int mapDBFtoDCT[DBF_NOACCESS+1] = {
|
||||
DCT_STRING,
|
||||
DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,
|
||||
DCT_REAL,DCT_REAL,
|
||||
DCT_INTEGER,
|
||||
DCT_MENU,
|
||||
DCT_MENUFORM,
|
||||
DCT_INLINK,DCT_OUTLINK,DCT_FWDLINK,
|
||||
DCT_NOACCESS};
|
||||
|
||||
/*forward references for private routines*/
|
||||
static void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(2,3);
|
||||
@@ -166,38 +156,6 @@ void dbFreePath(DBBASE *pdbbase)
|
||||
}
|
||||
|
||||
|
||||
static void entryErrMessage(DBENTRY *pdbentry,long status,char *mess)
|
||||
{
|
||||
char message[200];
|
||||
char *pmessage=&message[0];
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
char *pname = NULL;
|
||||
|
||||
*pmessage=0;
|
||||
if(pdbentry->precordType) pname = pdbentry->precordType->name;
|
||||
if(pname) {
|
||||
strcat(pmessage,"RecordType:");
|
||||
strcat(pmessage,pname);
|
||||
}
|
||||
if(precnode){
|
||||
if (dbIsAlias(pdbentry))
|
||||
strcat(pmessage," Record Alias:");
|
||||
else
|
||||
strcat(pmessage," Record:");
|
||||
strcat(pmessage,(char *)precnode->precord);
|
||||
}
|
||||
if(pflddes) {
|
||||
char *pstr=pflddes->name;
|
||||
|
||||
strcat(pmessage," Field:");
|
||||
strcat(pmessage,pstr);
|
||||
}
|
||||
strcat(pmessage,"\n");
|
||||
strcat(pmessage,mess);
|
||||
errMessage(status,pmessage);
|
||||
}
|
||||
|
||||
static void zeroDbentry(DBENTRY *pdbentry)
|
||||
{
|
||||
/*NOTE that pdbbase and message MUST NOT be set to NULL*/
|
||||
@@ -1398,19 +1356,6 @@ long dbNextField(DBENTRY *pdbentry,int dctonly)
|
||||
}
|
||||
}
|
||||
|
||||
int dbGetFieldType(DBENTRY *pdbentry)
|
||||
{
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
long status;
|
||||
|
||||
if(!pflddes){
|
||||
status = S_dbLib_flddesNotFound;
|
||||
entryErrMessage(pdbentry,status,"dbGetFieldType");
|
||||
return(status);
|
||||
}
|
||||
return(mapDBFtoDCT[pflddes->field_type]);
|
||||
}
|
||||
|
||||
int dbGetNFields(DBENTRY *pdbentry,int dctonly)
|
||||
{
|
||||
dbRecordType *precordType = pdbentry->precordType;
|
||||
@@ -3216,48 +3161,21 @@ int dbGetNLinks(DBENTRY *pdbentry)
|
||||
return((int)precordType->no_links);
|
||||
}
|
||||
|
||||
long dbGetLinkField(DBENTRY *pdbentry,int index)
|
||||
long dbGetLinkField(DBENTRY *pdbentry, int index)
|
||||
{
|
||||
dbRecordType *precordType = pdbentry->precordType;
|
||||
dbFldDes *pflddes;
|
||||
dbRecordType *precordType = pdbentry->precordType;
|
||||
dbFldDes *pflddes;
|
||||
|
||||
if (!precordType)
|
||||
return S_dbLib_recordTypeNotFound;
|
||||
|
||||
if (index < 0 || index >= precordType->no_links)
|
||||
return S_dbLib_badLink;
|
||||
|
||||
if(!precordType) return(S_dbLib_recordTypeNotFound);
|
||||
if(index<0 || index>=precordType->no_links) return(S_dbLib_badLink);
|
||||
pdbentry->indfield = precordType->link_ind[index];
|
||||
pdbentry->pflddes = pflddes = precordType->papFldDes[pdbentry->indfield];
|
||||
dbGetFieldAddress(pdbentry);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int dbGetLinkType(DBENTRY *pdbentry)
|
||||
{
|
||||
dbFldDes *pflddes;
|
||||
DBLINK *plink;
|
||||
int field_type;
|
||||
|
||||
dbGetFieldAddress(pdbentry);
|
||||
pflddes = pdbentry->pflddes;
|
||||
if(!pflddes) return(-1);
|
||||
plink = (DBLINK *)pdbentry->pfield;
|
||||
if(!plink) return(-1);
|
||||
field_type = pflddes->field_type;
|
||||
switch (field_type) {
|
||||
case DBF_INLINK:
|
||||
case DBF_OUTLINK:
|
||||
case DBF_FWDLINK:
|
||||
switch(plink->type) {
|
||||
case CONSTANT:
|
||||
return(DCT_LINK_CONSTANT);
|
||||
case PV_LINK:
|
||||
case PN_LINK:
|
||||
case DB_LINK:
|
||||
case CA_LINK:
|
||||
return(DCT_LINK_PV);
|
||||
default:
|
||||
return(DCT_LINK_FORM);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dbDumpPath(DBBASE *pdbbase)
|
||||
@@ -3556,68 +3474,110 @@ void dbDumpBreaktable(DBBASE *pdbbase,const char *name)
|
||||
return;
|
||||
}
|
||||
|
||||
static char *bus[VXI_IO+1] = {"","","VME","CAMAC","AB",
|
||||
"GPIB","BITBUS","","","","","","INST","BBGPIB","VXI"};
|
||||
void dbReportDeviceConfig(dbBase *pdbbase,FILE *report)
|
||||
static char *bus[LINK_NTYPES] = {
|
||||
"", /* CONSTANT */
|
||||
NULL, /* PV_LINK */
|
||||
"VME",
|
||||
"CAMAC",
|
||||
"AB",
|
||||
"GPIB",
|
||||
"BITBUS",
|
||||
NULL, /* MACRO_LINK */
|
||||
NULL, /* JSON_LINK */
|
||||
NULL, /* PN_LINK */
|
||||
NULL, /* DB_LINK */
|
||||
NULL, /* CA_LINK */
|
||||
"INST",
|
||||
"BBGPIB",
|
||||
"VXI"
|
||||
};
|
||||
void dbReportDeviceConfig(dbBase *pdbbase, FILE *report)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
char linkValue[messagesize];
|
||||
char dtypValue[50];
|
||||
char cvtValue[40];
|
||||
int ilink,nlinks;
|
||||
struct link *plink;
|
||||
int linkType;
|
||||
FILE *stream = (report==0) ? stdout : report;
|
||||
DBENTRY dbentry, *pdbentry = &dbentry;
|
||||
long status;
|
||||
FILE *stream = report ? report : stdout;
|
||||
|
||||
if(!pdbbase) {
|
||||
fprintf(stderr,"pdbbase not specified\n");
|
||||
return;
|
||||
if (!pdbbase) {
|
||||
fprintf(stderr, "dbReportDeviceConfig: pdbbase not specified\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dbInitEntry(pdbbase,pdbentry);
|
||||
status = dbFirstRecordType(pdbentry);
|
||||
while(!status) {
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while(!status) {
|
||||
nlinks = dbGetNLinks(pdbentry);
|
||||
for(ilink=0; ilink<nlinks; ilink++) {
|
||||
status = dbGetLinkField(pdbentry,ilink);
|
||||
if(status || dbGetLinkType(pdbentry)!=DCT_LINK_FORM) continue;
|
||||
plink = pdbentry->pfield;
|
||||
linkType = plink->type;
|
||||
if(bus[linkType][0]==0) continue;
|
||||
strncpy(linkValue, dbGetString(pdbentry), NELEMENTS(linkValue)-1);
|
||||
linkValue[NELEMENTS(linkValue)-1] = '\0';
|
||||
status = dbFindField(pdbentry,"DTYP");
|
||||
if(status) break;
|
||||
strcpy(dtypValue,dbGetString(pdbentry));
|
||||
status = dbFindField(pdbentry,"LINR");
|
||||
if(status) {
|
||||
cvtValue[0] = 0;
|
||||
} else {
|
||||
if(strcmp(dbGetString(pdbentry),"LINEAR")!=0) {
|
||||
cvtValue[0] = 0;
|
||||
} else {
|
||||
strcpy(cvtValue,"cvt(");
|
||||
status = dbFindField(pdbentry,"EGUL");
|
||||
if(!status) strcat(cvtValue,dbGetString(pdbentry));
|
||||
status = dbFindField(pdbentry,"EGUF");
|
||||
if(!status) {
|
||||
strcat(cvtValue,",");
|
||||
strcat(cvtValue,dbGetString(pdbentry));
|
||||
}
|
||||
strcat(cvtValue,")");
|
||||
}
|
||||
}
|
||||
fprintf(stream,"%-8s %-20s %-20s %-20s %-s\n",
|
||||
bus[linkType],linkValue,dtypValue,
|
||||
dbGetRecordName(pdbentry),cvtValue);
|
||||
break;
|
||||
}
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
status = dbNextRecordType(pdbentry);
|
||||
while (!status) {
|
||||
const int nlinks = dbGetNLinks(pdbentry);
|
||||
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while (!status) {
|
||||
int ilink;
|
||||
|
||||
for (ilink=0; ilink<nlinks; ilink++) {
|
||||
char linkValue[messagesize];
|
||||
char dtypValue[50];
|
||||
char cvtValue[40];
|
||||
struct link *plink;
|
||||
int linkType;
|
||||
|
||||
status = dbGetLinkField(pdbentry, ilink);
|
||||
if (status)
|
||||
continue;
|
||||
|
||||
plink = pdbentry->pfield;
|
||||
linkType = plink->type;
|
||||
if (plink->text) { /* Not yet parsed */
|
||||
dbLinkInfo linfo;
|
||||
|
||||
if (dbParseLink(plink->text, pdbentry->pflddes->field_type, &linfo))
|
||||
continue;
|
||||
|
||||
linkType = linfo.ltype;
|
||||
if (linkType && bus[linkType])
|
||||
strncpy(linkValue, plink->text, messagesize-1);
|
||||
|
||||
dbFreeLinkInfo(&linfo);
|
||||
}
|
||||
else {
|
||||
strncpy(linkValue, dbGetString(pdbentry), messagesize-1);
|
||||
}
|
||||
|
||||
if (!linkType || !bus[linkType])
|
||||
continue;
|
||||
linkValue[messagesize-1] = '\0';
|
||||
|
||||
status = dbFindField(pdbentry, "DTYP");
|
||||
if (status)
|
||||
break; /* Next record type */
|
||||
|
||||
strcpy(dtypValue, dbGetString(pdbentry));
|
||||
status = dbFindField(pdbentry, "LINR");
|
||||
if (status) {
|
||||
cvtValue[0] = 0;
|
||||
}
|
||||
else {
|
||||
if (strcmp(dbGetString(pdbentry), "LINEAR") != 0) {
|
||||
cvtValue[0] = 0;
|
||||
}
|
||||
else {
|
||||
strcpy(cvtValue,"cvt(");
|
||||
status = dbFindField(pdbentry, "EGUL");
|
||||
if (!status)
|
||||
strcat(cvtValue, dbGetString(pdbentry));
|
||||
status = dbFindField(pdbentry, "EGUF");
|
||||
if (!status) {
|
||||
strcat(cvtValue, ",");
|
||||
strcat(cvtValue, dbGetString(pdbentry));
|
||||
}
|
||||
strcat(cvtValue, ")");
|
||||
}
|
||||
}
|
||||
fprintf(stream,"%-8s %-20s %-20s %-20s %-s\n",
|
||||
bus[linkType], linkValue, dtypValue,
|
||||
dbGetRecordName(pdbentry), cvtValue);
|
||||
break;
|
||||
}
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
status = dbNextRecordType(pdbentry);
|
||||
}
|
||||
dbFinishEntry(pdbentry);
|
||||
finishOutstream(stream);
|
||||
|
||||
@@ -28,25 +28,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*Field types as seen by static database access clients*/
|
||||
#define DCT_STRING 0
|
||||
#define DCT_INTEGER 1
|
||||
#define DCT_REAL 2
|
||||
#define DCT_MENU 3
|
||||
#define DCT_MENUFORM 4
|
||||
#define DCT_INLINK 5
|
||||
#define DCT_OUTLINK 6
|
||||
#define DCT_FWDLINK 7
|
||||
#define DCT_NOACCESS 8
|
||||
|
||||
/*Link types as seen by static database access clients*/
|
||||
#define DCT_LINK_CONSTANT 0
|
||||
#define DCT_LINK_FORM 1
|
||||
#define DCT_LINK_PV 2
|
||||
|
||||
typedef dbBase DBBASE;
|
||||
|
||||
typedef struct{
|
||||
typedef struct dbEntry {
|
||||
DBBASE *pdbbase;
|
||||
dbRecordType *precordType;
|
||||
dbFldDes *pflddes;
|
||||
@@ -57,9 +41,6 @@ typedef struct{
|
||||
short indfield;
|
||||
} DBENTRY;
|
||||
|
||||
struct dbAddr;
|
||||
struct dbCommon;
|
||||
|
||||
/* Static database access routines*/
|
||||
epicsShareFunc DBBASE * dbAllocBase(void);
|
||||
epicsShareFunc void dbFreeBase(DBBASE *pdbbase);
|
||||
@@ -68,18 +49,6 @@ epicsShareFunc void dbFreeEntry(DBENTRY *pdbentry);
|
||||
epicsShareFunc void dbInitEntry(DBBASE *pdbbase,
|
||||
DBENTRY *pdbentry);
|
||||
|
||||
/** Initialize DBENTRY from a valid dbAddr*.
|
||||
* Constant time equivalent of dbInitEntry() then dbFindRecord(),
|
||||
* and finally dbFollowAlias()
|
||||
*/
|
||||
epicsShareFunc void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY *pdbentry);
|
||||
|
||||
/** Initialize DBENTRY from a valid record (dbCommon*).
|
||||
* Constant time equivalent of dbInitEntry() then dbFindRecord(),
|
||||
* and finally dbFollowAlias() when no field is specified.
|
||||
*/
|
||||
epicsShareFunc void dbInitEntryFromRecord(struct dbCommon *prec, DBENTRY *pdbentry);
|
||||
|
||||
epicsShareFunc void dbFinishEntry(DBENTRY *pdbentry);
|
||||
epicsShareFunc DBENTRY * dbCopyEntry(DBENTRY *pdbentry);
|
||||
epicsShareFunc void dbCopyEntryContents(DBENTRY *pfrom,
|
||||
@@ -139,7 +108,6 @@ epicsShareFunc long dbGetAttributePart(DBENTRY *pdbentry,
|
||||
|
||||
epicsShareFunc long dbFirstField(DBENTRY *pdbentry, int dctonly);
|
||||
epicsShareFunc long dbNextField(DBENTRY *pdbentry, int dctonly);
|
||||
epicsShareFunc int dbGetFieldType(DBENTRY *pdbentry);
|
||||
epicsShareFunc int dbGetNFields(DBENTRY *pdbentry, int dctonly);
|
||||
epicsShareFunc char * dbGetFieldName(DBENTRY *pdbentry);
|
||||
epicsShareFunc char * dbGetDefault(DBENTRY *pdbentry);
|
||||
@@ -231,7 +199,6 @@ epicsShareFunc linkSup * dbFindLinkSup(dbBase *pdbbase,
|
||||
|
||||
epicsShareFunc int dbGetNLinks(DBENTRY *pdbentry);
|
||||
epicsShareFunc long dbGetLinkField(DBENTRY *pdbentry, int index);
|
||||
epicsShareFunc int dbGetLinkType(DBENTRY *pdbentry);
|
||||
|
||||
/* Dump routines */
|
||||
epicsShareFunc void dbDumpPath(DBBASE *pdbbase);
|
||||
|
||||
@@ -179,7 +179,7 @@ long dbFreeRecord(DBENTRY *pdbentry)
|
||||
if(!pdbRecordType) return(S_dbLib_recordTypeNotFound);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
if(!precnode->precord) return(S_dbLib_recNotFound);
|
||||
free(CONTAINER(precnode->precord, dbCommonPvt, common));
|
||||
free(dbRec2Pvt(precnode->precord));
|
||||
precnode->precord = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ caserverio_INCLUDES = -I$(SRC)/ca/client
|
||||
camessage_INCLUDES = -I$(SRC)/ca/client
|
||||
|
||||
INC += rsrv.h
|
||||
INC += server.h
|
||||
|
||||
DBD += rsrv.dbd
|
||||
|
||||
|
||||
@@ -183,17 +183,16 @@ static long special(DBADDR *paddr, int after)
|
||||
|
||||
#define indexof(field) int64inRecord##field
|
||||
|
||||
static long get_units(DBADDR *paddr,char *units)
|
||||
static long get_units(DBADDR *paddr, char *units)
|
||||
{
|
||||
int64inRecord *prec=(int64inRecord *)paddr->precord;
|
||||
int64inRecord *prec = (int64inRecord *) paddr->precord;
|
||||
|
||||
if(paddr->pfldDes->field_type == DBF_LONG) {
|
||||
strncpy(units,prec->egu,DB_UNITS_SIZE);
|
||||
if (paddr->pfldDes->field_type == DBF_INT64) {
|
||||
strncpy(units, prec->egu, DB_UNITS_SIZE);
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
|
||||
{
|
||||
int64inRecord *prec=(int64inRecord *)paddr->precord;
|
||||
@@ -255,7 +254,7 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
|
||||
|
||||
static void checkAlarms(int64inRecord *prec, epicsTimeStamp *timeLast)
|
||||
{
|
||||
enum {
|
||||
enum {
|
||||
range_Lolo = 1,
|
||||
range_Low,
|
||||
range_Normal,
|
||||
|
||||
@@ -12,6 +12,8 @@ SRC_DIRS += $(STDDIR)/softIoc
|
||||
PROD_IOC_DEFAULT = softIoc
|
||||
PROD_IOC_iOS = -nil-
|
||||
|
||||
PROD_LDFLAGS_vxWorks = --whole-archive
|
||||
|
||||
DBD += base.dbd
|
||||
DBD += asSub.dbd
|
||||
DBD += softIoc.dbd
|
||||
|
||||
@@ -212,7 +212,7 @@ sub _getline {
|
||||
|
||||
my $line = readline $self->{stdout};
|
||||
if (defined $line) {
|
||||
chomp $line;
|
||||
$line =~ s/[\r\n]+ $//x; # chomp broken on Windows?
|
||||
printf "#%d >> %s\n", $self->{pid}, $line if $self->{debug};
|
||||
}
|
||||
elsif (eof($self->{stdout})) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <testMain.h>
|
||||
#include <dbUnitTest.h>
|
||||
#include <errlog.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbAccess.h>
|
||||
#include <epicsEvent.h>
|
||||
@@ -16,6 +17,7 @@
|
||||
#include <iocsh.h>
|
||||
#include "registryFunction.h"
|
||||
#include <subRecord.h>
|
||||
#include <dbScan.h>
|
||||
|
||||
epicsEventId done;
|
||||
static int waitFor;
|
||||
@@ -28,11 +30,17 @@ long doneSubr(subRecord *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void dummydone(void *usr, struct dbCommon* prec)
|
||||
{
|
||||
epicsEventMustTrigger(done);
|
||||
}
|
||||
|
||||
void asyncproctest_registerRecordDeviceDriver(struct dbBase *);
|
||||
|
||||
MAIN(asyncproctest)
|
||||
{
|
||||
testPlan(21);
|
||||
testPlan(27);
|
||||
|
||||
done = epicsEventMustCreate(epicsEventEmpty);
|
||||
|
||||
@@ -99,6 +107,40 @@ MAIN(asyncproctest)
|
||||
testdbGetFieldEqual("chain3", DBF_LONG, 7);
|
||||
testdbGetFieldEqual("chain3.A", DBF_LONG, 2);
|
||||
|
||||
testDiag("===== Chain 4 ======");
|
||||
|
||||
{
|
||||
dbCommon *dummy=testdbRecordPtr("chain4_dummy");
|
||||
|
||||
testdbPutFieldOk("chain4_pos.PROC", DBF_LONG, 0);
|
||||
|
||||
/* sync once queue to wait for any queued RPRO */
|
||||
scanOnceCallback(dummy, dummydone, NULL);
|
||||
|
||||
if (epicsEventWaitWithTimeout(done, 10.0) != epicsEventOK)
|
||||
testAbort("Processing timed out");
|
||||
|
||||
testdbGetFieldEqual("chain4_pos", DBF_SHORT, 1);
|
||||
testdbGetFieldEqual("chain4_rel", DBF_SHORT, 1);
|
||||
testdbGetFieldEqual("chain4_lim", DBF_SHORT, 1);
|
||||
}
|
||||
|
||||
testDiag("===== Chain 5 ======");
|
||||
|
||||
{
|
||||
dbCommon *dummy=testdbRecordPtr("chain4_dummy");
|
||||
|
||||
testdbPutFieldOk("chain5_cnt.PROC", DBF_LONG, 0);
|
||||
|
||||
/* sync once queue to wait for any queued RPRO */
|
||||
scanOnceCallback(dummy, dummydone, NULL);
|
||||
|
||||
if (epicsEventWaitWithTimeout(done, 10.0) != epicsEventOK)
|
||||
testAbort("Processing timed out");
|
||||
|
||||
testdbGetFieldEqual("chain5_cnt", DBF_SHORT, 1);
|
||||
}
|
||||
|
||||
testIocShutdownOk();
|
||||
|
||||
testdbCleanup();
|
||||
|
||||
@@ -53,3 +53,41 @@ record(sub, "done3") {
|
||||
field(FLNK, "chain3")
|
||||
field(TPRO, "$(TPRO=)")
|
||||
}
|
||||
|
||||
|
||||
# loop breaking regression
|
||||
# should _not_ RPRO
|
||||
record(calcout,"chain4_pos") {
|
||||
field(CALC, "E:=E+1;E")
|
||||
field(OUT,"chain4_rel.A PP")
|
||||
field(TPRO, "$(TPRO=)")
|
||||
}
|
||||
|
||||
record(calc,"chain4_rel") {
|
||||
field(CALC, "E:=E+1;E")
|
||||
field(FLNK,"chain4_lim")
|
||||
field(TPRO, "$(TPRO=)")
|
||||
}
|
||||
|
||||
record(calc,"chain4_lim") {
|
||||
field(CALC, "E:=E+1;E")
|
||||
field(INPA,"chain4_pos PP")
|
||||
field(INPB,"chain4_pos.HIGH PP")
|
||||
field(INPC,"chain4_pos.LOW PP")
|
||||
field(FLNK,"chain4_pos")
|
||||
field(TPRO, "$(TPRO=)")
|
||||
}
|
||||
|
||||
record(bo, "chain4_dummy") {
|
||||
field(TPRO, "$(TPRO=)")
|
||||
}
|
||||
|
||||
# loop breaking regression part 2
|
||||
# selft link should _not_ RPRO
|
||||
record(calcout,"chain5_cnt") {
|
||||
field(CALC, "E:=E+1;E")
|
||||
field(INPA,"chain5_cnt.A PP")
|
||||
field(OUT,"chain5_cnt.A PP")
|
||||
field(FLNK,"chain5_cnt")
|
||||
field(TPRO, "$(TPRO=)")
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ $ENV{HARNESS_ACTIVE} = 1 if scalar @ARGV && shift eq '-tap';
|
||||
$ENV{EPICS_CA_AUTO_ADDR_LIST} = 'NO';
|
||||
$ENV{EPICS_CA_ADDR_LIST} = 'localhost';
|
||||
$ENV{EPICS_CA_SERVER_PORT} = 55064;
|
||||
$ENV{EPICS_CAS_BEACON_PORT} = 55065;
|
||||
$ENV{EPICS_CAS_INTF_ADDR_LIST} = 'localhost';
|
||||
|
||||
$ENV{EPICS_PVA_AUTO_ADDR_LIST} = 'NO';
|
||||
@@ -29,13 +30,32 @@ my $prefix = "test-$$";
|
||||
my $ioc = EPICS::IOC->new();
|
||||
#$ioc->debug(1);
|
||||
|
||||
$SIG{__DIE__} = $SIG{INT} = $SIG{QUIT} = $SIG{ALRM} = sub {
|
||||
$ioc->kill
|
||||
if ref($ioc) eq 'EPICS::IOC' && $ioc->started;
|
||||
$SIG{__DIE__} = $SIG{INT} = $SIG{QUIT} = sub {
|
||||
$ioc->kill;
|
||||
BAIL_OUT('Caught signal');
|
||||
};
|
||||
|
||||
alarm 30;
|
||||
|
||||
# Watchdog utilities
|
||||
|
||||
sub kill_bail {
|
||||
my $doing = shift;
|
||||
return sub {
|
||||
$ioc->kill;
|
||||
BAIL_OUT("Timeout $doing");
|
||||
}
|
||||
}
|
||||
|
||||
sub watchdog (&$$) {
|
||||
my ($do, $timeout, $abort) = @_;
|
||||
$SIG{ALRM} = $abort;
|
||||
alarm $timeout;
|
||||
&$do;
|
||||
alarm 0;
|
||||
}
|
||||
|
||||
|
||||
# Start the IOC
|
||||
|
||||
my $softIoc = "$bin/softIocPVA$exe";
|
||||
$softIoc = "$bin/softIoc$exe"
|
||||
@@ -43,42 +63,78 @@ $softIoc = "$bin/softIoc$exe"
|
||||
BAIL_OUT("Can't find a softIoc executable")
|
||||
unless -x $softIoc;
|
||||
|
||||
$ioc->start($softIoc, '-x', $prefix);
|
||||
$ioc->cmd; # Wait for command prompt
|
||||
watchdog {
|
||||
$ioc->start($softIoc, '-x', $prefix);
|
||||
$ioc->cmd; # Wait for command prompt
|
||||
} 10, kill_bail('starting softIoc');
|
||||
|
||||
|
||||
# Get Base Version number from PV
|
||||
|
||||
my $pv = "$prefix:BaseVersion";
|
||||
|
||||
my @pvs = $ioc->dbl('stringin');
|
||||
grep(m/$pv/, @pvs)
|
||||
or BAIL_OUT('No BaseVersion record found');
|
||||
watchdog {
|
||||
my @pvs = $ioc->dbl('stringin');
|
||||
grep(m/^ $pv $/x, @pvs)
|
||||
or BAIL_OUT('No BaseVersion record found');
|
||||
} 10, kill_bail('running dbl');
|
||||
|
||||
my $version = $ioc->dbgf("$pv");
|
||||
my $version;
|
||||
watchdog {
|
||||
$version = $ioc->dbgf("$pv");
|
||||
} 10, kill_bail('getting BaseVersion');
|
||||
like($version, qr/^ \d+ \. \d+ \. \d+ /x,
|
||||
"Got BaseVersion '$version' from iocsh");
|
||||
|
||||
note("CA server configuration:\n",
|
||||
map(" $_\n", $ioc->cmd('casr', 1)));
|
||||
|
||||
my $caget = "$bin/caget$exe";
|
||||
# Channel Access
|
||||
|
||||
SKIP: {
|
||||
skip "caget not available", 1 unless -x $caget;
|
||||
my $caVersion = `$caget -w5 $pv`;
|
||||
like($caVersion, qr/$pv \s+ \Q$version\E/x,
|
||||
'Got same BaseVersion from caget');
|
||||
my $caget = "$bin/caget$exe";
|
||||
skip "caget not available", 1
|
||||
unless -x $caget;
|
||||
|
||||
# CA Server Diagnostics
|
||||
|
||||
watchdog {
|
||||
note("CA server configuration:\n",
|
||||
map(" $_\n", $ioc->cmd('casr', 1)));
|
||||
} 10, kill_bail('running casr');
|
||||
|
||||
# CA Client test
|
||||
|
||||
watchdog {
|
||||
my $caVersion = `$caget -w5 $pv`;
|
||||
like($caVersion, qr/^ $pv \s+ \Q$version\E $/x,
|
||||
'Got same BaseVersion from caget');
|
||||
} 10, kill_bail('doing caget');
|
||||
}
|
||||
|
||||
my $pvget = "$bin/pvget$exe";
|
||||
|
||||
# PV Access
|
||||
|
||||
SKIP: {
|
||||
my $pvget = "$bin/pvget$exe";
|
||||
skip "softIocPVA not available", 1
|
||||
if $softIoc eq "$bin/softIoc$exe";
|
||||
note("PVA server configuration:\n",
|
||||
map(" $_\n", $ioc->cmd('pvasr')));
|
||||
|
||||
# PVA Server Diagnostics
|
||||
|
||||
watchdog {
|
||||
note("PVA server configuration:\n",
|
||||
map(" $_\n", $ioc->cmd('pvasr')));
|
||||
} 10, kill_bail('running pvasr');
|
||||
|
||||
skip "pvget not available", 1
|
||||
unless -x $pvget;
|
||||
my $pvaVersion = `$pvget -w5 $pv`;
|
||||
like($pvaVersion, qr/$pv \s .* \Q$version\E/x,
|
||||
'Got same BaseVersion from pvget');
|
||||
|
||||
# PVA Client test
|
||||
|
||||
watchdog {
|
||||
my $pvaVersion = `$pvget -w5 $pv`;
|
||||
like($pvaVersion, qr/^ $pv \s .* \Q$version\E \s* $/x,
|
||||
'Got same BaseVersion from pvget');
|
||||
} 10, kill_bail('doing pvget');
|
||||
}
|
||||
|
||||
$ioc->kill;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
EPICS_LIBCOM_MAJOR_VERSION = 3
|
||||
EPICS_LIBCOM_MINOR_VERSION = 17
|
||||
EPICS_LIBCOM_MAINTENANCE_VERSION = 2
|
||||
EPICS_LIBCOM_MAINTENANCE_VERSION = 3
|
||||
EPICS_LIBCOM_DEVELOPMENT_FLAG = 0
|
||||
|
||||
@@ -319,7 +319,7 @@ static const iocshArg epicsMutexShowAllArg1 = { "level",iocshArgInt};
|
||||
static const iocshArg * const epicsMutexShowAllArgs[2] =
|
||||
{&epicsMutexShowAllArg0,&epicsMutexShowAllArg1};
|
||||
static const iocshFuncDef epicsMutexShowAllFuncDef =
|
||||
{"epicsMutexShowAll",1,epicsMutexShowAllArgs};
|
||||
{"epicsMutexShowAll",2,epicsMutexShowAllArgs};
|
||||
static void epicsMutexShowAllCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
epicsMutexShowAll(args[0].ival,args[1].ival);
|
||||
|
||||
@@ -568,6 +568,186 @@ static MAC_ENTRY *create( MAC_HANDLE *handle, const char *name, int special )
|
||||
return entry;
|
||||
}
|
||||
|
||||
#define SUCCESS 0
|
||||
#define NOVALUE 1
|
||||
#define UNTERMINATED 2
|
||||
#define DIVZERO 3
|
||||
|
||||
static int parseExpr( const char** pp, int* v, int level );
|
||||
|
||||
/* Value is a number or an expression in () */
|
||||
static int parseValue( const char** pp, int* v )
|
||||
{
|
||||
int status;
|
||||
int val;
|
||||
const char *p = *pp;
|
||||
int neg = 0;
|
||||
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p == '+' || *p == '-') neg = *p++ == '-';
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p == '(')
|
||||
{
|
||||
p++;
|
||||
if ((status = parseExpr(&p, &val, 0)) != SUCCESS) return status;
|
||||
if (*p++ != ')')
|
||||
{
|
||||
printf("macLib: missing ) after '%s'\n", *pp);
|
||||
return UNTERMINATED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char* e;
|
||||
val = strtol(p, &e, 0);
|
||||
if (e == p) return NOVALUE;
|
||||
p = e;
|
||||
}
|
||||
if (neg) val = -val;
|
||||
*pp = p;
|
||||
*v = val;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Expr is a sum or product of Values or a conditional */
|
||||
static int parseExpr( const char** pp, int* v, int level )
|
||||
{
|
||||
const char *p = *pp;
|
||||
int o = 0;
|
||||
int val0, val1, val2;
|
||||
int status = SUCCESS;
|
||||
int stat1, stat2;
|
||||
|
||||
val0 = 0;
|
||||
/* handle sums and differences */
|
||||
do {
|
||||
if ((stat1 = parseValue(&p, &val1)) != SUCCESS)
|
||||
{
|
||||
if (o && stat1 == NOVALUE)
|
||||
printf ("macLib: missing operand after '%c'\n", o);
|
||||
return stat1;
|
||||
}
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
o = *p;
|
||||
/* handle products and quotients */
|
||||
while (o == '*' || o == '/' || o == '%')
|
||||
{
|
||||
p++;
|
||||
if ((stat2 = parseValue(&p, &val2)) != SUCCESS)
|
||||
{
|
||||
if (stat2 == NOVALUE)
|
||||
printf ("macLib: missing operand after '%c'\n", o);
|
||||
return stat2;
|
||||
}
|
||||
if (o == '*') val1 *= val2;
|
||||
else if (val2 == 0)
|
||||
{
|
||||
status = DIVZERO;
|
||||
val1 = 1;
|
||||
}
|
||||
else if (o == '/') val1 /= val2;
|
||||
else val1 %= val2;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
o = *p;
|
||||
}
|
||||
val0 += val1;
|
||||
} while (o == '+' || o == '-');
|
||||
|
||||
/* handle comparisons */
|
||||
o = *p;
|
||||
if (o == '<' || o == '>')
|
||||
{
|
||||
p++;
|
||||
if ((stat1 = parseExpr(&p, &val1, 1)) != SUCCESS)
|
||||
{
|
||||
if (stat1 == NOVALUE)
|
||||
printf ("macLib: missing expression after '%c'\n", o);
|
||||
return stat1;
|
||||
}
|
||||
if (o == '<')
|
||||
val0 = (val0 < val1);
|
||||
else
|
||||
val0 = (val0 > val1);
|
||||
}
|
||||
|
||||
/* handle conditionals */
|
||||
if (*p == '?' && level == 0)
|
||||
{
|
||||
p++;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p != ':')
|
||||
{
|
||||
stat1 = parseExpr(&p, &val1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
val1 = val0;
|
||||
stat1 = status;
|
||||
}
|
||||
if (*p != ':')
|
||||
{
|
||||
printf("macLib: missing : after '%s'\n", *pp);
|
||||
return UNTERMINATED;
|
||||
}
|
||||
p++;
|
||||
stat2 = parseExpr(&p, &val2, 0);
|
||||
status = val0 ? stat1 : stat2;
|
||||
val0 = val0 ? val1 : val2;
|
||||
}
|
||||
|
||||
*v = val0;
|
||||
*pp = p;
|
||||
return status;
|
||||
}
|
||||
|
||||
static MAC_ENTRY *evalExpr( MAC_HANDLE *handle, const char *expr )
|
||||
{
|
||||
MAC_ENTRY *entry = NULL;
|
||||
int status;
|
||||
const char* p = expr;
|
||||
int value;
|
||||
char valuestr[40];
|
||||
char format[20] = "%d";
|
||||
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p == '%')
|
||||
{
|
||||
int i = 1;
|
||||
p++;
|
||||
while (i < sizeof(format) && strchr(" #-+0", *p))
|
||||
format[i++] = *p++;
|
||||
while (i < sizeof(format) && strchr("0123456789", *p))
|
||||
format[i++] = *p++;
|
||||
if (i < sizeof(format) && strchr("diouxXc", *p))
|
||||
{
|
||||
format[i++] = *p++;
|
||||
format[i] = 0;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
status = parseExpr(&p, &value, 0);
|
||||
if (status == DIVZERO)
|
||||
printf ("macLib: division by zero\n");
|
||||
if (status != SUCCESS)
|
||||
return NULL;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p)
|
||||
{
|
||||
printf("macLib: rubbish at end of expression: %s\n", p);
|
||||
return NULL;
|
||||
}
|
||||
sprintf(valuestr, format, value);
|
||||
entry = create( handle, expr, TRUE );
|
||||
if ( entry )
|
||||
{
|
||||
entry->type = "calculation";
|
||||
if ( rawval( handle, entry, valuestr ) == NULL )
|
||||
return NULL;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up macro entry with matching "special" attribute by name
|
||||
*/
|
||||
@@ -579,6 +759,10 @@ static MAC_ENTRY *lookup( MAC_HANDLE *handle, const char *name, int special )
|
||||
printf( "lookup-> level = %d, name = %s, special = %d\n",
|
||||
handle->level, name, special );
|
||||
|
||||
if ( (special == FALSE) ) {
|
||||
entry = evalExpr( handle, name );
|
||||
if (entry) return entry;
|
||||
}
|
||||
/* search backwards so scoping works */
|
||||
for ( entry = last( handle ); entry != NULL; entry = previous( entry ) ) {
|
||||
if ( entry->special != special )
|
||||
@@ -698,6 +882,7 @@ static void trans( MAC_HANDLE *handle, MAC_ENTRY *entry, int level,
|
||||
/* return immediately if raw value is NULL */
|
||||
if ( *rawval == NULL ) return;
|
||||
|
||||
|
||||
/* discard quotes and escapes if level is > 0 (i.e. if these aren't
|
||||
the user's quotes and escapes) */
|
||||
discard = ( level > 0 );
|
||||
|
||||
@@ -18,9 +18,6 @@ void osdMonotonicInit(void)
|
||||
{
|
||||
unsigned i;
|
||||
clockid_t ids[] = {
|
||||
#ifdef CLOCK_MONOTONIC_RAW
|
||||
CLOCK_MONOTONIC_RAW, /* Linux specific */
|
||||
#endif
|
||||
#ifdef CLOCK_HIGHRES
|
||||
CLOCK_HIGHRES, /* solaris specific */
|
||||
#endif
|
||||
|
||||
@@ -567,14 +567,13 @@ static epicsThreadOSD *createImplicit(void)
|
||||
pthreadInfo->osiPriority = 0;
|
||||
|
||||
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
{
|
||||
struct sched_param param;
|
||||
int policy;
|
||||
if(pthread_getschedparam(tid,&policy,¶m) == 0)
|
||||
pthreadInfo->osiPriority =
|
||||
(param.sched_priority - pcommonAttr->minPriority) * 100.0 /
|
||||
if(pthread_getschedparam(tid,&pthreadInfo->schedPolicy,&pthreadInfo->schedParam) == 0) {
|
||||
if ( pcommonAttr->usePolicy && pthreadInfo->schedPolicy == pcommonAttr->schedPolicy ) {
|
||||
pthreadInfo->osiPriority =
|
||||
(pthreadInfo->schedParam.sched_priority - pcommonAttr->minPriority) * 100.0 /
|
||||
(pcommonAttr->maxPriority - pcommonAttr->minPriority + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
|
||||
|
||||
status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo);
|
||||
@@ -905,11 +904,13 @@ epicsShareFunc void epicsShareAPI *epicsThreadPrivateGet(epicsThreadPrivateId id
|
||||
|
||||
epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum ()
|
||||
{
|
||||
double hz;
|
||||
hz = sysconf ( _SC_CLK_TCK );
|
||||
if(hz<0)
|
||||
return 0.0;
|
||||
return 1.0 / hz;
|
||||
#ifdef CLOCK_REALTIME
|
||||
struct timespec res;
|
||||
if (clock_getres(CLOCK_REALTIME, &res) == 0)
|
||||
return res.tv_sec + 1e-9 * res.tv_nsec;
|
||||
else
|
||||
#endif
|
||||
return 1e-3;
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsThreadGetCPUs(void)
|
||||
|
||||
@@ -288,4 +288,15 @@ TESTPROD_HOST += cvtFastPerform
|
||||
cvtFastPerform_SRCS += cvtFastPerform.cpp
|
||||
testHarness_SRCS += cvtFastPerform.cpp
|
||||
|
||||
ifeq ($(OS_CLASS),Linux)
|
||||
ifeq ($(USE_POSIX_THREAD_PRIORITY_SCHEDULING),YES)
|
||||
TESTPROD_HOST += nonEpicsThreadPriorityTest
|
||||
nonEpicsThreadPriorityTest_SRCS += nonEpicsThreadPriorityTest.cpp
|
||||
nonEpicsThreadPriorityTest_SYS_LIBS += $(POSIX_LDLIBS:-l%=%)
|
||||
testHarness_SRCS += nonEpicsThreadPriorityTest.cpp
|
||||
epicsRunLibComTests_CFLAGS += -DHAVE_PTHREAD_PRIORITY_SCHEDULING
|
||||
TESTS += nonEpicsThreadPriorityTest
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
using namespace epics::atomic;
|
||||
|
||||
namespace {
|
||||
|
||||
template < class T >
|
||||
@@ -52,7 +54,7 @@ static void add ( void *arg )
|
||||
using epics::atomic::increment;
|
||||
TestDataAddSub < T > * const pTestData =
|
||||
reinterpret_cast < TestDataAddSub < T > * > ( arg );
|
||||
add ( pTestData->m_testValue, TestDataAddSub < T > :: delta );
|
||||
epics::atomic::add ( pTestData->m_testValue, TestDataAddSub < T > :: delta );
|
||||
increment ( pTestData->m_testIterations );
|
||||
}
|
||||
|
||||
|
||||
100
modules/libcom/test/nonEpicsThreadPriorityTest.cpp
Normal file
100
modules/libcom/test/nonEpicsThreadPriorityTest.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include <epicsThread.h>
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __rtems__
|
||||
|
||||
/* RTEMS is posix but currently does not use the pthread API */
|
||||
MAIN(nonEpicsThreadPriorityTest)
|
||||
{
|
||||
testPlan(1);
|
||||
testSkip(1, "Platform does not use pthread API");
|
||||
return testDone();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void *nonEpicsTestFunc(void *arg)
|
||||
{
|
||||
unsigned int pri;
|
||||
// epicsThreadGetIdSelf() creates an EPICS context
|
||||
// verify that the priority computed by epics context
|
||||
// is OK
|
||||
pri = epicsThreadGetPriority( epicsThreadGetIdSelf() );
|
||||
if ( ! testOk( 0 == pri, "'createImplicit' assigned correct priority (%d) to non-EPICS thread", pri) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
|
||||
static void testFunc(void *arg)
|
||||
{
|
||||
epicsEventId ev = (epicsEventId)arg;
|
||||
int policy;
|
||||
struct sched_param param;
|
||||
int status;
|
||||
pthread_t tid;
|
||||
void *rval;
|
||||
pthread_attr_t attr;
|
||||
|
||||
status = pthread_getschedparam(pthread_self(), &policy,¶m);
|
||||
if ( status ) {
|
||||
testSkip(1, "pthread_getschedparam failed");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( SCHED_FIFO != policy ) {
|
||||
testSkip(1, "nonEpicsThreadPriorityTest must be executed with privileges to use SCHED_FIFO");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( pthread_attr_init( &attr ) ) {
|
||||
testSkip(1, "pthread_attr_init failed");
|
||||
goto done;
|
||||
}
|
||||
if ( pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ) ) {
|
||||
testSkip(1, "pthread_attr_setinheritsched failed");
|
||||
goto done;
|
||||
}
|
||||
if ( pthread_attr_setschedpolicy ( &attr, SCHED_OTHER ) ) {
|
||||
testSkip(1, "pthread_attr_setschedpolicy failed");
|
||||
goto done;
|
||||
}
|
||||
param.sched_priority = 0;
|
||||
if ( pthread_attr_setschedparam ( &attr, ¶m ) ) {
|
||||
testSkip(1, "pthread_attr_setschedparam failed");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( pthread_create( &tid, &attr, nonEpicsTestFunc, 0 ) ) {
|
||||
testSkip(1, "pthread_create failed");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( pthread_join( tid, &rval ) ) {
|
||||
testSkip(1, "pthread_join failed");
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
epicsEventSignal( ev );
|
||||
}
|
||||
|
||||
MAIN(nonEpicsThreadPriorityTest)
|
||||
{
|
||||
testPlan(2);
|
||||
epicsEventId testComplete = epicsEventMustCreate(epicsEventEmpty);
|
||||
epicsThreadMustCreate("nonEpicsThreadPriorityTest", epicsThreadPriorityLow,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
testFunc, testComplete);
|
||||
epicsEventWaitStatus status = epicsEventWait(testComplete);
|
||||
testOk(status == epicsEventWaitOK,
|
||||
"epicsEventWait returned %d", status);
|
||||
return testDone();
|
||||
}
|
||||
#endif
|
||||
Submodule modules/normativeTypes updated: 41d56fdf89...e803240fbf
1
modules/pcas
Submodule
1
modules/pcas
Submodule
Submodule modules/pcas added at 49c4882f73
Submodule modules/pvAccess updated: 5e79342219...78410499f0
Submodule modules/pvData updated: d776f6eaf0...8c275cbc1c
Submodule modules/pvDatabase updated: 07a951c3a2...b3f96f730f
Submodule modules/pva2pva updated: a245adb5cf...521154fd52
Reference in New Issue
Block a user