Compare commits
173 Commits
PSI-7.0.9.
...
PSI-7.0.9.
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c2436720a | |||
| bd0c7e7823 | |||
| 46f046c751 | |||
| 60277e0980 | |||
| 12d24d3108 | |||
| 3b846dda9a | |||
| 15cbbe074f | |||
| 3bb6433fe6 | |||
| 0f29b34f68 | |||
| 427c3b4de1 | |||
| b259f5ee44 | |||
| 525cddc43f | |||
| 65cc904262 | |||
| 6196554b17 | |||
| 04a59727ec | |||
| 9921a8ae19 | |||
| 243a18ee43 | |||
|
|
def6cdb61f | ||
|
|
7236f3ad5f | ||
|
|
2422e56d20 | ||
|
|
c39f39cb93 | ||
|
|
f911f8ca3e | ||
|
|
693c95e1d0 | ||
|
|
38376b95ea | ||
|
|
f7f7443c4f | ||
|
|
f34dd44c29 | ||
|
|
e294bb443c | ||
|
|
de6d4e74ef | ||
|
|
ea421f61f5 | ||
|
|
4a81f5c518 | ||
|
|
5813dcd639 | ||
|
|
ae0435c6b2 | ||
|
|
2e00d068d3 | ||
|
|
7449a947ed | ||
|
|
b8e70783d8 | ||
|
|
a2be1c4f4f | ||
|
|
87b8050437 | ||
|
|
b9b2da26fd | ||
|
|
344efb14a9 | ||
|
|
94aa917f5d | ||
|
|
cca6db9d53 | ||
|
|
f3c72ea38e | ||
|
|
43afae523e | ||
|
|
1a4223caa6 | ||
|
|
144ab9074d | ||
|
|
b34465add6 | ||
|
|
d89039dbc6 | ||
|
|
7b6ec35110 | ||
|
|
70d5df05c7 | ||
|
|
2fc955bf8a | ||
|
|
71e4b4ce2a | ||
|
|
482b3943ed | ||
|
|
4edf6baae2 | ||
|
|
4fbe6daab7 | ||
|
|
383d29c93a | ||
|
|
6f562e0ad2 | ||
|
|
455978d9fb | ||
|
|
6683d81eb9 | ||
|
|
d87ad35d37 | ||
|
|
a9b66218c6 | ||
|
|
4cf7077ee2 | ||
|
|
71e86e51bd | ||
|
|
43003ea18a | ||
|
|
61deabd787 | ||
|
|
3ece668f6b | ||
|
|
d7a02342e5 | ||
|
|
ecd76e5b5b | ||
|
|
9b92a98d06 | ||
|
|
16fd65639a | ||
|
|
f3e24ea8e3 | ||
|
|
dd09670b35 | ||
|
|
04c7cdd33a | ||
|
|
3a822ccb0c | ||
|
|
45b2be0171 | ||
|
|
1468319f31 | ||
|
|
82994d600f | ||
|
|
8752372af1 | ||
|
|
41f19bd798 | ||
|
|
a89b12f9ef | ||
|
|
132cc8b90a | ||
|
|
bdb3744e7e | ||
|
|
124f7b9d9b | ||
|
|
579c15e4f2 | ||
|
|
326c8d588f | ||
|
|
77140abe70 | ||
|
|
3d7a6b0b50 | ||
|
|
463ddf4694 | ||
|
|
389f51e55c | ||
|
|
855696b4b1 | ||
|
|
e45da11703 | ||
|
|
94b37fafb6 | ||
|
|
8ecf71c0a4 | ||
|
|
5aff8cee30 | ||
|
|
32517665b9 | ||
|
|
d4ad7c315e | ||
|
|
99682610a0 | ||
|
|
9eca4bc448 | ||
|
|
d2c73046f4 | ||
|
|
62b8653c39 | ||
|
|
1515f4d792 | ||
|
|
91063e4caa | ||
|
|
7b010cecd8 | ||
|
|
569e94b9fe | ||
|
|
bb78ba223c | ||
|
|
42ba2875cc | ||
|
|
5a7b5b3709 | ||
|
|
7876a5f5cf | ||
|
|
2bf9e70ac8 | ||
| 0223ee8465 | |||
| fe3ccfcafd | |||
| 37741efa38 | |||
| 51b57e0043 | |||
|
|
333446e0fe | ||
|
|
8735a7b17c | ||
|
|
81ba6a8a24 | ||
|
|
5c87283866 | ||
|
|
1b167f5de8 | ||
|
|
2f0fbbe1c6 | ||
| 4750b7ee93 | |||
| c9f80d82cc | |||
|
|
93f6c4692f | ||
| 72ca94e04c | |||
| 3de1d93059 | |||
| 8855d15a3b | |||
| 87bb7d430f | |||
| 3963b35c17 | |||
| ec5badc737 | |||
| ca48a217a5 | |||
| 27db57d386 | |||
| 02d25c3c48 | |||
| 4d63e65b9d | |||
|
|
9731d07e68 | ||
|
|
3daba7803b | ||
| ea402b0f73 | |||
|
|
21368dc7b4 | ||
|
|
a7c2292d48 | ||
|
|
0f6fd8fff7 | ||
|
|
c485055bd5 | ||
|
|
35923b5085 | ||
|
|
42e7cbc71d | ||
|
|
8c6336014a | ||
|
|
52d9ef1d20 | ||
|
|
c0da3dd1f9 | ||
|
|
55d918e74c | ||
| ca74f94faa | |||
| 8d46bd3a41 | |||
| 226b752470 | |||
| f7778539e8 | |||
| 45ea3d5664 | |||
| c67982aa3f | |||
|
|
0cbc4eb107 | ||
|
|
72936844ae | ||
|
|
8e29e13a13 | ||
|
|
a85ef1ad1c | ||
| 5e1bd8956b | |||
| b833f12129 | |||
|
|
e13d65f6f5 | ||
|
|
eb1263795e | ||
|
|
ad326751fa | ||
|
|
f827bd7e34 | ||
|
|
7372b4e5bb | ||
|
|
26e9e407f6 | ||
|
|
a0059b6e91 | ||
|
|
feae322e9a | ||
|
|
1b1bb34c83 | ||
|
|
fe6d946d32 | ||
|
|
004c55503b | ||
|
|
a9ba1c95b2 | ||
|
|
72d751f07d | ||
|
|
d279897181 | ||
|
|
cad535a956 | ||
|
|
6fc6304f19 | ||
|
|
0c75f1fe99 |
@@ -6,3 +6,7 @@ root = true
|
||||
# as some compilers complain about files not ending in newline
|
||||
[*]
|
||||
insert_final_newline = true
|
||||
|
||||
# Part of readline test that needs file without final newline
|
||||
[modules/libcom/test/multiline-input.txt]
|
||||
insert_final_newline = false
|
||||
|
||||
31
.github/workflows/ci-scripts-build.yml
vendored
31
.github/workflows/ci-scripts-build.yml
vendored
@@ -45,9 +45,8 @@ jobs:
|
||||
CI_CROSS_TARGETS: ${{ matrix.cross }}
|
||||
EXTRA: ${{ matrix.extra }}
|
||||
TEST: ${{ matrix.test }}
|
||||
CHOCO: llvm
|
||||
strategy:
|
||||
fail-fast: true
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Job names also name artifacts, character limitations apply
|
||||
include:
|
||||
@@ -154,33 +153,27 @@ jobs:
|
||||
configuration: default
|
||||
name: "MacOS clang"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
- os: windows-2022
|
||||
cmp: vs2022
|
||||
configuration: debug
|
||||
name: "Win2019 MSC-19"
|
||||
name: "Win-22 MSC-22"
|
||||
extra: "CMD_CXXFLAGS=-analysis"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
- os: windows-2022
|
||||
cmp: vs2022
|
||||
configuration: static-debug
|
||||
name: "Win2019 MSC-19, static"
|
||||
name: "Win-22 MSC-22, static"
|
||||
extra: "CMD_CXXFLAGS=-analysis"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
- os: windows-2022
|
||||
cmp: vs2022
|
||||
configuration: debug
|
||||
name: "Win2019 MSC-19, debug"
|
||||
name: "Win-22 MSC-22, debug"
|
||||
|
||||
- os: windows-2022
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
name: "Win2022 mingw"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: clang+vs2019
|
||||
configuration: default
|
||||
name: "Win2019 clang-cl"
|
||||
choco: ["llvm"]
|
||||
name: "Win-22 mingw"
|
||||
|
||||
# Cross builds
|
||||
|
||||
@@ -329,7 +322,7 @@ jobs:
|
||||
yum -y install \
|
||||
curl make gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker \
|
||||
python3 gdb make perl gcc-c++ glibc-devel readline-devel ncurses-devel perl-devel perl-Test-Simple \
|
||||
libevent-devel sudo re2c
|
||||
libevent-devel sudo re2c perl-version
|
||||
[ -e /usr/bin/python ] || ln -sf /usr/bin/python3 /usr/bin/python
|
||||
|
||||
# fake out cue.py
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,7 +1,7 @@
|
||||
[submodule "modules/pvData"]
|
||||
path = modules/pvData
|
||||
# url = https://github.com/epics-base/pvDataCPP
|
||||
url = git@git.psi.ch:epics_base/pvData.git
|
||||
url = ./pvData.git
|
||||
branch = master
|
||||
[submodule "modules/pvAccess"]
|
||||
path = modules/pvAccess
|
||||
|
||||
@@ -71,7 +71,7 @@ EPICS_TS_NTP_INET=
|
||||
# Number of lines of command history to keep.
|
||||
# IOCSH_HISTEDIT_DISABLE
|
||||
# Prevents use of readline or equivalent if defined.
|
||||
IOCSH_PS1="epics> "
|
||||
IOCSH_PS1=ANSI_GREEN("epics> ")
|
||||
IOCSH_HISTSIZE=50
|
||||
IOCSH_HISTEDIT_DISABLE=
|
||||
|
||||
|
||||
@@ -582,11 +582,11 @@ $(INSTALL_DOC)/%: $(COMMON_DIR)/%
|
||||
|
||||
$(INSTALL_DOC)/%: %
|
||||
$(ECHO) "Installing doc $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(INSTALL_DOC)
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_DOC)/%: ../%
|
||||
$(ECHO) "Installing doc $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(INSTALL_DOC)
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_HTML)/$(HTMLS_DIR)/%: $(COMMON_DIR)/%
|
||||
$(ECHO) "Installing generated html $@"
|
||||
|
||||
@@ -41,7 +41,7 @@ RELEASE.host: $(RELEASE_LOCAL)
|
||||
|
||||
$(RELEASE_LOCAL): Makefile $(CONFIG)/CONFIG_SITE \
|
||||
$(wildcard $(CONFIG)/CONFIG_SITE.local)
|
||||
$(ECHO) Creating $@ with
|
||||
$(ECHO) "Creating $@ with"
|
||||
$(ECHO) " $(PARENT_MODULE) = $(INSTALL_ABSOLUTE)"
|
||||
@echo $(PARENT_MODULE) = $(INSTALL_ABSOLUTE)> $@
|
||||
|
||||
|
||||
@@ -165,7 +165,8 @@ MOD_SYS_LDFLAGS += $(CPU_CFLAGS) -Wl,-r -nostdlib
|
||||
GESYS_LIBS += -lgcc
|
||||
GESYS_LIBS += -lc -lm -lrtemscpu -lrtemsbsp -lrtems++
|
||||
GESYS_LIBS += -lcexp -ltecla_r -lspencer_regexp -lpmelf -lpmbfd
|
||||
GESYS_LIBS += -lnfs -ltelnetd -lrtems-gdb-stub
|
||||
GESYS_LIBS += -lnfs -ltelnetd -lrtems-gdb-stub -lbsd -ltftpfs -lz
|
||||
GESYS_LIBS += -lnetworking
|
||||
|
||||
# While not part of the Generic Image it provides symbols which
|
||||
# would conflict.
|
||||
|
||||
@@ -6,24 +6,17 @@
|
||||
# These settings are designed for users of Homebrew.
|
||||
# Users of other third-party package managers are welcome to
|
||||
# provide patches appropriate for their manager.
|
||||
ifneq (,$(wildcard /opt/homebrew))
|
||||
# Default location on aarch64
|
||||
HOMEBREW_DIR = /opt/homebrew
|
||||
else ifneq (,$(wildcard /usr/local/Homebrew))
|
||||
# Default location on x86_64
|
||||
HOMEBREW_DIR = /usr/local
|
||||
else ifneq (,$(wildcard /opt/local/include/readline))
|
||||
# MacPorts
|
||||
READLINE_DIR = /opt/local
|
||||
endif
|
||||
HOMEBREW_DIR := $(shell brew --prefix 2>/dev/null)
|
||||
INCLUDES += $(HOMEBREW_DIR:%=-I%/include)
|
||||
LDFLAGS += $(HOMEBREW_DIR:%=-L%/lib)
|
||||
|
||||
# Look for Homebrew's readline
|
||||
ifneq (,$(wildcard $(HOMEBREW_DIR)/opt/readline))
|
||||
READLINE_DIR = $(HOMEBREW_DIR)/opt/readline
|
||||
INCLUDES_READLINE += -I$(HOMEBREW_DIR)/opt/readline/include
|
||||
LDFLAGS_READLINE += -L$(HOMEBREW_DIR)/opt/readline/lib
|
||||
endif
|
||||
|
||||
# Use GNU readline if it's avaiilable
|
||||
ifneq (,$(wildcard $(READLINE_DIR)/include/readline/readline.h))
|
||||
INCLUDES_READLINE = -I$(READLINE_DIR)/include
|
||||
LDFLAGS_READLINE = -L$(READLINE_DIR)/lib
|
||||
endif
|
||||
# Look for MacPorts
|
||||
MACPORT_DIR := $(patsubst %/bin/port,%,$(shell which port))
|
||||
INCLUDES += $(MACPORT_DIR:%=-I%/include)
|
||||
LDFLAGS += $(MACPORT_DIR:%=-L%/lib)
|
||||
|
||||
@@ -1992,6 +1992,9 @@ PREDEFINED = __cplusplus \
|
||||
LIBCA_API \
|
||||
DBRECSTD_API \
|
||||
EPICS_ALWAYS_INLINE \
|
||||
EPICS_NORETURN \
|
||||
EPICS_PRINTF_FMT(x)=x \
|
||||
EPICS_PRINTF_STYLE(a,b)= \
|
||||
epicsShareExtern \
|
||||
epicsShareClass \
|
||||
epicsShareFunc \
|
||||
|
||||
@@ -11,124 +11,7 @@ EXPAND_ME += RTD_SRC
|
||||
|
||||
DOXYGEN ?= doxygen
|
||||
|
||||
libcom_HEADERS += adjustment
|
||||
libcom_HEADERS += alarm
|
||||
libcom_HEADERS += alarmString
|
||||
libcom_HEADERS += asTrapWrite
|
||||
libcom_HEADERS += bucketLib
|
||||
libcom_HEADERS += cantProceed
|
||||
libcom_HEADERS += compilerDependencies
|
||||
libcom_HEADERS += cvtFast
|
||||
libcom_HEADERS += dbmf
|
||||
libcom_HEADERS += devLibVME
|
||||
libcom_HEADERS += devLibVMEImpl
|
||||
libcom_HEADERS += ellLib
|
||||
libcom_HEADERS += envDefs
|
||||
libcom_HEADERS += epicsAlgorithm
|
||||
libcom_HEADERS += epicsAssert
|
||||
libcom_HEADERS += epicsAtomic
|
||||
libcom_HEADERS += epicsEvent
|
||||
libcom_HEADERS += epicsExit
|
||||
libcom_HEADERS += epicsExport
|
||||
libcom_HEADERS += epicsGeneralTime
|
||||
libcom_HEADERS += epicsGuard
|
||||
libcom_HEADERS += epicsMessageQueue
|
||||
libcom_HEADERS += epicsMutex
|
||||
libcom_HEADERS += epicsReadline
|
||||
libcom_HEADERS += epicsRingBytes
|
||||
libcom_HEADERS += epicsRingPointer
|
||||
libcom_HEADERS += epicsSignal
|
||||
libcom_HEADERS += epicsSpin
|
||||
libcom_HEADERS += epicsStackTrace
|
||||
libcom_HEADERS += epicsStdio
|
||||
libcom_HEADERS += epicsStdlib
|
||||
libcom_HEADERS += epicsString
|
||||
libcom_HEADERS += epicsTempFile
|
||||
libcom_HEADERS += epicsThread
|
||||
libcom_HEADERS += epicsTime
|
||||
libcom_HEADERS += epicsTypes
|
||||
libcom_HEADERS += epicsUnitTest
|
||||
libcom_HEADERS += errlog
|
||||
libcom_HEADERS += freeList
|
||||
libcom_HEADERS += iocsh
|
||||
libcom_HEADERS += ipAddrToAsciiAsynchronous
|
||||
libcom_HEADERS += logClient
|
||||
libcom_HEADERS += macLib
|
||||
libcom_HEADERS += osiPoolStatus
|
||||
libcom_HEADERS += osiProcess
|
||||
libcom_HEADERS += osiSock
|
||||
libcom_HEADERS += postfix
|
||||
libcom_HEADERS += shareLib
|
||||
libcom_HEADERS += testMain
|
||||
libcom_HEADERS += yajl_alloc
|
||||
libcom_HEADERS += yajl_common
|
||||
libcom_HEADERS += yajl_gen
|
||||
libcom_HEADERS += yajl_parse
|
||||
|
||||
database_HEADERS += chfPlugin
|
||||
database_HEADERS += dbChannel
|
||||
database_HEADERS += dbCommon
|
||||
database_HEADERS += dbDefs
|
||||
database_HEADERS += dbExtractArray
|
||||
database_HEADERS += dbLink
|
||||
database_HEADERS += dbServer
|
||||
database_HEADERS += dbState
|
||||
database_HEADERS += dbStaticLib
|
||||
database_HEADERS += dbUnitTest
|
||||
database_HEADERS += devLib
|
||||
database_HEADERS += devSup
|
||||
database_HEADERS += drvSup
|
||||
database_HEADERS += initHooks
|
||||
|
||||
record_HEADERS += aaiRecord
|
||||
record_HEADERS += aaoRecord
|
||||
record_HEADERS += aiRecord
|
||||
record_HEADERS += aoRecord
|
||||
record_HEADERS += aSubRecord
|
||||
record_HEADERS += biRecord
|
||||
record_HEADERS += boRecord
|
||||
record_HEADERS += calcRecord
|
||||
record_HEADERS += calcoutRecord
|
||||
record_HEADERS += compressRecord
|
||||
record_HEADERS += dfanoutRecord
|
||||
record_HEADERS += eventRecord
|
||||
record_HEADERS += fanoutRecord
|
||||
record_HEADERS += histogramRecord
|
||||
record_HEADERS += int64inRecord
|
||||
record_HEADERS += int64outRecord
|
||||
record_HEADERS += longinRecord
|
||||
record_HEADERS += longoutRecord
|
||||
record_HEADERS += lsiRecord
|
||||
record_HEADERS += lsoRecord
|
||||
record_HEADERS += mbbiRecord
|
||||
record_HEADERS += mbbiDirectRecord
|
||||
record_HEADERS += mbboRecord
|
||||
record_HEADERS += mbboDirectRecord
|
||||
record_HEADERS += permissiveRecord
|
||||
record_HEADERS += printfRecord
|
||||
record_HEADERS += selRecord
|
||||
record_HEADERS += seqRecord
|
||||
record_HEADERS += stateRecord
|
||||
record_HEADERS += stringinRecord
|
||||
record_HEADERS += stringoutRecord
|
||||
record_HEADERS += subRecord
|
||||
record_HEADERS += subArrayRecord
|
||||
record_HEADERS += waveformRecord
|
||||
|
||||
menu_HEADERS += menuAlarmSevr
|
||||
menu_HEADERS += menuAlarmStat
|
||||
menu_HEADERS += menuConvert
|
||||
menu_HEADERS += menuFtype
|
||||
menu_HEADERS += menuIvoa
|
||||
menu_HEADERS += menuOmsl
|
||||
menu_HEADERS += menuPini
|
||||
menu_HEADERS += menuPost
|
||||
menu_HEADERS += menuPriority
|
||||
menu_HEADERS += menuScan
|
||||
menu_HEADERS += menuSimm
|
||||
menu_HEADERS += menuYesNo
|
||||
|
||||
HEADER_TYPES = libcom database record menu
|
||||
include $(TOP)/documentation/Makefile.headers
|
||||
|
||||
HEADER_MD_FILES = $(foreach t, $(HEADER_TYPES), \
|
||||
$(addsuffix _h.md, $($t_HEADERS)))
|
||||
@@ -137,10 +20,80 @@ API_RST_FILES = $(addsuffix -api.rst, $(HEADER_TYPES))
|
||||
RTD_SRC = $(COMMON_DIR)/rtd-src
|
||||
|
||||
DOCS += README.md
|
||||
DOCS += RELEASE_NOTES.md
|
||||
DOCS += ca-cli.md
|
||||
|
||||
OLD_NOTES = $(wildcard ../RELEASE-*.md)
|
||||
DOCS += $(OLD_NOTES:../%=%)
|
||||
|
||||
ifneq ($(EPICS_DEV_SNAPSHOT),)
|
||||
# Between releases the release target is disabled
|
||||
DOCS += RELEASE_NOTES.md
|
||||
REASON = EPICS_DEV_SNAPSHOT not empty
|
||||
else
|
||||
# Not a snapshot, user may be creating a new release
|
||||
ifdef T_A
|
||||
DOC = ../
|
||||
endif
|
||||
# Could we be in the middle of anything?
|
||||
NOTES_FILE = RELEASE-$(EPICS_SHORT_VERSION).md
|
||||
NOTES_PATH = $(DOC)$(NOTES_FILE)
|
||||
NOTES_GIT := $(firstword $(shell git status --porcelain $(NOTES_PATH)))
|
||||
ifeq ($(NOTES_GIT),A)
|
||||
# New file was added to the Git index; allow unrelease
|
||||
else ifeq ($(NOTES_GIT),AD)
|
||||
# File was added to the Git index but deleted; allow unrelease
|
||||
else ifeq ($(wildcard $(NOTES_PATH)),)
|
||||
# No file yet, allow release
|
||||
else
|
||||
# File exists but isn't in Git
|
||||
REASON := $(NOTES_FILE) exists but isn't in Git
|
||||
NOTES_FILE =
|
||||
NOTES_PATH =
|
||||
endif
|
||||
endif
|
||||
|
||||
NEW_DIR = ../new-notes
|
||||
NEW_NOTES = $(wildcard $(NEW_DIR)/*.md)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
ifndef T_A
|
||||
release unrelease doxygen rtd sphinx: inc
|
||||
$(MAKE) -C O.$(EPICS_HOST_ARCH) $@
|
||||
else
|
||||
|
||||
MAKENOTES = ../make-notes.pl
|
||||
|
||||
ifneq ($(NOTES_PATH),)
|
||||
$(NOTES_PATH): $(NEW_NOTES) $(MAKENOTES)
|
||||
@$(RM) $@
|
||||
$(PERL) $(MAKENOTES) -o $@ -V $(EPICS_SHORT_VERSION) \
|
||||
-d $(abspath $(NEW_DIR))
|
||||
release-git: $(NOTES_PATH)
|
||||
$(if $(NEW_NOTES), \
|
||||
git rm -q $(NEW_NOTES))
|
||||
git add $<
|
||||
release: $(INSTALL_DOC)/RELEASE_NOTES.md $(INSTALL_DOC)/$(NOTES_FILE)
|
||||
|
||||
unrelease:
|
||||
$(if $(wildcard $(NOTES_PATH)), \
|
||||
git restore --staged $(NOTES_PATH); \
|
||||
$(RM) $(NOTES_PATH))
|
||||
git restore --staged $(NEW_DIR)
|
||||
git restore $(NEW_DIR)
|
||||
|
||||
REL_DEP = release-git $(NOTES_PATH)
|
||||
else
|
||||
REL_DEV = -D
|
||||
release unrelease:
|
||||
$(error "make $@" not available, $(REASON))
|
||||
endif
|
||||
|
||||
$(COMMON_DIR)/RELEASE_NOTES.md: $(REL_DEP) $(NEW_NOTES) $(MAKENOTES)
|
||||
@$(RM) $@
|
||||
$(PERL) $(MAKENOTES) -o $@ -V $(EPICS_SHORT_VERSION) $(REL_DEV) \
|
||||
-d $(abspath $(NEW_DIR)) $(OLD_NOTES) $(NOTES_PATH)
|
||||
|
||||
$(HEADER_MD_FILES): %_h.md: ../HEADER_h.md
|
||||
$(EXPAND_TOOL) -t $(INSTALL_LOCATION) -DHEADER=$* $< $@
|
||||
|
||||
@@ -151,24 +104,23 @@ $(API_RST_FILES): %-api.rst: ../%-API.rst
|
||||
@$(foreach h, $($*_HEADERS), \
|
||||
echo " $h_h.rst" >> $@;)
|
||||
|
||||
ifndef T_A
|
||||
doxygen rtd sphinx: inc
|
||||
$(MAKE) -C O.$(EPICS_HOST_ARCH) $@
|
||||
else
|
||||
|
||||
doxygen: Doxyfile
|
||||
@$(MKDIR) $(RTD_SRC)
|
||||
$(DOXYGEN)
|
||||
DOX = doxygen
|
||||
|
||||
rtd: doxygen $(API_RST_FILES) $(HEADER_MD_FILES)
|
||||
rsync -av $(INSTALL_DOC)/ $(RTD_SRC)/
|
||||
# Use "make sphinx DOX=" to skip running doxygen
|
||||
rtd: $(DOX) $(API_RST_FILES) $(HEADER_MD_FILES)
|
||||
rsync -av --exclude=RELEASE-*.md $(INSTALL_DOC)/ $(RTD_SRC)/
|
||||
rsync -av $(HEADER_MD_FILES) $(RTD_SRC)/
|
||||
rsync -av $(API_RST_FILES) $(RTD_SRC)/
|
||||
rsync -av ../index.rst ../conf.py $(RTD_SRC)/
|
||||
RTD = rtd
|
||||
|
||||
sphinx: rtd
|
||||
# Use "make sphinx RTD=" to skip earlier steps
|
||||
sphinx: $(RTD)
|
||||
cd $(COMMON_DIR); $(PYTHON) -m sphinx rtd-src readthedocs
|
||||
rsync -av $(COMMON_DIR)/readthedocs $(INSTALL_HTML)/
|
||||
endif
|
||||
|
||||
.PHONY: doxygen rtd sphinx
|
||||
.PHONY: release release-git unrelease doxygen rtd sphinx
|
||||
|
||||
129
documentation/Makefile.headers
Normal file
129
documentation/Makefile.headers
Normal file
@@ -0,0 +1,129 @@
|
||||
# Makefile.headers
|
||||
#
|
||||
# Lists of C/C++ header files to include in each
|
||||
# section of the documentation
|
||||
|
||||
HEADER_TYPES = libcom ca database record menu
|
||||
|
||||
libcom_HEADERS += adjustment
|
||||
libcom_HEADERS += alarm
|
||||
libcom_HEADERS += alarmString
|
||||
libcom_HEADERS += asTrapWrite
|
||||
libcom_HEADERS += bucketLib
|
||||
libcom_HEADERS += cantProceed
|
||||
libcom_HEADERS += compilerDependencies
|
||||
libcom_HEADERS += cvtFast
|
||||
libcom_HEADERS += dbmf
|
||||
libcom_HEADERS += devLibVME
|
||||
libcom_HEADERS += devLibVMEImpl
|
||||
libcom_HEADERS += ellLib
|
||||
libcom_HEADERS += envDefs
|
||||
libcom_HEADERS += epicsAlgorithm
|
||||
libcom_HEADERS += epicsAssert
|
||||
libcom_HEADERS += epicsAtomic
|
||||
libcom_HEADERS += epicsEvent
|
||||
libcom_HEADERS += epicsExit
|
||||
libcom_HEADERS += epicsExport
|
||||
libcom_HEADERS += epicsGeneralTime
|
||||
libcom_HEADERS += epicsGuard
|
||||
libcom_HEADERS += epicsMessageQueue
|
||||
libcom_HEADERS += epicsMutex
|
||||
libcom_HEADERS += epicsReadline
|
||||
libcom_HEADERS += epicsRingBytes
|
||||
libcom_HEADERS += epicsRingPointer
|
||||
libcom_HEADERS += epicsSignal
|
||||
libcom_HEADERS += epicsSpin
|
||||
libcom_HEADERS += epicsStackTrace
|
||||
libcom_HEADERS += epicsStdio
|
||||
libcom_HEADERS += epicsStdlib
|
||||
libcom_HEADERS += epicsString
|
||||
libcom_HEADERS += epicsTempFile
|
||||
libcom_HEADERS += epicsThread
|
||||
libcom_HEADERS += epicsTime
|
||||
libcom_HEADERS += epicsTypes
|
||||
libcom_HEADERS += epicsUnitTest
|
||||
libcom_HEADERS += errlog
|
||||
libcom_HEADERS += freeList
|
||||
libcom_HEADERS += iocsh
|
||||
libcom_HEADERS += ipAddrToAsciiAsynchronous
|
||||
libcom_HEADERS += logClient
|
||||
libcom_HEADERS += macLib
|
||||
libcom_HEADERS += osiPoolStatus
|
||||
libcom_HEADERS += osiProcess
|
||||
libcom_HEADERS += osiSock
|
||||
libcom_HEADERS += postfix
|
||||
libcom_HEADERS += shareLib
|
||||
libcom_HEADERS += testMain
|
||||
libcom_HEADERS += yajl_alloc
|
||||
libcom_HEADERS += yajl_common
|
||||
libcom_HEADERS += yajl_gen
|
||||
libcom_HEADERS += yajl_parse
|
||||
|
||||
ca_HEADERS += cadef
|
||||
ca_HEADERS += caerr
|
||||
ca_HEADERS += caeventmask
|
||||
ca_HEADERS += db_access
|
||||
|
||||
database_HEADERS += chfPlugin
|
||||
database_HEADERS += dbChannel
|
||||
database_HEADERS += dbCommon
|
||||
database_HEADERS += dbDefs
|
||||
database_HEADERS += dbExtractArray
|
||||
database_HEADERS += dbLink
|
||||
database_HEADERS += dbServer
|
||||
database_HEADERS += dbState
|
||||
database_HEADERS += dbStaticLib
|
||||
database_HEADERS += dbUnitTest
|
||||
database_HEADERS += devLib
|
||||
database_HEADERS += devSup
|
||||
database_HEADERS += drvSup
|
||||
database_HEADERS += initHooks
|
||||
|
||||
record_HEADERS += aaiRecord
|
||||
record_HEADERS += aaoRecord
|
||||
record_HEADERS += aiRecord
|
||||
record_HEADERS += aoRecord
|
||||
record_HEADERS += aSubRecord
|
||||
record_HEADERS += biRecord
|
||||
record_HEADERS += boRecord
|
||||
record_HEADERS += calcRecord
|
||||
record_HEADERS += calcoutRecord
|
||||
record_HEADERS += compressRecord
|
||||
record_HEADERS += dfanoutRecord
|
||||
record_HEADERS += eventRecord
|
||||
record_HEADERS += fanoutRecord
|
||||
record_HEADERS += histogramRecord
|
||||
record_HEADERS += int64inRecord
|
||||
record_HEADERS += int64outRecord
|
||||
record_HEADERS += longinRecord
|
||||
record_HEADERS += longoutRecord
|
||||
record_HEADERS += lsiRecord
|
||||
record_HEADERS += lsoRecord
|
||||
record_HEADERS += mbbiRecord
|
||||
record_HEADERS += mbbiDirectRecord
|
||||
record_HEADERS += mbboRecord
|
||||
record_HEADERS += mbboDirectRecord
|
||||
record_HEADERS += permissiveRecord
|
||||
record_HEADERS += printfRecord
|
||||
record_HEADERS += selRecord
|
||||
record_HEADERS += seqRecord
|
||||
record_HEADERS += stateRecord
|
||||
record_HEADERS += stringinRecord
|
||||
record_HEADERS += stringoutRecord
|
||||
record_HEADERS += subRecord
|
||||
record_HEADERS += subArrayRecord
|
||||
record_HEADERS += waveformRecord
|
||||
|
||||
menu_HEADERS += menuAlarmSevr
|
||||
menu_HEADERS += menuAlarmStat
|
||||
menu_HEADERS += menuConvert
|
||||
menu_HEADERS += menuFtype
|
||||
menu_HEADERS += menuIvoa
|
||||
menu_HEADERS += menuOmsl
|
||||
menu_HEADERS += menuPini
|
||||
menu_HEADERS += menuPost
|
||||
menu_HEADERS += menuPriority
|
||||
menu_HEADERS += menuScan
|
||||
menu_HEADERS += menuSimm
|
||||
menu_HEADERS += menuYesNo
|
||||
|
||||
@@ -232,14 +232,16 @@ required path and other environment variables.
|
||||
* **`EPICS_HOST_ARCH`**
|
||||
|
||||
Some host builds of EPICS require that the environment variable
|
||||
`EPICS_HOST_ARCH` be defined. The perl script `EpicsHostArch.pl` in the
|
||||
`base/startup` directory prints the value which the build will use if
|
||||
the variable is not set before the build starts. Architecture names
|
||||
start with the operating system followed by a dash and the host CPU
|
||||
architecture, e.g. `linux-x86_64`. Some architecture names have another
|
||||
dash followed by another keyword, for example when building for Windows
|
||||
but using the MinGW compiler the name must be `windows-x64-mingw`. See
|
||||
`configure/CONFIG_SITE` for a list of supported host architecture names.
|
||||
`EPICS_HOST_ARCH` be defined. The shell script `EpicsHostArch` in the
|
||||
`base/startup` directory (which finds and calls the perl script
|
||||
`EpicsHostArch.pl` in the `base/src/tools` directory) prints the
|
||||
value which the build will use if the variable is not set before
|
||||
the build starts. Architecture names start with the operating system
|
||||
followed by a dash and the host CPU architecture, e.g. `linux-x86_64`.
|
||||
Some architecture names have another dash followed by another keyword,
|
||||
for example when building for Windows but using the MinGW compiler the
|
||||
name must be `windows-x64-mingw`. See `configure/CONFIG_SITE` for a
|
||||
list of supported host architecture names.
|
||||
|
||||
* **`PATH`**
|
||||
As already mentioned, you must have the `perl` executable and you may
|
||||
|
||||
890
documentation/RELEASE-3.15.md
Normal file
890
documentation/RELEASE-3.15.md
Normal file
@@ -0,0 +1,890 @@
|
||||
# Changes incorporated from the 3.15 branch
|
||||
|
||||
## Changes from the 3.15 branch since 3.15.9
|
||||
|
||||
### Support for Apple M1/M2 (arm64) Processors
|
||||
|
||||
Thanks to Jeong Han Lee this release comes with build support for Apple's new
|
||||
M1/M2 CPUs running macOS, using the target name `darwin-aarch64`.
|
||||
|
||||
### Set thread names on Windows
|
||||
|
||||
On MS Windows, epicsThread names are made available to the OS and debugger
|
||||
using `SetThreadDescription()` if available as well as using the older
|
||||
exception mechanism.
|
||||
|
||||
### Fix timers on MS Windows for non-EPICS threads
|
||||
|
||||
The waitable timer changes in 3.15.9 broke calls to `epicsThreadSleep()` and
|
||||
similar routines that used timers (including `ca_pend_event()`) when made from
|
||||
threads that were not started using the epicsThread APIs.
|
||||
[This problem](https://github.com/epics-base/epics-base/pull/200)
|
||||
[has now been fixed](https://github.com/epics-base/epics-base/pull/201).
|
||||
|
||||
## Changes made between 3.15.8 and 3.15.9
|
||||
|
||||
### Use waitable timers on Microsoft Windows
|
||||
|
||||
The `epicsEventWaitWithTimeout()` and `epicsThreadSleep()` functions have
|
||||
been changed to use waitable timers. On Windows 10 version 1803 or higher
|
||||
they will use high resolution timers for more consistent timing.
|
||||
|
||||
See [this Google Groups thread](https://groups.google.com/a/chromium.org/g/scheduler-dev/c/0GlSPYreJeY)
|
||||
for a comparison of the performance of different timers.
|
||||
|
||||
### Build target for documentation
|
||||
|
||||
The build target `inc` now works again after a very long hiatus. It now
|
||||
generates and installs just the dbd, header and html files, without compiling
|
||||
any C/C++ code. This can be used to speed up CI jobs that only generate
|
||||
documentation.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- The error status returned by a record support's `special()` method is now propagated out of the `dbPut()` routine again (broken since 3.15.0).
|
||||
- [gh: #80](https://github.com/epics-base/epics-base/issues/80), VS-2015 and
|
||||
later have working strtod()
|
||||
- [lp: #1776141](https://bugs.launchpad.net/epics-base/+bug/1776141), Catch
|
||||
buffer overflow from long link strings
|
||||
- [lp: #1899697](https://bugs.launchpad.net/epics-base/+bug/1899697), Records
|
||||
in wrong PHAS order
|
||||
|
||||
### Change to the `junitfiles` self-test build target
|
||||
|
||||
The names of the generated junit xml test output files have been changed
|
||||
from `<testname>.xml` to `<testname>-results.xml`, to allow better
|
||||
distinction from other xml files. (I.e., for easy wildcard matching.)
|
||||
|
||||
### Fixes and code cleanups
|
||||
|
||||
Issues reported by various static code checkers.
|
||||
|
||||
## Changes made between 3.15.7 and 3.15.8
|
||||
|
||||
### Bug fixes
|
||||
|
||||
The following launchpad bugs have fixes included in this release:
|
||||
|
||||
- [lp: 1812084](https://bugs.launchpad.net/epics-base/+bug/1812084), Build
|
||||
failure on RTEMS 4.10.2
|
||||
- [lp: 1829770](https://bugs.launchpad.net/epics-base/+bug/1829770), event
|
||||
record device support broken with constant INP
|
||||
- [lp: 1829919](https://bugs.launchpad.net/epics-base/+bug/1829919), IOC
|
||||
segfaults when calling dbLoadRecords after iocInit
|
||||
- [lp: 1838792](https://bugs.launchpad.net/epics-base/+bug/1838792), epicsCalc
|
||||
bit-wise operators on aarch64
|
||||
- [lp: 1841608](https://bugs.launchpad.net/epics-base/+bug/1841608), logClient
|
||||
falsely sends error logs on all connections
|
||||
- [lp: 1853168](https://bugs.launchpad.net/epics-base/+bug/1853168), undefined
|
||||
reference to `clock_gettime()`
|
||||
- [lp: 1862328](https://bugs.launchpad.net/epics-base/+bug/1862328), Race
|
||||
condition on IOC start leaves rsrv unresponsive
|
||||
- [lp: 1868486](https://bugs.launchpad.net/epics-base/+bug/1868486),
|
||||
epicsMessageQueue lost messages
|
||||
|
||||
### Improvements to the self-test build targets
|
||||
|
||||
This release contains changes that make it possible to integrate another test
|
||||
running and reporting system (such as Google's gtest) into the EPICS build
|
||||
system. The built-in test-runner and reporting system will continue to be used
|
||||
by the test programs inside Base however.
|
||||
|
||||
These GNUmake `tapfiles` and `test-results` build targets now collect a list of
|
||||
the directories that experienced test failures and display those at the end of
|
||||
running and/or reporting all of the tests. The GNUmake process will also only
|
||||
exit with an error status after running and/or reporting all of the test
|
||||
results; previously the `-k` flag to make was needed and even that didn't always
|
||||
work.
|
||||
|
||||
Continuous Integration systems are recommended to run `make tapfiles` (or if
|
||||
they can read junittest output instead of TAP `make junitfiles`) followed by
|
||||
`make -s test-results` to display the results of the tests. If multiple CPUs are
|
||||
available the `-j` flag can be used to run tests in parallel, giving the maximum
|
||||
jobs that should be allowed so `make -j4 tapfiles` for a system with 4 CPUs say.
|
||||
Running many more jobs than you have CPUs is likely to be slower and is not
|
||||
recommended.
|
||||
|
||||
### Calc Engine Fixes and Enhancements
|
||||
|
||||
The code that implements bit operations for Calc expressions has been reworked
|
||||
to better handle some CPU architectures and compilers. As part of this work a
|
||||
new operator has been added: `>>>` performs a logical right-shift, inserting
|
||||
zero bits into the most significant bits (the operator `>>` is an arithmetic
|
||||
right-shift which copies the sign bit as it shifts the value rightwards).
|
||||
|
||||
### IOC logClient Changes
|
||||
|
||||
The IOC's error logging system has been updated significantly to fix a number
|
||||
of issues including:
|
||||
|
||||
- Only send errlog messages to iocLogClient listeners
|
||||
- Try to minimize lost messages while the log server is down:
|
||||
+ Detect disconnects sooner
|
||||
+ Don't discard the buffer on disconnect
|
||||
+ Flush the buffer immediately after a server reconnects
|
||||
|
||||
### epicsThread: Main thread defaults to allow blocking I/O
|
||||
|
||||
VxWorks IOCs (and potentially RTEMS IOCs running GeSys) have had problems with
|
||||
garbled error messages from dbStaticLib routines for some time — messages
|
||||
printed before `iocInit` were being queued through the errlog thread instead of
|
||||
being output immediately. This has been fixed by initializing the main thread
|
||||
with its `OkToBlock` flag set instead of cleared. IOCs running on other
|
||||
operating systems that use iocsh to execute the startup script previously had
|
||||
that set anyway in iocsh so were not affected, but this change might cause other
|
||||
programs that don't use iocsh to change their behavior slightly if they use
|
||||
`errlogPrintf()`, `epicsPrintf()` or `errPrintf()`.
|
||||
|
||||
### catools: Handle data type changes in camonitor
|
||||
|
||||
The camonitor program didn't properly cope if subscribed to a channel whose data
|
||||
type changed when its IOC was rebooted without restarting the camonitor program.
|
||||
This has now been fixed.
|
||||
|
||||
### More Record Reference Documentation
|
||||
|
||||
The remaining record types have had their reference pages moved from the Wiki,
|
||||
and some new reference pages have been written to cover the analog array and
|
||||
long string input and output record types plus the printf record type, none of
|
||||
which were previously documented. The wiki reference pages covering the fields
|
||||
common to all, input, and output record types have also been added, thanks to
|
||||
Rolf Keitel. The POD conversion scripts have also been improved and they now
|
||||
properly support linking to subsections in a different document, although the
|
||||
POD changes to add the cross-links that appeared in the original wiki pages
|
||||
still needs to be done in most cases.
|
||||
|
||||
### Fix build issues with newer MinGW versions
|
||||
|
||||
The `clock_gettime()` routine is no longer used under MinGW since newer versions
|
||||
don't provide it any more.
|
||||
|
||||
### Fix race for port in RSRV when multiple IOCs start simultaneously
|
||||
|
||||
If multiple IOCs were started at the same time, by systemd say, they could race
|
||||
to obtain the Channel Access TCP port number 5064. This issue has been fixed.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.6 and 3.15.7
|
||||
|
||||
### GNU Readline detection on Linux
|
||||
|
||||
Most Linux architectures should now configure themselves automatically to use
|
||||
the GNU Readline library if its main header file can be found in the expected
|
||||
place, and not try to use Readline if the header file isn't present. For older
|
||||
Linux architectures where libncurses or libcurses must also be linked with, the
|
||||
manual configuration of the `COMMANDLINE_LIBRARY` variable in the appropriate
|
||||
`configure/os/CONFIG_SITE.Common.<arch>` file will still be necessary.
|
||||
|
||||
### Replace `EPICS_TIMEZONE` with `EPICS_TZ`
|
||||
|
||||
The `EPICS_TIMEZONE` environment parameter provided time-zone information for
|
||||
the IOC's locale in the old ANSI format expected by VxWorks for its `TIMEZONE`
|
||||
environment variable, and can also used by RTEMS to set its `TZ` environment
|
||||
variable. However the `TIMEZONE` value has to be updated every year since it
|
||||
contains the exact dates of the daylight-savings time changes. The Posix TZ
|
||||
format that RTEMS uses contains rules that for calculating those dates, thus its
|
||||
value would only need updating if the rules (or the locale) are changed.
|
||||
|
||||
This release contains changes that replace the `EPICS_TIMEZONE` environment
|
||||
parameter with one called `EPICS_TZ` and a routine for VxWorks that calculates
|
||||
the `TIMEZONE` environment variable from the current `TZ` value. This routine
|
||||
will be run once at start-up, when the EPICS clock has synchronized to its NTP
|
||||
server. The calculations it contains were worked out and donated to EPICS by
|
||||
Larry Hoff in 2009; it is unforunate that it has taken 10 years for them to be
|
||||
integrated into Base.
|
||||
|
||||
The default value for the `EPICS_TZ` environment parameter is set in the Base
|
||||
`configure/CONFIG_SITE_ENV` file, which contains example settings for most EPICS
|
||||
sites that use VxWorks, and a link to a page describing the Posix TZ format for
|
||||
any locations that I missed.
|
||||
|
||||
If a VxWorks IOC runs continuously without being rebooted from December 31st to
|
||||
the start of daylight savings time the following year, its `TIMEZONE` value will
|
||||
be wrong as it was calculated for the previous year. This only affects times
|
||||
that are converted to a string on the IOC however and is easily fixed; just run
|
||||
the command `tz2timezone()` on the VxWorks shell and the calculation will be
|
||||
redone for the current year. IOCs that get rebooted at least once before the
|
||||
start of summer time will not need this to be done.
|
||||
|
||||
### Added new decimation channel filter
|
||||
|
||||
A new server-side filter has been added to the IOC for reducing the number
|
||||
and frequency of monitor updates from a channel by a client-specified factor.
|
||||
The filter's behaviour is quite simplistic, it passes the first monitor event it
|
||||
sees to the client and then drops the next N-1 events before passing another
|
||||
event. For example to sample a 60Hz channel at 1Hz, a 10Hz channel every 6
|
||||
seconds, or a 1Hz channel once every minute:
|
||||
|
||||
```
|
||||
Hal$ camonitor 'test:channel.{"dec":{"n":60}}'
|
||||
...
|
||||
```
|
||||
|
||||
More information is included in the filters documentation, which can be found
|
||||
in the `html/filters.html` document that is generated during the build.
|
||||
|
||||
### Imported Record Reference Documentation from Wiki
|
||||
|
||||
The remaining record types that had 3.14 reference documentation in the EPICS
|
||||
Wiki have had that documentation converted and imported into their DBD files.
|
||||
The preferred form for future updates to the record type descriptions is now an
|
||||
emailed patch file, a Pull Request through GitHub, or a Merge Request through
|
||||
Launchpad. Note that in some cases the behavior of a record type in a 7.0.x
|
||||
release may differ from that of the same record type in a 3.15 release, although
|
||||
this would be unusual, so it may be important to indicate the branch that your
|
||||
changes apply to.
|
||||
|
||||
**NOTE:** *These documentation changes have modified the order of the fields in
|
||||
some record definitions. As a result this release is not compatible with record
|
||||
or device support binaries that were compiled against earlier releases.*
|
||||
|
||||
### `make test-results` for Windows
|
||||
|
||||
The make target `test-results` should now work properly on Windows. Some Perl
|
||||
installations used versions of `prove.bat` that would only display the results of
|
||||
up to 3 tests or didn't return an error status in the event of tests failing. The
|
||||
build system now calls its own perl script to summarize the results instead of
|
||||
passing a list of TAP filenames to `prove`.
|
||||
|
||||
### Add option to avoid CALLBACK conflict
|
||||
|
||||
If a macro `EPICS_NO_CALLBACK` is defined, then callback.h will no longer
|
||||
(re)define CALLBACK. The name `CALLBACK` is used by the WIN32 API, and
|
||||
redefinition in callback.h cause errors if some windows headers are later
|
||||
included.
|
||||
|
||||
Code which defines `EPICS_NO_CALLBACK`, but still wishes to use callbacks,
|
||||
should use the alternate name `epicsCallback` introduced in 3.15.6, 3.16.2, and
|
||||
7.0.2. It is also possible, though not encouraged, to use `struct callbackPvt`
|
||||
which has been present since the callback API was introduced.
|
||||
|
||||
### Cleaning up with Multiple CA contexts in a Process
|
||||
|
||||
Bruno Martins reported a problem with the CA client library at shutdown in a
|
||||
process that uses multiple CA client contexts. The first context that triggers
|
||||
the CA client exit handler prevents any others from being able to clean up
|
||||
because it resets the ID of an internal epicsThreadPrivate variable which is
|
||||
shared by all clients. This action has been removed from the client library,
|
||||
which makes cleanup of clients like this possible.
|
||||
|
||||
### Perl CA bindings fixed for macOS Mojave
|
||||
|
||||
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).
|
||||
|
||||
### Routine `epicsTempName()` removed from libCom
|
||||
|
||||
This routine was a simple wrapper around the C89 function `tmpnam()`
|
||||
which is now seen as unsafe and causes warning messages to be generated by
|
||||
most modern compilers. The two internal uses of this function have been
|
||||
modified to call `epicsTempFile()` instead. We were unable to find any
|
||||
published code that used this function, so it was removed immediately instead
|
||||
of being deprecated.
|
||||
|
||||
### DBD Parsing of Record Types
|
||||
|
||||
The Perl DBD file parser has been made slightly more liberal; the order in
|
||||
which DBD files must be parsed is now more flexible, so that a record type
|
||||
definition can now be parsed after a device support that referred to that
|
||||
record type. A warning message will be displayed when the device support is
|
||||
seen, but the subsequent loading of the record type will be accepted without
|
||||
triggering an error. See
|
||||
[Launchpad bug 1801145](https://bugs.launchpad.net/epics-base/+bug/1801145).
|
||||
|
||||
### menuScan and several record types documented with POD
|
||||
|
||||
The EPICS Wiki pages describing a number of standard record types has been
|
||||
converted into the Perl POD documentation format and added to the DBD files,
|
||||
so at build-time an HTML version of these documents is generated and installed
|
||||
into the htmls directory. Thanks to Tony Pietryla.
|
||||
|
||||
### CA client tools learned `-V` option
|
||||
|
||||
This displays the version numbers of EPICS Base and the CA protocol.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.5 and 3.15.6
|
||||
|
||||
### Unsetting environment variables
|
||||
|
||||
The new command `epicsEnvUnset varname` can be used to
|
||||
unset an environment variable.
|
||||
|
||||
### Warning indicators in msi (and macLib) output
|
||||
|
||||
The libCom macro expansion library has been modified so that when the
|
||||
`SUPPRESS_WARNINGS` flag is set it will no longer include any `,undefined`
|
||||
or `,recursive` indicators in its output when undefined or recursive
|
||||
macros are encountered. These indicators were harmless when the output was fed
|
||||
into an IOC along with a definition for the macro, but when the `msi`
|
||||
tool was used to generate other kinds of files they caused problems. If the
|
||||
`msi -V` flag is used the markers will still be present in the output
|
||||
whenever the appropriate condition is seen.
|
||||
|
||||
### Improvements to msi
|
||||
|
||||
In addition to fixing its response to discovering parsing errors in its
|
||||
substitution input file (reported as Launchpad
|
||||
[bug 1503661](https://bugs.launchpad.net/epics-base/+bug/1503661))
|
||||
so it now deletes the incomplete output file, the msi program has been cleaned
|
||||
up a little bit internally.
|
||||
|
||||
### All array records now post monitors on their array-length fields
|
||||
|
||||
The waveform record has been posting monitors on its NORD field since Base
|
||||
3.15.0.1; we finally got around to doing the equivalent in all the other
|
||||
built-in record types, which even required modifying device support in some
|
||||
cases. This fixes
|
||||
[Launchpad bug 1730727](https://bugs.launchpad.net/epics-base/+bug/1730727).
|
||||
|
||||
### HOWTO: Converting Wiki Record Reference to POD
|
||||
|
||||
Some documentation has been added to the `dbdToHtml.pl` script
|
||||
explaining how Perl POD (Plain Old Documentation) markup can be added to
|
||||
`.dbd` files to generate HTML documentation for the record types. To see
|
||||
these instructions, run `perl bin/<host>/dbdToHtml.pl -H`
|
||||
or `perldoc bin/<host>/dbdToHtml.pl`.
|
||||
|
||||
### Fix problem with numeric soft events
|
||||
|
||||
Changing from numeric to named soft events introduced an incompatibility
|
||||
when a numeric event 1-255 is converted from a DOUBLE, e.g. from a calc record.
|
||||
The `post_event()` API is not marked deprecated any more.
|
||||
|
||||
Also `scanpel` has been modified to accept a glob pattern for
|
||||
event name filtering and to show events with no connected records as well.
|
||||
|
||||
### Add `osiSockOptMcastLoop_t` and osiSockTest
|
||||
|
||||
Added a new OS-independent typedef for multicast socket options, and a test
|
||||
file to check their correct operation.
|
||||
|
||||
### Support for `CONFIG_SITE.local` in Base
|
||||
|
||||
This feature is mostly meant for use by developers; configuration
|
||||
settings that would normally appear in `base/configure/CONFIG_SITE` can now
|
||||
be put in a locally created `base/configure/CONFIG_SITE.local` file instead
|
||||
of having go modify or replace the original. A new `.gitignore` pattern
|
||||
tells git to ignore all `configure/*.local` files.
|
||||
|
||||
### Fix broken `EPICS_IOC_LOG_FILE_LIMIT=0` setting
|
||||
|
||||
The Application Developers' Guide says this is allowed and disables the
|
||||
limit on the log-file, but it hasn't actually worked for some time (if ever).
|
||||
Note that the iocLogServer will be removed from newer Base release sometime
|
||||
soon as its functionality can be implemented by other dedicated log servers
|
||||
such as logstash or syslog-ng.
|
||||
|
||||
Fixes [lp:1786858](https://bugs.launchpad.net/bugs/1786858)
|
||||
and part of [lp:1786966](https://bugs.launchpad.net/bugs/1786966).
|
||||
|
||||
### Cleanup of startup directory
|
||||
|
||||
The files in the startup directory have not been maintained in recent years
|
||||
and have grown crufty (technical term). This release includes the following
|
||||
updates to these files:
|
||||
|
||||
- The Perl `EpicsHostArch.pl` script has been rewritten, and support
|
||||
for a few previously missing host architectures has been added to it.
|
||||
- The `EpicsHostArch.pl` script has also been moved into the standard
|
||||
`src/tools` directory, from where it will be installed into
|
||||
`lib/perl`. In this new location it is no longer executable, so it must
|
||||
be run by the `perl` executable.
|
||||
- The build system has been adjusted to look for `EpicsHostArch.pl` in
|
||||
both places if the `EPICS_HOST_ARCH` environment variable has not been
|
||||
set at build-time.
|
||||
- Sites that used the original Perl script to set `EPICS_HOST_ARCH` as part of
|
||||
their standard environment will need to adjust their scripts when they
|
||||
upgrade to this release.
|
||||
- The `EpicsHostArch` shell script has been replaced with a wrapper
|
||||
routine that calls the Perl `EpicsHostArch.pl` script. Sites that rely on
|
||||
this script to set `EPICS_HOST_ARCH` should consider switching to the
|
||||
Perl script instead.
|
||||
- The `Site.cshrc` and `Site.profile` files have been renamed to
|
||||
`unix.csh` and `unix.sh`, respectively.
|
||||
- The existing `win32.bat` file has been cleaned up and a new
|
||||
`windows.bat` file added for 64-bit targets. The contents of these files
|
||||
should be seen as examples, don't uncomment or install parts for software
|
||||
that you don't explicitly know that you need.
|
||||
|
||||
### Recent Apple XCode Build Issues
|
||||
|
||||
The latest version of XCode will not compile calls to `system()` or
|
||||
`clock_settime()` for iOS targets. There were several places in Base
|
||||
where these were being compiled, although there were probably never called. The
|
||||
code has now been modified to permit iOS builds to complete again.
|
||||
|
||||
### Prevent illegal alarm severities
|
||||
|
||||
A check has been added to `recGblResetAlarms()` that prevents records
|
||||
from getting an alarm severity higher than `INVALID_ALARM`. It is still possible
|
||||
for a field like HSV to get set to a value that is not a legal alarm severity,
|
||||
but the core IOC code should never copy such a value into a record's SEVR or
|
||||
ACKS fields. With this fix the record's alarm severity will be limited to
|
||||
`INVALID_ALARM`.
|
||||
|
||||
### Fixes for Launchpad bugs
|
||||
|
||||
The following launchpad bugs have fixes included:
|
||||
|
||||
- [lp: 1786320](https://bugs.launchpad.net/epics-base/+bug/1786320), dbCa
|
||||
subscribes twice to ENUM
|
||||
- [lp: 541221](https://bugs.launchpad.net/epics-base/+bug/541221),
|
||||
`assert (pca->pgetNative)` failed in ../dbCa.c
|
||||
- [lp: 1747091](https://bugs.launchpad.net/epics-base/+bug/1747091),
|
||||
epicsTimeGetEvent() / generalTime bug
|
||||
- [lp: 1743076](https://bugs.launchpad.net/epics-base/+bug/1743076), Segfault
|
||||
in `ca_attach_context()` during exits
|
||||
- [lp: 1751380](https://bugs.launchpad.net/epics-base/+bug/1751380), Deadlock
|
||||
in `ca_clear_subscription()`
|
||||
- [lp: 1597809](https://bugs.launchpad.net/epics-base/+bug/1597809), Setting
|
||||
NAME field in DB file may break IOC
|
||||
- [lp: 1770292](https://bugs.launchpad.net/epics-base/+bug/1770292),
|
||||
`get_alarm_double()` inconsistent across record types
|
||||
- [lp: 1771298](https://bugs.launchpad.net/epics-base/+bug/1771298),
|
||||
Conversion of NaN to integer relies on undefined behavior
|
||||
|
||||
### Updated VxWorks Timezone settings
|
||||
|
||||
Removed the settings for 2017; fixed the hour of the change for MET.
|
||||
|
||||
### Fixed camonitor server side relative timestamps bug
|
||||
|
||||
Initialize the first time-stamp from the first monitor, not the client-side
|
||||
current time in this configuration.
|
||||
|
||||
### Build changes for MSVC
|
||||
|
||||
Windows builds using Visual Studio 2015 and later now use the `-FS`
|
||||
compiler option to allow parallel builds to work properly.
|
||||
|
||||
We now give the `-FC` option to tell the compiler to print absolute
|
||||
paths for source files in diagnostic messages.
|
||||
|
||||
### Extend maximum Posix epicsEventWaitWithTimeout() delay
|
||||
|
||||
The Posix implementation of epicsEventWaitWithTimeout() was limiting the
|
||||
timeout delay to at most 60 minutes (3600.0 seconds). This has been changed to
|
||||
10 years; significantly longer maximum delays cause problems on systems where
|
||||
`time_t` is still a signed 32-bit integer so cannot represent absolute
|
||||
time-stamps after 2038-01-19. Our assumption is that such 32-bit systems will
|
||||
have been retired before the year 2028, but some additional tests have been
|
||||
added to the epicsTimeTest program to detect and fail if this assumption is
|
||||
violated.
|
||||
|
||||
### New test-related make targets
|
||||
|
||||
This release adds several new make targets intended for use by developers
|
||||
and Continuous Integration systems which simplify the task of running the
|
||||
built-in self-test programs and viewing the results. Since these targets are
|
||||
intended for limited use they can have requirements for the build host which
|
||||
go beyond the standard minimum set needed to build and run Base.
|
||||
|
||||
#### `test-results` - Summarize test results
|
||||
|
||||
The new make target `test-results` will run the self-tests if
|
||||
necessary to generate a TAP file for each test, then summarizes the TAP output
|
||||
files in each test directory in turn, displaying the details of any failures.
|
||||
This step uses the program `prove` which comes with Perl, but also needs
|
||||
`cat` to be provided in the default search path so will not work on most
|
||||
Windows systems.
|
||||
|
||||
#### `junitfiles` - Convert test results to JUnit XML Format
|
||||
|
||||
The new make target `junitfiles` will run the self-tests if necessary
|
||||
and then convert the TAP output files into the more commonly-supported JUnit
|
||||
XML format. The program that performs this conversion needs the Perl module
|
||||
`XML::Generator` to have been installed.
|
||||
|
||||
#### `clean-tests` - Delete test result files
|
||||
|
||||
The new make target `clean-tests` removes any test result files from
|
||||
previous test runs. It cleans both TAP and JUnit XML files.
|
||||
|
||||
### Fix DNS related crash on exit
|
||||
|
||||
The attempt to fix DNS related delays for short lived CLI programs (eg. caget)
|
||||
in [lp:1527636](https://bugs.launchpad.net/epics-base/+bug/1527636) introduced a
|
||||
bug which cased these short lived clients to crash on exit. This bug should now
|
||||
be fixed.
|
||||
|
||||
### Server bind issue on Windows
|
||||
|
||||
When a National Instruments network variables CA server is already running on
|
||||
a Windows system and an IOC or PCAS server is started, the IOC's attempt to
|
||||
bind a TCP socket to the CA server port number fails, but Windows returns a
|
||||
different error status value than the IOC is expecting in that circumstance
|
||||
(because the National Instruments code requests exclusive use of that port,
|
||||
unlike the EPICS code) so the IOC fails to start properly. The relevent EPICS
|
||||
bind() checks have now been updated so the IOC will request that a dynamic port
|
||||
number be allocated for this TCP socket instead when this happens.
|
||||
|
||||
### Checking Periodic Scan Rates
|
||||
|
||||
Code has been added to the IOC startup to better protect it against bad
|
||||
periodic scan rates, including against locales where `.` is not
|
||||
accepted as a decimal separator character. If the scan period in a menuScan
|
||||
choice string cannot be parsed, the associated periodic scan thread will no
|
||||
longer be started by the IOC and a warning message will be displayed at iocInit
|
||||
time. The `scanppl` command will also flag the faulty menuScan value.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.4 and 3.15.5
|
||||
|
||||
### dbStatic Library Speedup and Cleanup
|
||||
|
||||
Loading of database files has been optimized to avoid over-proportionally
|
||||
long loading times for large databases. As a part of this, the alphabetical
|
||||
ordering of records instances (within a record type) has been dropped. In the
|
||||
unexpected case that applications were relying on the alphabetic order, setting
|
||||
`dbRecordsAbcSorted = 1` before loading the databases will retain the
|
||||
old behavior.
|
||||
|
||||
The routine `dbRenameRecord()` has been removed, as it was intended
|
||||
to be used by database configuration tools linked against a host side version
|
||||
of the dbStatic library that is not being built anymore.
|
||||
|
||||
### Launchpad Bug-fixes
|
||||
|
||||
In addition to the more detailed change descriptions below, the following
|
||||
Launchpad bugs have also been fixed in this release:
|
||||
|
||||
- [lp:1440186](https://bugs.launchpad.net/epics-base/+bug/1440186) Crash due
|
||||
to a too small buffer being provided in `dbContextReadNotifyCache()`
|
||||
- [lp:1479316](https://bugs.launchpad.net/epics-base/+bug/1479316) Some data
|
||||
races found using Helgrind
|
||||
- [lp:1495833](https://bugs.launchpad.net/epics-base/+bug/1495833) biRecord
|
||||
prompt groups are nonsensical
|
||||
- [lp:1606848](https://bugs.launchpad.net/epics-base/+bug/1606848) WSAIoctl
|
||||
`SIO_GET_INTERFACE_LIST` failed in Windows
|
||||
|
||||
### Whole-Program Optimization for MS Visual Studio Targets
|
||||
|
||||
When using the Microsoft compilers a new build system variable is provided that
|
||||
controls whether whole program optimization is used or not. For static builds
|
||||
using Visual Studio 2010 this optimization must be disabled. This is controlled
|
||||
in the files `configure/os/CONFIG_SITE.Common.windows-x64-static` and
|
||||
`configure/os/CONFIG_SITE.Common.win32-x86-static` by setting the variable
|
||||
`OPT_WHOLE_PROGRAM=NO` to override the default value `YES` that would otherwise
|
||||
be used.
|
||||
|
||||
Note that enabling this optimization slows down the build process. It is not
|
||||
possible to selectively disable this optimization, when building a particular
|
||||
module say; Microsoft's linker will restart itself automatically with the
|
||||
`-LTCG` flag set and display a warning if it is asked to link any object
|
||||
files that were compiled with the `-GL` flag.
|
||||
|
||||
### Add dynamic (variable length) array support to PCAS
|
||||
|
||||
Dynamic array sizing support was added to the IOC server (RSRV) in the
|
||||
Base-3.14.12 release, but has not until now been supported in the Portable
|
||||
Channel Access Server (PCAS). Channel Access server applications using the
|
||||
PCAS may not need to be modified at all; if they already push monitors with
|
||||
different gdd array lengths, those variable sizes will be forwarded to any CA
|
||||
clients who have requested variable length updates. The example CAS server
|
||||
application has been modified to demonstrate this feature.
|
||||
|
||||
In implementing the above, the gdd method `gdd::put(const gdd *)` now
|
||||
copies the full-sized array from the source gdd if the destination gdd is of
|
||||
type array, has no allocated memory and a boundary size of 0.
|
||||
|
||||
### Additional epicsTime conversion
|
||||
|
||||
The EPICS timestamp library (epicsTime) inside libCom's OSI layer has
|
||||
been extended by routines that convert from `struct tm` to the EPICS
|
||||
internal `epicsTime` type, assuming UTC - i.e. without going through
|
||||
the timezone mechanism. This solves issues with converting from the structured
|
||||
type to the EPICS timestamp at driver level from multiple threads at a high
|
||||
repetition rate, where the timezone mechanism was blocking on file access.
|
||||
|
||||
### MinGW Cross-builds from Linux
|
||||
|
||||
The build configuration files that allow cross-building of the 32-bit
|
||||
win32-x86-mingw cross-target have been adjusted to default to building shared
|
||||
libraries (DLLs) as this is now supported by recent MinGW compilers. The 64-bit
|
||||
windows-x64-mingw cross-target was already being built that way by default. The
|
||||
configuration options to tell the minGW cross-compiler to link programs with
|
||||
static versions of the compiler support libraries have now been moved into the
|
||||
`CONFIG_SITE.linux-x86.<target>` files.
|
||||
|
||||
### General Time updates
|
||||
|
||||
The `iocInit` code now performs a sanity check of the current time
|
||||
returned by the generalTime subsystem and will print a warning if the wall-clock
|
||||
time returned has not been initialized yet. This is just a warning message; when
|
||||
a time provider does synchonize the IOC will subsequently pick up and use the
|
||||
correct time. This check code also primes the registered event system provider
|
||||
if there is one so the `epicsTimeGetEventInt()` routine will work on IOCs
|
||||
that ask for event time within an interrupt service routine.
|
||||
|
||||
The osiClockTime provider's synchronization thread (which is only used on
|
||||
some embedded targets) will now poll the other time providers at 1Hz until the
|
||||
first time it manages to get a successful timestamp, after which it will poll
|
||||
for updates every 60 seconds as before.
|
||||
|
||||
The routine `generalTimeGetExceptPriority()` was designed for use by
|
||||
backup (lower priority) time providers like the osiClockTime provider which do
|
||||
not have their own absolute time reference and rely on other providers for an
|
||||
absolute time source. This routine no longer implements the ratchet mechanism
|
||||
that prevented the time it returned from going backwards. If the backup clock's
|
||||
tick-timer runs fast the synchronization of the backup time provider would never
|
||||
allow it to be corrected backwards when the ratchet was in place. The regular
|
||||
`epicsTimeGetCurrent()` API still uses the ratchet mechanism, so this
|
||||
change will not cause the IOC to see time going backwards.
|
||||
|
||||
### Microsoft Visual Studio builds
|
||||
|
||||
The build configuration files for builds using the Microsoft compilers have been
|
||||
updated, although there should be no noticable difference at most sites. One
|
||||
extra compiler warning is now being suppressed for C++ code, `C4344: behavior
|
||||
change: use of explicit template arguments results in ...` which is gratuitous
|
||||
and was appearing frequently in builds of the EPICS V4 modules.
|
||||
|
||||
Cross-builds of the windows-x64 target from a win32-x86 host have been
|
||||
removed as they don't actually work within the context of a single `make`
|
||||
run. Significant changes to the build configuration files would be necessary for
|
||||
these kinds of cross-builds to work properly, which could be done if someone
|
||||
needs them (email Andrew Johnson before working on this, and see
|
||||
[this stack-overflow answer](http://stackoverflow.com/questions/5807647/how-do-you-compile-32-bit-and-64-bit-applications-at-the-same-time-in-visual-stu) for a starting point).
|
||||
|
||||
### Bazaar keywords such as 'Revision-Id' removed
|
||||
|
||||
In preparation for moving to git in place of the Bazaar revision control
|
||||
system we have removed all the keywords from the Base source code.
|
||||
|
||||
### Linux systemd service file for CA Repeater
|
||||
|
||||
Building this version of Base on a Linux system creates a systemd service
|
||||
file suitable for starting the Channel Access Repeater under systemd. The file
|
||||
will be installed into the target bin directory, from where it can be copied
|
||||
into the appropriate systemd location and modified as necessary. Installation
|
||||
instructions are included as comments in the file.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.3 and 3.15.4
|
||||
|
||||
### New string input device support "getenv"
|
||||
|
||||
A new "getenv" device support for both the stringin and lsi (long string
|
||||
input) record types can be used to read the value of an environment variable
|
||||
from the IOC at runtime. See base/db/softIocExit.db for sample usage.
|
||||
|
||||
### Build rules and `DELAY_INSTALL_LIBS`
|
||||
|
||||
A new order-only prerequisite build rule has been added to ensure that
|
||||
library files (and DLL stubs on Windows) get installed before linking any
|
||||
executables, which resolves parallel build problems on high-powered CPUs. There
|
||||
are some (rare) cases though where a Makefile has to build an executable and run
|
||||
it to be able to compile code for a library built by the same Makefile. With
|
||||
this new build rule GNUmake will complain about a circular dependency and the
|
||||
build will probably fail in those cases. To avoid this problem the failing
|
||||
Makefile should set `DELAY_INSTALL_LIBS = YES` before including the
|
||||
`$(TOP)/configure/RULES` file, disabling the new build rule.
|
||||
|
||||
### IOC environment variables and build parameters
|
||||
|
||||
The IOC now sets a number of environment variables at startup that provide the
|
||||
version of EPICS Base it was built against (`EPICS_VERSION_...`) and its build
|
||||
architecture (ARCH). In some cases this allows a single iocBoot/ioc directory to
|
||||
be used to run the same IOC on several different architectures without any
|
||||
changes.
|
||||
|
||||
There are also 3 new environment parameters (`EPICS_BUILD_...`) available that
|
||||
C/C++ code can use to find out the target architecture, OS class and compiler
|
||||
class it was built with. These may be useful when writing interfaces to other
|
||||
languages.
|
||||
|
||||
### New implementation of `promptgroup`/`gui_group` field property
|
||||
|
||||
The mechanism behind the `promptgroup()` field property inside a record type
|
||||
definition has been changed. Instead of using a fixed set of choices,
|
||||
the static database access library now collects the used gui group names
|
||||
while parsing DBD information. Group names should start with a two-digit number
|
||||
plus space-dash-space to allow proper sorting of groups.
|
||||
|
||||
The include file `guigroup.h` that defined the fixed set of choices
|
||||
has been deprecated. Instead, use the conversion functions between index number
|
||||
and group string that have been added to dbStaticLib.
|
||||
|
||||
When a DBD file containing record-type descriptions is expanded, any
|
||||
old-style `GUI_xxx` group names will be replaced by a new-style
|
||||
string for use by the IOC. This permits an older record type to be used with
|
||||
the 3.15.4 release, although eventually record types should be converted by
|
||||
hand with better group names used.
|
||||
|
||||
### CA server configuration changes
|
||||
|
||||
RSRV now honors `EPICS_CAS_INTF_ADDR_LIST` and binds only to the provided list
|
||||
of network interfaces. Name searches (UDP and TCP) on other network interfaces
|
||||
are ignored. For example on a computer with interfaces 10.5.1.1/24, 10.5.2.1/24,
|
||||
and 10.5.3.1/24, setting `EPICS_CAS_INTF_ADDR_LIST='10.5.1.1 10.5.2.1'` will
|
||||
accept traffic on the .1.1 and .2.1, but ignore from .3.1
|
||||
|
||||
RSRV now honors `EPICS_CAS_IGNORE_ADDR_LIST` and ignores UDP messages received
|
||||
from addresses in this list.
|
||||
|
||||
Previously, CA servers (RSRV and PCAS) would build the beacon address list using
|
||||
`EPICS_CA_ADDR_LIST` if `EPICS_CAS_BEACON_ADDR_LIST` was no set. This is no
|
||||
longer done. Sites depending on this should set both environment variables to
|
||||
the same value.
|
||||
|
||||
### IPv4 multicast for name search and beacons
|
||||
|
||||
libca, RSRV, and PCAS may now use IPv4 multicasting for UDP traffic (name search
|
||||
and beacons). This is disabled by default. To enable multicast address(s) must
|
||||
be listed in `EPICS_CA_ADDR_LIST` for clients and `EPICS_CAS_INTF_ADDR_LIST` for
|
||||
servers (IOCs should set both). For example:
|
||||
|
||||
EPICS_CAS_INTF_ADDR_LIST='224.0.2.9' EPICS_CA_ADDR_LIST=224.0.2.9
|
||||
|
||||
Please note that no IPv4 multicast address is officially assigned for Channel
|
||||
Access by IANA. The example 224.0.2.9 is taken from the AD-HOC Block I range.
|
||||
|
||||
### Moved `mlockall()` into its own epicsThread routine
|
||||
|
||||
Since EPICS Base 3.15.0.2 on Posix OSs the initialization of the epicsThread
|
||||
subsystem has called `mlockall()` when the OS supports it and thread
|
||||
priority scheduling is enabled. Doing so has caused problems in third-party
|
||||
applications that call the CA client library, so the functionality has been
|
||||
moved to a separate routine `epicsThreadRealtimeLock()` which will be
|
||||
called by the IOC at iocInit (unless disabled by setting the global variable
|
||||
`dbThreadRealtimeLock` to zero).
|
||||
|
||||
### Added dbQuietMacroWarnings control
|
||||
|
||||
When loading database files, macros get expanded even on comment lines. If a
|
||||
comment contains an undefined macro, the load still continues but an error
|
||||
message gets printed. For this release the error message has been changed to a
|
||||
warning, but even this warning can be made less verbose by setting this new
|
||||
variable to a non-zero value before loading the file, like this:
|
||||
|
||||
```
|
||||
var dbQuietMacroWarnings 1 iocsh
|
||||
dbQuietMacroWarnings=1 VxWorks
|
||||
```
|
||||
|
||||
This was [Launchpad bug
|
||||
541119](https://bugs.launchpad.net/bugs/541119).
|
||||
|
||||
-----
|
||||
|
||||
## Changes from the 3.14 branch between 3.15.3 and 3.15.4
|
||||
|
||||
### NTP Time Provider adjusts to OS tick rate changes
|
||||
|
||||
Dirk Zimoch provided code that allows the NTP Time provider (used on VxWorks
|
||||
and RTEMS only) to adapt to changes in the OS clock tick rate after the provider
|
||||
has been initialized. Note that changing the tick rate after iocInit() is not
|
||||
advisable, and that other software might still misbehave if initialized before
|
||||
an OS tick rate change. This change was back-ported from the 3.15 branch.
|
||||
|
||||
### Making IOC `ca_get` operations atomic
|
||||
|
||||
When a CA client gets data from an IOC record using a compound data type such
|
||||
as `DBR_TIME_DOUBLE` the value field is fetched from the database in a
|
||||
separate call than the other metadata, without keeping the record locked. This
|
||||
allows some other thread such as a periodic scan thread a chance to interrupt
|
||||
the get operation and process the record in between. CA monitors have always
|
||||
been atomic as long as the value data isn't a string or an array, but this race
|
||||
condition in the CA get path has now been fixed so the record will stay locked
|
||||
between the two fetch operations.
|
||||
|
||||
This fixes
|
||||
[Launchpad bug 1581212](https://bugs.launchpad.net/epics-base/+bug/1581212),
|
||||
thanks to Till Strauman and Dehong Zhang.
|
||||
|
||||
### New `CONFIG_SITE` variable for running self-tests
|
||||
|
||||
The 'make runtests' and 'make tapfiles' build targets normally only run the
|
||||
self-tests for the main `EPICS_HOST_ARCH` architecture. If the host is
|
||||
able to execute self-test programs for other target architectures that are being
|
||||
built by the host, such as when building a `-debug` version of the host
|
||||
architecture for example, the names of those other architectures can be added to
|
||||
the new `CROSS_COMPILER_RUNTEST_ARCHS` variable in either the
|
||||
`configure/CONFIG_SITE` file or in an appropriate
|
||||
`configure/os/CONFIG_SITE.<host>.Common` file to have the test
|
||||
programs for those targets be run as well.
|
||||
|
||||
### Additional RELEASE file checks
|
||||
|
||||
An additional check has been added at build-time for the contents of the
|
||||
`configure/RELEASE` file(s), which will mostly only affect users of the Debian
|
||||
EPICS packages published by NSLS-2. Support modules may share an install path,
|
||||
but all such modules must be listed adjacent to each other in any `RELEASE`
|
||||
files that point to them. For example the following will fail the new checks:
|
||||
|
||||
```
|
||||
AUTOSAVE = /usr/lib/epics
|
||||
ASYN = /home/mdavidsaver/asyn
|
||||
EPICS_BASE = /usr/lib/epics
|
||||
```
|
||||
|
||||
giving the compile-time error
|
||||
|
||||
```
|
||||
This application's RELEASE file(s) define
|
||||
EPICS_BASE = /usr/lib/epics
|
||||
after but not adjacent to
|
||||
AUTOSAVE = /usr/lib/epics
|
||||
Module definitions that share paths must be grouped together.
|
||||
Either remove a definition, or move it to a line immediately
|
||||
above or below the other(s).
|
||||
Any non-module definitions belong in configure/CONFIG_SITE.
|
||||
```
|
||||
|
||||
In many cases such as the one above the order of the `AUTOSAVE` and
|
||||
`ASYN` lines can be swapped to let the checks pass, but if the
|
||||
`AUTOSAVE` module depended on `ASYN` and hence had to appear
|
||||
before it in the list this error indicates that `AUTOSAVE` should also be
|
||||
built in its own private area; a shared copy would likely be incompatible with
|
||||
the version of `ASYN` built in the home directory.
|
||||
|
||||
### String field buffer overflows
|
||||
|
||||
Two buffer overflow bugs that can crash the IOC have been fixed, caused by
|
||||
initializing a string field with a value larger than the field size
|
||||
([Launchpad bug 1563191](https://bugs.launchpad.net/bugs/1563191)).
|
||||
|
||||
### Fixed stack corruption bug in epicsThread C++ API
|
||||
|
||||
The C++ interface to the epicsThread API could corrupt the stack on thread
|
||||
exit in some rare circumstances, usually at program exit. This bug has been
|
||||
fixed ([Launchpad bug 1558206](https://bugs.launchpad.net/bugs/1558206)).
|
||||
|
||||
### RTEMS NTP Support Issue
|
||||
|
||||
On RTEMS the NTP Time Provider could in some circumstances get out of sync
|
||||
with the server because the `osdNTPGet()` code wasn't clearing its input socket
|
||||
before sending out a new request. This
|
||||
([Launchpad bug 1549908](https://bugs.launchpad.net/bugs/1549908))
|
||||
has now been fixed.
|
||||
|
||||
### CALC engine bitwise operator fixes
|
||||
|
||||
The bitwise operators in the CALC engine have been modified to work properly
|
||||
with values that have bit 31 (0x80000000) set. This modification involved
|
||||
back-porting some earlier changes from the 3.15 branch, and fixes
|
||||
[Launchpad bug 1514520](https://code.launchpad.net/bugs/1514520).
|
||||
|
||||
### Fix `ipAddrToAsciiAsync()`: Don't try to join the daemon thread
|
||||
|
||||
On process exit, don't try to stop the worker thread that makes DNS lookups
|
||||
asynchronous. Previously this would wait for any lookups still in progress,
|
||||
delaying the exit unnecessarily. This was most obvious with catools (eg.
|
||||
cainfo).
|
||||
[lp:1527636](https://bugs.launchpad.net/bugs/1527636)
|
||||
|
||||
### Fix `epicsTime_localtime()` on Windows
|
||||
|
||||
Simpler versions of the `epicsTime_gmtime()` and `epicsTime_localtime()`
|
||||
routines have been included in the Windows implementations, and a new test
|
||||
program added. The original versions do not report DST status properly. Fixes
|
||||
[Launchpad bug 1528284](https://bugs.launchpad.net/bugs/1528284).
|
||||
756
documentation/RELEASE-3.16.md
Normal file
756
documentation/RELEASE-3.16.md
Normal file
@@ -0,0 +1,756 @@
|
||||
# Changes incorporated from the 3.16 branch
|
||||
|
||||
## Changes made between 3.16.1 and 3.16.2
|
||||
|
||||
### Launchpad Bugs
|
||||
|
||||
The list of tracked bugs fixed in this release can be found on the
|
||||
[Launchpad Milestone page for EPICS Base 3.16.2](https://launchpad.net/epics-base/+milestone/3.16.2).
|
||||
|
||||
### Status reporting for the callback and scanOnce task queues
|
||||
|
||||
Two new iocsh commands and some associated underlying APIs have been added to
|
||||
show the state of the queues that feed the three callback tasks and the
|
||||
scanOnce task, including a high-water mark which can optionally be reset. The
|
||||
new iocsh commands are `callbackQueueShow` and `scanOnceQueueShow`; both take
|
||||
an optional integer argument which must be non-zero to reset the high-water
|
||||
mark.
|
||||
|
||||
### Support for event codes greater than or equal to `NUM_TIME_EVENTS`
|
||||
|
||||
Event numbers greater than or equal to `NUM_TIME_EVENTS` are now allowed if
|
||||
supported by the registered event time provider, which must provide its own
|
||||
advancing timestamp validation for such events.
|
||||
|
||||
Time events numbered 0 through `(NUM_TIME_EVENTS-1)` are still validated by code
|
||||
in epicsGeneralTime.c that checks for advancing timestamps and enforces that
|
||||
restriction.
|
||||
|
||||
### Type-safe Device and Driver Support Tables
|
||||
|
||||
Type-safe versions of the device and driver support structures `dset` and
|
||||
`drvet` have been added to the devSup.h and drvSup.h headers respectively. The
|
||||
original structure definitions have not been changed so existing support
|
||||
modules will still build normally, but older modules can be modified and new
|
||||
code written to be compatible with both.
|
||||
|
||||
The old structure definitions will be replaced by the new ones if the macros
|
||||
`USE_TYPED_DSET` and/or `USE_TYPED_DRVET` are defined when the appropriate
|
||||
header is included. The best place to define these is in the Makefile, as with
|
||||
the `USE_TYPED_RSET` macro that was introduced in Base-3.16.1 and described
|
||||
below. See the comments in devSup.h for a brief usage example, or look at
|
||||
[this commit](https://github.com/epics-modules/ipac/commit/a7e0ff4089b9aa39108bc8569e95ba7fcf07cee9)
|
||||
to the ipac module to see a module conversion.
|
||||
|
||||
A helper function `DBLINK* dbGetDevLink(dbCommon *prec)` has also been added
|
||||
to devSup.h which fetches a pointer to the INP or OUT field of the record.
|
||||
|
||||
### RTEMS build configuration update, running tests under QEMU
|
||||
|
||||
This release includes the ability to run the EPICS unit tests built for a
|
||||
special version of the RTEMS-pc386 target architecture on systems that have an
|
||||
appropriate QEMU emulator installed (`qemu-system-i386`). It is also now
|
||||
possible to create sub-architectures of RTEMS targets, whereas previously the
|
||||
EPICS target architecture name had to be `RTEMS-$(RTEMS_BSP)`.
|
||||
|
||||
The new target `RTEMS-pc386-qemu` builds binaries that can be run in the
|
||||
`qemu-system-i386` PC System emulator. This target is a derivative of the
|
||||
original `RTEMS-pc386` target but with additional software to build an in-
|
||||
memory file-system, and some minor modifications to allow the unit tests to
|
||||
work properly under QEMU. When this target is enabled, building any of the
|
||||
make targets that cause the built-in self-tests to be run (such as `make
|
||||
runtests`) will also run the tests for RTEMS using QEMU.
|
||||
|
||||
To allow the new 3-component RTEMS target name, the EPICS build system for
|
||||
RTEMS was modified to allow a `configure/os/CONFIG.Common.<arch>` file to set
|
||||
the `RTEMS_BSP` variable to inform the build what RTEMS BSP to use. Previously
|
||||
this was inferred from the value of the `T_A` make variable, but that prevents
|
||||
having multiple EPICS targets that build against the same BSP. All the
|
||||
included RTEMS target configuration files have been updated; build
|
||||
configuration files for out-of-tree RTEMS targets will continue to work as the
|
||||
original rules are used to set `RTEMS_BSP` if it hasn't been set when needed.
|
||||
|
||||
### Link type enhancements
|
||||
|
||||
This release adds three new link types: "state", "debug" and "trace". The
|
||||
"state" link type gets and puts boolean values from/to the dbState library
|
||||
that was added in the 3.15.1 release. The "debug" link type sets the
|
||||
`jlink::debug` flag in its child link, while the "trace" link type also causes
|
||||
the arguments and return values for all calls to the child link's jlif and
|
||||
lset routines to be printed on stdout. The debug flag can no longer be set
|
||||
using an info tag. The addition of the "trace" link type has allowed over 200
|
||||
lines of conditional diagnostic printf() calls to be removed from the other
|
||||
link types.
|
||||
|
||||
The "calc" link type can now be used for output links as well as input links.
|
||||
This allows modification of the output value and even combining it with values
|
||||
from other input links. See the separate JSON Link types document for details.
|
||||
|
||||
A new `start_child()` method was added to the end of the jlif interface table.
|
||||
|
||||
The `lset` methods have now been properly documented in the dbLink.h header
|
||||
file using Doxygen annotations, although we do not run Doxygen on the source
|
||||
tree yet to generate API documentation.
|
||||
|
||||
Link types that utilize child links must now indicate whether the child will
|
||||
be used for input, output or forward linking by the return value from its
|
||||
`parse_start_map()` method. The `jlif_key_result` enum now contains 3 values
|
||||
`jlif_key_child_inlink`, `jlif_key_child_outlink` and `jlif_key_child_fwdlink`
|
||||
instead of the single `jlif_key_child_link` that was previously used for this.
|
||||
|
||||
### GNUmake targets for debugging
|
||||
|
||||
Some additional build rules have been added to help debug configuration
|
||||
problems with the build system. Run `make show-makefiles` to get a sorted list
|
||||
of all the files that the build system includes when building in the current
|
||||
directory.
|
||||
|
||||
A new pattern rule for `PRINT.%` can be used to show the value of any GNUmake
|
||||
variable for the current build directory (make sure you are in the right
|
||||
directory though, many variables are only set when inside the `O.<arch>` build
|
||||
directory). For example `make PRINT.T_A` will display the build target
|
||||
architecture name from inside a `O.<arch>` directory but the variable will be
|
||||
empty from an application top or src directory. `make PRINT.EPICS_BASE` will
|
||||
show the path to Base from any EPICS application directory though.
|
||||
|
||||
### Propagate PUTF across Asynchronous record processing
|
||||
|
||||
The IOC contains a mechanism involving the PUTF and RPRO fields of each record
|
||||
to ensure that if a record is busy when it receives a put to one of its
|
||||
fields, the record will be processed again to ensure that the new field value
|
||||
has been correctly acted on. Until now that mechanism only worked if the put
|
||||
was to the asynchronous record itself, so puts that were chained from some
|
||||
other record via a DB link did not cause reprocessing.
|
||||
|
||||
In this release the mechanism has been extended to propagate the PUTF state
|
||||
across DB links until all downstream records have been reprocessed. Some
|
||||
additional information about the record state can be shown by setting the TPRO
|
||||
field of an upstream record, and even more trace data is displayed if the
|
||||
debugging variable `dbAccessDebugPUTF` is set in addition to TPRO.
|
||||
|
||||
### Finding info fields
|
||||
|
||||
A new iocsh command `dbli` lists the info fields defined in the database, and
|
||||
can take a glob pattern to limit output to specific info names. The newly
|
||||
added dbStaticLib function `dbNextMatchingInfo()` iterates through the info
|
||||
fields defined in the current record, and is used to implement the new
|
||||
command.
|
||||
|
||||
### Output from `dbpr` command enhanced
|
||||
|
||||
The "DataBase Print Record" command `dbpr` now generates slightly better
|
||||
output, with more field types having their own display methods. This release
|
||||
also includes additional protection against buffer overflows while printing
|
||||
long links in `dbpr`, and corrects the output of long strings from the `dbgf`
|
||||
command.
|
||||
|
||||
### Record types mbbiDirect and mbboDirect upgraded to 32 bit
|
||||
|
||||
The VAL fields and related fields of these records are now `DBF_LONG`. (Not
|
||||
`DBF_ULONG` in order to prevent Channel Access from promoting them to
|
||||
`DBF_DOUBLE`.) Additional bit fields `B10`...`B1F` have been added.
|
||||
|
||||
Device support that accesses `VAL` or the bit fields directly (most don't) and
|
||||
aims for compatibility with old and new versions of these records should use
|
||||
at least 32 bit integer types to avoid bit loss. The number of bit fields can
|
||||
be calculated using `8 * sizeof(prec->val)` which is correct in both versions.
|
||||
|
||||
### Restore use of ledlib for VxWorks command editing
|
||||
|
||||
The epicsReadline refactoring work described below unfortunately disabled the
|
||||
VxWorks implementation of the osdReadline.c API that uses ledlib for command
|
||||
editing and history. This functionality has now been restored, see Launchpad
|
||||
[bug #1741578](https://bugs.launchpad.net/bugs/1741578).
|
||||
|
||||
### Constant link types
|
||||
|
||||
Constant links can now hold 64-bit integer values, either as scalars or
|
||||
arrays. Only base 10 is supported by the JSON parser though, the JSON standard
|
||||
doesn't allow for hexadecimal numbers.
|
||||
|
||||
### Upgraded the YAJL JSON Library
|
||||
|
||||
The third-party YAJL library that has been included in libCom for several
|
||||
years has been upgraded to version 2.1.0 and several bugs fixed. This has an
|
||||
updated API, requiring any code that uses it to parse its own JSON files to be
|
||||
modified to match. The changes are mainly that it uses `size_t` instead
|
||||
`unsigned int` for string lengths, but it also uses `long long` instead of
|
||||
`long` for JSON integer values, which was the main motivation for the upgrade.
|
||||
|
||||
The self-tests that YAJL comes with have been imported and are now run as an
|
||||
EPICS Unit Test program, and the JSON syntax accepted by the parser was
|
||||
extended to permit trailing commas in both arrays and maps. The difference
|
||||
between the old and new YAJL APIs can be detected at compile time by looking
|
||||
for the macro `EPICS_YAJL_VERSION` which is defined in the `yajl_common.h`
|
||||
header file along with a brief description of the API changes.
|
||||
|
||||
### Timestamp support for the calc link type
|
||||
|
||||
A new optional parameter can be given when specifying a calc JSON link. The
|
||||
`time` parameter is a string containing a single letter `A..L` that selects
|
||||
one of the input links to be used for the timestamp of calculation if
|
||||
requested. The timestamp will be fetched atomically with the value from the
|
||||
chosen input link (providing that input link type supports the readLocked()
|
||||
method).
|
||||
|
||||
### Silence errors from puts to constant link types
|
||||
|
||||
A soft channel output record with the OUT link unset uses the CONSTANT link
|
||||
type. The new link type code was causing some soft channel device supports to
|
||||
return an error status from the write method of that link type, which would
|
||||
cause a `ca_put()` operation to such a record to generate an exception. This has
|
||||
been silenced by giving the constant link types a dummy putValue method. A new
|
||||
test program has been added to prevent regressions of this behaviour.
|
||||
|
||||
### RSRV expanding large buffer causes crash
|
||||
|
||||
In the 3.16.1 release a crash can occur in the IOC's RSRV server when a large
|
||||
array is made even larger; the previous array buffer was not being released
|
||||
correctly. See Launchpad
|
||||
[bug #1706703](https://bugs.launchpad.net/epics-base/+bug/1706703).
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.16.0.1 and 3.16.1
|
||||
|
||||
### IOC Database Support for 64-bit integers
|
||||
|
||||
The IOC now supports the 64-bit integer field types `DBF_INT64` and
|
||||
`DBF_UINT64`, and there are new record types `int64in` and `int64out` derived
|
||||
from the `longin` and `longout` types respectively that use the `DBF_INT64`
|
||||
data type for their VAL and related fields. The usual range of Soft Channel
|
||||
device support are included for these new record types.
|
||||
|
||||
All internal IOC APIs such as dbAccess can handle the new field types and
|
||||
their associated request values `DBR_INT64` and `DBR_UINT64`, which are
|
||||
implemented using the `epicsInt64` and `epicsUInt64` typedef's from the
|
||||
`epicsTypes.h` header.
|
||||
|
||||
The waveform record type has been updated to support these new field types.
|
||||
**All waveform device support layers must be updated to recognize the new type
|
||||
enumeration values**, which had to be inserted before the `FLOAT` value in the
|
||||
enum `dbfType` and in `menuFtype`. C or C++ code can detect at compile-time
|
||||
whether this version of base provides 64-bit support by checking for the
|
||||
presence of the `DBR_INT64` macro as follows (Note that `DBF_INT64` is an
|
||||
enum tag and not a preprocessor macro):
|
||||
|
||||
```
|
||||
#ifdef DBR_INT64
|
||||
/* Code where Base has INT64 support */
|
||||
#else
|
||||
/* Code for older versions */
|
||||
#endif
|
||||
```
|
||||
|
||||
If the code uses the old `db_access.h` types (probably because it's calling
|
||||
Channel Access APIs) then it will have to test against the EPICS version
|
||||
number instead, like this:
|
||||
|
||||
```
|
||||
#include <epicsVersion.h>
|
||||
|
||||
#ifndef VERSION_INT
|
||||
# define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
|
||||
#endif
|
||||
#ifndef EPICS_VERSION_INT
|
||||
# define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
|
||||
#endif
|
||||
|
||||
#if EPICS_VERSION_INT >= VERSION_INT(3,16,1,0)
|
||||
/* Code where Base has INT64 support */
|
||||
#else
|
||||
/* Code for older versions */
|
||||
#endif
|
||||
```
|
||||
|
||||
Channel Access does not (and probably never will) directly support 64-bit
|
||||
integer types, so the new field types are presented to the CA server as
|
||||
`DBF_DOUBLE` values. This means that field values larger than 2^52
|
||||
(0x10\_0000\_0000\_0000 = 4503599627370496) cannot be transported over Channel
|
||||
Access without their least significant bits being truncated. The EPICS V4
|
||||
pvAccess network protocol _can_ transport 64-bit data types however, and a
|
||||
future release of the pvaSrv module will connect this ability to the fields of
|
||||
the IOC.
|
||||
|
||||
Additional 64-bit support will be provided in later release. For instance the
|
||||
JSON parser for the new Link Support feature only handles integers up to 32
|
||||
bits wide, so constant array initializer values cannot hold larger values in
|
||||
this release.
|
||||
|
||||
### Add `EPICS_CA_MCAST_TTL`
|
||||
|
||||
A new environment parameter `EPICS_CA_MCAST_TTL` is used to set the Time To Live
|
||||
(TTL) value of any IP multi-cast CA search or beacon packets sent.
|
||||
|
||||
### `EPICS_CA_MAX_ARRAY_BYTES` is optional
|
||||
|
||||
A new environment parameter `EPICS_CA_AUTO_ARRAY_BYTES` is now used by libca and
|
||||
RSRV (CA clients and the IOC CA server). The default is equivalent to setting
|
||||
`EPICS_CA_AUTO_ARRAY_BYTES=YES` which removes the need to set
|
||||
`EPICS_CA_MAX_ARRAY_BYTES` and always attempts to allocate sufficiently large
|
||||
network buffers to transfer large arrays properly over the network. In this case
|
||||
the value of the `EPICS_CA_MAX_ARRAY_BYTES` parameter is ignored.
|
||||
|
||||
Explicitly setting `EPICS_CA_AUTO_ARRAY_BYTES=NO` will continue to honor the
|
||||
buffer setting in `EPICS_CA_AUTO_ARRAY_BYTES` as in previous releases.
|
||||
|
||||
The default setting for `EPICS_CA_AUTO_ARRAY_BYTES` can be changed by adding the
|
||||
line
|
||||
|
||||
```makefile
|
||||
EPICS_CA_AUTO_ARRAY_BYTES=NO
|
||||
```
|
||||
|
||||
to the `configure/CONFIG_SITE_ENV` file before building Base. Sites that wish to
|
||||
override this only for specific IOC architectures can create new files for each
|
||||
architecture named `configure/os/CONFIG_SITE_ENV.<target-arch>` with the above
|
||||
setting in before building Base. The configuration can also be explicitly
|
||||
changed by setting the environment variable in the IOC's startup script,
|
||||
anywhere above the `iocInit` line.
|
||||
|
||||
The PCAS server (used by the PV Gateway and other CA servers) now always behaves
|
||||
as if `EPICS_CA_AUTO_ARRAY_BYTES` is set to `YES` (it ignores the configuration
|
||||
parameter and environment variable).
|
||||
|
||||
### Channel Access "modernization"
|
||||
|
||||
Drop support for CA clients advertising protocol versions less than 4.
|
||||
|
||||
This effects clients from Base older than 3.12.0-beta1. Newer clients will
|
||||
continue to be able to connect to older servers. Older clients will be ignored
|
||||
by newer servers.
|
||||
|
||||
This allows removal of UDP echo and similar protocol features which are not
|
||||
compatible with secure protocol design practice.
|
||||
|
||||
### Lookup-tables using the subArrray record
|
||||
|
||||
The subArray record can now be used as a lookup-table from a constant array
|
||||
specified in its INP field. For example:
|
||||
|
||||
```
|
||||
record(subArray, "powers-of-2") {
|
||||
field(FTVL, "LONG")
|
||||
field(MALM, 12)
|
||||
field(INP, [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048])
|
||||
field(INDX, 0)
|
||||
field(NELM, 1)
|
||||
}
|
||||
```
|
||||
|
||||
The INDX field selects which power of 2 to set the VAL field to. In previous
|
||||
releases the INP field would have to have been pointed to a separate waveform
|
||||
record that was initialized with the array values somehow at initialization
|
||||
time.
|
||||
|
||||
### Synchronized Timestamps with TSEL=-2
|
||||
|
||||
Most Soft Channel input device support routines have supported fetching the
|
||||
timestamp through the INP link along with the input data. However before now
|
||||
there was no guarantee that the timestamp provided by a CA link came from the
|
||||
same update as the data, since the two were read from the CA input buffer at
|
||||
separate times without maintaining a lock on that buffer in between. This
|
||||
shortcoming could be fixed as a result of the new link support code, which
|
||||
allows code using a link to pass a subroutine to the link type which will be
|
||||
run with the link locked. The subroutine may make multiple requests for
|
||||
metadata from the link, but must not block.
|
||||
|
||||
### Extensible Link Types
|
||||
|
||||
A major new feature introduced with this release of EPICS Base is an
|
||||
Extensible Link Type mechanism, also known as Link Support or JSON Link Types.
|
||||
This addition permits new kinds of link I/O to be added to an IOC in a similar
|
||||
manner to the other extension points already supported (e.g. record, device
|
||||
and driver support).
|
||||
|
||||
A new link type must implement two related APIs, one for parsing the JSON
|
||||
string which provides the link address and the other which implements the link
|
||||
operations that get called at run-time to perform I/O. The link type is built
|
||||
into the IOC by providing a new `link` entry in a DBD file.
|
||||
|
||||
#### New Link Types Added
|
||||
|
||||
This release contains two new JSON link types, `const` and `calc`:
|
||||
|
||||
* The `const` link type is almost equivalent to the old CONSTANT link type
|
||||
with the updates described below to accept arrays and strings, except that
|
||||
there is no need to wrap a scalar string constant inside array brackets since
|
||||
a constant string will never be confused with a PV name.
|
||||
|
||||
* The `calc` link type allows CALC expressions to be used to combine
|
||||
values from other JSON links to produce its value. Until additional JSON link
|
||||
types are created though, the `calc` link type has little practical utility as
|
||||
it can currently only fetch inputs from other `calc` links or from `const`
|
||||
links.
|
||||
|
||||
```
|
||||
field(INP, {calc:{expr:"A+B+1",
|
||||
args:[5, # A
|
||||
{const:6}] # B
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
The new link types are documented in a separate document that gets generated at build time and installed as `html/links.html`.
|
||||
|
||||
#### Device Support Addressing using `JSON_LINK`
|
||||
|
||||
The API to allow device support to use JSON addresses is currently
|
||||
incomplete; developers are advised not to try creating device support that
|
||||
specifies a `JSON_LINK` address type.
|
||||
|
||||
#### Support Routine Modifications for Extensible Link Types
|
||||
|
||||
For link fields in external record types and soft device support to be able
|
||||
to use the new link types properly, various changes are required to utilize
|
||||
the new Link Support API as defined in the dbLink.h header file and outlined
|
||||
below. The existing built-in Database and Channel Access link types have been
|
||||
altered to implement the link APIs, so will work properly after these
|
||||
conversions:
|
||||
|
||||
* Make all calls to `recGblInitConstantLink()` unconditional on the link
|
||||
type, i.e. change this code:
|
||||
|
||||
```C
|
||||
if (prec->siml.type == CONSTANT) {
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
}
|
||||
```
|
||||
|
||||
into this:
|
||||
|
||||
```C
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
```
|
||||
|
||||
Note that `recGblInitConstantLink()` still returns TRUE if the field was
|
||||
successfully initialized from the link (implying the link is constant).
|
||||
This change will work properly with all Base releases currently in use.
|
||||
|
||||
* Code that needs to identify a constant link should be modified to use
|
||||
the new routine `dbLinkIsConstant()` instead, which returns TRUE for constant
|
||||
or undefined links, FALSE for links whose `dbGetLink()` routine may return
|
||||
different values on different calls. For example this:
|
||||
|
||||
```C
|
||||
if (prec->dol.type != CONSTANT)
|
||||
```
|
||||
|
||||
should become this:
|
||||
|
||||
```C
|
||||
if (!dbLinkIsConstant(&prec->dol))
|
||||
```
|
||||
|
||||
When the converted software is also required to build against older versions
|
||||
of Base, this macro definition may be useful:
|
||||
|
||||
```C
|
||||
#define dbLinkIsConstant(lnk) ((lnk)->type == CONSTANT)
|
||||
```
|
||||
|
||||
* Any code that calls dbCa routines directly, or that explicitly checks if
|
||||
a link has been resolved as a CA link using code such as
|
||||
|
||||
```C
|
||||
if (prec->inp.type == CA_LINK)
|
||||
```
|
||||
|
||||
will still compile and run, but will only work properly with the old CA link
|
||||
type. To operate with the new extensible link types such code must be
|
||||
modified to use the new generic routines defined in dbLink.h and should
|
||||
never attempt to examine or modify data inside the link. After conversion
|
||||
the above line would probably become:
|
||||
|
||||
```C
|
||||
if (dbLinkIsVolatile(&prec->inp))
|
||||
```
|
||||
|
||||
A volatile link is one like a Channel Access link which may disconnect and
|
||||
reconnect without notice at runtime. Database links and constant links are
|
||||
not volatile; unless their link address is changed they will always remain
|
||||
in the same state they started in. For compatibility when building against
|
||||
older versions of Base, this macro definition may be useful:
|
||||
|
||||
```C
|
||||
#define dbLinkIsVolatile(lnk) ((lnk)->type == CA_LINK)
|
||||
```
|
||||
|
||||
* The current connection state of a volatile link can be found using the
|
||||
routine `dbIsLinkConnected()` which will only return TRUE for a volatile link
|
||||
that is currently connected. Code using the older dbCa API returning this
|
||||
information used to look like this:
|
||||
|
||||
```C
|
||||
stat = dbCaIsLinkConnected(plink);
|
||||
```
|
||||
|
||||
which should become:
|
||||
|
||||
```C
|
||||
stat = dbIsLinkConnected(plink);
|
||||
```
|
||||
|
||||
Similar changes should be made for calls to the other dbCa routines.
|
||||
|
||||
* A full example can be found by looking at the changes to the calcout
|
||||
record type, which has been modified in this release to use the new dbLink
|
||||
generic API.
|
||||
|
||||
### Constant Link Values
|
||||
|
||||
Previously a constant link (i.e. a link that did not point to another PV,
|
||||
either locally or over Channel Access) was only able to provide a single
|
||||
numeric value to a record initialization; any string given in a link field
|
||||
that was not recognized as a number was treated as a PV name. In this release,
|
||||
constant links can be expressed using JSON array syntax and may provide array
|
||||
initialization of values containing integers, doubles or strings. An array
|
||||
containing a single string value can also be used to initialize scalar
|
||||
strings, so the stringin, stringout, lsi (long string input), lso (long string
|
||||
output), printf, waveform, subArray and aai (analog array input) record types
|
||||
and/or their soft device supports have been modified to support this.
|
||||
|
||||
Some examples of constant array and string initialized records are:
|
||||
|
||||
```
|
||||
record(stringin, "const:string") {
|
||||
field(INP, ["Not-a-PV-name"])
|
||||
}
|
||||
record(waveform, "const:longs") {
|
||||
field(FTVL, LONG)
|
||||
field(NELM, 10)
|
||||
field(INP, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
}
|
||||
record(aai, "const:doubles") {
|
||||
field(FTVL, DOUBLE)
|
||||
field(NELM, 10)
|
||||
field(INP, [0, 1, 1.6e-19, 2.718, 3.141593])
|
||||
}
|
||||
record(aSub, "select") {
|
||||
field(FTA, STRING)
|
||||
field(NOA, 4)
|
||||
field(INPA, ["Zero", "One", "Two", "Three"])
|
||||
field(FTB, SHORT)
|
||||
field(NOB, 1)
|
||||
field(FTVA, STRING)
|
||||
field(NOVA, 1)
|
||||
field(SNAM, "select_asub")
|
||||
}
|
||||
```
|
||||
|
||||
Reminder: Link initialization with constant values normally only occurs at
|
||||
record initialization time. The calcout and printf record types are the only
|
||||
exceptions in the Base record types to this rule, so it is generally not
|
||||
useful to change a const link value after iocInit.
|
||||
|
||||
### Database Parsing of "Relaxed JSON" Values
|
||||
|
||||
A database file can now provide a "relaxed JSON" value for a database field
|
||||
value or an info tag. Only a few field types can currently accept such values,
|
||||
but the capability is now available for use in other places in the future.
|
||||
When writing to a JSON-capable field at run-time however, only strictly
|
||||
compliant JSON may be used (the dbStaticLib parser rewrites relaxed JSON
|
||||
values into strict JSON before passing them to the datase for interpretation,
|
||||
where the strict rules must be followed).
|
||||
|
||||
"Relaxed JSON" was developed to maximize compatibility with the previous
|
||||
database parser rules and reduce the number of double-quotes that would be
|
||||
needed for strict JSON syntax. The parser does accept strict JSON too though,
|
||||
which should be used when machine-generating database files. The differences
|
||||
are:
|
||||
|
||||
* Strings containing only the characters `a-z A-Z 0-9 _ - + .` do not have to
|
||||
be enclosed in double-quote characters.
|
||||
|
||||
* The above rule applies to map keys as well as to regular string values.
|
||||
|
||||
* The JSON keywords `null`, `true` and `false` (all lower-case) will be
|
||||
recognized as keywords, so they must be quoted to use any of these single words
|
||||
as a string.
|
||||
|
||||
* Comments may be used, introduced as usual by the `#` character and extending
|
||||
to the end of the line.
|
||||
|
||||
A JSON field or info value is only enclosed in quotes when the value being
|
||||
provided is a single string, and even here the quotes can be omitted in some
|
||||
cases as described above. The following shows both correct and incorrect
|
||||
excerpts from a database file:
|
||||
|
||||
```
|
||||
record(ai, math:pi) {
|
||||
field(INP, {const: 3.14159265358979}) # Correct
|
||||
field(SIOL, "{const: 3.142857}") # Wrong
|
||||
|
||||
info(autosave, { # White-space and comments are allowed
|
||||
fields:[DESC, SIMM],
|
||||
pass0:[VAL]
|
||||
}) # Correct
|
||||
}
|
||||
```
|
||||
|
||||
Note that the record, field and info-tag names do *not* accept JSON values, so
|
||||
they follows the older bareword rules for quoting where the colon `:` and
|
||||
several additional characters are legal in a bareword string. Only the value
|
||||
(after the comma) is parsed as JSON. The autosave module has not been modified
|
||||
to accept JSON syntax, the above is only an example of how JSON might be used.
|
||||
|
||||
### Echoless comments in iocsh
|
||||
|
||||
The way comments are parsed by the iocsh interpreter has changed. The
|
||||
interpreter can be selectively disabled from echoing comments coming from a
|
||||
script by starting those lines with `#-` rather than just `#`.
|
||||
|
||||
### Typed record support methods
|
||||
|
||||
The table of record support functions (rset methods for short) no longer has
|
||||
entries of type `RECSUPFUN` (which says: any number and type of arguments).
|
||||
Instead, rset methods are now typed by default. The `RECSUPFUN` typedef has
|
||||
been deprecated and casts to it as well as using the untyped `struct rset`
|
||||
will create compilation warnings.
|
||||
|
||||
Existing code (e.g. external record supports) will generate such warnings when
|
||||
compiled against this version of Base, but it will work without changes.
|
||||
|
||||
For a conversion period, the new typed rset definitions are activated by
|
||||
defining `USE_TYPED_RSET`, preferably by setting `USR_CPPFLAGS +=
|
||||
-DUSE_TYPED_RSET` inside a Makefile. After activating the new typed rset in
|
||||
this way and making the following changes, the result should still compile and
|
||||
work properly against older versions of Base.
|
||||
|
||||
The first parameter of `init_record` and `process` has been changed to `struct
|
||||
dbCommon *`. Record types that use `void*` here should be changed to use
|
||||
`struct dbCommon*`, and cast the argument to their own `xxxRecord *`.
|
||||
|
||||
When compiled against this release, compiler warnings about incompatible types
|
||||
for the method pointers should be taken seriously. When compiled against older
|
||||
versions of base, such warnings are unavoidable.
|
||||
|
||||
Record types written in C++ need to take more drastic measures because of the
|
||||
stricter type checking in C++. To remain compatible with older versions of
|
||||
base you will need to use something like:
|
||||
|
||||
```
|
||||
#include "epicsVersion.h"
|
||||
#ifdef VERSION_INT
|
||||
# if EPICS_VERSION_INT < VERSION_INT(3,16,0,2)
|
||||
# define RECSUPFUN_CAST (RECSUPFUN)
|
||||
# else
|
||||
# define RECSUPFUN_CAST
|
||||
# endif
|
||||
#else
|
||||
# define RECSUPFUN_CAST (RECSUPFUN)
|
||||
#endif
|
||||
```
|
||||
|
||||
and then replace `(RECSUPFUN)` with `RECSUPFUN_CAST` when initializing the
|
||||
rset. Further changes might also be needed, e.g. to adapt `const`-ness of
|
||||
method parameters.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.3 and 3.16.0.1
|
||||
|
||||
### Build support for CapFast and dbst removed
|
||||
|
||||
The build rules associated with the CapFast-related tools `sch2edif` and
|
||||
`e2db` and the database optimization tool `dbst` have been removed, along with
|
||||
the `DB_OPT` build configuration variable.
|
||||
|
||||
### compressRecord buffering order
|
||||
|
||||
The compressRecord has a new field `BALG` which can select between FIFO
|
||||
(append) and LIFO (prepend) ordering for insertion of new elements. FIFO
|
||||
ordering is the default, matching the behviour of previous versions.
|
||||
|
||||
### Valgrind Instrumentation
|
||||
|
||||
Valgrind is a software debugging suite provided by many Linux distributions.
|
||||
The header valgrind/valgrind.h is now included in, and installed by, Base.
|
||||
When included by a C or C++ source file this header defines some macros which
|
||||
expand to provide hints to the Valgrind runtime. These have no effect on
|
||||
normal operation of the software, but when run using the valgrind tool they
|
||||
can help to find memory leaks and buffer overflows. Suitable hints have been
|
||||
added to several free-lists within libCom, including freeListLib, allowing
|
||||
valgrind to provide more accurate information about the source of potential
|
||||
leaks.
|
||||
|
||||
valgrind.h automatically disables itself when the build target is not
|
||||
supported by the valgrind tool. It can also explicitly be disabled by defining
|
||||
the macro `NVALGRIND`. See `src/libCom/Makefile` for a commented-out example.
|
||||
|
||||
As a matter of policy valgrind.h will never be included by any header file
|
||||
installed by Base, so its use will remain purely an implementation detail
|
||||
hidden from application software. Support modules which choose to use
|
||||
valgrind.h are advised to do likewise.
|
||||
|
||||
### Database Multi-locking
|
||||
|
||||
The IOC record locking code has been re-written with an expanded API; global
|
||||
locks are no longer required by the IOC database implementation.
|
||||
|
||||
The new API functions center around `dbScanLockMany()`, which behaves like
|
||||
`dbScanLock()` applied to an arbitrary group of records. `dbLockerAlloc()` is
|
||||
used to prepare a list or record pointers, then `dbScanLockMany()` is called.
|
||||
When it returns, all of the records listed may be accessed (in any order) until
|
||||
`dbScanUnlockMany()` is called.
|
||||
|
||||
The Application Developer's Guide has been updated to describe the API and
|
||||
implementation is more detail.
|
||||
|
||||
Previously a global mutex `lockSetModifyLock` was locked and unlocked during
|
||||
`dbScanLock()`, acting as a sequencing point for otherwise unrelated calls. The
|
||||
new dbLock.c implementation does not include any global mutex in `dbScanLock()`
|
||||
or `dbScanLockMany()`. Locking and unlocking of unrelated lock sets is now
|
||||
completely concurrent.
|
||||
|
||||
### Generate Version Header
|
||||
|
||||
A Perl script and Makefile rules have been added to allow modules to generate
|
||||
a C header file with a macro defined with an automatically updated identifier.
|
||||
This is a VCS revision ID (Darcs, Git, Mercurial, Subversion, and Bazaar are
|
||||
supported) or the date/time of the build if no VCS system is in use.
|
||||
|
||||
The makeBaseApp example template has been updated with a new device support
|
||||
which makes this identifier visible via a lsi (long string input) record.
|
||||
|
||||
### epicsTime API return status
|
||||
|
||||
The epicsTime routines that used to return epicsTimeERROR now return a
|
||||
specific `S_time_` status value, allowing the caller to discover the reason for
|
||||
any failure. The identifier `epicsTimeERROR` is no longer defined, so any
|
||||
references to it in source code will no longer compile. The identifier
|
||||
epicsTimeOK still exists and has the value 0 as before, so most code that uses
|
||||
these APIs can be changed in a way that is backwards-compatible with the
|
||||
previous return status.
|
||||
|
||||
Time providers that have to return a status value and still need to be built
|
||||
with earlier versions of Base can define the necessary status symbols like
|
||||
this:
|
||||
|
||||
```
|
||||
#include "epicsTime.h"
|
||||
|
||||
#ifndef M_time
|
||||
/* S_time_... status values were not provided before Base 3.16 */
|
||||
#define S_time_unsynchronized epicsTimeERROR
|
||||
#define S_time_...whatever... epicsTimeERROR
|
||||
#endif
|
||||
```
|
||||
|
||||
### Refactoring of epicsReadline
|
||||
|
||||
The epicsReadline code has been reorganized to allow the commandline history
|
||||
editor to be disabled at runtime. The `EPICS_COMMANDLINE_LIBRARY` build setting
|
||||
still selects the preferred editor, but the new `IOCSH_HISTEDIT_DISABLE`
|
||||
environment variable can be set at runtime to disable history editing and make
|
||||
the IOC or other program use the basic editor instead. This is useful when
|
||||
starting and controlling an IOC from another program through its stdin and
|
||||
stdout streams since history editors often insert invisible escape codes into
|
||||
the stdout stream, making it hard to parse.
|
||||
|
||||
### Callback subsystem API
|
||||
|
||||
Added a new macro `callbackGetPriority(prio, callback)` to the callback.h
|
||||
header and removed the need for dbScan.c to reach into the internals of its
|
||||
`CALLBACK` objects.
|
||||
65
documentation/RELEASE-7.0.1.1.md
Normal file
65
documentation/RELEASE-7.0.1.1.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
## EPICS Release 7.0.1.1
|
||||
|
||||
### Changed SIML failure behavior
|
||||
|
||||
A failure when fetching the simulation mode through `SIML` will not put the
|
||||
record into INVALID alarm state anymore. Instead, as long as the record's
|
||||
current alarm severity (`SEVR`)is `NO_ALARM`, its alarm status (`STAT`) will be
|
||||
set to `LINK_ALARM` without increasing the severity. This allows clients to get
|
||||
some notification of a failing or bad `SIML` link without otherwise affecting
|
||||
record processing.
|
||||
|
||||
### `dbVerify()` has been restored to dbStaticLib
|
||||
|
||||
This routine was removed in Base-3.16.1 but has been reimplemented in this
|
||||
release by special request. Note that the error message strings that it
|
||||
returns when verification fails have changed, but are still designed for
|
||||
display to the user.
|
||||
|
||||
### Simulation mode improvements
|
||||
|
||||
Records that support simulation mode have two new fields, `SSCN` (Simulation
|
||||
Scan Mode) and `SDLY` (Simulation Delay). `SSCN` is a menu field that provides
|
||||
an alternate value for the `SCAN` field to be used while the record is in
|
||||
simulation mode. This is especially useful for I/O scanned records, for which
|
||||
simulation mode was not working at all. Setting `SDLY` to a positive value
|
||||
makes the record process asynchronously in simulation mode, with the second
|
||||
stage processing happening after the specified time (in seconds).
|
||||
|
||||
### Extend the dbServer API with init/run/pause/stop methods
|
||||
|
||||
This change permits IOCs to be built that omit the CA server (RSRV) by
|
||||
removing its registrar entry which is now provided in the new `rsrv.dbd` file.
|
||||
Other server layers can be built into the IOC (alongside RSRV or in place of
|
||||
it) by registering them in a similar manner. The dbServer API is documented
|
||||
with Doxygen comments in the header file.
|
||||
|
||||
Specific IOC server layers can be disabled at runtime by adding their name to
|
||||
the environment variable `EPICS_IOC_IGNORE_SERVERS` (separated by spaces if more
|
||||
than one should be ignored).
|
||||
|
||||
### Grand source-code reorganization
|
||||
|
||||
EPICS 7.0.1 contains the IOC Database, RSRV server and the Channel Access
|
||||
client code from EPICS Base 3.16.1 along with all the original record types
|
||||
and soft device support, but GDD and the Portable Channel Access Server have
|
||||
been unbundled and are now available separately. In their place we have
|
||||
brought in the more recently written EPICS V4 C++ libraries (collectively
|
||||
referred to as the PVA modules). The directory tree for EPICS is somewhat
|
||||
larger as a result, and the original structure of the Base directories has
|
||||
been split into 4 separate Git repositories. External modules should build
|
||||
against this new structure with little or no changes needed, except that some
|
||||
allowance may be needed for the merging of the V4 modules.
|
||||
|
||||
There should be rather more description and documantation of these changes
|
||||
than is currently available, but as developers we generally much prefer to
|
||||
write code than documentation. Send questions to the tech-talk mailing list
|
||||
and we'll be happy to try and answer them!
|
||||
58
documentation/RELEASE-7.0.2.1.md
Normal file
58
documentation/RELEASE-7.0.2.1.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
## EPICS Release 7.0.2.1
|
||||
|
||||
### Linking shared libraries on macOS
|
||||
|
||||
The linker flag `-flat_namespace` 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.
|
||||
|
||||
### Fix `DB_LINK` loop breaking
|
||||
|
||||
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.
|
||||
|
||||
Instead in 7.0.2 the targeted record would be processed if processing began
|
||||
with a remote action (or some other caller of `dbPutField()`). This would
|
||||
result in the loop running a second time. The loop would be broken on the
|
||||
second iteration.
|
||||
|
||||
[See lp: #1809570](https://bugs.launchpad.net/epics-base/+bug/1809570)
|
||||
|
||||
### Old dbStaticLib APIs removed
|
||||
|
||||
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:
|
||||
|
||||
* `int dbGetFieldType(DBENTRY *pdbentry)`
|
||||
* `int dbGetLinkType(DBENTRY *pdbentry)`
|
||||
* `DCT_STRING`
|
||||
* `DCT_INTEGER`
|
||||
* `DCT_REAL`
|
||||
* `DCT_MENU`
|
||||
* `DCT_MENUFORM`
|
||||
* `DCT_INLINK`
|
||||
* `DCT_OUTLINK`
|
||||
* `DCT_FWDLINK`
|
||||
* `DCT_NOACCESS`
|
||||
* `DCT_LINK_CONSTANT`
|
||||
* `DCT_LINK_FORM`
|
||||
* `DCT_LINK_PV`
|
||||
|
||||
### Fix for `dbhcr` before `iocInit`
|
||||
|
||||
The `dbhcr` command used to work before `iocInit` 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.
|
||||
41
documentation/RELEASE-7.0.2.2.md
Normal file
41
documentation/RELEASE-7.0.2.2.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
## EPICS Release 7.0.2.2
|
||||
|
||||
### Build System changes
|
||||
|
||||
* The GNUmake build targets `cvsclean` and `depclean` are now available from
|
||||
any directory; previously they were only available from application top
|
||||
directories.
|
||||
|
||||
* The approach that EPICS Base uses for building submodules inside the parent
|
||||
module looks useful for support modules too. The rules for building submodules
|
||||
have been modified and extracted into a new `RULES_MODULES` file, so a support
|
||||
module will be able to use them too without having to copy them into its own
|
||||
`modules/Makefile`. There are some specific requirements that support modules
|
||||
and their submodules must follow, which are described as comments in the new
|
||||
`base/configure/RULES_MODULES` file itself.
|
||||
|
||||
### `EPICS_BASE_VERSION` Update Policy change
|
||||
|
||||
In the past, a build of EPICS using sources checked out from the repository
|
||||
branch between official releases would have shown the version number of the
|
||||
previous release, followed by a -DEV suffix, for example 7.0.2.1-DEV.
|
||||
|
||||
The policy that controls when the number gets updated has been changed, and
|
||||
now immediately after a release has been tagged the version number will be
|
||||
updated to the next patch release version, plus the -DEV suffix as before.
|
||||
Thus following 7.0.2.2 the version number will show as 7.0.2.3-DEV. This does
|
||||
not require the next official release to be numbered 7.0.2.3 though, it could
|
||||
become 7.0.3 or even 7.1.0 if the changes incorporated into it are more
|
||||
substantial than bug fixes.
|
||||
|
||||
### Drop `CLOCK_MONOTONIC_RAW` from posix/osdMonotonic.c
|
||||
|
||||
Turns out this is ~10x slower to query than `CLOCK_MONOTONIC`.
|
||||
24
documentation/RELEASE-7.0.2.md
Normal file
24
documentation/RELEASE-7.0.2.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
## EPICS Release 7.0.2
|
||||
|
||||
### Launchpad Bugs
|
||||
|
||||
The list of tracked bugs fixed in this release can be found on the
|
||||
[Launchpad Milestone page for EPICS Base 7.0.2](https://launchpad.net/epics-base/+milestone/7.0.2).
|
||||
|
||||
### Git Branches Recombined
|
||||
|
||||
The four separate Git branches `core/master`, `libcom/master`, `ca/master` and
|
||||
`database/master` have been recombined into one branch called `7.0`. Keeping
|
||||
these as 4 separate branches in the same repository made it impossible to
|
||||
create merge requests that contained changes in more than one of these
|
||||
modules. The layout of the source files has not changed at all however, so the
|
||||
source code for libcom, ca and the database are still found separately under
|
||||
the module subdirectory.
|
||||
200
documentation/RELEASE-7.0.3.1.md
Normal file
200
documentation/RELEASE-7.0.3.1.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
## EPICS Release 7.0.3.1
|
||||
|
||||
**IMPORTANT NOTE:** *Some record types in this release will not be compatible
|
||||
with device support binaries compiled against earlier versions of those record
|
||||
types, because importing the record documentation from the EPICS Wiki
|
||||
[as described below](#imported-record-reference-documentation-from-wiki)
|
||||
also modified the order of some of the fields in the record definitions.*
|
||||
As long as all support modules and IOCs are rebuilt from source after updating
|
||||
them to use this release of EPICS Base, these changes should not have any
|
||||
affect.
|
||||
|
||||
|
||||
### logClient reliability
|
||||
|
||||
On supported targets (Linux, Mac, Windows) logClient will attempt to avoid dropping
|
||||
undelivered log messages when the connection to the log server is closed/reset.
|
||||
|
||||
### Timers and delays use monotonic clock
|
||||
|
||||
Many internal timers and delay calculations use a monotonic clock
|
||||
epicsTimeGetMonotonic() instead of the realtime epicsTimeGetCurrent(). This is
|
||||
intended to make IOCs less susceptible to jumps in system time.
|
||||
|
||||
### Iocsh `on error ...`
|
||||
|
||||
A new statement is added to enable IOC shell commands to signal error
|
||||
conditions, and for scripts to respond. This first is through the new function
|
||||
|
||||
```C
|
||||
int iocshSetError(int err);
|
||||
```
|
||||
|
||||
A script may be prefixed with eg. "on error break" to stop at the failed
|
||||
command.
|
||||
|
||||
```sh
|
||||
on error continue | break | wait [value] | halt
|
||||
```
|
||||
|
||||
A suggested form for IOC shell commands is:
|
||||
|
||||
```C
|
||||
static void doSomethingCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
iocshSetError(doSomething(...)); /* return 0 == success */
|
||||
}
|
||||
```
|
||||
|
||||
### Relocatable Builds
|
||||
|
||||
Allows built trees to be copied or moved without invalidating RPATH entires.
|
||||
|
||||
The `LINKER_USE_RPATH` Makefile variable (see `configure/CONFIG_SITE`) may be
|
||||
set to `YES`, `NO`, and a new third option `ORIGIN`. This is limited to
|
||||
targets using the ELF executable format (eg. Linux).
|
||||
|
||||
When `LINKER_USE_RPATH=ORIGIN`, the variable `LINKER_ORIGIN_ROOT` is set to
|
||||
one of the parents of the build directory. Any libraries being linked
|
||||
to which are found under this root will have a relative RPATH entry.
|
||||
Other libraries continue to result in absolute RPATH entries.
|
||||
|
||||
An effect of this might change a support library from being linked with
|
||||
`-Wl,-rpath /build/epics-base/lib/linux-x86`
|
||||
to being linked with
|
||||
`-Wl,-rpath \$ORIGIN/../../../epics-base/lib/linux-x86`
|
||||
if the support module directory is `/build/mymodule`
|
||||
and `LINKER_ORIGIN_ROOT=/build`.
|
||||
|
||||
The API functions `epicsGetExecDir()` and `epicsGetExecName()` are also
|
||||
added to `osiFileName.h` to provide runtime access to the directory or
|
||||
filename of the executable with which the process was started.
|
||||
|
||||
### Decouple `LINKER_USE_RPATH` and `STATIC_BUILD`
|
||||
|
||||
Previously, setting `STATIC_BUILD=NO` implied `LINKER_USE_RPATH=NO`.
|
||||
This is no longer the case. Setting `LINKER_USE_RPATH=YES` will
|
||||
always emit RPATH entries. This was found to be helpful when linking
|
||||
against some 3rd party libraries which are only available as shared objects.
|
||||
|
||||
### Channel Access Security: Check Hostname Against DNS
|
||||
|
||||
Host names given in a `HAG` entry of an IOC's Access Security Configuration
|
||||
File (ACF) have to date been compared against the hostname provided by the CA
|
||||
client at connection time, which may or may not be the actual name of that
|
||||
client. This allows rogue clients to pretend to be a different host, and the
|
||||
IOC would believe them.
|
||||
|
||||
An option is now available to cause an IOC to ask its operating system to look
|
||||
up the IP address of any hostnames listed in its ACF (which will normally be
|
||||
done using the DNS or the `/etc/hosts` file). The IOC will then compare the
|
||||
resulting IP address against the client's actual IP address when checking
|
||||
access permissions at connection time. This name resolution is performed at
|
||||
ACF file load time, which has a few consequences:
|
||||
|
||||
1. If the DNS is slow when the names are resolved this will delay the process
|
||||
of loading the ACF file.
|
||||
|
||||
2. If a host name cannot be resolved the IOC will proceed, but this host name
|
||||
will never be matched.
|
||||
|
||||
3. Any changes in the hostname to IP address mapping will not be picked up by
|
||||
the IOC unless and until the ACF file gets reloaded.
|
||||
|
||||
Optionally, IP addresses may be added instead of, or in addition to, host
|
||||
names in the ACF file.
|
||||
|
||||
This feature can be enabled before `iocInit` with
|
||||
|
||||
```
|
||||
var("asCheckClientIP",1)
|
||||
```
|
||||
|
||||
or with the VxWorks target shell use
|
||||
|
||||
```C
|
||||
asCheckClientIP = 1
|
||||
```
|
||||
|
||||
### New and modified epicsThread APIs
|
||||
|
||||
#### `epicsThreadCreateOpt()`
|
||||
|
||||
A new routine `epicsThreadCreateOpt()` is an alternative to
|
||||
`epicsThreadCreate()` which takes some arguments via a structure (`struct
|
||||
epicsThreadOpts`) to allow for future extensions.
|
||||
|
||||
```C
|
||||
typedef struct epicsThreadOpts {
|
||||
unsigned int priority;
|
||||
unsigned int stackSize;
|
||||
unsigned int joinable;
|
||||
} epicsThreadOpts;
|
||||
#define EPICS_THREAD_OPTS_INIT { \
|
||||
epicsThreadPriorityLow, epicsThreadStackMedium, 0}
|
||||
epicsThreadId epicsThreadCreateOpt(const char * name,
|
||||
EPICSTHREADFUNC funptr, void * parm, const epicsThreadOpts *opts);
|
||||
```
|
||||
|
||||
The final `opts` parameter may be `NULL` to use the default values of thread
|
||||
priority (low) and stack size (medium). Callers wishing to provide alternative
|
||||
settings for these thread options or to create a joinable thread (see below)
|
||||
should create and pass in an `epicsThreadOpts` structure as shown below.
|
||||
Always initialize one of these structures using the `EPICS_THREAD_OPTS_INIT`
|
||||
macro to ensure that any additional fields that get added in the future are
|
||||
set to their default values.
|
||||
|
||||
```C
|
||||
void startitup(void) {
|
||||
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
|
||||
epicsThreadId tid;
|
||||
|
||||
opts.priority = epicsThreadPriorityMedium;
|
||||
tid = epicsThreadCreateOpt("my thread", &threadMain, NULL, &opts);
|
||||
}
|
||||
```
|
||||
|
||||
C or C++ Code that also needs to build on earlier versions of Base can use
|
||||
`#ifdef EPICS_THREAD_OPTS_INIT` to determine whether the
|
||||
`epicsThreadCreateOpt()` API is available on this Base version.
|
||||
|
||||
#### Thread stack sizes
|
||||
|
||||
The `stackSize` member of the `epicsThreadOpts` structure and the equivalent
|
||||
parameters to the `epicsThreadCreate()` and `epicsThreadMustCreate()` routines
|
||||
can now be passed either one of the `epicsThreadStackSizeClass` enum values or
|
||||
a value returned from the `epicsThreadGetStackSize()` routine.
|
||||
|
||||
#### `epicsThreadMustJoin()`
|
||||
|
||||
If the new `joinable` flag of an `epicsThreadOpts` structure is non-zero (the
|
||||
default value is zero), the new API routine `epicsThreadMustJoin()` *must* be
|
||||
called with the thread's `epicsThreadId` when/after the thread exits, to free
|
||||
up thread resources. This function will block until the thread's main function
|
||||
has returned, allowing the parent to wait for its child thread. The child's
|
||||
`epicsThreadId` will no longer be valid and should not be used after the
|
||||
`epicsThreadMustJoin()` routine returns.
|
||||
|
||||
A thread that was originally created with its joinable flag set may itself
|
||||
call `epicsThreadMustJoin()`, passing in its own epicsThreadId. This marks the
|
||||
thread as no longer being joinable, so it will then free the thread resources
|
||||
itself when its main function returns. The `epicsThreadId` of a thread that is
|
||||
not joinable gets invalidated as soon as its main function returns.
|
||||
|
||||
### Non-VME RTEMS targets now define pdevLibVME
|
||||
|
||||
Previously IOC executables that made calls to devLib routines would fail to
|
||||
link when built for some non-VME based RTEMS targets, which would have to be
|
||||
explicitly filtered out by sites that build Base for those targets. [This
|
||||
fix](https://bugs.launchpad.net/epics-base/+bug/1841692) makes that no longer
|
||||
necessary, all RTEMS targets should now link although the IOC won't be able to
|
||||
be used with the VME I/O on those systems (that we don't have VMEbus I/O
|
||||
support for in libCom).
|
||||
27
documentation/RELEASE-7.0.3.md
Normal file
27
documentation/RELEASE-7.0.3.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
## EPICS Release 7.0.3
|
||||
|
||||
### `epicsTimeGetCurrent()` optimization
|
||||
|
||||
Add a fast path to epicsTimeGetCurrent() and related calls in the common case
|
||||
where only the default OS current time provider is registered. This path does
|
||||
not take the global mutex guarding the time providers list, potentially
|
||||
reducing lock contention.
|
||||
|
||||
### dbEvent tweak Queue size
|
||||
|
||||
The size of the queue used by dbEvent to push monitor updates has been
|
||||
slightly increased based on `DBR_TIME_DOUBLE` to better fill an ethernet frame.
|
||||
This may result in slightly fewer, but larger frames being sent.
|
||||
|
||||
### mbbo/mbbiDirect number of bits as precision
|
||||
|
||||
Report NOBT as "precision" through the dbAccess API. This is not accessible
|
||||
through CA, but is planned to be used through QSRV.
|
||||
54
documentation/RELEASE-7.0.4.1.md
Normal file
54
documentation/RELEASE-7.0.4.1.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
## EPICS Release 7.0.4.1
|
||||
|
||||
### ARM Architecture Changes
|
||||
|
||||
Build configuration files for a new cross-build architecture `linux-aarch64`
|
||||
have been added, and the targets `linux-arm_el` and `linux-arm_eb` removed.
|
||||
The 64-bit ARM architecture target doesn't have build files for self-hosting
|
||||
yet but they should be relatively easy to add, contributions welcome!
|
||||
|
||||
### Bug fixes
|
||||
|
||||
The following bugs/issues have fixes included in this release:
|
||||
|
||||
- [lp: 1884339](https://bugs.launchpad.net/epics-base/+bug/1884339),
|
||||
Inaccessible CA servers on Windows
|
||||
- [github: 83](https://github.com/epics-base/epics-base/issues/83)
|
||||
osdTimeGetCurrent doesn't work for subprocess on macOS
|
||||
- Recent Cygwin build problem with a missing `TCP_NODELAY` declaration.
|
||||
|
||||
### Perl CA Bindings under Conda
|
||||
|
||||
Builds of the Perl CA bindings weren't working properly when the Perl
|
||||
installation was from Conda. This release also fixed the capr.pl script
|
||||
to handle the INT64 data types, and to be able to properly handle missing
|
||||
fields, as happens if the IOC is running an older EPICS version for example.
|
||||
|
||||
### epicsMessageQueue implementation on RTEMS
|
||||
|
||||
The implementation of the `epicsMessageQueue` used on RTEMS has switched from
|
||||
the native RTEMS-specific one to the EPICS generic version, avoiding a bug
|
||||
in the RTEMS Kernel message queue code.
|
||||
|
||||
### Record Name Validation
|
||||
|
||||
Historically, there have been very few restrictions on which characters
|
||||
may be present in record and alias names. Base 3.14.12.3 added a warning
|
||||
for names containing space, single or double quote, period/dot, or
|
||||
dollar sign.
|
||||
|
||||
```
|
||||
Bad character ' ' in record name "bad practice"
|
||||
```
|
||||
|
||||
7.0.4.1 Turns this warning into an error, and adds a new warning
|
||||
if a record name begins with a minus, plus, left square bracket,
|
||||
or left curly bracket.
|
||||
191
documentation/RELEASE-7.0.4.md
Normal file
191
documentation/RELEASE-7.0.4.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
## EPICS Release 7.0.4
|
||||
|
||||
### Bug fixes
|
||||
|
||||
The following launchpad bugs have fixes included in this release:
|
||||
|
||||
- [lp: 1812084](https://bugs.launchpad.net/bugs/1812084), Build failure on
|
||||
RTEMS 4.10.2
|
||||
- [lp: 1829919](https://bugs.launchpad.net/bugs/1829919), IOC segfaults when
|
||||
calling dbLoadRecords after iocInit
|
||||
- [lp: 1838792](https://bugs.launchpad.net/bugs/1838792), epicsCalc bit-wise
|
||||
operators on aarch64
|
||||
- [lp: 1853148](https://bugs.launchpad.net/bugs/1853148), mingw compiler
|
||||
problem with printf/scanf formats
|
||||
- [lp: 1852653](https://bugs.launchpad.net/bugs/1852653), `USE_TYPED_DSET`
|
||||
incompatible with C++
|
||||
- [lp: 1862328](https://bugs.launchpad.net/bugs/1862328), Race condition on
|
||||
IOC start leaves rsrv unresponsive
|
||||
- [lp: 1866651](https://bugs.launchpad.net/bugs/1866651), thread joinable race
|
||||
- [lp: 1868486](https://bugs.launchpad.net/bugs/1868486), epicsMessageQueue
|
||||
lost messages
|
||||
- [lp: 1868680](https://bugs.launchpad.net/bugs/1868680), Access Security file
|
||||
reload (asInit) fails
|
||||
|
||||
### `*_API` macros in EPICS headers
|
||||
|
||||
Internally, the Com and ca libraries now express dllimport/export (Windows)
|
||||
and symbol visibility (GCC) using library-specific macros (eg. `LIBCOM_API`)
|
||||
instead of the macros `epicsShareFunc`, `epicsShareClass`, `epicsShareDef` etc.
|
||||
that are defined in the `shareLib.h` header.
|
||||
This change may affect some user code which uses the `epicsShare*` macros
|
||||
without having explicitly included the `shareLib.h` header themselves.
|
||||
Such code should be changed to include `shareLib.h` directly.
|
||||
|
||||
A new helper script `makeAPIheader.pl` and build rules to generate a
|
||||
library-specific `*API.h` header file has been added. Run `makeAPIheader.pl -h`
|
||||
for information on how to use this in your own applications, but note that the
|
||||
resulting sources will not be able to be compiled using earlier versions of
|
||||
EPICS Base.
|
||||
|
||||
### IOCsh usage messages
|
||||
|
||||
At the iocShell prompt `help <cmd>` now prints a descriptive usage message
|
||||
for many internal IOCsh commands in addition to the command parameters.
|
||||
Try `help *` to see all commands, or a glob pattern such as `help db*` to see
|
||||
a subset.
|
||||
|
||||
External code may provide usage messages when registering commands using a
|
||||
new `const char *usage` member of the `iocshFuncDef` structure.
|
||||
The `iocsh.h` header also now defines a macro `IOCSHFUNCDEF_HAS_USAGE` which
|
||||
can be used to detect Base versions that support this feature at compile-time.
|
||||
|
||||
### Variable names in RELEASE files
|
||||
|
||||
`configure/RELEASE` files are parsed by both GNUmake and the `convertRelease.pl`
|
||||
script. While GNUmake is quite relaxed about what characters may be used in a
|
||||
RELEASE variable name, the `convertRelease.pl` script parser has only recognized
|
||||
variable names that match the Perl regular expression `\w+`, i.e. upper and
|
||||
lower-case letters, digits and underscore characters.
|
||||
|
||||
The script has been modified so now RELEASE variable names must start with a
|
||||
letter or underscore, and be followed by any number of letters, digits,
|
||||
underscore or hyphen characters, matching the regular expression
|
||||
`[A-Za-z_][A-Za-z_0-9-]*`. The hyphen character `-` was not previously allowed
|
||||
and if used would have prevented a build from finding include files and
|
||||
libraries in any module using that in its RELEASE variable name.
|
||||
|
||||
This change does disallow names that start with a digit which used to be
|
||||
allowed, but hopefully nobody has been relying on that ability. The regular
|
||||
expression used for names can be found in the file `src/tools/EPICS/Release.pm`
|
||||
and can be adjusted locally if necessary.
|
||||
|
||||
### caRepeater /dev/null
|
||||
|
||||
On \*NIX targets caRepeater will now partially daemonize by redirecting
|
||||
stdin/out/err to /dev/null. This prevents caRepeater from inheriting
|
||||
the stdin/out of a process, like caget, which has spawned it in the
|
||||
background. This has been known to cause problems in some cases when
|
||||
caget is itself being run from a shell script.
|
||||
|
||||
caRepeater will now understand the `-v` argument to retain stdin/out/err
|
||||
which may be necessary to see any error messages it may emit.
|
||||
|
||||
### `state` record deprecated
|
||||
|
||||
IOCs now emit a warning when a database file containing the `state` record is
|
||||
loaded. This record has been deprecated for a while and will be removed
|
||||
beginning with EPICS 7.1. Consider using the `stringin` record instead.
|
||||
|
||||
### Record types publish dset's
|
||||
|
||||
The record types in Base now define their device support entry table (DSET)
|
||||
structures in the record header file. While still optional, developers of
|
||||
external support modules are encouraged to start converting their code to use
|
||||
the record's new definitions instead of the traditional approach of copying the
|
||||
structure definitions into each source file that needs them. By following the
|
||||
instructions below it is still possible for the converted code to build and
|
||||
work with older Base releases.
|
||||
|
||||
This would also be a good time to modify the device support to use the type-safe
|
||||
device support entry tables that were introduced in Base-3.16.2 -- see
|
||||
[this entry below](#type-safe-device-and-driver-support-tables) for the
|
||||
description of that change, which is also optional for now.
|
||||
|
||||
Look at the aiRecord for example. Near the top of the generated `aiRecord.h`
|
||||
header file is a new section that declares the `aidset`:
|
||||
|
||||
```C
|
||||
/* Declare Device Support Entry Table */
|
||||
struct aiRecord;
|
||||
typedef struct aidset {
|
||||
dset common;
|
||||
long (*read_ai)(struct aiRecord *prec);
|
||||
long (*special_linconv)(struct aiRecord *prec, int after);
|
||||
} aidset;
|
||||
#define HAS_aidset
|
||||
```
|
||||
|
||||
Notice that the common members (`number`, `report()`, `init()`, `init_record()`
|
||||
and `get_ioint_info()` don't appear directly but are included by embedding the
|
||||
`dset common` member instead. This avoids the need to have separate definitions
|
||||
of those members in each record dset, but does require those members to be
|
||||
wrapped inside another set of braces `{}` when initializing the data structure
|
||||
for the individual device supports. It also requires changes to code that
|
||||
references those common members, but that code usually only appears inside the
|
||||
record type implementation and very rarely in device supports.
|
||||
|
||||
An aiRecord device support that will only be built against this or later
|
||||
versions of EPICS can now declare its dset like this:
|
||||
|
||||
```C
|
||||
aidset devAiSoft = {
|
||||
{ 6, NULL, NULL, init_record, NULL },
|
||||
read_ai, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAiSoft);
|
||||
```
|
||||
|
||||
However most device support that is not built into EPICS itself will need to
|
||||
remain compatible with older EPICS versions, which is why the ai record's header
|
||||
file also declares the preprocessor macro `HAS_aidset`. This makes it easy to
|
||||
define the `aidset` in the device support code when it's needed, and not when
|
||||
it's provided in the header:
|
||||
|
||||
```C
|
||||
#ifndef HAS_aidset
|
||||
typedef struct aidset {
|
||||
dset common;
|
||||
long (*read_ai)(aiRecord *prec);
|
||||
long (*special_linconv)(aiRecord *prec, int after);
|
||||
} aidset;
|
||||
#endif
|
||||
aidset devAiSoft = {
|
||||
{ 6, NULL, NULL, init_record, NULL },
|
||||
read_ai, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAiSoft);
|
||||
```
|
||||
|
||||
The above `typedef struct` declaration was copied directly from the new
|
||||
aiRecord.h file and wrapped in the `#ifndef HAS_aidset` conditional.
|
||||
|
||||
This same pattern should be followed for all record types except for the lsi,
|
||||
lso and printf record types, which have published their device support entry
|
||||
table structures since they were first added to Base but didn't previously embed
|
||||
the `dset common` member. Device support for these record types therefore can't
|
||||
use the dset name since the new definitions are different from the originals and
|
||||
will cause a compile error, so this pattern should be used instead:
|
||||
|
||||
```C
|
||||
#ifndef HAS_lsidset
|
||||
struct {
|
||||
dset common;
|
||||
long (*read_string)(lsiRecord *prec);
|
||||
}
|
||||
#else
|
||||
lsidset
|
||||
#endif
|
||||
devLsiEtherIP = {
|
||||
{5, NULL, lsi_init, lsi_init_record, get_ioint_info},
|
||||
lsi_read
|
||||
};
|
||||
```
|
||||
326
documentation/RELEASE-7.0.5.md
Normal file
326
documentation/RELEASE-7.0.5.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
The external PVA submodules continue to maintain their own release notes files
|
||||
as before, but the entries describing changes in those submodules since version
|
||||
7.0.5 have been copied into the associated EPICS Release Notes files, and will
|
||||
be added to new EPICS Release Notes published in the future.
|
||||
|
||||
## EPICS Release 7.0.5
|
||||
|
||||
### Fix aai's Device Support Initialization
|
||||
|
||||
Krisztian Loki [reported](https://github.com/epics-base/epics-base/issues/97)
|
||||
segfaults occurring when a Soft Channel aai record INP field was a DB link to
|
||||
an array field of a compress record. This was caused by the aai record's
|
||||
pass-0 device support initialization clashing with the semantics of the new
|
||||
link support API.
|
||||
|
||||
The aai record
|
||||
[has been modified](https://github.com/epics-base/epics-base/pull/114) to
|
||||
allow the Soft Channel device support to request a pass-1 initialization
|
||||
callback. See the Device Support section of the Array Analogue Input Record
|
||||
Reference pages in this release for the API changes, which are fully backwards
|
||||
compatible for existing aai device support.
|
||||
|
||||
### Prevent default DTYPs from changing
|
||||
|
||||
[Kay Kasemir reported](https://bugs.launchpad.net/epics-base/+bug/1908305) that
|
||||
it is possible to change the Base record type's default DTYP if a `device()`
|
||||
entry is seen before the `recordtype()` definition to which it refers. The
|
||||
default DTYP is the first device loaded, which is normally the `Soft Channel`
|
||||
support from Base. A warning was being displayed by dbdExpand when a `device()`
|
||||
entry was see first, but that was easily missed.
|
||||
|
||||
The DBD file parser in dbdExpand.pl has now been modified to make this an error,
|
||||
although the registerRecordDeviceDriver.pl script will still accept `device()`
|
||||
entries without having their `recordtype()` loaded since this is necessary to
|
||||
compile device supports as loadable modules.
|
||||
|
||||
|
||||
### Priority inversion safe Posix mutexes
|
||||
|
||||
On Posix systems, epicsMutex now support priority inheritance if available.
|
||||
The IOC needs to run with `SCHED_FIFO` engaged to use these.
|
||||
Support for Posix implementations before POSIX.1-2001 (`_XOPEN_SOURCE < 500`,
|
||||
glibc version < 2.3.3) has been dropped.
|
||||
|
||||
The IOC shell's `epicsMutexShowAll` command prints "PI is enabled" if both
|
||||
libc and kernel support is present.
|
||||
|
||||
### Fix for Periodic Scan threads hanging on Windows
|
||||
|
||||
Since 7.0.3.1 a Windows IOC could not run for more than 49.7 days; at that
|
||||
time the periodic scan threads would stop processing. This issue should now
|
||||
have been fixed and the Monotonic time functions on Windows should return
|
||||
values which count at nanosecond resolution. However we have not waited 49.7
|
||||
days to test the final software, so there is a small chance that it's still
|
||||
broken.
|
||||
|
||||
This fixes [lauchpad bug #1896295](https://bugs.launchpad.net/bugs/1896295).
|
||||
|
||||
### Support for Apple M1/M2 (arm64) Processors
|
||||
|
||||
Thanks to Jeong Han Lee this release comes with build support for Apple's new
|
||||
M1/M2 CPUs running macOS, using the target name `darwin-aarch64`.
|
||||
|
||||
It should also be possible to build universal binaries containing code for
|
||||
both the Intel and arm64 processors under either target name: In the
|
||||
appropriate `configure/os/CONFIG_SITE.Common.darwin-*` file add the other
|
||||
architecture class name to the `ARCH_CLASS` variable (after a space).
|
||||
|
||||
### New String Comparison Routine `epicsStrSimilarity()`
|
||||
|
||||
The new `epicsStrSimilarity()` routine in epicsString.h uses a modified
|
||||
Levenshtein distance to compare two strings, with a character case difference
|
||||
being half the weight of a full substitution. The double return value falls in
|
||||
the range 0.0 (identical) through 1.0 (no characters matching), or -1.0 for
|
||||
error. This is used to provide a new "Did you mean ..." suggestion when a .db
|
||||
file provides an invalid choice string for a `DBF_MENU` or `DBF_DEVICE` field.
|
||||
|
||||
### Build System: New `VALID_BUILDS` type "Command"
|
||||
|
||||
Target architectures that support command-line programs that run the `main()`
|
||||
routine can now be marked as such in their `VALID_BUILDS` definition. This
|
||||
enables a new set of Makefile target variables `PROD_CMD` (similar to
|
||||
`PROD_HOST`), `LIBRARY_CMD` (like `LIBRARY_HOST`, etc.), `LOADABLE_LIBRARY_CMD`,
|
||||
`OBJS_CMD`, `SCRIPTS_CMD`, `TARGETS_CMD`, `TESTLIBRARY_CMD`, `TESTSCRIPTS_CMD`
|
||||
and `TESTPROD_CMD`. The CA client tools and programs such as `caRepeater` are now built for all such targets (previously they were built for all targets except where the OS was VxWorks, RTEMS and iOS).
|
||||
|
||||
If you have created your own site-specific target architectures you may need to
|
||||
update the `VALID_BUILDS` variable if it gets set in your locally added
|
||||
`configure/os/CONFIG.Common.<arch>` files. This is usually only needed for
|
||||
cross-compiled targets though since `CONFIG.Common.UnixCommon` sets it.
|
||||
|
||||
The other `VALID_BUILDS` types are "Host" for target architectures that can
|
||||
compile and run their own programs (`PROD_HOST` etc.), and "Ioc" for targets
|
||||
that can run IOCs (`PROD_IOC` etc.).
|
||||
|
||||
### Support for JSON5
|
||||
|
||||
The YAJL parser and generator routines in libcom and in the IOC's dbStatic
|
||||
parser now support the JSON5 standard. This adds various features to JSON
|
||||
without altering the API for the code other than adding a new option to the
|
||||
YAJL parser which can be used to disable JSON5 support if desired. The new
|
||||
features include:
|
||||
|
||||
- The ability to handle numeric values `Infinity`, `-Infinity` and `NaN`.
|
||||
- String values and map keys may be enclosed in single quotes `'`, inside which
|
||||
the double-quote character `"` doesn't have to be escaped with a back-slash
|
||||
`\`, although a single-quote character `'` (or apostrophy) must be escaped
|
||||
inside a single-quoted string.
|
||||
- Numbers may start with a plus sign, `+`.
|
||||
- Integers may be expressed in hexadecimal with a leading `0x` or `0X`.
|
||||
- Floating-point numbers may start or end with their decimal point `.`
|
||||
(after the sign or before the exponent respectively if present).
|
||||
- Map keys that match the regex `[A-Za-z_][A-Za-z_0-9]*` don't have to be
|
||||
enclosed in quotes at all. The dbStatic parser adds `.+-` to the characters
|
||||
allowed but will add quotes around such keys before passing them to YAJL.
|
||||
- Arrays and maps allow a comma before the closing bracket/brace character.
|
||||
- The YAJL parser will elide a backslash followed by a newline characters from
|
||||
a string value. The dbStatic parser doesn't allow that however.
|
||||
|
||||
Code that must also compile against the older API can use the new C macro
|
||||
`HAS_JSON5` to detect the new version. This macro is defined on including
|
||||
either the `yajl_parse.h` or `yajl_gen.h` headers, which also provide the
|
||||
new configuration options to turn on JSON5 support.
|
||||
|
||||
All APIs in the IOC that previously accepted JSON will now accept JSON5.
|
||||
This includes JSON field modifiers (channel filters), JSON link addresses,
|
||||
constant input link array values and database info-tag values. JSON values
|
||||
that get parsed by the dbLoadRecords() routine are still more liberal than
|
||||
the other uses as the ability to use unquoted strings that was called
|
||||
"relaxed JSON" is still supported, whereas the JSON5 standard and the YAJL
|
||||
parser only allow unquoted strings to be used for keys in a JSON map.
|
||||
|
||||
This also fixes [lauchpad bug #1714455](https://bugs.launchpad.net/bugs/1714455).
|
||||
|
||||
|
||||
### Character Escape Changes
|
||||
|
||||
- The libCom routines `epicsStrnRawFromEscaped()` and `dbTranslateEscape()`
|
||||
declared in epicsString.h no longer accept octal escaped characters such as
|
||||
`\123` or `\41`.
|
||||
- The routine `epicsStrnEscapedFromRaw()` now generates hex
|
||||
excaped characters for unprintable characters such as `\x1f`.
|
||||
- Hex escape character sequences `\xXX` must now contain exactly 2 hex digits.
|
||||
- An escape sequence `\0` now generates a zero byte in the raw string, but the
|
||||
other digits `1-9` should not appear after a back-slash.
|
||||
|
||||
These changes are to more closely follow the JSON5 standard, which doesn't
|
||||
support octal character escapes or the `\a` (Bel, `\x07`) escape sequence.
|
||||
|
||||
### Filters in database input links
|
||||
|
||||
Input database links can now use channel filters, it is not necessary to
|
||||
make them CA links for the filters to work.
|
||||
|
||||
### ai Soft Channel support
|
||||
|
||||
The Soft Channel device support for ai records now returns failure when
|
||||
fetching the INP link fails.
|
||||
|
||||
### Support for zero-length arrays
|
||||
|
||||
Several modifications have been made to properly support zero-length
|
||||
array values inside the IOC and over Channel Access. Some of these changes
|
||||
may affect external code that interfaces with the IOC, either directly or
|
||||
over the CA client API so we recommend thorough testing of any external
|
||||
code that handles array fields when upgrading to this release.
|
||||
|
||||
Since these changes affect the Channel Access client-side API they will
|
||||
require rebuilding any CA Gateways against this version or Base to
|
||||
properly handle zero-length arrays. The `caget`, `caput` and `camonitor`
|
||||
client programs are known to work with empty arrays as long as they were
|
||||
built with this or a later version of EPICS.
|
||||
|
||||
#### Change to the db\_access.h `dbr_size_n(TYPE, COUNT)` macro
|
||||
|
||||
When called with COUNT=0 this macro no longer returns the number of bytes
|
||||
required for a scalar (1 element) but for an empty array (0 elements).
|
||||
Make sure code that uses this doesn't call it with COUNT=0 when it really
|
||||
means COUNT=1.
|
||||
|
||||
Note that the db\_access.h header file is included by cadef.h so the change
|
||||
can impact Channel Access client programs that use this macro.
|
||||
|
||||
#### Channel Access support for zero-length arrays
|
||||
|
||||
The `ca_array_put()` and `ca_array_put_callback()` routines now accept an
|
||||
element count of zero, and will write a zero-length array to the PV if
|
||||
possible. No error will be raised if the target is a scalar field though,
|
||||
and the field's value will not be changed.
|
||||
|
||||
The `ca_array_get_callback()` and `ca_create_subscription()` routines
|
||||
still accept a count of zero to mean fetch as many elements as the PV
|
||||
currently holds.
|
||||
|
||||
Client programs should be prepared for the `count` fields of any
|
||||
`struct event_handler_args` or `struct exception_handler_args` passed to
|
||||
their callback routines to be zero.
|
||||
|
||||
#### Array records
|
||||
|
||||
The soft device support for the array records aai, waveform, and subArray
|
||||
as well as the aSub record type now correctly report reading 0 elements
|
||||
when getting an empty array from an input link.
|
||||
|
||||
#### Array support for dbpf
|
||||
|
||||
The dbpf command now accepts array values, including empty arrays, when
|
||||
provided as a JSON string. This must be enclosed in quotes so the iocsh
|
||||
argument parser sees the JSON as a single argument:
|
||||
|
||||
```
|
||||
epics> dbpf wf10:i32 '[1, 2, 3, 4, 5]'
|
||||
DBF_LONG[5]: 1 = 0x1 2 = 0x2 3 = 0x3 4 = 0x4 5 = 0x5
|
||||
```
|
||||
|
||||
#### Reading empty arrays as scalar values
|
||||
|
||||
Record links that get a scalar value from an array that is currently
|
||||
empty will cause the record that has the link field to be set to an
|
||||
`INVALID/LINK` alarm status.
|
||||
The record code must call `dbGetLink()` with `pnRequest=NULL` for it to
|
||||
be recognized as a request for a scalar value though.
|
||||
|
||||
This changes the semantics of passing `pnRequest=NULL` to `dbGetLink()`,
|
||||
which now behaves differently than passing it a pointer to a long integer
|
||||
containing the value 1, which was previously equivalent.
|
||||
The latter can successfully fetch a zero-element array without triggering
|
||||
a LINK alarm.
|
||||
|
||||
#### Writing empty arrays to scalar fields
|
||||
|
||||
Record links that put a zero-element array into a scalar field will now set
|
||||
the target record to `INVALID/LINK` alarm without changing the field's value.
|
||||
Previously the field was set to 0 in this case (with no alarm).
|
||||
The target field must be marked as `special(SPC_DBADDR)` to be recognized
|
||||
as an array field, and its record support must define a `put_array_info()`
|
||||
routine.
|
||||
|
||||
### Timestamp before processing output links
|
||||
|
||||
The record processing code for records with output links has been modified to
|
||||
update the timestamp via recGblGetTimeStamp() _before_ processing the output
|
||||
links. This ensures that other records which get processed via an output link
|
||||
can use TSEL links to fetch the timestamp corresponding to the data processed
|
||||
by the output link.
|
||||
|
||||
This change could result in a slightly earlier timestamp for records whose
|
||||
output link is handled by a device driver, but only if the device driver does
|
||||
not handle its own timestamping via TSE -2 and instead uses TSE 0 or TSE -1 to
|
||||
get current time or best time, and the time spent in the device driver is
|
||||
greater than your timestamp provider resolution. For these situations it is
|
||||
recommended to set TSE to -2 and set the timestamp in the driver code.
|
||||
|
||||
### Add registerAllRecordDeviceDrivers()
|
||||
|
||||
A new iocsh command `registerAllRecordDeviceDrivers` is provided and also
|
||||
defined as a function in iocshRegisterCommon.h. This uses dynamic symbol
|
||||
lookup with `epicsFindSymbol()` to perform the same function as a generated
|
||||
`*_registerRecordDeviceDriver()` function. This allows for an alternative
|
||||
approach to dynamic loading of support modules without code generation.
|
||||
|
||||
This feature is not intended for use by IOCs constructed using the standard
|
||||
EPICS application build process and booted from a startup script in an iocBoot
|
||||
subdirectory, although it might work in some of those cases — the
|
||||
generated registerRecordDeviceDriver.cpp file is normally required to link
|
||||
everything referred to in the DBD file into the IOC's executable. It also
|
||||
won't work with some static build configurations, or if the symbol table has
|
||||
been stripped from the executable.
|
||||
|
||||
### Using a `{const:"string"}` to initialize an array of `DBF_CHAR`
|
||||
|
||||
It is now possible to use a JSON Const link with a string value to initialize
|
||||
an aai or waveform record that has `FTVL` set to `CHAR` through the INP link.
|
||||
The string length is not limited to 40 characters. This should also work for
|
||||
aSub record inputs similarly configured as long strings.
|
||||
|
||||
```
|
||||
record(waveform, "wf") {
|
||||
field(NELM, 100)
|
||||
field(FTVL, CHAR)
|
||||
field(INP, {const:"This is a waveform and more than 40 characters"})
|
||||
}
|
||||
```
|
||||
|
||||
### RELEASE files may use `undefine`
|
||||
|
||||
GNUmake added the directive `undefine` in version 3.82 to allow variables to
|
||||
be undefined. Support for this has been added to the EPICS Release file parser,
|
||||
so `undefine` can now be used in configure/RELEASE files to unset variables.
|
||||
|
||||
|
||||
### Submodule updates
|
||||
|
||||
The pvData module was updated to version 8.0.4:
|
||||
|
||||
- Incompatible changes
|
||||
- Remove `ByteBuffer::align()`
|
||||
- Compatible changes
|
||||
- Deprecate `SerializableControl::alignBuffer()` and
|
||||
`DeserializableControl::alignData()`
|
||||
- `shared_vector_convert<>()` fix convert of empty, untyped, array
|
||||
|
||||
The pvAccess module was updated to version 7.1.3:
|
||||
|
||||
- Bug fixes
|
||||
- Increase default TCP timeout to 40 seconds.
|
||||
Applies a 4/3 multiplier on `$EPICS_PVA_CONN_TMO` for compatibility.
|
||||
- CA Provider implementation restructured to simplify, reduce duplication
|
||||
and fix issues #163 and #165.
|
||||
- Changes
|
||||
- Enable building of pvtools to all except vxWorks, RTEMS and iOS.
|
||||
|
||||
The pva2pva module was updated to version 1.3.0:
|
||||
|
||||
- Changes
|
||||
- Add `dbLoadGroup()` iocsh function to read group JSON definitions
|
||||
from a file. Mappings in files must refer to full record names
|
||||
instead of fields. eg. 'recname.VAL' instead of 'VAL'.
|
||||
85
documentation/RELEASE-7.0.6.1.md
Normal file
85
documentation/RELEASE-7.0.6.1.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
The external PVA submodules continue to maintain their own release notes files
|
||||
as before, but the entries describing changes in those submodules since version
|
||||
7.0.5 have been copied into the associated EPICS Release Notes files, and will
|
||||
be added to new EPICS Release Notes published in the future.
|
||||
|
||||
## EPICS Release 7.0.6.1
|
||||
|
||||
### `mbboDirectRecord` enhancements
|
||||
|
||||
The bit fields `B0` - `B1F` of this record are now always updated and have a
|
||||
monitor posted when the `VAL` field is set and the record processed. It is now
|
||||
possible to initialize the record's value by setting the bit fields inside a
|
||||
database file as long as no other method was used to initialize it (suc as
|
||||
setting `VAL` directly, using `DOL`, or by an initial readback from device
|
||||
support). A new internal field `OBIT` was added to store information about
|
||||
monitors posted on the bit fields.
|
||||
|
||||
### Minimum Perl Version is now 5.10.1
|
||||
|
||||
Some scripts now make use of features that were introduced to this Perl version
|
||||
that was released in 2009.
|
||||
|
||||
### DB Links to `DBF_MENU` fields fixed
|
||||
|
||||
[GH:183](https://github.com/epics-base/epics-base/issues/183)
|
||||
These were broken in a previous release, but now work again.
|
||||
|
||||
### Long String access to CALC fields fixed
|
||||
|
||||
[GH:194](https://github.com/epics-base/epics-base/issues/194)
|
||||
This was broken in a previous release, but now works again.
|
||||
|
||||
### Minor Changes
|
||||
|
||||
+ Many code comments have been spell-checked and corrected.
|
||||
+ Passing a `-DDEBUG` compiler flag no longer breaks the build.
|
||||
+ Parallel builds of RTEMS-mvme2100 and RTEMS-mvme2700 targets now work.
|
||||
+ Illegal characters seen in JSON strings in a database file should now get a
|
||||
better error message.
|
||||
|
||||
### Other Launchpad Bugs and GitHub Issues Fixed
|
||||
|
||||
+ [lp:1938459](https://bugs.launchpad.net/epics-base/+bug/1938459)
|
||||
[GH:191](https://github.com/epics-base/epics-base/pull/191) int64in only
|
||||
checks lower 32 bits for change
|
||||
+ [lp:1941875](https://bugs.launchpad.net/epics-base/+bug/1941875) Buggy
|
||||
warning message "Record/Alias name '...' should not contain non-printable ...
|
||||
+ [GH:187](https://github.com/epics-base/epics-base/issues/187) waveformRecord
|
||||
missing PACT=true?
|
||||
+ [GH:189](https://github.com/epics-base/epics-base/pull/189) Fix a couple
|
||||
memory leaks and a segfault
|
||||
+ [GH:200](https://github.com/epics-base/epics-base/pull/200) and
|
||||
[GH:201](https://github.com/epics-base/epics-base/pull/201) Fix timers on MS
|
||||
Windows for non-EPICS threads
|
||||
|
||||
### Compiler interface for epicsAtomic tidied up
|
||||
|
||||
[GH:192](https://github.com/epics-base/epics-base/pull/192)
|
||||
Both GCC and CLANG compiler intrisics used for the epicsAtomic APIs have been revised; implementations using CLANG should now run faster as they now use the compiler's built-in atomic functions instead of taking a mutex.
|
||||
|
||||
### The epicsTime code has been reimplemented
|
||||
|
||||
[GH:185](https://github.com/epics-base/epics-base/pull/185)
|
||||
This was done to simplify the code and may have improved performance slightly for some uses. Support for the old NTP-specific `struct l_fp` has been dropped but all other routines and methods of the `class epicsTime` function as before.
|
||||
|
||||
### Updates to Record Reference documentation
|
||||
|
||||
Many of the built-in record types have had improvements to their documentation with additional fields added to the tables, rewrites of descriptions and links to other documents added or fixed.
|
||||
|
||||
### Submodule updates
|
||||
|
||||
The pvAccess module was updated to version 7.1.4:
|
||||
|
||||
- Changes to caProvider
|
||||
- Resolve issues with pv structures that don't have a value field
|
||||
- Add NULL checks for handling unusual structures
|
||||
- Speed up channel creation when using large numbers of channels
|
||||
283
documentation/RELEASE-7.0.6.md
Normal file
283
documentation/RELEASE-7.0.6.md
Normal file
@@ -0,0 +1,283 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
The external PVA submodules continue to maintain their own release notes files
|
||||
as before, but the entries describing changes in those submodules since version
|
||||
7.0.5 have been copied into the associated EPICS Release Notes files, and will
|
||||
be added to new EPICS Release Notes published in the future.
|
||||
|
||||
## EPICS Release 7.0.6
|
||||
|
||||
### Support for obsolete architectures removed
|
||||
|
||||
These target architectures have been removed:
|
||||
|
||||
+ darwin-ppc, darwin-ppcx86
|
||||
+ linux-386, linux-486, linux-586, linux-686, linux-athlon (cross-build)
|
||||
+ linux-cris, linux-cris\_v10, linux-cris\_v32 (cross-build)
|
||||
+ RTEMS-at91rm9200ek, RTEMS-gen68360, RTEMS-mcp750, RTEMS-mvme167,
|
||||
RTEMS-psim (cross-build)
|
||||
|
||||
### Experimental Support for RTEMS 5
|
||||
|
||||
The new major release of the RTEMS real-time OS contains many changes
|
||||
including the ability to support SMP systems. This release of EPICS
|
||||
can still be built with RTEMS 4.9.x or 4.10.x and should work just
|
||||
the same as earlier releases, although due to code having moved around
|
||||
we recommend thorough testing before this release is first used in
|
||||
production systems.
|
||||
|
||||
This release of EPICS comes with support for several new RTEMS targets
|
||||
running on RTEMS 5:
|
||||
|
||||
- RTEMS-beagleboneblack
|
||||
- RTEMS-pc686
|
||||
- RTEMS-qoriq\_e500 (MVME2500)
|
||||
- RTEMS-xilinx\_zynq\_a9\_qemu
|
||||
- RTEMS-xilinx\_zynq\_zedboard
|
||||
|
||||
The EPICS support for RTEMS 4 has always relied on RTEMS-specific
|
||||
kernel APIs which cannot be used on an SMP system, so a new port was
|
||||
created to use the Posix real-time APIs that are now recommended for
|
||||
RTEMS 5. Note that a single installation of EPICS cannot build both
|
||||
RTEMS 4 and RTEMS 5 targets, if you need to support targets running
|
||||
on both versions you must use a separate installation, and be sure
|
||||
to run `make distclean` if switching a single source tree from one
|
||||
to the other (both header files and dependency files are different
|
||||
between the two and must be cleaned out).
|
||||
|
||||
The configuration variable `RTEMS_VERSION` in the EPICS config file
|
||||
`configure/os/CONFIG_SITE.Common.RTEMS` must be set to the full 3-
|
||||
part version number for RTEMS 4 releases, e.g. `4.9.1`, `4.10.2`
|
||||
but for RTEMS 5.1 and later it must only contain the major version
|
||||
number e.g. `5`.
|
||||
|
||||
Some RTEMS BSPs can be built and may work with the newer libbsd
|
||||
network stack which RTEMS is moving over to, but most of the MVME
|
||||
boards (and the uC5282) still require the legacy network stack.
|
||||
|
||||
The dependency on bspExt has been removed, EPICS now provides its
|
||||
own routine for VMEbus probing (or uses one built into the BSP).
|
||||
|
||||
Anyone using this release on RTEMS is advised to discuss problems
|
||||
building or running it on either the tech-talk or core-talk email
|
||||
lists so the core developers can help with and find out about any
|
||||
problems with the old or new port.
|
||||
|
||||
Known Issues:
|
||||
- MVME2100 and MVME2700 need changes to the RTEMS 5 BSP to build.
|
||||
- VMEBus support is not yet available for the MVME2500 BSP.
|
||||
- There are some known issues with floating point on MVME2500,
|
||||
probably related to its newer e500 FPU.
|
||||
- Changed network driver for beatnik to work with libbsd. Some
|
||||
issues with DHCP, but network stack usable. Can load env from
|
||||
NVRAM.
|
||||
|
||||
### `epicsEnvShow` accepts a glob pattern
|
||||
|
||||
The optional argument to epicsEnvShow can now be a glob pattern.
|
||||
|
||||
### New function `epicsStrnGlobMatch()`
|
||||
|
||||
The function `epicsStrnGlobMatch(char* str, size_t len, char* pattern)`
|
||||
works exactly the same as `epicsStrGlobMatch()` but takes an additional
|
||||
length arguments which limits the number of characters of `str` to match.
|
||||
|
||||
### Automatic fallback to thread when unable to exec caRepeater
|
||||
|
||||
A process using libca which does not find an existing caRepeater process
|
||||
will attempt to start one by running the caRepeater executable.
|
||||
This is not always possible, usually when caRepeater is not in `$PATH`.
|
||||
Now, instead of printing a warning, an internal caRepeater thread
|
||||
will be started (as is done be RTEMS and vxWorks targets).
|
||||
|
||||
If this fallback occurs, the lifetime of the caRepeater thread
|
||||
may be shorter than the lifetime of a separate caRepeater process
|
||||
would have been.
|
||||
|
||||
It remains the recommended practice to explicitly start a caRepeater
|
||||
instance. Examples of both systemd (`caRepeater.service`) and sysv
|
||||
(`S99caRepeater`) scripts may be found under `bin/`.
|
||||
|
||||
### Glob pattern allowed in `var` command
|
||||
|
||||
When used with one argument, the `var` command can be used with a glob pattern
|
||||
for printing matching variables.
|
||||
|
||||
### Formalize/fix `FINAL_LOCATION`
|
||||
|
||||
The `FINAL_LOCATION` make variable has for some time been an undocumented
|
||||
means of performing a staged build. This is a build which "installs" to
|
||||
a temporary location, which will later be moved to a final location.
|
||||
|
||||
This has now been added to `configure/CONFIG_SITE`.
|
||||
|
||||
Usage analogous to the autotools recipe
|
||||
|
||||
```sh
|
||||
./configure --prefix=/usr/lib/epics
|
||||
make install DESTDIR=/tmp/build
|
||||
```
|
||||
|
||||
would be
|
||||
|
||||
```sh
|
||||
make INSTALL_LOCATION=/tmp/build FINAL_LOCATION=/usr/lib/epics
|
||||
```
|
||||
|
||||
`FINAL_LOCATION` is now correctly used in systemd and sysv init scripts
|
||||
`caRepeater.service`, `S99caRepeater`, and `S99logServer`.
|
||||
|
||||
### IOCsh sets `${PWD}`
|
||||
|
||||
IOC shell will now ensure `${PWD}` is set on startup,
|
||||
and updated by the `cd` iocsh function.
|
||||
|
||||
### Add Alarm Message and Time Tag Fields
|
||||
|
||||
Two new fields have been added to `dbCommon` so will be present in all
|
||||
records: `AMSG` and `UTAG`.
|
||||
|
||||
#### `AMSG`
|
||||
|
||||
`AMSG` can hold an arbitrary 40-character string, providing additional
|
||||
information about the alarm condition indicated in `STAT` and `SEVR`. With no
|
||||
alarm it will hold an empty string. The new `recGblSetSevrMsg()` function can
|
||||
be used in place of `recGblSetSevr()` to signal an alarm while providing a
|
||||
message.
|
||||
|
||||
For example, a device support's `read_bi()` routine for a hypothetical
|
||||
multi-channel ethernet attached device might flag a communication error
|
||||
between the IOC and controller, or an error involving a certain channel like
|
||||
this:
|
||||
|
||||
```c
|
||||
static long read_bi(biRecord* prec) {
|
||||
...
|
||||
if (!priv->connected) {
|
||||
recGblSetSevrMsg(prec, COMM_ALARM, INVALID_ALARM,
|
||||
"No controller connected");
|
||||
return S_dev_noDevice;
|
||||
}
|
||||
if (!priv->err) {
|
||||
recGblSetSevrMsg(prec, READ_ALARM, INVALID_ALARM,
|
||||
"Channel %u disconnexted", priv->chan);
|
||||
return S_dev_noDevice;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
```
|
||||
|
||||
#### `UTAG`
|
||||
|
||||
`UTAG` holds an `epicsUInt64` value which is semantically part of the record's
|
||||
timestamp (`TIME`). The value defaults to zero if not explicitly set. Device
|
||||
support or an event time provider which supports this feature may write a tag
|
||||
value directly to the `dbCommon::utag` field.
|
||||
|
||||
`TSEL` links will copy both `TIME` and `UTAG` between records if the link type
|
||||
supports this (CA links do not).
|
||||
|
||||
A `utag` server side channel filter has been added which can be configured to
|
||||
filter out monitor updates which don't pass the test `(UTAG & M) == V` where
|
||||
`M` and `V` are client specified integers. For example running the command
|
||||
`camonitor BPM0:X.{utag:{M:1,V:1}}` will only show updates for which
|
||||
`(UTAG & 1) == 1` i.e. the least significant bit of the `UTAG` field is set.
|
||||
|
||||
This feature is intended for use by intelligent devices which can provide
|
||||
contextual information along with a value/alarm/time. For example, a beam
|
||||
diagnostic device which is aware of whether a beam signal should be present
|
||||
(eg. from a global timing system).
|
||||
|
||||
#### Link Support
|
||||
|
||||
Two new optional methods have been added to the Link Support Entry Table
|
||||
(`struct lset`): `lset::getAlarmMsg()` and `lset::getTimeStampTag()`. See
|
||||
comments in dbLink.h for details on implementing these.
|
||||
|
||||
Two new accessor functions have also been added which call these methods:
|
||||
`dbGetAlarmMsg()` and `dbGetTimeStampTag()`.
|
||||
|
||||
#### Compatibility
|
||||
|
||||
User code wishing to call these interfaces while maintaining compatibility with older
|
||||
versions of Base may add some of the following macro definitions, and ensure
|
||||
that the variables referenced by output pointers are initialized.
|
||||
|
||||
```c
|
||||
#ifndef HAS_ALARM_MESSAGE
|
||||
# define recGblSetSevrMsg(REC, STAT, SEVR, ...) recGblSetSevr(REC, STAT, SEVR)
|
||||
#endif
|
||||
#ifndef dbGetAlarmMsg
|
||||
# define dbGetAlarmMsg(LINK, STAT, SEVR, BUF, BUFLEN) dbGetAlarm(LINK, STAT, SEVR)
|
||||
#endif
|
||||
#ifndef dbGetTimeStampTag
|
||||
# define dbGetTimeStampTag(LINK, STAMP, TAG) dbGetTimeStamp(LINK, STAMP)
|
||||
#endif
|
||||
```
|
||||
|
||||
|
||||
### Timeouts for Unit Test Programs
|
||||
|
||||
The unit test programs that are run by the `make runtests` or `make tapfiles`
|
||||
commands get executed by a `.t` wrapper script which is normally generated by
|
||||
the EPICS `makeTestfile.pl` program. Those generated wrapper scripts now
|
||||
impose a time-limit on the test program they execute, and will kill it if it
|
||||
runs for longer than 500 seconds (8 minutes 20) without exiting. That
|
||||
time-limit can be changed for any such test by modifying the Makefile which
|
||||
creates and runs the `.t` wrapper script.
|
||||
|
||||
Setting the environment variable `EPICS_UNITTEST_TIMEOUT` to the desired
|
||||
number of seconds while the Makefile is generating the test script changes the
|
||||
timeout in that script. For example:
|
||||
|
||||
```
|
||||
TESTSCRIPTS_HOST += hourLongTest.t
|
||||
hourLongTest.t: export EPICS_UNITTEST_TIMEOUT=3600
|
||||
```
|
||||
|
||||
When selecting such a timeout remember that different Continuous Integration
|
||||
systems such as GitHub Actions and Appveyor run on processors with different
|
||||
speeds, so allow enough head-room for slower systems to complete the test.
|
||||
|
||||
Test programs written directly in Perl as a `.plt` script should implement a
|
||||
similar timeout for themselves. The "netget" test in Base does this in a way
|
||||
that works on Windows as well as Unix-like hosts.
|
||||
|
||||
### Submodule updates
|
||||
|
||||
The pvAccess module was updated to version 7.1.4:
|
||||
|
||||
- Changes
|
||||
- Adjust argument parsing with pvput (Jesus Vasquez).
|
||||
|
||||
The pva2pva module was updated to version 1.3.1:
|
||||
|
||||
- Bug Fixes
|
||||
- Correct handling for server side filters.
|
||||
- Changes
|
||||
- Syncing softMain.cpp with epics-base
|
||||
|
||||
The pvDatabase module was updated to version 4.6.0:
|
||||
|
||||
* Access Security is now supported.
|
||||
* <b>special</b> has been revised and extended.
|
||||
* addRecord, removeRecord, processRecord, and traceRecord are replaced by pvdbcr versions.
|
||||
* <b>support</b> is DEPRECATED
|
||||
|
||||
The pvaClient module was updated to version 4.8.0:
|
||||
|
||||
* `PvaClientNTMultiData::getChannelChangeFlags` is a new method. It fixes
|
||||
issue #66.
|
||||
* Fix for issue #68. Both `PvaClientArray` and `PvaClientField` are not longer
|
||||
present. Neither was previously implemented.
|
||||
* Several public methods are now protected. They were never meant to be called
|
||||
by clients.
|
||||
* Issue #70 has been fixed.
|
||||
* Changes was made to increase the performance of `pvaMultiChannel`.
|
||||
* doxygen changes were made.
|
||||
298
documentation/RELEASE-7.0.7.md
Normal file
298
documentation/RELEASE-7.0.7.md
Normal file
@@ -0,0 +1,298 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
The external PVA submodules continue to maintain their own release notes files
|
||||
as before, but the entries describing changes in those submodules since version
|
||||
7.0.5 have been copied into the associated EPICS Release Notes files, and will
|
||||
be added to new EPICS Release Notes published in the future.
|
||||
|
||||
## EPICS Release 7.0.7
|
||||
|
||||
### Doxygen Annotations
|
||||
|
||||
Thanks to several attendees at the 2022 EPICS Codeathon the number of header
|
||||
files with Doxygen annotations in the EPICS Core has again increased.
|
||||
|
||||
### Build System updates
|
||||
|
||||
The top-level make targets `uninstall`, `archuninstall` and similar no
|
||||
longer trigger the `clean` target which empties build directories, this
|
||||
was a bug introduced in 7.0.5.
|
||||
|
||||
The `make distclean` target now properly deletes the generated file(s)
|
||||
`modules/RELEASE.<host>.local` which are essential to build the external
|
||||
submodules under the `modules` directory, and should not crash if the
|
||||
build is configured with `INSTALL_LOCATION` pointing to an empty external directory (i.e. if you run `make distclean` twice in succession). When
|
||||
`INSTALL_LOCATION` is set in the files `configure/CONFIG_SITE` or
|
||||
`configure/CONFIG_SITE.local` the `modules/RELEASE.<host>.local` file
|
||||
will now be regenerated in case the install path has been modified.
|
||||
|
||||
Note that passing `INSTALL_LOCATION=<path>` on the make command-line will
|
||||
only work if you have run `make distclean` immediately beforehand, as the
|
||||
`modules/RELEASE.<host>.local` file must be recreated using the new path.
|
||||
|
||||
### Enhancements to `capr.pl`
|
||||
|
||||
The `capr.pl` script can now display records from older Base versions to
|
||||
which fields have since been added, and shows long strings and array data
|
||||
up to 10 elements, use the new `-n` option to increase that number.
|
||||
The script is fully event-driven and prints all the field data received by
|
||||
the end of the CA wait time (`-w` option which defaults to 2 seconds).
|
||||
The interest level can now be specified using the `-l` option before the
|
||||
PV name, and the new `-D` flag outputs debugging information.
|
||||
|
||||
### Time Synchronization on VxWorks
|
||||
|
||||
VxWorks 6.9 can do its own OS clock time synchronization, if it has been
|
||||
configured by setting `SNTPC_PRIMARY_IPV4_ADDR`. Since EPICS 3.15.3 the
|
||||
IOC time support code has checked for the existence of the VxWorks time
|
||||
synchronization task and avoided starting the EPICS one if the OS task
|
||||
exists and the OS clock gives a "recent" time (i.e. after when EPICS was
|
||||
compiled), unless the environment variable `EPICS_TS_FORCE_NTPTIME` is
|
||||
also set. However a logic error in that code required the environment
|
||||
variable to be set in more cases than it should have.
|
||||
|
||||
This error has been fixed and the IOC should work normally if the VxWorks
|
||||
task is configured and running. The `TIMEZONE` value for the year is also
|
||||
now calculated at initialization in this configuration, previously it was
|
||||
only done when the IOC synchronzation task was used. Setting the above
|
||||
environment variable will now cause the IOC support code to shut down the
|
||||
VxWorks synchronization thread (if running) before starting the EPICS one.
|
||||
|
||||
Running the iocsh command `ClockTime_Report` now shows whether the VxWorks
|
||||
task is running as well as giving the state of the IOC synchronization task.
|
||||
The `ClockTime_Init` command can also be used to stop or restart the IOC
|
||||
time synchronization task while the IOC is running, depending on the `0` or
|
||||
`1` parameter passed to it. This last change also applies to RTEMS IOCs.
|
||||
|
||||
### Incompatible change to `struct db_field_log`
|
||||
|
||||
This change may cause channel filters which manipulate array updates
|
||||
to fail to compile.
|
||||
|
||||
To avoid potential speculation issues arising from overlapping code pointers
|
||||
with data values, `union dbfl_ref` is modified to remove the `dtor` member.
|
||||
`dtor` is moved out into the enclosing `struct db_field_log`.
|
||||
|
||||
So eg. using a `db_field_log* p`, the expression `p->u.r.dtor` must be
|
||||
changed to `(p)->dtor`.
|
||||
|
||||
### Fix undef ts on first camonitor update of NORD from waveformRecord
|
||||
|
||||
The order over operations when processing a waveformRecord is adjusted
|
||||
so that updates to NORD is posted with the correct timestamp.
|
||||
|
||||
### Automatic `COMMANDLINE_LIBRARY` with newer compilers
|
||||
|
||||
When built with a compiler supporting `__has_include<>`, the presence
|
||||
of a `readline/readline.h` header will be used to automatically determine
|
||||
a default value for `COMMANDLINE_LIBRARY`.
|
||||
|
||||
Mingw builds with readline support now link `-ltermcap` instead of `-lcurses`.
|
||||
|
||||
This should not effect sites which set explicitly set `COMMANDLINE_LIBRARY`
|
||||
as the only definition in Base now has the form `COMMANDLINE_LIBRARY ?= ...`.
|
||||
|
||||
### Perl CA support for empty long strings
|
||||
|
||||
The Perl CA bindings have been fixed to handle zero-length long string data
|
||||
properly.
|
||||
|
||||
### `aao` gains `OMSL` and `DOL`
|
||||
|
||||
The `aao` record types gains the same `DOL` functionality found
|
||||
in other output record types (`ao`, `longout`, etc.)
|
||||
|
||||
### Server exports `RSRV_SERVER_PORT`
|
||||
|
||||
During `iocInit()`, the environment variable `RSRV_SERVER_PORT` is set
|
||||
with the TCP port number selected.
|
||||
|
||||
### `dbdExpand.pl` sorts all items by name
|
||||
|
||||
DBD files generated by the `dbdExpand.pl` script are now sorted within each
|
||||
item type by the primary name of the item. The result should resolve any
|
||||
issues with reproducable builds. No option is provided to prevent the sorting,
|
||||
previously the order was essentially random and varied each time.
|
||||
|
||||
### `dbExpand.pl` sorts records by name
|
||||
|
||||
Records are now output by this program in order, sorted by name. The new flag
|
||||
`-s` can be given to output the records in the same order they were read in,
|
||||
instead of sorting them.
|
||||
|
||||
Note that there are currently no build rules provided with Base which make use
|
||||
of this program.
|
||||
|
||||
### Simulation Mode RAW Support for Output Record Types
|
||||
|
||||
SIMM=RAW support has been added for the relevant output record types
|
||||
(ao, bo, mbbo, mbboDirect).
|
||||
RAW simulation mode will have those records do the appropriate conversion
|
||||
and write RVAL to the location pointed to by SIOL.
|
||||
|
||||
### Fixed leak from a non-EPICS thread
|
||||
|
||||
On some targets, if a thread not created by `epicsThreadCreate*()` directly
|
||||
or indirectly calls an `epicsThread*()` function, a specific tracking struct
|
||||
is allocated.
|
||||
|
||||
Prior to this release, on POSIX and WIN32 targets, this
|
||||
struct would not be `free()`d, resulting in a memory leak.
|
||||
|
||||
This release fixed the leak on POSIX targets.
|
||||
|
||||
See the associated github [issue 241](https://github.com/epics-base/epics-base/issues/241)
|
||||
for WIN32 status.
|
||||
|
||||
### Fixed leak from a non-EPICS thread
|
||||
|
||||
On some targets, if a thread not created by `epicsThreadCreate*()` directly
|
||||
or indirectly calls an `epicsThread*()` function, a specific tracking struct
|
||||
is allocated.
|
||||
|
||||
Prior to this release, on POSIX and WIN32 targets, this
|
||||
allocation would not be `free()`d, resulting in a memory leak.
|
||||
|
||||
This release fixed the leak on POSIX and WIN32 targets (excluding
|
||||
MSVC before vs2012, and the WINE runtime).
|
||||
|
||||
### Fixed leak from a non-EPICS thread
|
||||
|
||||
On some targets, if a thread not created by `epicsThreadCreate*()` directly
|
||||
or indirectly calls an `epicsThread*()` function, a specific tracking struct
|
||||
is allocated.
|
||||
|
||||
Prior to this release, on POSIX and WIN32 targets, this
|
||||
struct would not be `free()`d, resulting in a memory leak.
|
||||
|
||||
This release fixed the leak on POSIX targets.
|
||||
|
||||
See the associated github [issue 241](https://github.com/epics-base/epics-base/issues/241)
|
||||
for WIN32 status.
|
||||
|
||||
### Fix `CHECK_RELEASE = WARN`
|
||||
|
||||
This now works again, it was broken in 2019 (7.0.3.1) by an errant commit.
|
||||
|
||||
### Document `DISP` as design-time field
|
||||
|
||||
The DISP field can be set to a non-zero value to prevent records being changed
|
||||
from outside the IOC (this is ancient behavior), but has never been documented
|
||||
as being usable at design-time (DCT=Yes in the Record Reference tables). This
|
||||
has now been changed.
|
||||
|
||||
### Make `epicsInt8` signed on all architectures
|
||||
|
||||
The `epicsInt8` and thus `DBF_CHAR` types have always been unsigned on
|
||||
architectures where `char` is unsigned, for example on many PowerPC CPU
|
||||
architectures. This was counter-intuitive, and resulted in IOC behavior
|
||||
differing between architectures when converting `DBF_CHAR` values into a
|
||||
signed integer or floating point type.
|
||||
|
||||
**WARNING**: This fix may change behavior of existing databases on target
|
||||
architectures with unsigned `char` (mainly PowerPC) when using input links to
|
||||
read from `CHAR` arrays. Architectures with signed `char` (usually x86) should
|
||||
be unaffected, although some compilers might generate new warnings.
|
||||
|
||||
### Allow hexadecimal and octal numbers in hardware links
|
||||
|
||||
[GH:213](https://github.com/epics-base/epics-base/pull/213)
|
||||
|
||||
Several types of hardware links (`VME_IO`, `CAMAC_IO`, etc) now accept
|
||||
hexadecimal and octal numbers. (Hexadecimal numbers had already been valid
|
||||
up to EPICS R3.15.) This change may introduce incompatibilities when using
|
||||
numbers with leading `0` as they will now be parsed as octal.
|
||||
|
||||
### Fix embedded implementations of `epicsEvent`
|
||||
|
||||
[GH:202](https://github.com/epics-base/epics-base/issues/202) and
|
||||
[GH:206](https://github.com/epics-base/epics-base/pull/206)
|
||||
|
||||
Heinz Junkes provided a new implementation of the `epicsEvent` API suitable for
|
||||
RTEMS Posix targets (RTEMS 5.1 and later). In review a few issues related to
|
||||
overflow of timeout values surfaced in this and other embedded implementations,
|
||||
and these were also been fixed in this Pull Request. The API documentation for
|
||||
this and some other routines has also been updated.
|
||||
|
||||
### Breakpoint Table Names
|
||||
|
||||
The names of breakpoint tables were made unnecessarily strict when DBD file
|
||||
processing was moved to Perl for the 3.15 release series. Table names may now
|
||||
contain the special characters `_` `-` `:` `;` `.` `[` `]` `<` `>` in addition
|
||||
to letters and digits.
|
||||
|
||||
### Fix for `undefined` in configure/RELEASE files
|
||||
|
||||
Prevents `Use of uninitialized value` warnings from convertRelease.pl.
|
||||
|
||||
### Colorized Messages for errlog
|
||||
|
||||
Many internal error messages now emit ANSI escape sequences to highlight the
|
||||
words "ERROR" and "WARNING" in an attempt to make occurrences more noticeable
|
||||
during IOC startup.
|
||||
|
||||
The macros `ERL_ERROR` and `ERL_WARNING` are defined for external usage,
|
||||
and expand as string constants. eg.
|
||||
|
||||
```c
|
||||
#include <errlog.h>
|
||||
#ifndef ERL_ERROR
|
||||
# define ERL_ERROR "ERROR"
|
||||
#endif
|
||||
void fn() {
|
||||
...
|
||||
errlogPrintf(ERL_ERROR ": something bad happens :(\n");
|
||||
```
|
||||
|
||||
ANSI escapes are automatically removed from errlog output not destined
|
||||
for a terminal. For example, for logClient, if stderr is redirected,
|
||||
or if unsupported (`$TERM` not set, or Windows < 10).
|
||||
|
||||
### `dbnd` filter pass through `DBE_ALARM|DBE_PROPERTY`
|
||||
|
||||
The `dbnd` server side filter now passes through alarm and property
|
||||
change events, even when not exceeding the deadband.
|
||||
|
||||
### Submodule updates
|
||||
|
||||
The pvData module was updated to version 8.0.5:
|
||||
|
||||
- Compatible changes
|
||||
- Internal changes to use the YAJL API for generating JSON and JSON-5 output.
|
||||
|
||||
The pvAccess module was updated to version 7.1.6:
|
||||
|
||||
- Changes to caProvider
|
||||
- Bug fix related to enum values.
|
||||
- More internal changes to improve performance when connecting tens of
|
||||
thousands of CA channels.
|
||||
- Several minor internal improvements.
|
||||
|
||||
The pva2pva module was updated to version 1.4.0:
|
||||
|
||||
- Bug Fixes
|
||||
- Apply ACF when writing to atomic group
|
||||
- Additions
|
||||
- Add new "structure" to @ref qsrv_group_map_types
|
||||
- Changes
|
||||
- Add Access Security hooks for single and group writes.
|
||||
- Enable "Async Soft Channel" for output links
|
||||
- When built against Base 7.0.6.1, set timeStamp.userTag from UTAG field.
|
||||
- Add DTYP="QSRV Set UTag" for longin, which sets UTAG=VAL.
|
||||
|
||||
The pvDatabase module was updated to version 4.7.0:
|
||||
|
||||
* Added support for the whole structure (master field) server side plugins.
|
||||
The whole structure is identified as the `_` string, and a pvRequest string
|
||||
that applies a plugin to it takes the form:
|
||||
|
||||
`field(_[XYZ=A:3;B:uniqueId])`
|
||||
|
||||
where `XYZ` is the name of a specific filter plugin that takes parameters
|
||||
`A` and `B` with values `3` and `uniqueId` respectively.
|
||||
60
documentation/RELEASE-7.0.8.1.md
Normal file
60
documentation/RELEASE-7.0.8.1.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
The external PVA submodules continue to maintain their own release notes files
|
||||
as before, but the entries describing changes in those submodules since version
|
||||
7.0.5 have been copied into the associated EPICS Release Notes files, and will
|
||||
be added to new EPICS Release Notes published in the future.
|
||||
|
||||
## EPICS Release 7.0.8.1
|
||||
|
||||
### Limit to `_FORTIFY_SOURCE=2`
|
||||
|
||||
GCC versions 12 and beyond and glibc have added some aggressive runtime
|
||||
checks for buffer overflows in libc functions at runtime, and the
|
||||
[Ubuntu 2024.04](https://wiki.ubuntu.com/ToolChain/CompilerFlags) release
|
||||
increased their default gcc fortification level from 2 to 3.
|
||||
This has started causing EPICS Base builds to fail on that version, and
|
||||
other OS releases may make that configuration change with similar results.
|
||||
This release detects a compiler configured with `_FORTIFY_SOURCE=3` and
|
||||
overrides it to 2.
|
||||
Later releases of Base will adjust the code, providing information to the
|
||||
compiler to avoid triggering these incorrect protections.
|
||||
|
||||
### Fix issue with compress record
|
||||
|
||||
In Base 7.0.8, an update to the compress record was added to allow for certain
|
||||
algorithms to use partially filled buffers in their computations. Unfortunately,
|
||||
this broke the behaviour of the records in certain cases. This has been fixed.
|
||||
|
||||
### Various minor changes
|
||||
|
||||
These included fixing minor memory leaks and documentation corrections. The
|
||||
`SIZV` field of lsi, lso and printf record VAL fields now can't exceed 32767
|
||||
characters, to match an internal limit.
|
||||
|
||||
### `epicsSocketAccept()` now returns `SOCKET`, not `int`
|
||||
|
||||
This might have some effect on downstream modules still using `int`, but the
|
||||
OS-specific osdSock.h headers which osiSock.h includes have all declared
|
||||
`SOCKET` (in most casese as a typedef for `int`) for many releases.
|
||||
This change removes a compiler warning on WIN32.
|
||||
Further details and the discussion about this change can be found
|
||||
[here](https://github.com/epics-base/epics-base/pull/458).
|
||||
|
||||
### `dbLoadRecords` allows macros with default values
|
||||
|
||||
Previously the parser assumed that files containing macro substitutions were
|
||||
bad if no macro definitions were provided; that assumption was made incorrect
|
||||
once macro substitutions were allowed to provide a default value.
|
||||
|
||||
### Hostname length limit in CA removed
|
||||
|
||||
Before this release, the CA client library only handled hostnames in address
|
||||
list environment variables up to 255 characters long.
|
||||
This limit has been removed.
|
||||
243
documentation/RELEASE-7.0.8.md
Normal file
243
documentation/RELEASE-7.0.8.md
Normal file
@@ -0,0 +1,243 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
The external PVA submodules continue to maintain their own release notes files
|
||||
as before, but the entries describing changes in those submodules since version
|
||||
7.0.5 have been copied into the associated EPICS Release Notes files, and will
|
||||
be added to new EPICS Release Notes published in the future.
|
||||
|
||||
## EPICS Release 7.0.8
|
||||
|
||||
### bi "Raw Soft Channel" use MASK
|
||||
|
||||
If MASK is non-zero, The raw device support will now apply MASK to the
|
||||
value read into RVAL.
|
||||
eg. allows extraction of a bit from an input integer.
|
||||
|
||||
```
|
||||
record(longin, "integer") {
|
||||
field(VAL, "0xff")
|
||||
}
|
||||
record(bi, "bit1") {
|
||||
field(DESC, "extract bit 1")
|
||||
field(DTYP, "Raw Soft Channel")
|
||||
field(INP , "integer")
|
||||
field(MASK, "0x2")
|
||||
field(ZNAM, "Clear")
|
||||
field(ONAM, "Set")
|
||||
}
|
||||
```
|
||||
|
||||
### ANSI escapes in stderr
|
||||
|
||||
ANSI escape charactor sequences may now be printed to the stderr stream.
|
||||
These escapes will appear in logs captured from that stream.
|
||||
Tools which parse and/or render these logs may need to be adjusted to
|
||||
either strip out the escapes, or to translate them into markup.
|
||||
(see [ansi2html](https://pypi.org/project/ansi2html/) for example)
|
||||
|
||||
### Allow explicit append with `dbRecordsOnceOnly!=0`
|
||||
|
||||
Previously setting `dbRecordsOnceOnly!=0` prevented any further changes to a record via a .db file. eg.
|
||||
|
||||
```
|
||||
record(ai, "myrec") {}
|
||||
```
|
||||
|
||||
`dbRecordsOnceOnly!=0` previously disallowed appending fields with either form:
|
||||
|
||||
```
|
||||
record("*", "myrec") {} # error
|
||||
record(ai, "myrec") {} # error
|
||||
```
|
||||
|
||||
Beginning with this release, `dbRecordsOnceOnly!=0` allows appending when explicitly intended (when record type is `"*"`).
|
||||
|
||||
```
|
||||
record("*", "myrec") {} # allowed
|
||||
record(ai, "myrec") {} # error
|
||||
```
|
||||
|
||||
### Add `$EPICS_CLI_TIMEOUT`
|
||||
|
||||
Add support for CA tools timeout from environment variable `$EPICS_CLI_TIMEOUT`
|
||||
which sets the default the default timeout for `caget` et al.
|
||||
The `-w` argument continues to take precedence.
|
||||
|
||||
### Fixed leak from a non-EPICS thread on WIN32
|
||||
|
||||
On Windows targets, if a thread not created by `epicsThreadCreate*()` directly
|
||||
or indirectly calls an `epicsThread*()` function, a specific tracking struct
|
||||
is allocated. Prior to this release the allocation would not be `free()`d,
|
||||
resulting in a memory leak.
|
||||
|
||||
A similar issue on POSIX targets was previously fixed.
|
||||
|
||||
### Change compiler for FreeBSD to clang
|
||||
|
||||
The default compiler for FreeBSD targets changes from GCC to clang.
|
||||
|
||||
### Expose `dbCreateAlias` in IOC shell
|
||||
|
||||
Add a new IOC shell command `dbCreateAlias` allow record aliases to be added.
|
||||
Intended for use before `iocInit`. eg. to add an alias "bar" for a record "foo".
|
||||
|
||||
```
|
||||
dbLoadRecords("some.db") # includes: record(ai, "foo") { ...
|
||||
dbCreateAlias("foo", "bar")
|
||||
iocInit()
|
||||
```
|
||||
|
||||
### dbEvent eventsRemaining missed on cancel
|
||||
|
||||
In some cases, RSRV may queue a subscription update, but not flush it.
|
||||
This partially addresses this issue.
|
||||
|
||||
### subRecord on bad INP links
|
||||
|
||||
Previously, if a subRecord has an invalid `INP*` link, it was silently failing
|
||||
(and not running the proc function). Now the the status code returned by the
|
||||
subroutine is returned from `dbProcess()`.
|
||||
|
||||
### COMMANDLINE\_LIBRARY fallback to GNU\_DIR
|
||||
|
||||
Fall back to the previous behavior when searching for `readline.h` with older compilers.
|
||||
|
||||
### Search for readline installed via HomeBrew.
|
||||
|
||||
Look for `/opt/local/include/readline` on OSX.
|
||||
|
||||
### Always stop worker threads
|
||||
|
||||
The SCAN and callback threads are now stopped during normal IOC shutdown.
|
||||
|
||||
### Allow runtime bypass of free list allocator
|
||||
|
||||
The environment variable `$EPICS_FREELIST_BYPASS` may be set to `YES` to cause the `freeListLib` functions to always call directly to `malloc()`/`free()`. May be useful when troubleshooting some kinds of memory allocation bugs which would otherwise be "hidden". eg. use-after-free data races. This may also improve the results of dynamic analysis tools which are not aware of this internal free list.
|
||||
|
||||
### `compress` record enhancement
|
||||
|
||||
The compress record now supports the use of partially-filled buffers when using
|
||||
any of the N-to-one algorithms. This is achieved by setting the new field `PBUF`
|
||||
to `YES`.
|
||||
|
||||
### Extended timestamp channel filter
|
||||
|
||||
The `"ts"` filter can now retrieve the record's timestamp in several numeric
|
||||
and string formats, some of which support full nanosecond precision.
|
||||
|
||||
Hal$ caget -a test:channel
|
||||
test:channel 2021-03-11 18:23:48.265386 42
|
||||
Hal$ caget -f9 'test:channel.{"ts": {"num": "dbl"}}'
|
||||
test:channel.{"ts": {"num": "dbl"}} 984331428.265386105
|
||||
Hal$ caget 'test:channel.{"ts": {"str": "iso"}}'
|
||||
test:channel.{"ts": {"str": "iso"}} 2021-03-11T18:23:48.265386+0100
|
||||
Hal$ caget -f1 'test:channel.{"ts": {"num": "ts"}}'
|
||||
test:channel.{"ts": {"num": "ts"}} 2 984331428.0 265386163.0
|
||||
|
||||
More information is included in the filters documentation, which can be found in
|
||||
the `html/filters.html` document that is generated during the build
|
||||
|
||||
### Allow adding new error symbols at any time
|
||||
|
||||
`errSymbolAdd` can now be called after early initialization.
|
||||
|
||||
### Add conditional output (OOPT) to the longout record
|
||||
|
||||
The longout record can now be configured using its new OOPT and OOCH fields
|
||||
to (not) write to its output link depending on the contents of VAL, in a
|
||||
similar manner to the calcout record. More information can be found on the
|
||||
reference page for the longout record type that accompanies this release.
|
||||
|
||||
This functionality was suggested in
|
||||
[lp# 1398215](https://bugs.launchpad.net/epics-base/+bug/1398215) and may
|
||||
be added to other output record types if the community finds it useful,
|
||||
please send feedback about the feature to tech-talk.
|
||||
|
||||
### IOC Shell
|
||||
|
||||
#### Tab completion
|
||||
|
||||
When built with optional GNU libreadline support, the interactive IOC shell
|
||||
will perform tab completion for command names as well as for some arguments
|
||||
of the built-in commands. For example, the record name argument of `dbpr`,
|
||||
and the path name argument of `cd`.
|
||||
|
||||
Externally defined commands have a limited ability to opt into completion by
|
||||
using the new `iocshArgStringRecord` and `iocshArgStringPath` argument types.
|
||||
Both function identically to `iocshArgString` but indicate how to suggest
|
||||
completion strings.
|
||||
|
||||
Builds on macOS (`darwin-x86` or `darwin-aarch64` targets) normally use Apple's
|
||||
libedit library in readline compatibility mode, which doesn't support the tab
|
||||
completion API that GNU readline provides. You can use Homebrew or some other
|
||||
third-party package manager to install the GNU readline package, then edit the
|
||||
`configure/os/CONFIG_SITE.darwinCommon.darwinCommon` file to have EPICS use the
|
||||
real thing to get tab completion in the IOC shell. The default settings in that
|
||||
file currently look for and use a Homebrew-installed readline if present.
|
||||
|
||||
#### Persist history
|
||||
|
||||
Attempt to read and write command to a file (`./.iocsh_history` by default).
|
||||
Name may be overwritten with by setting `$EPICS_IOCSH_HISTFILE` to an
|
||||
alternate path, or disabled by setting to an empty string.
|
||||
|
||||
#### Changes to help output
|
||||
|
||||
Rework the `help` command output to improve formatting and readability,
|
||||
and include a visual marker (a line of underlines) between different help commands.
|
||||
|
||||
### Add FMOD as CALC Expression
|
||||
|
||||
The floating point modulo function `FMOD(NUM,DEN)` has been added to the CALC
|
||||
expression engine and is available to all software using that (calc and calcout
|
||||
record types, access security library and some extensions).
|
||||
|
||||
### Submodule updates
|
||||
|
||||
The pvData module was updated to version 8.0.6:
|
||||
|
||||
- Compatible changes
|
||||
- Actually enable JSON-5 output in PVStructure::Formatter::JSON when available.
|
||||
- Fix unaligned access issues for some ARM/Linux targets.
|
||||
|
||||
The pvAccess module was updated to version 7.1.7:
|
||||
|
||||
- Changes
|
||||
- Registering the PVA server with the IOC now sets the `PVAS_SERVER_PORT`
|
||||
variable in the environment.
|
||||
|
||||
The pva2pva module was updated to version 1.4.1:
|
||||
|
||||
- Bug Fixes
|
||||
- `dbLoadGroup` was fixed
|
||||
- Additions
|
||||
- Support for "meta" member at top of array of structs
|
||||
|
||||
The pvDatabase module was updated to version 4.7.1:
|
||||
|
||||
* Added data distributor plugin which can be used for distributing data between
|
||||
a group of clients. The plugin is triggered by the request string of the
|
||||
form:
|
||||
|
||||
`_[distributor=group:<group id>;set:<set_id>;trigger:<field_name>;updates:<n_updates>;mode:<update_mode>]`
|
||||
|
||||
The plugin parameters are optional and are described bellow:
|
||||
|
||||
- group: this parameter indicates a group that client application belongs to (default value: "default"); groups of clients are completely independent of each other
|
||||
|
||||
- set: this parameter designates a client set that application belongs to within its group (default value: "default")
|
||||
|
||||
- trigger: this is the PV structure field that distinguishes different channel updates (default value: "timeStamp"); for example, for area detector images one could use the "uniqueId" field of the NTND structure
|
||||
|
||||
- updates: this parameter configures how many sequential updates a client (or a set of clients) will receive before the data distributor starts updating the next one (default value: "1")
|
||||
|
||||
- mode: this parameter configures how channel updates are to be distributed between clients in a set:
|
||||
- one: update goes to one client per set
|
||||
- all: update goes to all clients in a set
|
||||
- default is "one" if client set id is not specified, and "all" if set id is specified
|
||||
134
documentation/RELEASE-7.0.9.md
Normal file
134
documentation/RELEASE-7.0.9.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
The external PVA submodules continue to maintain their own release notes files
|
||||
as before, but the entries describing changes in those submodules since version
|
||||
7.0.5 have been copied into the associated EPICS Release Notes files, and will
|
||||
be added to new EPICS Release Notes published in the future.
|
||||
|
||||
## EPICS Release 7.0.9
|
||||
|
||||
### Core documentation published at ReadTheDocs
|
||||
|
||||
The `documentation` directory's `Makefile` can now run various publication scripts including Sphinx and Doxygen to generate formatted documentation that is now being published
|
||||
[at docs.epics-controls.org](https://docs.epics-controls.org/projects/base/en/latest/index.html)
|
||||
and integrated into the main [EPICS Documentation website](https://docs.epics-controls.org/en/latest/index.html).
|
||||
The best place to find out more about these mechanisms is the
|
||||
[Contribution Guide](https://docs.epics-controls.org/en/latest/CONTRIBUTING.html)
|
||||
although it doesn't currently cover the new processes added to epics-base.
|
||||
|
||||
Much of the documentation generated from .dbd.pod files at build time is now
|
||||
also being converted into MarkDown (.md) files and installed into the top-level
|
||||
`doc` directory. Some users might find it quicker to look up information about a
|
||||
record type by opening these files in a text editor intead of opening a browser
|
||||
and loading the HTML versions or finding and opening the files from the EPICS
|
||||
Documentation site.
|
||||
|
||||
### Post monitors from compress record when it's reset
|
||||
|
||||
Writing into a compress record's `RES` field now posts a monitor event instead
|
||||
of only changing `VAL`. Monitor clients will therefore receive an empty array.
|
||||
|
||||
### The AMSG error message propagates through MSS links
|
||||
|
||||
A database link with the MSS attribute will now propagate not only SEVR and
|
||||
STAT, but also AMSG. This field contains additional information that complements
|
||||
STAT. Links with MS or MSI attributes do not propagate STAT, and therefore do
|
||||
not propagate AMSG, either.
|
||||
|
||||
Channel Access links do not propagate AMSG, regardless of the MSS attribute,
|
||||
because the message is not available as Channel metadata.
|
||||
|
||||
### Reloading record aliases
|
||||
|
||||
Aliases can now be defined more than once as long as they still refer to the
|
||||
same record, unless the global variable `dbRecordsOnceOnly` is non-zero.
|
||||
This allows database files to be loaded multiple times, even if they contain
|
||||
alias definitions.
|
||||
|
||||
### `DBE_PROPERTY` event rate changed
|
||||
|
||||
Updating property fields now only posts `DBE_PROPERTY` events if the
|
||||
field actually changed.
|
||||
|
||||
### Changes to msi related to include paths
|
||||
|
||||
There are two changes to `msi` included here.
|
||||
|
||||
`msi` now treats files included by .template or .substutiions files in a more
|
||||
consistent way: for relative paths, it will always look relative to the current
|
||||
working directory if no `-I` flags are passed, and if they are passed then it
|
||||
will search for the _relative_ path from each of those flags. That is, the
|
||||
following will now find the file `bar.template` located at
|
||||
`/some/path/rel/path/bar.template`
|
||||
```
|
||||
$ cat foo.substitutions
|
||||
file rel/path/bar.template {
|
||||
# contents
|
||||
}
|
||||
$ msi -I /some/path foo.substitutions
|
||||
```
|
||||
|
||||
Note that this does provide one change from previous behaviour: when opening a
|
||||
file from the command line, `msi` will not use the `-I`-specified paths to
|
||||
search for the file, but will only work relative to the current working
|
||||
directory, consistent with most commandline utilities.
|
||||
|
||||
### Allow users to delete previously created records from the database
|
||||
|
||||
From this release, record instances and aliases that have already been loaded
|
||||
by an IOC can be removed from the database again before the call to iocInit
|
||||
by loading a second instance of the named records but using `"#"` in place of
|
||||
the record type. Values for the fields are not required or advised, just use
|
||||
an empty record body `{}`. This is useful when a template defines records that
|
||||
are not wanted in some IOCs, without having to split or duplicate the original
|
||||
template.
|
||||
|
||||
For example this will remove the record named "unwanted":
|
||||
|
||||
```
|
||||
record("#", "unwanted") {}
|
||||
```
|
||||
|
||||
### Only keep readline history for interactive sessions
|
||||
|
||||
Previously, all IOCsh commands were persisited in the libreadline history
|
||||
(when readline support is included).
|
||||
Going forward, only interactive commands are saved.
|
||||
|
||||
### Type change to asTrap serverSpecific data
|
||||
|
||||
Change `void*` to `dbChannel*` in `asTrapWriteBeforeWithData()` and
|
||||
`asTrapWriteMessage::serverSpecific` to reflect the reality since
|
||||
the `dbAddr*` to `dbChannel*` migration.
|
||||
External code wishing to support both before and after 3.15 should
|
||||
already be conditionally casting to/from the appropriate type.
|
||||
|
||||
### Fix issues with `_FORTIFY_SOURCE=3`
|
||||
|
||||
This release fixes the false positives failures whhen building with `_FORTIFY_SOURCE` level 3.
|
||||
The override introduced in 7.0.8.1 has been removed.
|
||||
|
||||
### Other
|
||||
|
||||
- genVersionHeader: work with git submodules and worktrees.
|
||||
- avoid UB with self `pthread_join()`
|
||||
- freebsd: Add support for x86 and amd64 builds
|
||||
- Clear AMSG when SEVR becomes zero.
|
||||
- `seqRecord` fix support for link `DLY0`
|
||||
- Add `ABORT_ON_ASSERT` flag to `CONFIG_SITE_ENV`
|
||||
- rationalize osdMutex
|
||||
|
||||
### Submodule updates
|
||||
|
||||
The pvDatabase module was updated to version 4.7.2:
|
||||
|
||||
* Resolved issue with changed field set in the case where the top level (master)
|
||||
field ("_") is not requested by the client, but the master field callback causes
|
||||
all fields to be marked as updated, rather than only those fields that have
|
||||
actually been modified.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,8 +52,6 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<dd>Responsible for managing and tagging the release</dd>
|
||||
<dt><strong>Core Developers</strong></dt>
|
||||
<dd>Responsible for maintaining the EPICS software</dd>
|
||||
<dt><strong>Application Developers</strong></dt>
|
||||
<dd>Responsible for support modules that depend on EPICS Base.</dd>
|
||||
<dt><strong>Website Editors</strong></dt>
|
||||
<dd>Responsible for the EPICS websites</dd>
|
||||
</dl>
|
||||
@@ -91,13 +89,16 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Release Manager<br />
|
||||
<td>Release Manager<br>
|
||||
& all developers</td>
|
||||
<td>Ensure that documentation will be updated before the release date:
|
||||
<td>Request that documentation be updated and information about new
|
||||
features be added before the release date:
|
||||
<ul>
|
||||
<li>Release Notes</li>
|
||||
<li>Doxygen annotations</li>
|
||||
<li>Other documents</li>
|
||||
<li>Other documents on
|
||||
<a href="https://docs.epics-controls.org/en/latest/">
|
||||
docs.epics-controls.org</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -113,16 +114,7 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Platform Developers</td>
|
||||
<td>Run the internal test programs on all available host platforms using
|
||||
<blockquote><tt>
|
||||
make -s runtests
|
||||
</tt></blockquote></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Platform Developers</td>
|
||||
<td>Run the CA client side regression tests on all available host
|
||||
platforms.</td>
|
||||
<td>Run the internal test programs on all appropriate platforms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
@@ -132,19 +124,6 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
setting <tt>STATIC_BUILD=YES</tt> or using a different
|
||||
<tt>INSTALL_LOCATION</tt> in configure/CONFIG_SITE.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Platform Developers</td>
|
||||
<td>Build the SNL Sequencer against this version of Base, and check that
|
||||
the makeBaseApp example builds and runs correctly with it.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Application Developers</td>
|
||||
<td>Build external applications against this version of Base on all
|
||||
available platforms and test as appropriate. Application code changes
|
||||
may be necessary where the EPICS Base APIs have been modified.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Release Manager</td>
|
||||
@@ -152,7 +131,9 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<ul>
|
||||
<li>Release Notes</li>
|
||||
<li>Doxygen annotations</li>
|
||||
<li>Other documents</li>
|
||||
<li>Other documents on
|
||||
<a href="https://docs.epics-controls.org/en/latest/">
|
||||
docs.epics-controls.org</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -173,59 +154,53 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Release Manager</td>
|
||||
<td>
|
||||
<p><b>For each external submodule</b> in turn (assuming it has not been
|
||||
tagged yet):</p>
|
||||
<h4>For each external submodule to be tagged</h4>
|
||||
<ol>
|
||||
<li><tt>git grep UNRELEASED</tt> and insert the module version to any
|
||||
doxygen annotations that have a <tt>@since UNRELEASED</tt> comment.
|
||||
<li><tt>cd base-7.0/modules/<module>; git grep UNRELEASED</tt>
|
||||
and insert the submodule's version number into any doxygen
|
||||
annotations that have a <tt>@since UNRELEASED</tt> comment.
|
||||
Commit (don't push yet).</li>
|
||||
|
||||
<li>Check that the module's Release Notes have been updated to cover
|
||||
all changes; add items as necessary, and set the module version
|
||||
number and release date if appropriate.
|
||||
Commit these changes (don't push).</li>
|
||||
<li>Check that the submodule's Release Notes have been updated to
|
||||
cover all changes; add missing items as necessary, and set the
|
||||
module version number and release date if appropriate.<br>
|
||||
Commit the changes to the submodule's Notes file (don't push).</li>
|
||||
|
||||
<li>Copy the new submodule version number and Release Notes entries
|
||||
into a new file named <tt><i>module</i>-<i>release</i></tt> in the
|
||||
<tt>base-7.0/documentation/new-notes</tt> directory.</li>
|
||||
|
||||
<li>Edit the module's release version file
|
||||
<tt>configure/CONFIG_<i>module</i>_VERSION</tt> and the
|
||||
<tt>Doxyfile</tt>s in the top-level and/or documentation
|
||||
directories. In these, set <tt>DEVELOPMENT_FLAG</tt> to 0 and remove
|
||||
directories. In these, set <tt>DEVELOPMENT_FLAG=0</tt> and remove
|
||||
<tt>-dev</tt> from the <tt>PROJECT_NUMBER</tt> string. Commit these
|
||||
changes (don't push):
|
||||
<blockquote><tt>
|
||||
git ci -m 'Final commit for <module-version>'
|
||||
git commit -m 'Final commit for <submodule-version>'
|
||||
</tt></blockquote>
|
||||
</li>
|
||||
|
||||
<li>Tag the module:
|
||||
<li>Tag the submodule:
|
||||
<blockquote><tt>
|
||||
git tag -m 'ANJ: Tag for EPICS 7.0.8.2' <module-version>
|
||||
git tag -m 'ANJ: Tag for EPICS 7.0.9.1' <submodule-version>
|
||||
</tt></blockquote>
|
||||
</li>
|
||||
|
||||
<li>Generate documentation or Release Notes using one of these:
|
||||
<ul>
|
||||
<li>For older modules with a RELEASE_NOTES.md file convert it to
|
||||
HTML and view in a browser to check the formatting as follows:
|
||||
<blockquote><tt>
|
||||
cd base-7.0/modules/<module>/documentation<br />
|
||||
pandoc -f gfm -t html -o RELEASE_NOTES.html RELEASE_NOTES.md
|
||||
</tt></blockquote>
|
||||
<li>Generate documentation for modules with <tt>release_notes.dox</tt>
|
||||
files. Prepare to update the github-pages website as follows:
|
||||
<blockquote><tt>
|
||||
cd base-7.0/modules/<module>/documentation<br>
|
||||
make commit<br>
|
||||
git push --force upstream gh-pages
|
||||
</tt></blockquote>
|
||||
<i>Q: Delay this <tt>git push</tt> until later?</i></li>
|
||||
|
||||
<li>For newer modules with release_notes.dox file, generate the
|
||||
new github-pages website as follows:
|
||||
<blockquote><tt>
|
||||
cd base-7.0/modules/<module>/documentation<br />
|
||||
make commit
|
||||
git push --force upstream gh-pages
|
||||
</tt></blockquote>
|
||||
<i>Q: Delay this <tt>git push</tt> until later?</i></li>
|
||||
</ul></li>
|
||||
|
||||
<li>Update the git submodule on the Base-7.0 branch to the
|
||||
<li>Update the Git submodule on the Base-7.0 branch to the
|
||||
newly-tagged version, check the module's status matches the tag:
|
||||
<blockquote><tt>
|
||||
cd base-7.0/modules<br />
|
||||
git add <module><br />
|
||||
cd base-7.0/modules<br>
|
||||
git add <module><br>
|
||||
git submodule status --cached
|
||||
</tt></blockquote>
|
||||
Don't commit the submodule updates yet.
|
||||
@@ -241,18 +216,41 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<li>Push commits and the new tag to the submodule's GitHub repository
|
||||
(assumed to be the <tt>upstream</tt> remote):
|
||||
<blockquote><tt>
|
||||
cd base-7.0/modules/<module><br />
|
||||
cd base-7.0/modules/<module><br>
|
||||
git push --follow-tags upstream master
|
||||
</tt></blockquote>
|
||||
</li>
|
||||
|
||||
</ol></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Release Manager</td>
|
||||
<td>
|
||||
<h4>After all submodules have been updated:</h4>
|
||||
<ol>
|
||||
|
||||
<li> Commit the submodule updates which were added for each submodule
|
||||
in step 7 above to the 7.0 branch (don't push):
|
||||
<blockquote><tt>
|
||||
cd base-7.0/modules<br>
|
||||
git commit -m "Update git submodules for release"
|
||||
</tt></blockquote></li>
|
||||
|
||||
<li>Make sure that the output from
|
||||
<tt>git submodule status --cached</tt> only shows the appropriate
|
||||
version tags in the right-most parenthesized column with no
|
||||
<tt>-<i>n</i>-g<i>xxxxxxx</i></tt> suffix.</li>
|
||||
|
||||
<li>Add and commit the new Release Note entry files that were created
|
||||
for each submodule in step 3 above (don't push):
|
||||
<blockquote><tt>
|
||||
cd base-7.0/documentation<br>
|
||||
git add new-notes<br>
|
||||
git commit -m "Add submodule release note entries"
|
||||
</tt></blockquote></li>
|
||||
|
||||
</ol>
|
||||
<p><b>After all submodules complete</b> commit the submodule updates
|
||||
which were added for each submodule in step 4 above to the 7.0 branch
|
||||
(don't push). After committing, make sure that the output from
|
||||
<tt>git submodule status --cached</tt> only shows the appropriate
|
||||
version tags in the right-most parenthesized column with no
|
||||
<tt>-<i>n</t>-g<i>xxxxxxx</i></tt> suffix.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -260,35 +258,81 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td>Release Manager</td>
|
||||
|
||||
<td>
|
||||
<p><tt>git grep UNRELEASED</tt> and insert the release version to any
|
||||
doxygen annotations that have a <tt>@since UNRELEASED</tt> comment.
|
||||
Commit (don't push).</p>
|
||||
<p>Edit the main EPICS Base version file and the built-in module version
|
||||
files:</p>
|
||||
<ul>
|
||||
<li><tt>configure/CONFIG_BASE_VERSION</tt></li>
|
||||
<li><tt>configure/CONFIG_LIBCOM_VERSION</tt></li>
|
||||
<li><tt>configure/CONFIG_CA_VERSION</tt></li>
|
||||
<li><tt>configure/CONFIG_DATABASE_VERSION</tt></li>
|
||||
</ul>
|
||||
<p>Version numbers should be set according to the level of changes made
|
||||
since the last release. Note that the <tt>MAINTENANCE_VERSION</tt> or
|
||||
<tt>PATCH_LEVEL</tt> value should have been incremented after the
|
||||
previous release tag was applied. Set all <tt>DEVELOPMENT_FLAG</tt>
|
||||
values to 0 and <tt>EPICS_DEV_SNAPSHOT</tt> to the empty string.</p>
|
||||
<p>Edit the headings in the Release Notes to show the appropriate
|
||||
version number and remove the warning about this being an unreleased
|
||||
version of EPICS.</p>
|
||||
<p>Commit these changes (don't push).</p>
|
||||
<h4>In the main epics-base repository</h4>
|
||||
<ol>
|
||||
<li><tt>cd base-7.0; git grep UNRELEASED</tt> and insert the release
|
||||
version to any doxygen annotations that have a
|
||||
<tt>@since UNRELEASED</tt> comment. Commit (don't push).</li>
|
||||
|
||||
<li>Edit the main EPICS Base version file and the built-in module
|
||||
version files:
|
||||
<ul>
|
||||
<li><tt>configure/CONFIG_BASE_VERSION</tt></li>
|
||||
<li><tt>configure/CONFIG_LIBCOM_VERSION</tt></li>
|
||||
<li><tt>configure/CONFIG_CA_VERSION</tt></li>
|
||||
<li><tt>configure/CONFIG_DATABASE_VERSION</tt></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Version numbers should be set according to the level of changes
|
||||
made since the last release. Note that the
|
||||
<tt>MAINTENANCE_VERSION</tt> or <tt>PATCH_LEVEL</tt> value will have
|
||||
been incremented immediately after the previous release tag was
|
||||
applied, so don't double-increment them. Set all
|
||||
<tt>DEVELOPMENT_FLAG</tt> values to 0 and set the
|
||||
<tt>EPICS_DEV_SNAPSHOT</tt> to an empty string (no quotes).</li>
|
||||
|
||||
<li>Commit the above changes (don't push):
|
||||
<blockquote><tt>
|
||||
cd base-7.0<br>
|
||||
git add configure/CONFIG_*_VERSION<br>
|
||||
git commit -m "Set core version numbers for release"
|
||||
</tt></blockquote></li>
|
||||
|
||||
<li><p>When <tt>EPICS_DEV_SNAPSHOT</tt> is empty because a release is
|
||||
being created, the <tt>documentation/Makefile</tt> supports a build
|
||||
target <tt>release</tt> for creating a new release notes file
|
||||
<tt>documentation/RELEASE-<i>version</i>.md</tt> from the Markdown
|
||||
files in the <tt>documentation/new-notes</tt> directory. When run,
|
||||
it copies the notes entries from all the <tt>new-notes/*.md</tt>
|
||||
files, then deletes the files and prepares a Git commit to apply
|
||||
those changes permanently to the repository.</p>
|
||||
|
||||
<p>Run these commands to generate the <tt>RELEASE-7.0.9.1.md</tt>
|
||||
file and remove the individual release note entry files:</p>
|
||||
|
||||
<blockquote><tt>
|
||||
cd base-7.0/documentation<br>
|
||||
make
|
||||
</tt></blockquote></li>
|
||||
|
||||
<li>The <tt>make release</tt> command add some changes into the Git
|
||||
index but didn't commit them. These commands let you check what
|
||||
was done and commit the result (don't push yet!):
|
||||
|
||||
<blockquote><tt>
|
||||
git status<br>
|
||||
git diff --staged<br>
|
||||
git commit -m "Generate RELEASE-7.0.9.1.md notes file"
|
||||
</tt></blockquote>
|
||||
|
||||
To undo those Git actions and confirm that happened, run these:
|
||||
|
||||
<blockquote><tt>
|
||||
make unrelease<br>
|
||||
git status
|
||||
</tt></blockquote></li>
|
||||
</ol>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Release Manager</td>
|
||||
<td>Tag the epics-base module in Git:
|
||||
<blockquote><tt>
|
||||
cd base-7.0<br />
|
||||
git tag -m 'ANJ: Tagged for release' R7.0.8.2
|
||||
cd base-7.0<br>
|
||||
git tag -m 'ANJ: Tagged for release' R7.0.9.1
|
||||
</tt></blockquote>
|
||||
<p>Don't push to GitHub yet.</p>
|
||||
</td>
|
||||
@@ -296,7 +340,8 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Release Manager</td>
|
||||
<td>Edit the main EPICS Base version file and the built-in module version
|
||||
<td><h4>After tagging the release</h4>
|
||||
Edit the main EPICS Base version file and the built-in module version
|
||||
files:
|
||||
<ul>
|
||||
<li><tt>configure/CONFIG_BASE_VERSION</tt></li>
|
||||
@@ -321,13 +366,13 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
script generates a gzipped tarfile directly from the tag, excluding the
|
||||
files and directories that are only used for continuous integration:
|
||||
<blockquote><tt>
|
||||
cd base-7.0<br />
|
||||
./.tools/make-tar.sh R7.0.8.2 ../base-7.0.8.2.tar.gz base-7.0.8.2/
|
||||
cd base-7.0<br>
|
||||
./.tools/make-tar.sh R7.0.9.1 ../base-7.0.9.1.tar.gz base-7.0.9.1/
|
||||
</tt></blockquote>
|
||||
Create a GPG signature file of the tarfile as follows:
|
||||
<blockquote><tt>
|
||||
cd ..<br />
|
||||
gpg --armor --sign --detach-sig base-7.0.8.2.tar.gz
|
||||
cd ..<br>
|
||||
gpg --armor --sign --detach-sig base-7.0.9.1.tar.gz
|
||||
</tt></blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -355,9 +400,15 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Website Editor</td>
|
||||
<td>Update the website subdirectory that holds the release
|
||||
documentation, and copy in the files from the base/documentation
|
||||
directory of the tarfile.</td>
|
||||
<td>Add the new release tar file to the website Base download index
|
||||
page.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Website Editor</td>
|
||||
<td>Create or update the website subdirectory that holds the release
|
||||
documentation, and copy in the files to be published with this
|
||||
release version.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
@@ -365,12 +416,6 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td>Update the webpage for the new release with links to the release
|
||||
documents and tar file.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Website Editor</td>
|
||||
<td>Add the new release tar file to the website Base download index
|
||||
page.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Website Editor</td>
|
||||
@@ -393,20 +438,23 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td>Upload the tar file and its <tt>.asc</tt> signature file to the
|
||||
epics-controls web-server.
|
||||
<blockquote><tt>
|
||||
scp base-7.0.8.2.tar.gz base-7.0.8.2.tar.gz.asc epics-controls:download/base<br />
|
||||
scp base-7.0.9.1.tar.gz base-7.0.9.1.tar.gz.asc epics-controls:download/base<br>
|
||||
</tt></blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Website Editor</td>
|
||||
<td>Follow instructions on
|
||||
<td><p>Follow instructions on
|
||||
<a href="https://epics-controls.org/resources-and-support/documents/epics-website-documentation/adding-a-page-for-a-new-release/">
|
||||
Add a page for a new release</a> to create a new release webpage (not
|
||||
required for a patch release, just edit the existing page). Update the
|
||||
TablePress "Point Releases" table and add the new download, and adjust
|
||||
the XYZ Html Snippet for the series download.
|
||||
</td>
|
||||
the Html Snippet for the series download.</p>
|
||||
<p>Not covered in those instructions: Go to Posts, find a previous
|
||||
release and use "Duplicate Post", then edit the result and publish it.
|
||||
This generates the News item.
|
||||
</p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -416,10 +464,11 @@ everything that has to be done since it's so easy to miss steps.</p>
|
||||
<td><input type="checkbox"></td>
|
||||
<td>Release Manager</td>
|
||||
<td>Go to the GitHub
|
||||
<a href="https://github.com/epics-base/epics-base/releases/new?tag=R7.0.8.2">
|
||||
Create release from tag R7.0.8.2</a> page.
|
||||
<a href="https://github.com/epics-base/epics-base/releases/new?tag=R7.0.9.1">
|
||||
Create release from tag R7.0.9.1</a> page.
|
||||
Upload the tar file and its <tt>.asc</tt> signature file to the new
|
||||
GitHub release page.</td>
|
||||
GitHub release page, or just drag-n-drop them into the page.
|
||||
Copy/paste the text from the previous release and edit. Submit.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox"></td>
|
||||
|
||||
7
documentation/ca-API.rst
Normal file
7
documentation/ca-API.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
Channel Access C/C++ APIs
|
||||
=========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: CA Header Files
|
||||
|
||||
22
documentation/ca-cli.md
Normal file
22
documentation/ca-cli.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Channel Access command-line interface
|
||||
|
||||
``` {toctree}
|
||||
:titlesonly:
|
||||
:caption: Tools
|
||||
|
||||
caget
|
||||
cainfo
|
||||
camonitor
|
||||
caput
|
||||
```
|
||||
|
||||
``` {toctree}
|
||||
:titlesonly:
|
||||
:caption: Utilities
|
||||
|
||||
acctst
|
||||
catime
|
||||
casw
|
||||
caEventRate
|
||||
ca_test
|
||||
```
|
||||
@@ -20,11 +20,19 @@ EPICS Base Documentation
|
||||
|
||||
ComponentReference
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
:caption: Command Line Reference
|
||||
|
||||
ca-cli
|
||||
msi
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: C/C++ Headers
|
||||
|
||||
libcom-api
|
||||
ca-api
|
||||
database-api
|
||||
record-api
|
||||
menu-api
|
||||
|
||||
146
documentation/make-notes.pl
Normal file
146
documentation/make-notes.pl
Normal file
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env perl
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2025 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# SPDX-License-Identifier: EPICS
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
# Tool to combine release note entries
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use File::Basename;
|
||||
use Getopt::Std;
|
||||
use version;
|
||||
|
||||
my $tool = basename($0);
|
||||
|
||||
our ($opt_d, $opt_h, $opt_o, $opt_D, $opt_V);
|
||||
|
||||
sub HELP_MESSAGE {
|
||||
print STDERR "Usage: $tool -o outfile.md -V 7.0.10 [-d new-notes] [-D] " .
|
||||
"RELEASE-*.md\n";
|
||||
exit 2;
|
||||
}
|
||||
|
||||
HELP_MESSAGE()
|
||||
if !getopts('hd:o:DV:') || $opt_h;
|
||||
|
||||
die "$tool: Release version '-V' option required\n"
|
||||
unless defined $opt_V;
|
||||
die "$tool: Version string '$opt_V' not legal\n"
|
||||
unless $opt_V =~ m/^ (0 | [1-9][0-9]*) (\. [0-9]{1,3}){0,3} $/x;
|
||||
die "$tool: Output filename '-o' required\n"
|
||||
unless defined $opt_o;
|
||||
die "$tool: Output filename '-o $opt_o' must end with '.md'\n"
|
||||
unless $opt_o =~ m/\.md $/x;
|
||||
die "$tool: New notes directory '-d $opt_d' doesn't exist\n"
|
||||
if defined $opt_d && !-d $opt_d;
|
||||
|
||||
open my $out, '>:encoding(UTF-8)', $opt_o or
|
||||
die "$tool: Can't create $opt_o: $!\n";
|
||||
|
||||
$SIG{__DIE__} = sub {
|
||||
die @_ if $^S; # Ignore eval deaths
|
||||
close $out;
|
||||
unlink $opt_o;
|
||||
};
|
||||
|
||||
my $REL_VERS = $opt_V;
|
||||
$REL_VERS .= '-DEV' if $opt_D;
|
||||
|
||||
my @notes;
|
||||
if ($opt_d) {
|
||||
# Directory handle for scanning the new-notes directory
|
||||
opendir my $dh, $opt_d or
|
||||
die "$tool: Can't open '-d' directory: $!\n";
|
||||
|
||||
foreach my $fn (sort grep !m/^ \. \.? $/x, readdir $dh) {
|
||||
next if $fn eq 'README.txt';
|
||||
die "$tool: Not markdown? File '$fn' lacks '.md' extension\n"
|
||||
unless $fn =~ m/\.md$/;
|
||||
local $/;
|
||||
my $file = "$opt_d/$fn";
|
||||
push @notes, do {
|
||||
open my $fh, '<:encoding(UTF-8)', $file or
|
||||
die "$tool: Can't open file $file: $!\n";
|
||||
<$fh>;
|
||||
};
|
||||
}
|
||||
close $dh;
|
||||
}
|
||||
|
||||
sub relVers {
|
||||
$_ = shift;
|
||||
m/RELEASE-([0-9.]+)\.md/;
|
||||
return $1;
|
||||
}
|
||||
|
||||
# Reverse sort of the RELEASE-<version>.md filenames
|
||||
my @OLD_REL_FILES = sort {
|
||||
version->parse(relVers($b)) <=> version->parse(relVers($a));
|
||||
} @ARGV;
|
||||
|
||||
print $out <<"__REL_INTRO__";
|
||||
# Release Notes
|
||||
|
||||
This document describes the changes that were included in the release of EPICS
|
||||
noted below. Release entries are now provided in a separate document for each
|
||||
version in the EPICS 7 series, but all are combined into a single page for
|
||||
publishing on the EPICS website. Separate release documents are also included
|
||||
from the older Base 3.15 and 3.16 series.
|
||||
|
||||
The external PVA submodules continue to maintain their own release notes files
|
||||
as before, but the entries describing changes in those submodules since version
|
||||
7.0.5 have been copied into the associated EPICS Release Notes files; they will
|
||||
also be manually added to new EPICS Release Notes published in the future.
|
||||
|
||||
|
||||
## EPICS Release $REL_VERS
|
||||
|
||||
__REL_INTRO__
|
||||
|
||||
print $out <<"__NEW_INTRO__" if $opt_D && scalar @notes;
|
||||
__This version of EPICS has not been released yet.__
|
||||
__When the changes described below get released, the version number used may be
|
||||
different to the one given above.__
|
||||
|
||||
The changes below have been merged into EPICS since the last published release.
|
||||
|
||||
__NEW_INTRO__
|
||||
|
||||
# Include the text from all the new entries
|
||||
print $out map { "$_\n" } @notes;
|
||||
|
||||
# Add myst include directives to incorporate older release files
|
||||
foreach my $rfile (@OLD_REL_FILES) {
|
||||
my $ver = relVers($rfile);
|
||||
if ($ver =~ m/^7\./) {
|
||||
print $out <<"__OLD_RELEASE_7__";
|
||||
-----
|
||||
|
||||
## EPICS Release $ver
|
||||
|
||||
```{include} ../$rfile
|
||||
:start-after: EPICS Release $ver
|
||||
```
|
||||
|
||||
__OLD_RELEASE_7__
|
||||
}
|
||||
elsif ($ver =~ m/^3\.1[56]/) {
|
||||
print $out <<"__OLD_RELEASE_3__";
|
||||
-----
|
||||
|
||||
```{include} ../$rfile
|
||||
:heading-offset: 1
|
||||
```
|
||||
|
||||
__OLD_RELEASE_3__
|
||||
}
|
||||
}
|
||||
|
||||
close $out;
|
||||
|
||||
7
documentation/new-notes/PR-518.md
Normal file
7
documentation/new-notes/PR-518.md
Normal file
@@ -0,0 +1,7 @@
|
||||
### Reduce symbol and macro pollution from epicsAtomic.h on WIN32
|
||||
|
||||
`epicsAtomic.h` no longer pulls in as many unneeded declarations and macros from
|
||||
`windows.h`. Prior to this change, including `epicsAtomic.h` at the wrong time
|
||||
could result in unexpected compiler errors. Due to the nature of `windows.h`,
|
||||
some unneeded declarations are still pulled in, however the number is greatly reduced.
|
||||
Code that needs these declarations should explicitly include `windows.h` before `epicsAtomic.h`.
|
||||
23
documentation/new-notes/PR-558.md
Normal file
23
documentation/new-notes/PR-558.md
Normal file
@@ -0,0 +1,23 @@
|
||||
### New `afterIocRunning` IOC Shell Command Added
|
||||
|
||||
This release incorporates [PR #558](https://github.com/epics-base/epics-base/pull/558) which added a new IOC shell command `afterIocRunning`. This command allows startup scripts to schedule arbitrary commands to be executed automatically after the IOC initialization phase (`iocInit`).
|
||||
|
||||
`afterIocRunning` allows you to write better-structured IOC shell files to include in your startup scripts without tracking where `iocInit` is located (and how IOC is deployed) e.g.:
|
||||
- to achieve the best maintainability (e.g. encapsulation of the context into one file),
|
||||
- to improve writing boot sequences,
|
||||
- to improve IOC startup flexibility and scripting capabilities,
|
||||
- it replaces the community [`afterInit`](https://github.com/paulscherrerinstitute/iocsh_utilities/blob/master/afterInit.c) and [`doAfterIocInit`](https://github.com/epics-modules/std/blob/master/stdApp/src/delayCmd.cpp) IOC shell commands,
|
||||
- community usage examples:
|
||||
- [`pf4filters.iocsh`](https://github.com/epics-modules/optics/blob/master/opticsApp/iocsh/pf4filters.iocsh) - enable/disable with a single comment ([full description](https://github.com/epics-base/epics-base/pull/558#issuecomment-2430057167))
|
||||
- [ALS-U autosave managment](https://github.com/epics-base/epics-base/pull/558#issuecomment-2430447220)
|
||||
|
||||
#### Features
|
||||
|
||||
- Define commands that run after IOC initialization completes.
|
||||
- Executes following `iocInit` and `autosave` initialization (important for proper PV configuration).
|
||||
- Supports any valid IOC shell command as an argument.
|
||||
- Example usages:
|
||||
- `afterIocRunning "dbpf <PV> <VAL>"`
|
||||
- `afterIocRunning "date"`
|
||||
- `afterIocRunning "dbpf $(P)EvtClkSource-Sel 'Upstream (fanout)'"`
|
||||
- `afterIocRunning "dbpf $(P)Enable-Sel Enabled"`
|
||||
5
documentation/new-notes/PR-587.md
Normal file
5
documentation/new-notes/PR-587.md
Normal file
@@ -0,0 +1,5 @@
|
||||
### fdManager file descriptor limit removed
|
||||
|
||||
In order to support file descriptors above 1023, fdManager now uses
|
||||
`poll()` instead of `select()` on all architectures that support it
|
||||
(Linux, MacOS, Windows, newer RTEMS).
|
||||
7
documentation/new-notes/PR-592.md
Normal file
7
documentation/new-notes/PR-592.md
Normal file
@@ -0,0 +1,7 @@
|
||||
### New `dbServerStats()` API for iocStats
|
||||
|
||||
A new routine provides the ability to request channel and client counts from
|
||||
named server layers that implement the `stats()` method, or to get a summary
|
||||
of the counts from all registered server layers. A preprocessor macro
|
||||
`HAS_DBSERVER_STATS` macro is defined in the `dbServer.h` header file to
|
||||
simplify code that needs to support older versions of Base as well.
|
||||
4
documentation/new-notes/PR-599.md
Normal file
4
documentation/new-notes/PR-599.md
Normal file
@@ -0,0 +1,4 @@
|
||||
### epicsExport simplifications
|
||||
|
||||
`epicsExportAddress()`, `epicsExportRegistrar()` and `epicsRegisterFunction()`
|
||||
no longer require to be wrapped in `extern "C" { }` in C++ code.
|
||||
14
documentation/new-notes/PR-603.md
Normal file
14
documentation/new-notes/PR-603.md
Normal file
@@ -0,0 +1,14 @@
|
||||
### Support for multiline strings in iocsh files
|
||||
|
||||
GitHub [PR #603](https://github.com/epics-base/epics-base/pull/603)
|
||||
|
||||
This update introduces support for multiline strings in IOC shell (iocsh) files.
|
||||
Previously, string values in iocsh files were limited to a single line, making
|
||||
it difficult to include longer or formatted text. With this change, users can
|
||||
now define strings that span multiple lines, improving readability and
|
||||
flexibility when configuring IOC shell scripts.
|
||||
|
||||
To create a multiline string, end a line with a backslash (`\`). The following
|
||||
line, including any leading whitespace, will be joined to the previous line.
|
||||
If the backslash is immediately followed by any character other than a newline,
|
||||
it will not be treated as a multiline continuation.
|
||||
4
documentation/new-notes/PR-613.md
Normal file
4
documentation/new-notes/PR-613.md
Normal file
@@ -0,0 +1,4 @@
|
||||
### Enhancement to IOC `dbgrep` command
|
||||
|
||||
`dbgrep` now takes an optional second string argument consisting of a list of field names
|
||||
separated by spaces, e.g. `dbgrep "*PRESSURE*", "VAL DESC"`
|
||||
5
documentation/new-notes/PR-626.md
Normal file
5
documentation/new-notes/PR-626.md
Normal file
@@ -0,0 +1,5 @@
|
||||
*** Add `dbglob` to replace `dbgrep`
|
||||
|
||||
A new IOC shell command, `dbglob` has been added, with `dbgrep` becoming
|
||||
an alias of this new function, with the intent of deprecating it in a
|
||||
future release.
|
||||
33
documentation/new-notes/PR-628.md
Normal file
33
documentation/new-notes/PR-628.md
Normal file
@@ -0,0 +1,33 @@
|
||||
### Conflict-free release note entries for GitHub pull requests
|
||||
|
||||
GitHub [PR #628](https://github.com/epics-base/epics-base/pull/628)
|
||||
|
||||
This release replaces the developer-edited `documentation/RELEASE_NOTES.md`
|
||||
source file in the EPICS tree with a process which generates that file from a
|
||||
series of individual files added for each changeset in the release, thus
|
||||
preventing merge conflicts when entries are added by many different pull
|
||||
requests.
|
||||
|
||||
For this new approach each pull request must add its own Markdown file to the
|
||||
`documentation/new-notes` directory, using a unique filename.
|
||||
When a release is made, all these files will be combined into a single
|
||||
`RELEASE-<version>.md` file and the `new-notes` directory emptied to prepare
|
||||
for development of the next release.
|
||||
|
||||
Developers can generate the `RELEASE_NOTES.md` file by running `make` in the
|
||||
`documentation` directory, which will install the result in the `doc` top-level
|
||||
directory along with the `RELEASE-<version>.md` files describing older EPICS
|
||||
releases going back to 3.15.
|
||||
The `documentation/Makefile` provides some other targets which can also be
|
||||
requested, but they require additional non-EPICS software such as Doxygen and
|
||||
Sphinx to have been installed first.
|
||||
|
||||
Between releases the generated `RELEASE_NOTES.md` file contains the text from
|
||||
any `new-notes` files added to document changes already merged.
|
||||
It also provides links to the older `RELEASE-<version>.md` files, so it remains
|
||||
the starting point for documentation on all release changes.
|
||||
|
||||
Detailed instructions on creating new entries are provided in a `README.txt`
|
||||
file in the `documentation/new-notes` directory.
|
||||
The release-time process that generates a new `RELEASE-<version>.md` file is
|
||||
described in the `documentation/ReleaseChecklist.html` file.
|
||||
6
documentation/new-notes/PR-636.md
Normal file
6
documentation/new-notes/PR-636.md
Normal file
@@ -0,0 +1,6 @@
|
||||
### Add support for EPICS_DB_INCLUDE_PATH to dbLoadTemplate
|
||||
|
||||
GitHub [PR #636](https://github.com/epics-base/epics-base/pull/636)
|
||||
|
||||
Allow finding the substitution file using path in `EPICS_DB_INCLUDE_PATH` or
|
||||
an additional parameter to `dbLoadTemplate`.
|
||||
32
documentation/new-notes/PR-644.md
Normal file
32
documentation/new-notes/PR-644.md
Normal file
@@ -0,0 +1,32 @@
|
||||
### Expand the use of colour in the IOCs output
|
||||
|
||||
This release includes various changes to iocsh.cpp and elsewhere to add and
|
||||
expand the use of color:
|
||||
|
||||
- When loading a startup script, the IOC Shell now displays comment lines in
|
||||
blue, and uses bold to make command lines stand out from other text.
|
||||
|
||||
- The `softIoc -v` output also uses the above color scheme for the commands it
|
||||
prints.
|
||||
|
||||
- The default IOC Shell prompt is now displayed in green; this color can be
|
||||
modified in the `configure/CONFIG_SITE_ENV` file for all targets, or set for
|
||||
a specific target by adding a `configure/os/CONFIG_SITE_ENV.<arch>` file.
|
||||
The value of the `IOCSH_PS1` environment paremeter in those files can use the
|
||||
`ANSI_ENV_*` and `ANSI_*()` color macros found in errlog.h to configure the
|
||||
appearance of the prompt. The C string literal concatenation syntax can be
|
||||
used to construct the prompt string:
|
||||
|
||||
```Makefile
|
||||
IOCSH_PS1 = ANSI_ESC_RED "e" ANSI_ESC_YELLOW "p" ANSI_ESC_GREEN "i" \
|
||||
ANSI_ESC_CYAN "c" ANSI_BLUE("s") "> "
|
||||
```
|
||||
|
||||
- More error messages printed by IOC Shell commands now appear in red, or use
|
||||
the red `ERROR` prefix that was introduced in previous releases.
|
||||
|
||||
- The word "Illegal" has been replaced with "Invalid" in several Shell error
|
||||
messages.
|
||||
|
||||
- The iocsh `var` command now shows the data type of the registered variables
|
||||
as well as their values.
|
||||
7
documentation/new-notes/PR-655.md
Normal file
7
documentation/new-notes/PR-655.md
Normal file
@@ -0,0 +1,7 @@
|
||||
### Records calc, calcout and sub extended
|
||||
|
||||
The record types calc, calcout and sub have been extended from
|
||||
12 inputs A-L to 21 inputs A-U.
|
||||
The macro `CALCPERFORM_NARGS` reflects this change.
|
||||
The new inputs can be used in calc links and access security as well.
|
||||
The size of CALC and OCAL fields have been doubled to 160 chars.
|
||||
4
documentation/new-notes/PR-676.md
Normal file
4
documentation/new-notes/PR-676.md
Normal file
@@ -0,0 +1,4 @@
|
||||
### IVOA for dfanout
|
||||
|
||||
The dfanout record now has invalid output handling with the usual fields
|
||||
`IVOA` and `IVOV` just like other output records.
|
||||
13
documentation/new-notes/PR-678.md
Normal file
13
documentation/new-notes/PR-678.md
Normal file
@@ -0,0 +1,13 @@
|
||||
### Allow hex and octal strings in dbPut and dbGet
|
||||
|
||||
It is now possible to convert hex and octal strings to integer fields
|
||||
with `dbPut()`, `dbGet()` and related functions like the iocsh command
|
||||
`dbpf` or through database links.
|
||||
|
||||
Possible incompatibility: Up to now, leading `0`s have been ignored,
|
||||
now they switch to octal mode.
|
||||
|
||||
For backward compatibility, this behavior can be switched off, returning
|
||||
to the old decimal only conversions, by setting the environment variable
|
||||
`EPICS_DB_CONVERT_DECIMAL_ONLY` to anything except the empty string or
|
||||
strings starting with `n`, `N`, `f`, `F` or `0` before `iocInit`.
|
||||
8
documentation/new-notes/PR-679.md
Normal file
8
documentation/new-notes/PR-679.md
Normal file
@@ -0,0 +1,8 @@
|
||||
### Apply log prefix to each line
|
||||
|
||||
If multi-line ioc log messages are sent with `errlogPrintf()`, apply
|
||||
`logClientPrefix` (e.g. set by `iocLogPrefix`) to each line in order to help
|
||||
browsing the log files.
|
||||
Also strip off any leading newlines which some calls have.
|
||||
|
||||
Extend `errlog` iocsh command to interpret escape chars (just like `echo`).
|
||||
52
documentation/new-notes/README.txt
Normal file
52
documentation/new-notes/README.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
documentation/new-notes/README.txt
|
||||
==================================
|
||||
|
||||
The documentation/new-notes directory is for new release note entries that
|
||||
describe changes merged into EPICS Base since the previous release.
|
||||
Files here must be written in Markdown (see below) and have the extension
|
||||
'.md' at the end of their filename.
|
||||
This README.txt file is the only other file that should appear here.
|
||||
|
||||
|
||||
Generating RELEASE_NOTES.md
|
||||
---------------------------
|
||||
|
||||
Running 'make' inside the Base documentation directory now generates a
|
||||
file RELEASE_NOTES.md and installs it into the top-level doc directory.
|
||||
|
||||
The file starts with a level-1 Markdown header and some introductory text.
|
||||
If any new-notes files are present a level-2 header is added with a Release
|
||||
version number and a -DEV suffix, followed by some notes explaining their
|
||||
unreleased status. The new-notes filenames are lexically sorted and their
|
||||
contents added in order, separated by an extra newline character.
|
||||
|
||||
Finally a series of myst Markdown directives are added which will include all
|
||||
the older RELEASE-<version>.md files present in the documentation directory
|
||||
into the published HTML version, sorted in version order with the newest first.
|
||||
|
||||
|
||||
Writing a Release Notes entry
|
||||
-----------------------------
|
||||
|
||||
Add a new file to the new-notes directory for your entry. If this is for a
|
||||
GitHub pull request to the epics-base project please use the name 'PR-nnn.md'
|
||||
where nnn is the number of the pull request. If you haven't created the pull
|
||||
request yet you can use the number from a related GitHub issue, or use some
|
||||
other name, then rename and push it after the PR has been created.
|
||||
|
||||
The file should start with a level-3 Markdown title for the entry, like this:
|
||||
|
||||
### Conflict-free release note entries for GitHub pull requests
|
||||
|
||||
GitHub [PR #628](https://github.com/epics-base/epics-base/pull/628)
|
||||
|
||||
* The three '#' characters of the title start in the left-most column.
|
||||
* The title should provide a short summary, and not end in a period.
|
||||
* A link to the GitHub pull-request may follow if desired as shown above
|
||||
(followed by a blank line to separate it from the next paragraph), or a
|
||||
link to the PR may be integrated into the text that follows.
|
||||
* Use blank lines between paragraphs of text, and code-blocks for examples.
|
||||
|
||||
Release note entries are not intended to provide full documentation of major
|
||||
features. For small features or changes though, they may provide all the
|
||||
information needed to understand and use the feature.
|
||||
@@ -5,7 +5,7 @@
|
||||
Name: epics-base-%{EpicsVersion}
|
||||
Summary: EPICS Base %{EpicsVersion}
|
||||
Version: 1
|
||||
Release: 2%{?dist}
|
||||
Release: 4%{?dist}
|
||||
License: EPICS Open License
|
||||
Group: Development/Languages
|
||||
URL: https://git.psi.ch/epics_base/base-7.0
|
||||
|
||||
@@ -12,6 +12,11 @@ TOP = ../../../..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
HTMLS += CAref.html
|
||||
DOCS += acctst.md
|
||||
DOCS += catime.md
|
||||
DOCS += casw.md
|
||||
DOCS += caEventRate.md
|
||||
DOCS += ca_test.md
|
||||
|
||||
#
|
||||
# includes to install from this subproject
|
||||
|
||||
18
modules/ca/src/client/acctst.md
Normal file
18
modules/ca/src/client/acctst.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# acctst
|
||||
|
||||
acctst <PV name> [progress logging level] [channel duplication count]
|
||||
[test repetition count] [enable preemptive callback]
|
||||
|
||||
## Description
|
||||
|
||||
Channel Access Client Library regression test.
|
||||
|
||||
The PV used with the test must be native type `DBR_DOUBLE` or `DBR_FLOAT`,
|
||||
and modified only by acctst while the test is running. Therefore,
|
||||
periodically scanned hardware attached analog input records do not work
|
||||
well. Test failure is indicated if the program stops prior to printing
|
||||
"test complete". If unspecified the progress logging level is zero,
|
||||
and no messages are printed while the test is progressing. If
|
||||
unspecified, the channel duplication count is 20000. If unspecified, the
|
||||
test repetition count is once only. If unspecified, preemptive callback
|
||||
is disabled.
|
||||
10
modules/ca/src/client/caEventRate.md
Normal file
10
modules/ca/src/client/caEventRate.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# caEventRate
|
||||
|
||||
caEventRate <PV name> [subscription count]
|
||||
|
||||
## Description
|
||||
|
||||
Connect to the specified PV, subscribe for monitor updates the specified
|
||||
number of times (default once), and periodically log the current sampled
|
||||
event rate, average event rate, and the standard deviation of the event
|
||||
rate in Hertz to standard out.
|
||||
10
modules/ca/src/client/ca_test.md
Normal file
10
modules/ca/src/client/ca_test.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# ca_test
|
||||
|
||||
ca_test <PV name> [value to be written]
|
||||
|
||||
## Description
|
||||
|
||||
If a value is specified it is written to the PV. Next, the current value
|
||||
of the PV is converted to each of the many external data type that can
|
||||
be specified at the CA client library interface, and each of these is
|
||||
formated and then output to the console.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file caerr.h
|
||||
*
|
||||
* \brief Channel access error definitions.
|
||||
*/
|
||||
|
||||
#ifndef INC_caerr_H
|
||||
#define INC_caerr_H
|
||||
@@ -75,72 +79,139 @@
|
||||
* servers on earlier releases that communicate with current clients
|
||||
* might still generate exceptions with these error constants
|
||||
*/
|
||||
|
||||
/// Normal successful completion
|
||||
#define ECA_NORMAL DEFMSG(CA_K_SUCCESS, 0) /* success */
|
||||
/// Maximum simultaneous IOC connections exceeded
|
||||
#define ECA_MAXIOC DEFMSG(CA_K_ERROR, 1) /* defunct */
|
||||
/// Unknown internet host
|
||||
#define ECA_UKNHOST DEFMSG(CA_K_ERROR, 2) /* defunct */
|
||||
/// Unknown internet service
|
||||
#define ECA_UKNSERV DEFMSG(CA_K_ERROR, 3) /* defunct */
|
||||
/// Unable to allocate a new socket
|
||||
#define ECA_SOCK DEFMSG(CA_K_ERROR, 4) /* defunct */
|
||||
/// Unable to connect to internet host or service
|
||||
#define ECA_CONN DEFMSG(CA_K_WARNING, 5) /* defunct */
|
||||
/// Unable to allocate additional dynamic memory
|
||||
#define ECA_ALLOCMEM DEFMSG(CA_K_WARNING, 6)
|
||||
/// Unknown IO channel
|
||||
#define ECA_UKNCHAN DEFMSG(CA_K_WARNING, 7) /* defunct */
|
||||
/// ECA_UKNFIELD - Record field specified inappropriate for channel specified
|
||||
#define ECA_UKNFIELD DEFMSG(CA_K_WARNING, 8) /* defunct */
|
||||
/// The requested data transfer is greater than available memory or EPICS_CA_MAX_ARRAY_BYTES
|
||||
#define ECA_TOLARGE DEFMSG(CA_K_WARNING, 9)
|
||||
/// User specified timeout on IO operation expired
|
||||
#define ECA_TIMEOUT DEFMSG(CA_K_WARNING, 10)
|
||||
/// Sorry, that feature is planned but not supported at this time
|
||||
#define ECA_NOSUPPORT DEFMSG(CA_K_WARNING, 11) /* defunct */
|
||||
/// The supplied string is unusually large
|
||||
#define ECA_STRTOBIG DEFMSG(CA_K_WARNING, 12) /* defunct */
|
||||
/// The request was ignored because the specified channel is disconnected
|
||||
#define ECA_DISCONNCHID DEFMSG(CA_K_ERROR, 13) /* defunct */
|
||||
/// The data type specifed is invalid
|
||||
#define ECA_BADTYPE DEFMSG(CA_K_ERROR, 14)
|
||||
/// Remote Channel not found
|
||||
#define ECA_CHIDNOTFND DEFMSG(CA_K_INFO, 15) /* defunct */
|
||||
/// Unable to locate all user specified channels
|
||||
#define ECA_CHIDRETRY DEFMSG(CA_K_INFO, 16) /* defunct */
|
||||
/// Channel Access Internal Failure
|
||||
#define ECA_INTERNAL DEFMSG(CA_K_FATAL, 17)
|
||||
/// The requested local DB operation failed
|
||||
#define ECA_DBLCLFAIL DEFMSG(CA_K_WARNING, 18) /* defunct */
|
||||
/// Channel read request failed
|
||||
#define ECA_GETFAIL DEFMSG(CA_K_WARNING, 19)
|
||||
/// Channel write request failed
|
||||
#define ECA_PUTFAIL DEFMSG(CA_K_WARNING, 20)
|
||||
/// Channel subscription request failed
|
||||
#define ECA_ADDFAIL DEFMSG(CA_K_WARNING, 21) /* defunct */
|
||||
/// Invalid element count requested
|
||||
#define ECA_BADCOUNT DEFMSG(CA_K_WARNING, 22)
|
||||
/// Invalid string
|
||||
#define ECA_BADSTR DEFMSG(CA_K_ERROR, 23)
|
||||
/// Virtual circuit disconnect
|
||||
#define ECA_DISCONN DEFMSG(CA_K_WARNING, 24)
|
||||
/// Identical process variable names on multiple servers
|
||||
#define ECA_DBLCHNL DEFMSG(CA_K_WARNING, 25)
|
||||
/// Request inappropriate within subscription (monitor) update callback
|
||||
#define ECA_EVDISALLOW DEFMSG(CA_K_ERROR, 26)
|
||||
/// Database value get for that channel failed during channel search
|
||||
#define ECA_BUILDGET DEFMSG(CA_K_WARNING, 27) /* defunct */
|
||||
/// Unable to initialize without the vxWorks VX_FP_TASK task option set
|
||||
#define ECA_NEEDSFP DEFMSG(CA_K_WARNING, 28) /* defunct */
|
||||
/// Event queue overflow has prevented first pass event after event add
|
||||
#define ECA_OVEVFAIL DEFMSG(CA_K_WARNING, 29) /* defunct */
|
||||
/// Bad event subscription (monitor) identifier
|
||||
#define ECA_BADMONID DEFMSG(CA_K_ERROR, 30)
|
||||
/// Remote channel has new network address
|
||||
#define ECA_NEWADDR DEFMSG(CA_K_WARNING, 31) /* defunct */
|
||||
/// New or resumed network connection
|
||||
#define ECA_NEWCONN DEFMSG(CA_K_INFO, 32) /* defunct */
|
||||
/// Specified task isnt a member of a CA context
|
||||
#define ECA_NOCACTX DEFMSG(CA_K_WARNING, 33) /* defunct */
|
||||
/// Attempt to use defunct CA feature failed
|
||||
#define ECA_DEFUNCT DEFMSG(CA_K_FATAL, 34) /* defunct */
|
||||
/// The supplied string is empty
|
||||
#define ECA_EMPTYSTR DEFMSG(CA_K_WARNING, 35) /* defunct */
|
||||
/// Unable to spawn the CA repeater thread- auto reconnect will fail
|
||||
#define ECA_NOREPEATER DEFMSG(CA_K_WARNING, 36) /* defunct */
|
||||
/// No channel id match for search reply- search reply ignored
|
||||
#define ECA_NOCHANMSG DEFMSG(CA_K_WARNING, 37) /* defunct */
|
||||
/// Reseting dead connection- will try to reconnect
|
||||
#define ECA_DLCKREST DEFMSG(CA_K_WARNING, 38) /* defunct */
|
||||
/// Server (IOC) has fallen behind or is not responding- still waiting
|
||||
#define ECA_SERVBEHIND DEFMSG(CA_K_WARNING, 39) /* defunct */
|
||||
/// No internet interface with broadcast available
|
||||
#define ECA_NOCAST DEFMSG(CA_K_WARNING, 40) /* defunct */
|
||||
/// Invalid event selection mask
|
||||
#define ECA_BADMASK DEFMSG(CA_K_ERROR, 41)
|
||||
/// IO operations have completed
|
||||
#define ECA_IODONE DEFMSG(CA_K_INFO, 42)
|
||||
/// IO operations are in progress
|
||||
#define ECA_IOINPROGRESS DEFMSG(CA_K_INFO, 43)
|
||||
/// Invalid synchronous group identifier
|
||||
#define ECA_BADSYNCGRP DEFMSG(CA_K_ERROR, 44)
|
||||
/// Put callback timed out
|
||||
#define ECA_PUTCBINPROG DEFMSG(CA_K_ERROR, 45)
|
||||
/// Read access denied
|
||||
#define ECA_NORDACCESS DEFMSG(CA_K_WARNING, 46)
|
||||
/// Write access denied
|
||||
#define ECA_NOWTACCESS DEFMSG(CA_K_WARNING, 47)
|
||||
/// Requested feature is no longer supported
|
||||
#define ECA_ANACHRONISM DEFMSG(CA_K_ERROR, 48)
|
||||
/// Empty PV search address list
|
||||
#define ECA_NOSEARCHADDR DEFMSG(CA_K_WARNING, 49)
|
||||
/// No reasonable data conversion between client and server types
|
||||
#define ECA_NOCONVERT DEFMSG(CA_K_WARNING, 50)
|
||||
/// Invalid channel identifier
|
||||
#define ECA_BADCHID DEFMSG(CA_K_ERROR, 51)
|
||||
/// Invalid function pointer
|
||||
#define ECA_BADFUNCPTR DEFMSG(CA_K_ERROR, 52)
|
||||
/// Thread is already attached to a client context
|
||||
#define ECA_ISATTACHED DEFMSG(CA_K_WARNING, 53)
|
||||
/// Not supported by attached service
|
||||
#define ECA_UNAVAILINSERV DEFMSG(CA_K_WARNING, 54)
|
||||
/// User destroyed channel
|
||||
#define ECA_CHANDESTROY DEFMSG(CA_K_WARNING, 55)
|
||||
/// Invalid channel priority
|
||||
#define ECA_BADPRIORITY DEFMSG(CA_K_ERROR, 56)
|
||||
/// Preemptive callback not enabled - additional threads may not join context
|
||||
#define ECA_NOTTHREADED DEFMSG(CA_K_ERROR, 57)
|
||||
/// Client's protocol revision does not support transfers exceeding 16k bytes
|
||||
#define ECA_16KARRAYCLIENT DEFMSG(CA_K_WARNING, 58)
|
||||
/// Virtual circuit connection sequence aborted
|
||||
#define ECA_CONNSEQTMO DEFMSG(CA_K_WARNING, 59)
|
||||
/// Virtual circuit unresponsive
|
||||
#define ECA_UNRESPTMO DEFMSG(CA_K_WARNING, 60)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Return a message character string corresponding to a user specified CA status code.
|
||||
*
|
||||
* \param[in] ca_status A CA status code.
|
||||
* \returns The corresponding error message string.
|
||||
*/
|
||||
LIBCA_API const char * epicsStdCall ca_message(long ca_status);
|
||||
|
||||
LIBCA_API extern const char * ca_message_text [];
|
||||
|
||||
@@ -8,37 +8,43 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/** \file caeventmask.h
|
||||
*
|
||||
* \brief Event selections
|
||||
*/
|
||||
|
||||
#ifndef INCLcaeventmaskh
|
||||
#define INCLcaeventmaskh
|
||||
|
||||
/*
|
||||
event selections
|
||||
(If any more than 8 of these are needed then update the
|
||||
select field in the event_block struct in db_event.c from
|
||||
unsigned char to unsigned short)
|
||||
*/
|
||||
|
||||
|
||||
DBE_VALUE
|
||||
Trigger an event when a significant change in the channel's value
|
||||
occurs. Relies on the monitor deadband field under DCT.
|
||||
|
||||
DBE_ARCHIVE (DBE_LOG)
|
||||
Trigger an event when an archive significant change in the channel's
|
||||
value occurs. Relies on the archiver monitor deadband field under DCT.
|
||||
|
||||
DBE_ALARM
|
||||
Trigger an event when the alarm state changes
|
||||
|
||||
DBE_PROPERTY
|
||||
Trigger an event when a property change (control limit, graphical
|
||||
limit, status string, enum string ...) occurs.
|
||||
|
||||
*/
|
||||
|
||||
/** \brief Trigger an event when a significant change in the channel's value occurs.
|
||||
*
|
||||
* Relies on the monitor deadband field under DCT.
|
||||
*/
|
||||
#define DBE_VALUE (1<<0)
|
||||
|
||||
/** \brief Trigger an event when an archive significant change in the channel's value occurs.
|
||||
*
|
||||
* Relies on the archiver monitor deadband field under DCT.
|
||||
*/
|
||||
#define DBE_ARCHIVE (1<<1)
|
||||
|
||||
/** \brief Same as ::DBE_ARCHIVE.
|
||||
*/
|
||||
#define DBE_LOG DBE_ARCHIVE
|
||||
|
||||
/** \brief Trigger an event when the alarm state changes.
|
||||
*/
|
||||
#define DBE_ALARM (1<<2)
|
||||
|
||||
/** \brief Trigger an event when a property change occurs.
|
||||
* (control limit, graphical limit, status string, enum string ...)
|
||||
*/
|
||||
#define DBE_PROPERTY (1<<3)
|
||||
|
||||
#endif
|
||||
|
||||
26
modules/ca/src/client/casw.md
Normal file
26
modules/ca/src/client/casw.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# casw
|
||||
|
||||
casw [-i <interest level>]
|
||||
|
||||
## Description
|
||||
|
||||
CA server "beacon anomaly" logging.
|
||||
|
||||
CA server beacon anomalies occur when a new server joins the network, a
|
||||
server is rebooted, network connectivity to a server is reestablished,
|
||||
or if a server's CPU exits a CPU load saturated state.
|
||||
|
||||
CA clients with unresolved channels reset their search request
|
||||
scheduling timers whenever they see a beacon anomaly.
|
||||
|
||||
This program can be used to detect situations where there are too many
|
||||
beacon anomalies. IP routing configuration problems may result in false
|
||||
beacon anomalies that might cause CA clients to use unnecessary
|
||||
additional network bandwidth and server CPU load when searching for
|
||||
unresolved channels.
|
||||
|
||||
If there are no new CA servers appearing on the network, and network
|
||||
connectivity remains constant, then casw should print no messages at
|
||||
all. At higher interest levels the program prints a message for every
|
||||
beacon that is received, and anomalous entries are flagged with a star.
|
||||
|
||||
15
modules/ca/src/client/catime.md
Normal file
15
modules/ca/src/client/catime.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# catime
|
||||
|
||||
catime <PV name> [channel count] [append number to pv name if true]
|
||||
|
||||
## Description
|
||||
|
||||
Channel Access Client Library performance test.
|
||||
|
||||
If unspecified, the channel count is 10000. If the "append number to pv
|
||||
name if true" argument is specified and it is greater than zero then
|
||||
the channel names in the test are numbered as follows.
|
||||
|
||||
<PV name>000000, <PV name>000001, ... <PV name>nnnnnn
|
||||
|
||||
|
||||
@@ -516,13 +516,40 @@ struct dbr_ctrl_double{
|
||||
dbr_double_t value; /* current value */
|
||||
};
|
||||
|
||||
/** \brief Returns the size in bytes for a `DBR_XXXX` type with `COUNT` elements.
|
||||
*
|
||||
* If the DBR type is a structure then the value field is the last field in the
|
||||
* structure. If `COUNT` is greater than one then `COUNT-1` elements are
|
||||
* appended to the end of the structure so that they can be addressed as an
|
||||
* array through a pointer to the value field.
|
||||
*
|
||||
* \sa dbr_size, dbr_value_size
|
||||
*
|
||||
* \param[in] TYPE The data type.
|
||||
* \param[in] COUNT The element count.
|
||||
* \returns The size in bytes of the specified type
|
||||
* with the specified number of elements.
|
||||
*/
|
||||
#define dbr_size_n(TYPE,COUNT)\
|
||||
((unsigned)((COUNT)<0?dbr_size[TYPE]:dbr_size[TYPE]+((COUNT)-1)*dbr_value_size[TYPE]))
|
||||
|
||||
/* size for each type - array indexed by the DBR_ type code */
|
||||
/** \brief Size in bytes for each `DBR_XXXX` type.
|
||||
*
|
||||
* Array indexed by the `DBR_XXXX` type code.
|
||||
*
|
||||
* \sa dbr_size_n()
|
||||
*/
|
||||
LIBCA_API extern const unsigned short dbr_size[];
|
||||
|
||||
/* size for each type's value - array indexed by the DBR_ type code */
|
||||
/** \brief Size in bytes for each type's value.
|
||||
*
|
||||
* Array indexed by the `DBR_XXXX` type code.
|
||||
*
|
||||
* If the type is a structure the size of the value field is returned otherwise
|
||||
* the size of the type is returned.
|
||||
*
|
||||
* \sa dbr_size_n()
|
||||
*/
|
||||
LIBCA_API extern const unsigned short dbr_value_size[];
|
||||
|
||||
#ifndef db_accessHFORdb_accessC
|
||||
@@ -685,6 +712,14 @@ union db_access_val{
|
||||
break; \
|
||||
}
|
||||
|
||||
/** \brief Returns a constant null terminated string
|
||||
* corresponding to the specified dbr type.
|
||||
*
|
||||
* \param[in] type The data type code.
|
||||
* A member of the set of `DBR_XXXX` in `db_access.h`.
|
||||
*
|
||||
* \returns The const string corresponding to the `DBR_XXXX` type.
|
||||
*/
|
||||
#define dbr_type_to_text(type) \
|
||||
( ((type) >= 0 && (type) < dbr_text_dim) ? \
|
||||
dbr_text[(type)] : dbr_text_invalid )
|
||||
|
||||
@@ -24,4 +24,9 @@ cainfo_SRCS = cainfo.c
|
||||
|
||||
PROD_LIBS = ca Com
|
||||
|
||||
DOCS += caget.md
|
||||
DOCS += cainfo.md
|
||||
DOCS += camonitor.md
|
||||
DOCS += caput.md
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
172
modules/ca/src/tools/caget.md
Normal file
172
modules/ca/src/tools/caget.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# caget
|
||||
|
||||
``` {program} caget
|
||||
```
|
||||
|
||||
caget [options] <PV name> ...
|
||||
|
||||
## Description
|
||||
|
||||
Get and print value for PV(s).
|
||||
|
||||
The values for one or multiple PVs are read and printed to stdout. The
|
||||
`DBR_...` format in which the data is read, the output format, and a
|
||||
number of details of how integer and float values are represented can be
|
||||
controlled using command line options.
|
||||
|
||||
When getting multiple PVs, their order on the command line is retained
|
||||
in the output.
|
||||
|
||||
## Options
|
||||
|
||||
::: {option} -h
|
||||
Print usage information
|
||||
:::
|
||||
|
||||
### Channel access options
|
||||
|
||||
::: {option} -w <sec>
|
||||
Wait time, specifies longer CA timeout, default is 1.0 second.
|
||||
:::
|
||||
|
||||
::: {option} -c
|
||||
Asynchronous get (use ca_get_callback instead of ca_get).
|
||||
:::
|
||||
|
||||
::: {option} -p <prio>
|
||||
CA priority (0--99, default 0=lowest)
|
||||
:::
|
||||
|
||||
### Format and data type options
|
||||
|
||||
Default output format is `name value`
|
||||
|
||||
::: {option} -t
|
||||
Terse mode --- print only value, without name.
|
||||
:::
|
||||
|
||||
::: {option} -a
|
||||
Wide mode `name timestamp value stat sevr` (read PVs as `DBR_TIME_xxx`)
|
||||
:::
|
||||
|
||||
::: {option} -d <type>
|
||||
Request specific dbr type; use string (`DBR_` prefix may be omitted)
|
||||
or number of one of the following types:
|
||||
|
||||
:STRING: 0
|
||||
:INT: 1
|
||||
:SHORT: 1
|
||||
:FLOAT: 2
|
||||
:ENUM: 3
|
||||
:CHAR: 4
|
||||
:LONG: 5
|
||||
:DOUBLE: 6
|
||||
:STS_STRING: 7
|
||||
:STS_INT: 8
|
||||
:STS_SHORT: 8
|
||||
:STS_FLOAT: 9
|
||||
:STS_ENUM: 10
|
||||
:STS_CHAR: 11
|
||||
:STS_LONG: 12
|
||||
:STS_DOUBLE: 13
|
||||
:TIME_STRING: 14
|
||||
:TIME_INT: 15
|
||||
:TIME_SHORT: 15
|
||||
:TIME_FLOAT: 16
|
||||
:TIME_ENUM: 17
|
||||
:TIME_CHAR: 18
|
||||
:TIME_LONG: 19
|
||||
:TIME_DOUBLE: 20
|
||||
:GR_STRING: 21
|
||||
:GR_INT: 22
|
||||
:GR_SHORT: 22
|
||||
:GR_FLOAT: 23
|
||||
:GR_ENUM: 24
|
||||
:GR_CHAR: 25
|
||||
:GR_LONG: 26
|
||||
:GR_DOUBLE: 27
|
||||
:CTRL_STRING: 28
|
||||
:CTRL_INT: 29
|
||||
:CTRL_SHORT: 29
|
||||
:CTRL_FLOAT: 30
|
||||
:CTRL_ENUM: 31
|
||||
:CTRL_CHAR: 32
|
||||
:CTRL_LONG: 33
|
||||
:CTRL_DOUBLE: 34
|
||||
:STSACK_STRING: 37
|
||||
:CLASS_NAME: 38
|
||||
:::
|
||||
|
||||
### Enum format
|
||||
|
||||
::: {option} -n
|
||||
Print `DBF_ENUM` value as number (default is enum string)
|
||||
:::
|
||||
|
||||
### Arrays
|
||||
|
||||
Value format: Print number of requested values, then list of values.
|
||||
|
||||
By default: print all values.
|
||||
|
||||
::: {option} -# <count>
|
||||
Print first \<count\> elements of an array.
|
||||
:::
|
||||
|
||||
::: {option} -S
|
||||
Print array of char as a string (long string).
|
||||
:::
|
||||
|
||||
### Floating point type format
|
||||
|
||||
By default: use `%g` format.
|
||||
|
||||
::: {option} -e <nr>
|
||||
Use `%e` format, with a precision of \<nr\> digits.
|
||||
:::
|
||||
|
||||
::: {option} -f <nr>
|
||||
Use `%f` format, with a precision of \<nr\> digits.
|
||||
:::
|
||||
|
||||
::: {option} -g <nr>
|
||||
Use `%g` format, with a precision of \<nr\> digits.
|
||||
:::
|
||||
|
||||
::: {option} -s
|
||||
Get value as string (honors server-side precision).
|
||||
:::
|
||||
|
||||
::: {option} -lx
|
||||
Round to long integer and print as hex number.
|
||||
:::
|
||||
|
||||
::: {option} -lo
|
||||
Round to long integer and print as octal number.
|
||||
:::
|
||||
|
||||
::: {option} -lb
|
||||
Round to long integer and print as binary number.
|
||||
:::
|
||||
|
||||
### Integer number format
|
||||
|
||||
By default: print as decimal number.
|
||||
|
||||
::: {option} -0x
|
||||
Print as hex number.
|
||||
:::
|
||||
|
||||
::: {option} -0o
|
||||
Print as octal number.
|
||||
:::
|
||||
|
||||
::: {option} -0b
|
||||
Print as binary number.
|
||||
:::
|
||||
|
||||
### Alternate output field separator
|
||||
|
||||
::: {option} -F <ofs>
|
||||
Use \<ofs\> as an alternate output field separator.
|
||||
:::
|
||||
40
modules/ca/src/tools/cainfo.md
Normal file
40
modules/ca/src/tools/cainfo.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# cainfo
|
||||
|
||||
``` {program} cainfo
|
||||
```
|
||||
|
||||
cainfo [options] <PV name> ...
|
||||
|
||||
## Description
|
||||
|
||||
Get and print channel and connection information for PV(s).
|
||||
|
||||
All available Channel Access related information about PV(s) is printed
|
||||
to stdout.
|
||||
|
||||
The {option}`-s` option allows to specify an interest level for calling Channel
|
||||
Access' internal report function `ca_client_status()`, that prints lots
|
||||
of internal informations on stdout, including environment settings, used
|
||||
CA ports etc.
|
||||
|
||||
## Options
|
||||
|
||||
::: {option} -h
|
||||
Print usage information
|
||||
:::
|
||||
|
||||
### CA options
|
||||
|
||||
::: {option} -w <sec>
|
||||
Wait time, specifies longer CA timeout, default is 1.0 second.
|
||||
:::
|
||||
|
||||
::: {option} -s <level>
|
||||
Call ca_client_status with the specified interest level
|
||||
:::
|
||||
|
||||
::: {option} -p <prio>
|
||||
CA priority (0--99, default 0=lowest)
|
||||
:::
|
||||
|
||||
|
||||
122
modules/ca/src/tools/camonitor.md
Normal file
122
modules/ca/src/tools/camonitor.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# camonitor
|
||||
|
||||
``` {program} camonitor
|
||||
```
|
||||
|
||||
camonitor [options] <PV name> ...
|
||||
|
||||
## Description
|
||||
|
||||
Subscribe to and print value updates for PV(s).
|
||||
|
||||
## Options
|
||||
|
||||
::: {option} -h
|
||||
Print usage information
|
||||
:::
|
||||
|
||||
### CA options
|
||||
|
||||
::: {option} -w <sec>
|
||||
Wait time, specifies longer CA timeout, default is 1.0 second.
|
||||
:::
|
||||
|
||||
::: {option} -m <msk>
|
||||
Specify CA event mask to use.
|
||||
|
||||
\<msk\> is any combination of `v` (value), `a` (alarm), `l` (log/archive),
|
||||
`p` (property).
|
||||
|
||||
Default event mask is `va`
|
||||
:::
|
||||
|
||||
::: {option} -p <prio>
|
||||
CA priority (0--99, default 0=lowest)
|
||||
:::
|
||||
|
||||
### Timestamps
|
||||
|
||||
Default: Print absolute timestamps (as reported by CA server)
|
||||
|
||||
::: {option} -t <key>
|
||||
Specify timestamp source(s) and type, with \<key\> containing:
|
||||
|
||||
`s` = CA server (remote) timestamps\
|
||||
`c` = CA client (local) timestamps (shown in `()`s)\
|
||||
`n` = no timestamps\
|
||||
`r` = relative timestamps (time elapsed since start of program)\
|
||||
`i` = incremental timestamps (time elapsed since last update)\
|
||||
`I` = incremental timestamps (time since last update, by channel)\
|
||||
|
||||
`r`, `i` or `I` require `s` or `c` to select the time source.
|
||||
:::
|
||||
|
||||
### Enum format
|
||||
|
||||
::: {option} -n
|
||||
Print `DBF_ENUM` values as number (default is enum string)
|
||||
:::
|
||||
|
||||
### Arrays
|
||||
|
||||
Array values: Print number of elements, then list of values.
|
||||
|
||||
By default: request and print all elements (dynamic arrays supported).
|
||||
|
||||
::: {option} -# <count>
|
||||
Request and print first \<count\> elements of an array.
|
||||
:::
|
||||
|
||||
::: {option} -S
|
||||
Print array of char as a string (long string).
|
||||
:::
|
||||
|
||||
### Floating point format
|
||||
|
||||
By default: use `%g` format.
|
||||
|
||||
::: {option} -e <nr>
|
||||
Use `%e` format, with a precision of \<nr\> digits.
|
||||
:::
|
||||
|
||||
::: {option} -f <nr>
|
||||
Use `%f` format, with a precision of \<nr\> digits.
|
||||
:::
|
||||
|
||||
::: {option} -g <nr>
|
||||
Use `%g` format, with a precision of \<nr\> digits.
|
||||
:::
|
||||
|
||||
::: {option} -s
|
||||
Get value as string (honors server-side precision).
|
||||
:::
|
||||
|
||||
::: {option} -lx
|
||||
Round to long integer and print as hex number.
|
||||
:::
|
||||
|
||||
::: {option} -lo
|
||||
Round to long integer and print as octal number.
|
||||
:::
|
||||
|
||||
::: {option} -lb
|
||||
Round to long integer and print as binary number.
|
||||
:::
|
||||
|
||||
### Integer number format
|
||||
|
||||
By default: print as decimal number.
|
||||
|
||||
::: {option} -0x
|
||||
Print as hex number.
|
||||
:::
|
||||
|
||||
::: {option} -0o
|
||||
Print as octal number.
|
||||
:::
|
||||
|
||||
::: {option} -0b
|
||||
Print as binary number.
|
||||
:::
|
||||
|
||||
|
||||
85
modules/ca/src/tools/caput.md
Normal file
85
modules/ca/src/tools/caput.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# caput
|
||||
|
||||
``` {program} caput
|
||||
```
|
||||
|
||||
caput [options] <PV name> <value> ...
|
||||
caput -a [options] <PV name> <no of elements> <value> ...
|
||||
|
||||
## Description
|
||||
|
||||
Put value to a PV.
|
||||
|
||||
The specified value is written to the PV (as a string). The PV's value is read
|
||||
before and after the write operation and printed as "Old" and "New" values on
|
||||
stdout.
|
||||
|
||||
There are two variants to the arguments for this command. For the scalar
|
||||
variant without the {option}`-a` flag, all the value arguments provided after
|
||||
the PV name are concatenated with a single space character between them, and
|
||||
the resulting string (up to 40 characters long unless the {option}`-S` flag is
|
||||
given) is written to the specified PV.
|
||||
|
||||
The array variant with the {option}`-a` flag writes an array of string values
|
||||
to the specified PV. The numeric argument giving the number of array elements
|
||||
is actually ignored, the array length to be written is actually controlled by
|
||||
the number of values provided on the command line.
|
||||
|
||||
## Options
|
||||
|
||||
::: {option} -h
|
||||
Print usage information
|
||||
:::
|
||||
|
||||
### CA options
|
||||
|
||||
::: {option} -w <sec>
|
||||
Wait time, specifies longer CA timeout, default is 1.0 second.
|
||||
:::
|
||||
|
||||
::: {option} -c
|
||||
Asynchronous get (use ca_get_callback instead of ca_get).
|
||||
:::
|
||||
|
||||
::: {option} -p <prio>
|
||||
CA priority (0--99, default 0=lowest)
|
||||
:::
|
||||
|
||||
### Format options
|
||||
|
||||
::: {option} -t
|
||||
Terse mode --- print only successfully written value, without name.
|
||||
:::
|
||||
|
||||
::: {option} -l
|
||||
Long mode `name timestamp value stat sevr` (read PVs as `DBR_TIME_xxx`)
|
||||
:::
|
||||
|
||||
### Enum Format
|
||||
|
||||
By default: Auto --- try value as ENUM string, then as index number
|
||||
|
||||
::: {option} -n
|
||||
Force interpretation of values as numbers
|
||||
:::
|
||||
|
||||
::: {option} -s
|
||||
Force interpretation of values as strings
|
||||
:::
|
||||
|
||||
### Arrays
|
||||
|
||||
By default: put scalar
|
||||
|
||||
Value format: all value arguments concatenated with spaces
|
||||
|
||||
::: {option} -S
|
||||
Put string as an array of chars (long string)
|
||||
:::
|
||||
|
||||
::: {option} -a
|
||||
Put array
|
||||
|
||||
Value format: number of values, then list of values
|
||||
:::
|
||||
|
||||
@@ -1251,7 +1251,9 @@ static void dbCaTask(void *arg)
|
||||
epicsMutexMustLock(pca->lock);
|
||||
prec = pca->plink->precord;
|
||||
epicsMutexUnlock(pca->lock);
|
||||
dbScanLock(prec);
|
||||
db_process(prec);
|
||||
dbScanUnlock(prec);
|
||||
}
|
||||
}
|
||||
SEVCHK(ca_flush_io(), "dbCaTask");
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
=head2 Operator Display Parameters
|
||||
|
||||
The B<NAME> field contains the record name which must be unique within an
|
||||
EPICS Channel Access name space. The name is supplied by the application
|
||||
@@ -43,7 +43,7 @@ record's purpose. Maximum length is 40 characters.
|
||||
size(29)
|
||||
}
|
||||
|
||||
=head3 Scan Fields
|
||||
=head2 Scan Fields
|
||||
|
||||
These fields contain information related to how and when a record processes. A
|
||||
few records have unique fields that also affect how they process. These
|
||||
@@ -245,7 +245,7 @@ The B<SPVT> field is for internal use by the scanning system.
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head3 Alarm Fields
|
||||
=head2 Alarm Fields
|
||||
|
||||
Alarm fields indicate the status and severity of record alarms, or determine
|
||||
how and when alarms are triggered. Of course, many records have alarm-related
|
||||
@@ -392,7 +392,7 @@ initial severity of the record being undefined after the IOC boots.
|
||||
extra("struct scan_element *spvt")
|
||||
}
|
||||
|
||||
=head3 Device Fields
|
||||
=head2 Device Fields
|
||||
|
||||
The B<RSET> field contains the address of the Record Support Entry Table. See
|
||||
the Application Developers Guide for details on usage.
|
||||
@@ -446,7 +446,7 @@ The B<DPVT> field is is for private use of the device support modules.
|
||||
menu(menuPriority)
|
||||
}
|
||||
|
||||
=head3 Debugging Fields
|
||||
=head2 Debugging Fields
|
||||
|
||||
The B<TPRO> field can be used to trace record processing. When this field is
|
||||
non-zero and the record is processed, a trace message will be be printed for
|
||||
@@ -461,7 +461,7 @@ database processing can be supported using this.
|
||||
=fields TPRO, BKPT
|
||||
|
||||
|
||||
=head3 Miscellaneous Fields
|
||||
=head2 Miscellaneous Fields
|
||||
|
||||
The B<ASG> string field sets the name of the access security group used for this
|
||||
record. If left empty, the record is placed in group C<DEFAULT>.
|
||||
|
||||
@@ -11,7 +11,7 @@ These fields usually have the same meaning whenever they are used.
|
||||
See also L<Fields Common to All Record Types|dbCommonRecord> and L<Fields Common
|
||||
to Output Record Types|dbCommonOutput>.
|
||||
|
||||
=head3 Input and Value Fields
|
||||
=head2 Input and Value Fields
|
||||
|
||||
The B<INP> field specifies an input link. It is used by the device support
|
||||
routines to obtain input. For soft analog records it can be a constant, a
|
||||
@@ -30,7 +30,7 @@ reads values directly into VAL, bypassing this field.
|
||||
The B<VAL> field contains the record's final value, after any needed
|
||||
conversions have been performed.
|
||||
|
||||
=head3 Device Input
|
||||
=head2 Device Input
|
||||
|
||||
A device input routine normally returns one of the following values to its
|
||||
associated record support routine:
|
||||
@@ -65,7 +65,7 @@ to the engineering units value.
|
||||
|
||||
=back
|
||||
|
||||
=head3 Device Support for Soft Records
|
||||
=head2 Device Support for Soft Records
|
||||
|
||||
In most cases, two soft output device support modules are provided: Soft Channel
|
||||
and Raw Soft Channel. Both allow INP to be a constant, a database link, or a
|
||||
@@ -83,7 +83,7 @@ If a value was returned by the link the UDF field is set to FALSE. The device
|
||||
support read routine normally returns the status from C<dbGetLink()>.
|
||||
|
||||
|
||||
=head3 Input Simulation Fields
|
||||
=head2 Input Simulation Fields
|
||||
|
||||
The B<SIMM> field controls simulation mode.
|
||||
By setting this field to YES or RAW, the record can be switched into
|
||||
@@ -121,7 +121,7 @@ The B<SSCN> field specifies the SCAN mechanism to be used in simulation mode.
|
||||
This is specifically useful for 'I/O Intr' scanned records, which would
|
||||
otherwise never be scanned in simulation mode.
|
||||
|
||||
=head3 Simulation Mode for Input Records
|
||||
=head2 Simulation Mode for Input Records
|
||||
|
||||
An input record can be switched into simulation mode of operation by setting
|
||||
the value of SIMM to YES or RAW.
|
||||
|
||||
@@ -11,7 +11,7 @@ These fields usually have the same meaning whenever they are used.
|
||||
See also L<Fields Common to All Record Types|dbCommonRecord> and L<Fields Common to
|
||||
Input Records|dbCommonInput>.
|
||||
|
||||
=head3 Output and Value Fields
|
||||
=head2 Output and Value Fields
|
||||
|
||||
The B<OUT> field specifies an output link. It is used by the device support
|
||||
routines to decide where to send output. For soft records, it can be a
|
||||
@@ -38,7 +38,7 @@ The B<RBV> field contains - whenever possible - the actual read back value
|
||||
obtained from the hardware itself or from the associated device driver.
|
||||
|
||||
|
||||
=head3 Device Support for Soft Records
|
||||
=head2 Device Support for Soft Records
|
||||
|
||||
Normally two soft output device support modules are provided, Soft Channel and
|
||||
and Raw Soft Channel. Both write a value through the output link OUT.
|
||||
@@ -50,7 +50,7 @@ The device support write routine normally calls C<dbPutLink()> which writes a
|
||||
value through the OUT link, and returns the status from that call.
|
||||
|
||||
|
||||
=head3 Input and Mode Select Fields
|
||||
=head2 Input and Mode Select Fields
|
||||
|
||||
The B<DOL> field is a link from which the desired output value can be fetched.
|
||||
DOL can be a constant, a database link, or a channel access link. If DOL is a
|
||||
@@ -63,7 +63,7 @@ value C<closed_loop>. By setting this field a record can be switched between
|
||||
supervisory and closed loop mode of operation. While in closed loop mode, the
|
||||
VAL field cannot be set via dbPuts.
|
||||
|
||||
=head3 Output Mode Selection
|
||||
=head2 Output Mode Selection
|
||||
|
||||
The fields DOL and OMSL are used to allow the output record to be part of a
|
||||
closed loop control algorithm. OMSL is meaningful only if DOL refers to a
|
||||
@@ -76,7 +76,7 @@ types with an OIF field and OIF is Full, VAL is set equal to the value obtained
|
||||
from the location referenced by DOL; if OIF is Incremental VAL is incremented by
|
||||
the value obtained from DOL.
|
||||
|
||||
=head3 Invalid Output Action Fields
|
||||
=head2 Invalid Output Action Fields
|
||||
|
||||
The B<IVOA> field specifies the output action for the case that the record is
|
||||
put into an INVALID alarm severity. IVOA can be one of the following actions:
|
||||
@@ -102,7 +102,7 @@ in engineering units. If a new severity has been set to INVALID and IVOA is
|
||||
C<Set output to IVOV>, then VAL is set to IVOV and converted to RVAL before
|
||||
device support is called.
|
||||
|
||||
=head3 Invalid Alarm Output Action
|
||||
=head2 Invalid Alarm Output Action
|
||||
|
||||
Whenever an output record is put into INVALID alarm severity, IVOA specifies
|
||||
an action to take. The record support process routine for each output record
|
||||
@@ -142,7 +142,7 @@ If IVOA not one of the above, an error message is generated.
|
||||
=back
|
||||
|
||||
|
||||
=head3 Output Simulation Fields
|
||||
=head2 Output Simulation Fields
|
||||
|
||||
The B<SIMM> field controls simulation mode. It has either the value YES or NO.
|
||||
By setting this field to YES, the record can be switched into simulation mode
|
||||
@@ -171,7 +171,7 @@ The B<SSCN> field specifies the SCAN mechanism to be used in simulation mode.
|
||||
This is specifically useful for 'I/O Intr' scanned records, which would
|
||||
otherwise never be scanned in simulation mode.
|
||||
|
||||
=head3 Simulation Mode for Output Records
|
||||
=head2 Simulation Mode for Output Records
|
||||
|
||||
An output record can be switched into simulation mode of operation by setting
|
||||
the value of SIMM to YES. During simulation, the record will be put into alarm
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
This section contains a description of the fields that are common to all record
|
||||
types. These fields are defined in dbCommon.dbd.
|
||||
|
||||
See also L<Fields Common to Input Record Types|dbCommonInput> and L<Fields
|
||||
Common to Output Record Types|dbCommonOutput>.
|
||||
See also L<Fields Common to Input Record Types|dbCommonInput> and
|
||||
L<Fields Common to Output Record Types|dbCommonOutput>.
|
||||
|
||||
=recordtype dbCommon
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ static long getStringChar(const dbAddr *paddr,
|
||||
*pdst++ = 0;
|
||||
else {
|
||||
char *end;
|
||||
long status = epicsParseInt8(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseInt8(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -195,7 +195,7 @@ static long getStringUchar(const dbAddr *paddr,
|
||||
*pdst++ = 0;
|
||||
else {
|
||||
char *end;
|
||||
long status = epicsParseUInt8(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseUInt8(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -219,7 +219,7 @@ static long getStringShort(const dbAddr *paddr,
|
||||
*pdst++ = 0;
|
||||
else {
|
||||
char *end;
|
||||
long status = epicsParseInt16(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseInt16(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -243,7 +243,7 @@ static long getStringUshort(const dbAddr *paddr,
|
||||
*pdst++ = 0;
|
||||
else {
|
||||
char *end;
|
||||
long status = epicsParseUInt16(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseUInt16(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -267,7 +267,7 @@ static long getStringLong(const dbAddr *paddr,
|
||||
*pdst++ = 0;
|
||||
else {
|
||||
char *end;
|
||||
long status = epicsParseInt32(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseInt32(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -291,7 +291,7 @@ static long getStringUlong(const dbAddr *paddr,
|
||||
*pdst++ = 0;
|
||||
else {
|
||||
char *end;
|
||||
long status = epicsParseUInt32(psrc, pdst, 10, &end);
|
||||
long status = epicsParseUInt32(psrc, pdst, dbConvertBase, &end);
|
||||
|
||||
if (status == S_stdlib_noConversion ||
|
||||
(!status && (*end == '.' || *end == 'e' || *end == 'E'))) {
|
||||
@@ -328,7 +328,7 @@ static long getStringInt64(const dbAddr *paddr,
|
||||
*pdst++ = 0;
|
||||
else {
|
||||
char *end;
|
||||
long status = epicsParseInt64(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseInt64(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -946,7 +946,7 @@ static long putStringChar(dbAddr *paddr,
|
||||
|
||||
while (nRequest--) {
|
||||
char *end;
|
||||
long status = epicsParseInt8(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseInt8(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -965,7 +965,7 @@ static long putStringUchar(dbAddr *paddr,
|
||||
|
||||
while (nRequest--) {
|
||||
char *end;
|
||||
long status = epicsParseUInt8(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseUInt8(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -984,7 +984,7 @@ static long putStringShort(dbAddr *paddr,
|
||||
|
||||
while (nRequest--) {
|
||||
char *end;
|
||||
long status = epicsParseInt16(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseInt16(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -1003,7 +1003,7 @@ static long putStringUshort(dbAddr *paddr,
|
||||
|
||||
while (nRequest--) {
|
||||
char *end;
|
||||
long status = epicsParseUInt16(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseUInt16(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -1022,7 +1022,7 @@ static long putStringLong(dbAddr *paddr,
|
||||
|
||||
while (nRequest--) {
|
||||
char *end;
|
||||
long status = epicsParseInt32(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseInt32(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -1041,7 +1041,7 @@ static long putStringUlong(dbAddr *paddr,
|
||||
|
||||
while (nRequest--) {
|
||||
char *end;
|
||||
long status = epicsParseUInt32(psrc, pdst, 10, &end);
|
||||
long status = epicsParseUInt32(psrc, pdst, dbConvertBase, &end);
|
||||
|
||||
if (status == S_stdlib_noConversion ||
|
||||
(!status && (*end == '.' || *end == 'e' || *end == 'E'))) {
|
||||
@@ -1074,7 +1074,7 @@ static long putStringInt64(dbAddr *paddr,
|
||||
|
||||
while (nRequest--) {
|
||||
char *end;
|
||||
long status = epicsParseInt64(psrc, pdst++, 10, &end);
|
||||
long status = epicsParseInt64(psrc, pdst++, dbConvertBase, &end);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -1178,7 +1178,7 @@ static long putStringEnum(dbAddr *paddr,
|
||||
epicsEnum16 val;
|
||||
char *end;
|
||||
|
||||
status = epicsParseUInt16(pfrom, &val, 10, &end);
|
||||
status = epicsParseUInt16(pfrom, &val, dbConvertBase, &end);
|
||||
if (!status && val < enumStrs.no_str) {
|
||||
*pfield = val;
|
||||
return 0;
|
||||
@@ -1219,7 +1219,7 @@ static long putStringMenu(dbAddr *paddr,
|
||||
}
|
||||
}
|
||||
|
||||
if (!epicsParseUInt16(pfrom, &val, 10, NULL)
|
||||
if (!epicsParseUInt16(pfrom, &val, dbConvertBase, NULL)
|
||||
&& val < nChoice) {
|
||||
*pfield = val;
|
||||
return 0;
|
||||
@@ -1258,7 +1258,7 @@ static long putStringDevice(dbAddr *paddr,
|
||||
}
|
||||
}
|
||||
|
||||
if (!epicsParseUInt16(pfrom, &val, 10, NULL) && val < nChoice) {
|
||||
if (!epicsParseUInt16(pfrom, &val, dbConvertBase, NULL) && val < nChoice) {
|
||||
*pfield = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -443,6 +443,17 @@ static long processTarget(dbCommon *psrc, dbCommon *pdst)
|
||||
epicsUInt8 pact = psrc->pact;
|
||||
epicsThreadId self = epicsThreadGetIdSelf();
|
||||
|
||||
#ifdef LOCKSET_DEBUG
|
||||
{
|
||||
lockSet *ls = dbLockGetRef(psrc->lset);
|
||||
assert(ls->owner == self);
|
||||
dbLockDecRef(ls);
|
||||
ls = dbLockGetRef(pdst->lset);
|
||||
assert(ls->owner == self);
|
||||
dbLockDecRef(ls);
|
||||
}
|
||||
#endif
|
||||
|
||||
psrc->pact = TRUE;
|
||||
|
||||
if (psrc->ppn)
|
||||
|
||||
@@ -98,7 +98,7 @@ static long cvt_st_c(const void *f, void *t, const dbAddr *paddr)
|
||||
*to = 0;
|
||||
return 0;
|
||||
}
|
||||
return epicsParseInt8(from, to, 10, &end);
|
||||
return epicsParseInt8(from, to, dbConvertBase, &end);
|
||||
}
|
||||
|
||||
/* Convert String to Unsigned Char */
|
||||
@@ -112,7 +112,7 @@ static long cvt_st_uc(const void *f, void *t, const dbAddr *paddr)
|
||||
*to = 0;
|
||||
return 0;
|
||||
}
|
||||
return epicsParseUInt8(from, to, 10, &end);
|
||||
return epicsParseUInt8(from, to, dbConvertBase, &end);
|
||||
}
|
||||
|
||||
/* Convert String to Short */
|
||||
@@ -126,7 +126,7 @@ static long cvt_st_s(const void *f, void *t, const dbAddr *paddr)
|
||||
*to = 0;
|
||||
return 0;
|
||||
}
|
||||
return epicsParseInt16(from, to, 10, &end);
|
||||
return epicsParseInt16(from, to, dbConvertBase, &end);
|
||||
}
|
||||
|
||||
/* Convert String to Unsigned Short */
|
||||
@@ -140,7 +140,7 @@ static long cvt_st_us(const void *f, void *t, const dbAddr *paddr)
|
||||
*to = 0;
|
||||
return 0;
|
||||
}
|
||||
return epicsParseUInt16(from, to, 10, &end);
|
||||
return epicsParseUInt16(from, to, dbConvertBase, &end);
|
||||
}
|
||||
|
||||
/* Convert String to Long */
|
||||
@@ -154,7 +154,7 @@ static long cvt_st_l(const void *f, void *t, const dbAddr *paddr)
|
||||
*to = 0;
|
||||
return 0;
|
||||
}
|
||||
return epicsParseInt32(from, to, 10, &end);
|
||||
return epicsParseInt32(from, to, dbConvertBase, &end);
|
||||
}
|
||||
|
||||
/* Convert String to Unsigned Long */
|
||||
@@ -169,7 +169,7 @@ static long cvt_st_ul(const void *f, void *t, const dbAddr *paddr)
|
||||
*to = 0;
|
||||
return 0;
|
||||
}
|
||||
status = epicsParseUInt32(from, to, 10, &end);
|
||||
status = epicsParseUInt32(from, to, dbConvertBase, &end);
|
||||
if (status == S_stdlib_noConversion ||
|
||||
(!status && (*end == '.' || *end == 'e' || *end == 'E'))) {
|
||||
/*
|
||||
@@ -198,7 +198,7 @@ static long cvt_st_q(const void *f, void *t, const dbAddr *paddr)
|
||||
*to = 0;
|
||||
return 0;
|
||||
}
|
||||
return epicsParseInt64(from, to, 10, &end);
|
||||
return epicsParseInt64(from, to, dbConvertBase, &end);
|
||||
}
|
||||
|
||||
/* Convert String to UInt64 */
|
||||
@@ -269,7 +269,7 @@ static long cvt_st_e(const void *f, void *t, const dbAddr *paddr)
|
||||
if (!status) {
|
||||
epicsEnum16 val;
|
||||
|
||||
status = epicsParseUInt16(from, &val, 10, NULL);
|
||||
status = epicsParseUInt16(from, &val, dbConvertBase, NULL);
|
||||
if (!status && val < enumStrs.no_str) {
|
||||
*to = val;
|
||||
return 0;
|
||||
@@ -306,7 +306,7 @@ static long cvt_st_menu(const void *f, void *t, const dbAddr *paddr)
|
||||
}
|
||||
}
|
||||
|
||||
if (!epicsParseUInt16(from, &val, 10, NULL) && val < nChoice) {
|
||||
if (!epicsParseUInt16(from, &val, dbConvertBase, NULL) && val < nChoice) {
|
||||
*to = val;
|
||||
return 0;
|
||||
}
|
||||
@@ -339,7 +339,7 @@ static long cvt_st_device(const void *f, void *t, const dbAddr *paddr)
|
||||
}
|
||||
}
|
||||
|
||||
if (!epicsParseUInt16(from, &val, 10, NULL) && val < nChoice) {
|
||||
if (!epicsParseUInt16(from, &val, dbConvertBase, NULL) && val < nChoice) {
|
||||
*to = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -233,16 +233,23 @@ static const iocshFuncDef dblaFuncDef = {"dbla",1,dblaArgs,
|
||||
"Example: dbla(\"alia*\")\n"};
|
||||
static void dblaCallFunc(const iocshArgBuf *args) { iocshSetError(dbla(args[0].sval));}
|
||||
|
||||
/* dbgrep */
|
||||
static const iocshArg dbgrepArg0 = { "pattern",iocshArgStringRecord};
|
||||
static const iocshArg * const dbgrepArgs[1] = {&dbgrepArg0};
|
||||
static const iocshFuncDef dbgrepFuncDef = {"dbgrep",1,dbgrepArgs,
|
||||
"List record names matching pattern.\n"
|
||||
/* dbglob */
|
||||
static const iocshArg dbglobArg0 = { "pattern",iocshArgStringRecord};
|
||||
static const iocshArg dbglobArg1 = { "fields",iocshArgString};
|
||||
static const iocshArg * const dbglobArgs[2] = {&dbglobArg0,&dbglobArg1};
|
||||
static const iocshFuncDef dbglobFuncDef = {"dbglob",2,dbglobArgs,
|
||||
"List record names matching pattern and optionally print field values. \n"
|
||||
"The pattern can contain any characters that are legal in record names as well as:\n"
|
||||
" - \"?\", which matches 0 or one characters.\n"
|
||||
" - \"*\", which matches 0 or more characters.\n\n"
|
||||
"Example: dbgrep(\"*gpibAi*\")\n"};
|
||||
static void dbgrepCallFunc(const iocshArgBuf *args) { iocshSetError(dbgrep(args[0].sval));}
|
||||
"Example: dbglob(\"*gpibAi*\")\n"
|
||||
" dbglob(\"*gpibAi*\",\"VAL DESC\")\n"};
|
||||
static void dbglobCallFunc(const iocshArgBuf *args) { iocshSetError(dbglob(args[0].sval,args[1].sval));}
|
||||
|
||||
/* dbgrep; alias for dbglob, so it should have the same arguments */
|
||||
static const iocshFuncDef dbgrepFuncDef = {"dbgrep",2,dbglobArgs,
|
||||
"See dbglob.\n"};
|
||||
static void dbgrepCallFunc(const iocshArgBuf *args) { iocshSetError(dbglob(args[0].sval,args[1].sval));}
|
||||
|
||||
/* dbgf */
|
||||
static const iocshArg dbgfArg0 = { "record name",iocshArgStringRecord};
|
||||
@@ -598,6 +605,7 @@ void dbIocRegister(void)
|
||||
iocshRegister(&dbnrFuncDef,dbnrCallFunc);
|
||||
iocshRegister(&dblaFuncDef,dblaCallFunc);
|
||||
iocshRegister(&dbliFuncDef,dbliCallFunc);
|
||||
iocshRegister(&dbglobFuncDef,dbglobCallFunc);
|
||||
iocshRegister(&dbgrepFuncDef,dbgrepCallFunc);
|
||||
iocshRegister(&dbgfFuncDef,dbgfCallFunc);
|
||||
iocshRegister(&dbpfFuncDef,dbpfCallFunc);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "dbLock.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsSpin.h"
|
||||
#include "epicsThread.h"
|
||||
|
||||
/* Define to enable additional error checking */
|
||||
#undef LOCKSET_DEBUG
|
||||
|
||||
@@ -680,7 +680,9 @@ int scanOnceCallback(struct dbCommon *precord, once_complete cb, void *usr)
|
||||
pushOK = epicsRingBytesPut(onceQ, (void*)&ent, sizeof(ent));
|
||||
|
||||
if (!pushOK) {
|
||||
if (newOverflow) errlogPrintf("scanOnce: Ring buffer overflow\n");
|
||||
if (newOverflow)
|
||||
errlogPrintf("%s : " ERL_WARNING " scanOnce: Ring buffer overflow\n",
|
||||
precord->name);
|
||||
newOverflow = FALSE;
|
||||
epicsAtomicIncrIntT(&onceQOverruns);
|
||||
} else {
|
||||
|
||||
@@ -100,13 +100,59 @@ long dba(const char*pname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* split a space separated list of field names and return the number of
|
||||
fields with each field an element of papfields. These elements
|
||||
point to within the fieldnames variable which is modified
|
||||
by the function. memory is allocated for *ppapfields and needs
|
||||
to be freed later by the calling routine */
|
||||
static int splitFieldsList(char *fieldnames, char ***ppapfields)
|
||||
{
|
||||
char *pnext = fieldnames;
|
||||
int nfields = 0, maxfields = 1;
|
||||
char* saveptr = NULL;
|
||||
/* this may overcount real fields e.g. " VAL " hence maxfields */
|
||||
while (*pnext && (pnext = strchr(pnext, ' '))) {
|
||||
maxfields++;
|
||||
while (*pnext == ' ') pnext++;
|
||||
}
|
||||
*ppapfields = dbCalloc(maxfields, sizeof(char *));
|
||||
pnext = epicsStrtok_r(fieldnames, " ", &saveptr);
|
||||
while(pnext != NULL) {
|
||||
(*ppapfields)[nfields++] = pnext;
|
||||
pnext = epicsStrtok_r(NULL, " ", &saveptr);
|
||||
}
|
||||
return nfields;
|
||||
}
|
||||
|
||||
static void printFieldsList(DBENTRY *pdbentry, char** papfields, int nfields)
|
||||
{
|
||||
int ifield;
|
||||
for (ifield = 0; ifield < nfields; ifield++) {
|
||||
char *pvalue;
|
||||
long status = dbFindField(pdbentry, papfields[ifield]);
|
||||
if (status) {
|
||||
if (!strcmp(papfields[ifield], "recordType")) {
|
||||
pvalue = dbGetRecordTypeName(pdbentry);
|
||||
}
|
||||
else {
|
||||
printf(", ");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pvalue = dbGetString(pdbentry);
|
||||
}
|
||||
printf(", \"%s\"", (pvalue ? pvalue : ""));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
long dbl(const char *precordTypename, const char *fields)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
int nfields = 0;
|
||||
int ifield;
|
||||
char *fieldnames = 0;
|
||||
char **papfields = 0;
|
||||
|
||||
@@ -121,25 +167,8 @@ long dbl(const char *precordTypename, const char *fields)
|
||||
if (fields && (*fields == '\0'))
|
||||
fields = NULL;
|
||||
if (fields) {
|
||||
char *pnext;
|
||||
|
||||
fieldnames = epicsStrDup(fields);
|
||||
nfields = 1;
|
||||
pnext = fieldnames;
|
||||
while (*pnext && (pnext = strchr(pnext,' '))) {
|
||||
nfields++;
|
||||
while (*pnext == ' ') pnext++;
|
||||
}
|
||||
papfields = dbCalloc(nfields,sizeof(char *));
|
||||
pnext = fieldnames;
|
||||
for (ifield = 0; ifield < nfields; ifield++) {
|
||||
papfields[ifield] = pnext;
|
||||
if (ifield < nfields - 1) {
|
||||
pnext = strchr(pnext, ' ');
|
||||
*pnext++ = 0;
|
||||
while (*pnext == ' ') pnext++;
|
||||
}
|
||||
}
|
||||
nfields = splitFieldsList(fieldnames, &papfields);
|
||||
}
|
||||
dbInitEntry(pdbbase, pdbentry);
|
||||
if (!precordTypename)
|
||||
@@ -154,24 +183,7 @@ long dbl(const char *precordTypename, const char *fields)
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while (!status) {
|
||||
printf("%s", dbGetRecordName(pdbentry));
|
||||
for (ifield = 0; ifield < nfields; ifield++) {
|
||||
char *pvalue;
|
||||
status = dbFindField(pdbentry, papfields[ifield]);
|
||||
if (status) {
|
||||
if (!strcmp(papfields[ifield], "recordType")) {
|
||||
pvalue = dbGetRecordTypeName(pdbentry);
|
||||
}
|
||||
else {
|
||||
printf(", ");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pvalue = dbGetString(pdbentry);
|
||||
}
|
||||
printf(", \"%s\"", pvalue ? pvalue : "");
|
||||
}
|
||||
printf("\n");
|
||||
printFieldsList(pdbentry, papfields, nfields);
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
if (precordTypename)
|
||||
@@ -283,14 +295,17 @@ long dbli(const char *pattern)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long dbgrep(const char *pmask)
|
||||
long dbglob(const char *pmask,const char *fields)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry = &dbentry;
|
||||
long status;
|
||||
int nfields = 0;
|
||||
char *fieldnames = 0;
|
||||
char **papfields = 0;
|
||||
|
||||
if (!pmask || !*pmask) {
|
||||
printf("Usage: dbgrep \"pattern\"\n");
|
||||
printf("Usage: dbglob \"pattern\" \"fields\"\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -298,24 +313,38 @@ long dbgrep(const char *pmask)
|
||||
printf("No database loaded\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fields && (*fields == '\0'))
|
||||
fields = NULL;
|
||||
if (fields) {
|
||||
fieldnames = epicsStrDup(fields);
|
||||
nfields = splitFieldsList(fieldnames, &papfields);
|
||||
}
|
||||
dbInitEntry(pdbbase, pdbentry);
|
||||
status = dbFirstRecordType(pdbentry);
|
||||
while (!status) {
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while (!status) {
|
||||
char *pname = dbGetRecordName(pdbentry);
|
||||
if (epicsStrGlobMatch(pname, pmask))
|
||||
puts(pname);
|
||||
if (epicsStrGlobMatch(pname, pmask)) {
|
||||
printf("%s", pname);
|
||||
printFieldsList(pdbentry, papfields, nfields);
|
||||
}
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
status = dbNextRecordType(pdbentry);
|
||||
}
|
||||
|
||||
if (nfields > 0) {
|
||||
free((void *)papfields);
|
||||
free((void *)fieldnames);
|
||||
}
|
||||
dbFinishEntry(pdbentry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long dbgrep(const char *pname, const char *fields) {
|
||||
return dbglob(pname, fields);
|
||||
}
|
||||
|
||||
long dbgf(const char *pname)
|
||||
{
|
||||
/* declare buffer long just to ensure correct alignment */
|
||||
|
||||
@@ -28,8 +28,10 @@ DBCORE_API long dbnr(int verbose);
|
||||
DBCORE_API long dbla(const char *pmask);
|
||||
/* list infos */
|
||||
DBCORE_API long dbli(const char *patern);
|
||||
/*list records with mask*/
|
||||
DBCORE_API long dbgrep(const char *pmask);
|
||||
/*list records filtered by glob pattern*/
|
||||
DBCORE_API long dbglob(const char *ppattern,const char *fields);
|
||||
/*list records filtered by glob pattern; alias for dbglob*/
|
||||
DBCORE_API long dbgrep(const char *ppatern,const char *fields);
|
||||
/*get field value*/
|
||||
DBCORE_API long dbgf(const char *pname);
|
||||
/*put field value*/
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "dbmf.h"
|
||||
@@ -38,7 +39,8 @@
|
||||
#include "iocInit.h"
|
||||
|
||||
/* This file is included from dbYacc.y
|
||||
* Duplicate some declarations to avoid warnings from analysis tools which don't know about this.
|
||||
* Duplicate some declarations to avoid warnings
|
||||
* from analysis tools that don't know about this.
|
||||
*/
|
||||
static int yyerror(char *str);
|
||||
static long pvt_yy_parse(void);
|
||||
@@ -199,8 +201,9 @@ static void freeInputFileList(void)
|
||||
|
||||
while((pinputFileNow=(inputFile *)ellFirst(&inputFileList))) {
|
||||
if(fclose(pinputFileNow->fp))
|
||||
errPrintf(0,__FILE__, __LINE__,
|
||||
"Closing file %s",pinputFileNow->filename);
|
||||
fprintf(stderr, ERL_WARNING
|
||||
": Error closing file '%s': %s\n",
|
||||
pinputFileNow->filename, strerror(errno));
|
||||
free((void *)pinputFileNow->filename);
|
||||
ellDelete(&inputFileList,(ELLNODE *)pinputFileNow);
|
||||
free((void *)pinputFileNow);
|
||||
@@ -225,7 +228,8 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
|
||||
char **macPairs;
|
||||
|
||||
if (ellCount(&tempList)) {
|
||||
fprintf(stderr, ERL_WARNING ": dbReadCOM: Parser stack dirty %d\n", ellCount(&tempList));
|
||||
fprintf(stderr, ERL_WARNING
|
||||
": dbReadCOM: Parser stack dirty %d\n", ellCount(&tempList));
|
||||
}
|
||||
|
||||
if (getIocState() != iocVoid) {
|
||||
@@ -274,8 +278,8 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
|
||||
if (pinputFile->filename)
|
||||
pinputFile->path = dbOpenFile(savedPdbbase, pinputFile->filename, &fp1);
|
||||
if (!pinputFile->filename || !fp1) {
|
||||
errPrintf(0, __FILE__, __LINE__,
|
||||
"dbRead opening file %s\n",pinputFile->filename);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Can't open file '%s'\n", pinputFile->filename);
|
||||
free((char*)pinputFile->filename);
|
||||
free(pinputFile);
|
||||
status = -1;
|
||||
@@ -294,7 +298,9 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
|
||||
status = pvt_yy_parse();
|
||||
|
||||
if (ellCount(&tempList) && !yyAbort)
|
||||
fprintf(stderr, ERL_WARNING ": dbReadCOM: Parser stack dirty w/o error. %d\n", ellCount(&tempList));
|
||||
fprintf(stderr, ERL_WARNING
|
||||
": dbReadCOM: Parser stack dirty w/o error. %d\n",
|
||||
ellCount(&tempList));
|
||||
while (ellCount(&tempList))
|
||||
popFirstTemp(); /* Memory leak on parser failure */
|
||||
|
||||
@@ -368,7 +374,8 @@ static int db_yyinput(char *buf, int max_size)
|
||||
int exp = macExpandString(macHandle,mac_input_buffer,
|
||||
my_buffer,MY_BUFFER_SIZE);
|
||||
if (exp < 0) {
|
||||
fprintf(stderr, "Warning: '%s' line %d has undefined macros\n",
|
||||
fprintf(stderr, ERL_WARNING
|
||||
": '%s' line %d has undefined macros\n",
|
||||
pinputFileNow->filename, pinputFileNow->line_num+1);
|
||||
}
|
||||
}
|
||||
@@ -377,8 +384,9 @@ static int db_yyinput(char *buf, int max_size)
|
||||
}
|
||||
if(fgetsRtn) break;
|
||||
if(fclose(pinputFileNow->fp))
|
||||
errPrintf(0,__FILE__, __LINE__,
|
||||
"Closing file %s",pinputFileNow->filename);
|
||||
fprintf(stderr, ERL_WARNING
|
||||
": Error closing file '%s': %s\n",
|
||||
pinputFileNow->filename, strerror(errno));
|
||||
free((void *)pinputFileNow->filename);
|
||||
ellDelete(&inputFileList,(ELLNODE *)pinputFileNow);
|
||||
free((void *)pinputFileNow);
|
||||
@@ -434,7 +442,7 @@ static void dbIncludeNew(char *filename)
|
||||
pinputFile->filename = macEnvExpand(filename);
|
||||
pinputFile->path = dbOpenFile(savedPdbbase, pinputFile->filename, &fp);
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Can't open include file \"%s\"\n", filename);
|
||||
fprintf(stderr, ERL_ERROR ": Can't open include file '%s'\n", filename);
|
||||
yyerror(NULL);
|
||||
free((void *)pinputFile->filename);
|
||||
free((void *)pinputFile);
|
||||
@@ -557,7 +565,7 @@ static void dbRecordtypeFieldHead(char *name,char *type)
|
||||
strcmp(pdbFldDes->name, "OUT")==0;
|
||||
i = dbFindFieldType(type);
|
||||
if (i < 0)
|
||||
yyerrorAbort("Illegal Field Type");
|
||||
yyerrorAbort("Invalid Field Type");
|
||||
pdbFldDes->field_type = i;
|
||||
}
|
||||
|
||||
@@ -589,7 +597,7 @@ static void dbRecordtypeFieldItem(char *name,char *value)
|
||||
} else if(strcmp(value,"ASL1")==0) {
|
||||
pdbFldDes->as_level = ASL1;
|
||||
} else {
|
||||
yyerror("Illegal Access Security value: Must be ASL0 or ASL1");
|
||||
yyerror("Invalid 'asl' value, must be ASL0 or ASL1");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -616,7 +624,7 @@ static void dbRecordtypeFieldItem(char *name,char *value)
|
||||
if(sscanf(value,"%hd",&pdbFldDes->special)==1) {
|
||||
return;
|
||||
}
|
||||
yyerror("Illegal 'special' value.");
|
||||
yyerror("Invalid 'special' value.");
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"pp")==0) {
|
||||
@@ -625,13 +633,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 'pp' value, must be YES/NO/TRUE/FALSE");
|
||||
yyerror("Invalid 'pp' value, must be YES/NO/TRUE/FALSE");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"interest")==0) {
|
||||
if(sscanf(value,"%hd",&pdbFldDes->interest)!=1)
|
||||
yyerror("Illegal 'interest' value, must be integer");
|
||||
yyerror("Invalid 'interest' value, must be integer");
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"base")==0) {
|
||||
@@ -640,13 +648,13 @@ static void dbRecordtypeFieldItem(char *name,char *value)
|
||||
} else if(strcmp(value,"HEX")==0) {
|
||||
pdbFldDes->base = CT_HEX;
|
||||
} else {
|
||||
yyerror("Illegal 'base' value, must be DECIMAL/HEX");
|
||||
yyerror("Invalid 'base' value, must be DECIMAL/HEX");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"size")==0) {
|
||||
if(sscanf(value,"%hd",&pdbFldDes->size)!=1)
|
||||
yyerror("Illegal 'size' value, must be integer");
|
||||
yyerror("Invalid 'size' value, must be integer");
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"extra")==0) {
|
||||
@@ -696,7 +704,8 @@ static void dbRecordtypeEmpty(void)
|
||||
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbRecordType = ptempListNode->item;
|
||||
fprintf(stderr, "Declaration of recordtype(%s) preceeded full definition.\n",
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Declaration of recordtype(%s) preceeded full definition.\n",
|
||||
pdbRecordType->name);
|
||||
yyerrorAbort(NULL);
|
||||
}
|
||||
@@ -737,10 +746,12 @@ static void dbRecordtypeBody(void)
|
||||
field_type = pdbFldDes->field_type;
|
||||
if((field_type>=DBF_INLINK) && (field_type<=DBF_FWDLINK))no_links++;
|
||||
if((field_type==DBF_STRING) && (pdbFldDes->size==0))
|
||||
fprintf(stderr,"recordtype(%s).%s size not specified\n",
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": recordtype(%s).%s size not specified\n",
|
||||
pdbRecordType->name,pdbFldDes->name);
|
||||
if((field_type==DBF_NOACCESS) && (pdbFldDes->extra==0))
|
||||
fprintf(stderr,"recordtype(%s).%s extra not specified\n",
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": recordtype(%s).%s extra not specified\n",
|
||||
pdbRecordType->name,pdbFldDes->name);
|
||||
}
|
||||
if (ellCount(&tempList))
|
||||
@@ -801,8 +812,9 @@ static void dbDevice(char *recordtype,char *linktype,
|
||||
int i,link_type;
|
||||
pgphentry = gphFind(savedPdbbase->pgpHash,recordtype,&savedPdbbase->recordTypeList);
|
||||
if(!pgphentry) {
|
||||
fprintf(stderr, "Record type \"%s\" not found for device \"%s\"\n",
|
||||
recordtype, choicestring);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Record type '%s' not found for device '%s'\n",
|
||||
recordtype, choicestring);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
@@ -814,8 +826,9 @@ static void dbDevice(char *recordtype,char *linktype,
|
||||
}
|
||||
}
|
||||
if(link_type==-1) {
|
||||
fprintf(stderr, "Bad link type \"%s\" for device \"%s\"\n",
|
||||
linktype, choicestring);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Bad link type '%s' for device '%s'\n",
|
||||
linktype, choicestring);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
@@ -1077,16 +1090,20 @@ int dbRecordNameValidate(const char *name)
|
||||
if(i==0) {
|
||||
/* first character restrictions */
|
||||
if(c=='-' || c=='+' || c=='[' || c=='{') {
|
||||
fprintf(stderr, "Warning: Record/Alias name '%s' should not begin with '%c'\n", name, c);
|
||||
fprintf(stderr, ERL_WARNING
|
||||
": Record/Alias name '%s' should not begin with '%c'\n",
|
||||
name, c);
|
||||
}
|
||||
}
|
||||
/* any character restrictions */
|
||||
if(c < ' ') {
|
||||
fprintf(stderr, "Warning: Record/Alias name '%s' should not contain non-printable 0x%02x\n",
|
||||
name, c);
|
||||
fprintf(stderr, ERL_WARNING
|
||||
": Record/Alias name '%s' contains non-printable 0x%02x\n",
|
||||
name, c);
|
||||
|
||||
} else if(c==' ' || c=='\t' || c=='"' || c=='\'' || c=='.' || c=='$') {
|
||||
fprintf(stderr, ERL_ERROR ": Bad character '%c' in Record/Alias name \"%s\"\n",
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Bad character '%c' in Record/Alias name \"%s\"\n",
|
||||
c, name);
|
||||
yyerrorAbort(NULL);
|
||||
return 1;
|
||||
@@ -1113,7 +1130,7 @@ static void dbRecordHead(char *recordType, char *name, int visible)
|
||||
status = dbFindRecord(pdbentry, name);
|
||||
if (status == 0)
|
||||
return; /* done */
|
||||
fprintf(stderr, ERL_ERROR ": Record \"%s\" not found\n", name);
|
||||
fprintf(stderr, ERL_ERROR ": Record '%s' not found\n", name);
|
||||
yyerror(NULL);
|
||||
duplicate = TRUE;
|
||||
return;
|
||||
@@ -1124,9 +1141,10 @@ static void dbRecordHead(char *recordType, char *name, int visible)
|
||||
if (status == 0) {
|
||||
dbDeleteRecord(pdbentry);
|
||||
} else {
|
||||
fprintf(stderr, ERL_WARNING ": Unable to delete record \"%s\". Not found.\n"
|
||||
" at file %s line %d\n",
|
||||
name, pinputFileNow->filename, pinputFileNow->line_num);
|
||||
fprintf(stderr, ERL_WARNING
|
||||
": Record '%s' not found, can't delete\n"
|
||||
" at file '%s', line %d\n",
|
||||
name, pinputFileNow->filename, pinputFileNow->line_num);
|
||||
}
|
||||
popFirstTemp();
|
||||
dbFreeEntry(pdbentry);
|
||||
@@ -1135,8 +1153,9 @@ static void dbRecordHead(char *recordType, char *name, int visible)
|
||||
}
|
||||
status = dbFindRecordType(pdbentry, recordType);
|
||||
if (status) {
|
||||
fprintf(stderr, "Record \"%s\" is of unknown type \"%s\"\n",
|
||||
name, recordType);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Record type '%s' for record '%s' not found\n",
|
||||
recordType, name);
|
||||
yyerrorAbort(NULL);
|
||||
return;
|
||||
}
|
||||
@@ -1146,23 +1165,24 @@ static void dbRecordHead(char *recordType, char *name, int visible)
|
||||
status = dbCreateRecord(pdbentry,name);
|
||||
if (status == S_dbLib_recExists) {
|
||||
if (strcmp(recordType, dbGetRecordTypeName(pdbentry)) != 0) {
|
||||
fprintf(stderr, ERL_ERROR ": Record \"%s\" of type \"%s\" redefined with new type "
|
||||
"\"%s\"\n", name, dbGetRecordTypeName(pdbentry), recordType);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": %s record '%s' already exists, can't load %s record\n",
|
||||
recordType, name, dbGetRecordTypeName(pdbentry));
|
||||
yyerror(NULL);
|
||||
duplicate = TRUE;
|
||||
return;
|
||||
}
|
||||
else if (dbRecordsOnceOnly) {
|
||||
fprintf(stderr, ERL_ERROR ": Record \"%s\" already defined and dbRecordsOnceOnly set.\n"
|
||||
"Used record type \"*\" to append.\n",
|
||||
name);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Record '%s' already defined; dbRecordsOnceOnly is set,\n"
|
||||
" so can't modify record.\n", name);
|
||||
yyerror(NULL);
|
||||
duplicate = TRUE;
|
||||
}
|
||||
}
|
||||
else if (status) {
|
||||
fprintf(stderr, "Can't create record \"%s\" of type \"%s\"\n",
|
||||
name, recordType);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Can't create %s record '%s'\n",
|
||||
recordType, name);
|
||||
yyerrorAbort(NULL);
|
||||
}
|
||||
|
||||
@@ -1181,8 +1201,9 @@ static void dbRecordField(char *name,char *value)
|
||||
pdbentry = ptempListNode->item;
|
||||
status = dbFindField(pdbentry,name);
|
||||
if (status) {
|
||||
fprintf(stderr, "%s Record \"%s\" does not have a field \"%s\"\n",
|
||||
dbGetRecordTypeName(pdbentry), dbGetRecordName(pdbentry), name);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": %s record '%s' doesn't have a field '%s'\n",
|
||||
dbGetRecordTypeName(pdbentry), dbGetRecordName(pdbentry), name);
|
||||
if(dbGetRecordName(pdbentry)) {
|
||||
DBENTRY temp;
|
||||
double bestSim = -1.0;
|
||||
@@ -1207,7 +1228,8 @@ static void dbRecordField(char *name,char *value)
|
||||
return;
|
||||
}
|
||||
if (pdbentry->indfield == 0) {
|
||||
fprintf(stderr, "Can't set \"NAME\" field of record \"%s\"\n",
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Can't set 'NAME' field of record '%s'\n",
|
||||
dbGetRecordName(pdbentry));
|
||||
yyerror(NULL);
|
||||
return;
|
||||
@@ -1225,8 +1247,10 @@ static void dbRecordField(char *name,char *value)
|
||||
char msg[128];
|
||||
|
||||
errSymLookup(status, msg, sizeof(msg));
|
||||
fprintf(stderr, "Can't set \"%s.%s\" to \"%s\" %s : %s\n",
|
||||
dbGetRecordName(pdbentry), name, value, pdbentry->message ? pdbentry->message : "", msg);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Can't set '%s.%s' to '%s' %s : %s\n",
|
||||
dbGetRecordName(pdbentry), name, value,
|
||||
pdbentry->message ? pdbentry->message : "", msg);
|
||||
dbPutStringSuggest(pdbentry, value);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
@@ -1256,8 +1280,9 @@ static void dbRecordInfo(char *name, char *value)
|
||||
|
||||
status = dbPutInfo(pdbentry,name,value);
|
||||
if (status) {
|
||||
fprintf(stderr, "Can't set \"%s\" info \"%s\" to \"%s\"\n",
|
||||
dbGetRecordName(pdbentry), name, value);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Can't set '%s' info(\"%s\") to '%s'\n",
|
||||
dbGetRecordName(pdbentry), name, value);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
@@ -1275,15 +1300,18 @@ static long createAlias(DBENTRY *pdbentry, const char *alias)
|
||||
if (status == 0) {
|
||||
if (tempEntry.precnode->aliasedRecnode != precnode) {
|
||||
if (tempEntry.precnode->aliasedRecnode)
|
||||
fprintf(stderr, ERL_ERROR ": Alias \"%s\" for \"%s\": name already used by an alias for \"%s\"\n",
|
||||
alias, dbGetRecordName(pdbentry),
|
||||
tempEntry.precnode->aliasedRecnode->recordname);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Alias '%s' for record '%s' already aliases '%s'\n",
|
||||
alias, dbGetRecordName(pdbentry),
|
||||
tempEntry.precnode->aliasedRecnode->recordname);
|
||||
else
|
||||
fprintf(stderr, ERL_ERROR ": Alias \"%s\" for \"%s\": name already used by a record\n",
|
||||
alias, dbGetRecordName(pdbentry));
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Alias '%s' for record '%s' is already a record name.\n",
|
||||
alias, dbGetRecordName(pdbentry));
|
||||
status = S_dbLib_recExists;
|
||||
} else if (dbRecordsOnceOnly) {
|
||||
fprintf(stderr, ERL_ERROR ": Alias \"%s\" already defined and dbRecordsOnceOnly set.\n",
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Alias '%s' already defined; dbRecordsOnceOnly is set.\n",
|
||||
alias);
|
||||
status = S_dbLib_recExists;
|
||||
}
|
||||
@@ -1320,8 +1348,9 @@ static void dbAlias(char *name, char *alias)
|
||||
|
||||
dbInitEntry(savedPdbbase, pdbEntry);
|
||||
if (dbFindRecord(pdbEntry, name)) {
|
||||
fprintf(stderr, "Alias \"%s\" refers to unknown record \"%s\"\n",
|
||||
alias, name);
|
||||
fprintf(stderr, ERL_ERROR
|
||||
": Alias '%s' names an unknown record '%s'\n",
|
||||
alias, name);
|
||||
yyerror(NULL);
|
||||
}
|
||||
else if (createAlias(pdbEntry, alias) != 0) {
|
||||
|
||||
@@ -2635,7 +2635,9 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DBF_NOACCESS:
|
||||
dbMsgPrint(pdbentry, "Can't set array field before iocInit()");
|
||||
/* fall through */
|
||||
default:
|
||||
return S_dbLib_badField;
|
||||
}
|
||||
@@ -3454,7 +3456,7 @@ void dbDumpDevice(DBBASE *pdbbase,const char *recordTypeName)
|
||||
" - get_ioint_info()"
|
||||
};
|
||||
int i, n = pdevSup->pdset->number;
|
||||
DEVSUPFUN *pfunc = &pdevSup->pdset->report;
|
||||
DEVSUPFUN *pfunc = (DEVSUPFUN*) &pdevSup->pdset->report;
|
||||
|
||||
printf("\t number: %d\n", n);
|
||||
for (i = 0; i < n; ++i, ++pfunc) {
|
||||
|
||||
@@ -19,7 +19,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
DBCORE_API int dbLoadTemplate(
|
||||
const char *sub_file, const char *cmd_collect);
|
||||
const char *sub_file, const char *cmd_collect, const char *path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "osiUnistd.h"
|
||||
#include "macLib.h"
|
||||
@@ -20,7 +21,10 @@
|
||||
|
||||
#include "epicsExport.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "dbStaticPvt.h"
|
||||
#include "dbLoadTemplate.h"
|
||||
#include "osiFileName.h"
|
||||
|
||||
static int line_num;
|
||||
static int yyerror(char* str);
|
||||
@@ -335,7 +339,7 @@ static int yyerror(char* str)
|
||||
|
||||
static int is_not_inited = 1;
|
||||
|
||||
int dbLoadTemplate(const char *sub_file, const char *cmd_collect)
|
||||
int dbLoadTemplate(const char *sub_file, const char *cmd_collect, const char *path)
|
||||
{
|
||||
FILE *fp;
|
||||
int i;
|
||||
@@ -356,8 +360,16 @@ int dbLoadTemplate(const char *sub_file, const char *cmd_collect)
|
||||
}
|
||||
|
||||
fp = fopen(sub_file, "r");
|
||||
// If the file does not exist locally, and it is not an absolute path...
|
||||
if (!fp && sub_file[0] != OSI_PATH_SEPARATOR[0]) {
|
||||
if (!path || !*path) {
|
||||
path = getenv("EPICS_DB_INCLUDE_PATH");
|
||||
}
|
||||
dbPath(pdbbase, path);
|
||||
dbOpenFile(pdbbase, sub_file, &fp);
|
||||
}
|
||||
if (!fp) {
|
||||
fprintf(stderr, "dbLoadTemplate: error opening sub file %s\n", sub_file);
|
||||
fprintf(stderr, "dbLoadTemplate: error opening sub file %s: %s\n", sub_file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,23 +15,24 @@
|
||||
/* dbLoadTemplate */
|
||||
static const iocshArg dbLoadTemplateArg0 = {"filename", iocshArgStringPath};
|
||||
static const iocshArg dbLoadTemplateArg1 = {"var1=value1,var2=value2", iocshArgString};
|
||||
static const iocshArg * const dbLoadTemplateArgs[2] = {
|
||||
&dbLoadTemplateArg0, &dbLoadTemplateArg1
|
||||
};
|
||||
static const iocshArg dbLoadTemplateArg2 = {"path1:path2:...", iocshArgString};
|
||||
static const iocshArg *const dbLoadTemplateArgs[3] = {
|
||||
&dbLoadTemplateArg0, &dbLoadTemplateArg1, &dbLoadTemplateArg2};
|
||||
static const iocshFuncDef dbLoadTemplateFuncDef = {
|
||||
"dbLoadTemplate",
|
||||
2,
|
||||
3,
|
||||
dbLoadTemplateArgs,
|
||||
"Load the substitution file given as first argument, apply the substitutions\n"
|
||||
"for each template in the substitution file, and load them using 'dbLoadRecords'.\n\n"
|
||||
"The second argument provides extra variables to substitute in the\n"
|
||||
"template files (not the substitution file).\n\n"
|
||||
"template files (not the substitution file). The third argument provides\n"
|
||||
"a list of paths to search through for the subsitution and template files.\n\n"
|
||||
"See 'help dbLoadRecords' for more information.\n\n"
|
||||
"Example: dbLoadTemplate db/my.substitutions 'user=myself,host=myhost'\n",
|
||||
"Example: dbLoadTemplate db/my.substitutions 'user=myself,host=myhost' 'path/to/subst:path2/to2/subst2'\n",
|
||||
};
|
||||
static void dbLoadTemplateCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
iocshSetError(dbLoadTemplate(args[0].sval, args[1].sval));
|
||||
iocshSetError(dbLoadTemplate(args[0].sval, args[1].sval, args[2].sval));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# msi: Macro Substitution and Include Tool
|
||||
|
||||
``` {program} msi
|
||||
```
|
||||
|
||||
(msitool)=
|
||||
## Introduction
|
||||
|
||||
@@ -18,7 +21,9 @@ substitution files accepted by the EPICS IOC's dbLoadTemplate command.
|
||||
|
||||
## Command Syntax
|
||||
|
||||
`msi -V -g -o outfile -I dir -M subs -S subfile template`
|
||||
``` bash
|
||||
msi -V -g -o outfile -I dir -M subs -S subfile template
|
||||
```
|
||||
|
||||
All parameters are optional. The -o, -I, -M, and -S switches may be
|
||||
separated from their associated value string by spaces if desired.
|
||||
@@ -26,80 +31,89 @@ Output will be written to stdout unless the -o option is given.
|
||||
|
||||
Switches have the following meanings:
|
||||
|
||||
- **-V**
|
||||
::: {option} -V
|
||||
Verbose warnings; if this parameter is specified then any undefined
|
||||
macro discovered in the template file which does not have an
|
||||
associated default value is considered an error. An error message is
|
||||
generated, and when msi terminates it will do so with an exit status
|
||||
of 2.
|
||||
:::
|
||||
|
||||
Verbose warnings; if this parameter is specified then any undefined
|
||||
macro discovered in the template file which does not have an
|
||||
associated default value is considered an error. An error message is
|
||||
generated, and when msi terminates it will do so with an exit status
|
||||
of 2.
|
||||
- **-g**
|
||||
::: {option} -g
|
||||
When this flag is given all macros defined in a substitution file
|
||||
will have global scope and thus their values will persist until a
|
||||
new value is given for this macro. This flag is provided for
|
||||
backwards compatibility as this was the behavior of previous
|
||||
versions of msi, but it does not follow common scoping rules and is
|
||||
discouraged.
|
||||
:::
|
||||
|
||||
When this flag is given all macros defined in a substitution file
|
||||
will have global scope and thus their values will persist until a
|
||||
new value is given for this macro. This flag is provided for
|
||||
backwards compatibility as this was the behavior of previous
|
||||
versions of msi, but it does not follow common scoping rules and is
|
||||
discouraged.
|
||||
- **-o _file_**
|
||||
::: {option} -o <file>
|
||||
Output will be written to the specifed \<file\> rather than to the
|
||||
standard output.
|
||||
:::
|
||||
|
||||
Output will be written to the specifed file rather than to the
|
||||
standard output.
|
||||
- **-I _dir_**
|
||||
::: {option} -I <dir>
|
||||
This parameter, which may be repeated or contain a colon-separated
|
||||
(or semi-colon separated on Windows) list of directory paths,
|
||||
specifies a search path for include commands. For example:
|
||||
|
||||
This parameter, which may be repeated or contain a colon-separated
|
||||
(or semi-colon separated on Windows) list of directory paths,
|
||||
specifies a search path for include commands. For example:
|
||||
``` bash
|
||||
msi -I /home/mrk/examples:. -I.. template
|
||||
```
|
||||
|
||||
msi -I /home/mrk/examples:. -I.. template
|
||||
specifies that all named files should be searched for in the following locations,
|
||||
in the order given:
|
||||
|
||||
specifies that all named files should be searched for in the following locations,
|
||||
in the order given:
|
||||
1. `/home/mrk/examples`
|
||||
2. `.` (the current directory)
|
||||
3. `..` (the parent of the current directory)
|
||||
|
||||
1. /home/mrk/examples
|
||||
2. . (the current directory)
|
||||
3. .. (the parent of the current directory)
|
||||
Note that relative path searching is handled as
|
||||
|
||||
Note that relative path searching is handled as
|
||||
|
||||
$ cat foo.substitutions
|
||||
file rel/path/bar.template {
|
||||
# contents
|
||||
}
|
||||
$ msi -I . -I /some/path foo.substitutions
|
||||
|
||||
which will try to find `bar.template` at the path `./rel/path/` followed by
|
||||
`/some/path/rel/path`.
|
||||
$ cat foo.substitutions
|
||||
file rel/path/bar.template {
|
||||
# contents
|
||||
}
|
||||
$ msi -I . -I /some/path foo.substitutions
|
||||
|
||||
which will try to find `bar.template` at the path `./rel/path/` followed by
|
||||
`/some/path/rel/path`.
|
||||
:::
|
||||
|
||||
- **-M _substitutions_**
|
||||
::: {option} -M <substitutions>
|
||||
This parameter specifies macro values for the template instance.
|
||||
Multiple macro values can be specified in one substitution
|
||||
parameter, or in multiple -M parameters. For example:
|
||||
|
||||
This parameter specifies macro values for the template instance.
|
||||
Multiple macro values can be specified in one substitution
|
||||
parameter, or in multiple -M parameters. For example:
|
||||
``` bash
|
||||
msi -M "a=aval,b=bval" -Mc=cval template
|
||||
```
|
||||
|
||||
msi -M "a=aval,b=bval" -Mc=cval template
|
||||
specifies that in the template file each occurrence of:
|
||||
|
||||
specifies that in the template file each occurrence of:
|
||||
- `$(a)` or `${a}` is replaced by _aval_
|
||||
- `$(b)` or `${b}` is replaced by _bval_
|
||||
- `$(c)` or `${c}` is replaced by _cval_
|
||||
:::
|
||||
|
||||
- `$(a)` or `${a}` is replaced by _aval_
|
||||
- `$(b)` or `${b}` is replaced by _bval_
|
||||
- `$(c)` or `${c}` is replaced by _cval_
|
||||
::: {option} -S <subfile>
|
||||
The substitution file. See below for format.
|
||||
:::
|
||||
|
||||
- **-S _subfile_**
|
||||
|
||||
The substitution file. See below for format.
|
||||
- **_template_**
|
||||
|
||||
The input file. If no file is specified then input is taken from
|
||||
stdin, i.e. msi can be used as a filter. See below for a description
|
||||
of commands that can be embedded in the template file.
|
||||
::: {option} <template>
|
||||
The input file. If no file is specified then input is taken from
|
||||
stdin, i.e. msi can be used as a filter. See below for a description
|
||||
of commands that can be embedded in the template file.
|
||||
:::
|
||||
|
||||
It is not possible to display usage by just typing msi since executing
|
||||
the command with no arguments is a valid command. To show usage specify
|
||||
an illegal switch, e.g.
|
||||
|
||||
msi -help
|
||||
``` bash
|
||||
msi -help
|
||||
```
|
||||
|
||||
|
||||
## Exit Status
|
||||
@@ -167,9 +181,9 @@ template file itself. These commands are:
|
||||
|
||||
Lines containing commands must be in one of these forms:
|
||||
|
||||
- include "_filename_"
|
||||
- {samp}`include "{filename}"`
|
||||
|
||||
- substitute "_name1=value1, name2=value2, ..._"
|
||||
- {samp}`substitute "{name1=value1, name2=value2, ...}"`
|
||||
|
||||
White space is allowed before and after the command verb, and after the
|
||||
quoted string. If embedded quotes are needed, the backslash character \
|
||||
@@ -227,11 +241,11 @@ dbTemplate format. We will discuss each separately.
|
||||
### Regular format
|
||||
|
||||
global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
|
||||
{var1=set1_val1, var2=set1_val2, ...}
|
||||
{var2=set2_val2, var1=set2_val1, ...}
|
||||
{var1=set1_val1, var2=set1_val2, ...}
|
||||
{var2=set2_val2, var1=set2_val1, ...}
|
||||
global {gbl_var1=gbl_val3, gbl_var2=gbl_val4, ...}
|
||||
{var1=set3_val1, var2=set3_val2, ...}
|
||||
{var2=set4_val2, var1=set4_val1, ...}
|
||||
{var1=set3_val1, var2=set3_val2, ...}
|
||||
{var2=set4_val2, var1=set4_val1, ...}
|
||||
|
||||
The template file is output with macro substitutions performed once for
|
||||
each set of braces containing macro replacement values.
|
||||
@@ -241,12 +255,12 @@ each set of braces containing macro replacement values.
|
||||
|
||||
global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
|
||||
pattern {var1, var2, ...}
|
||||
{set1_val1, set1_val2, ...}
|
||||
{set2_val1, set2_val2, ...}
|
||||
{set1_val1, set1_val2, ...}
|
||||
{set2_val1, set2_val2, ...}
|
||||
pattern {var2, var1, ...}
|
||||
global {gbl_var1=gbl_val3, gbl_var2=gbl_val4, ...}
|
||||
{set3_val2, set3_val1, ...}
|
||||
{set4_val2, set4_val2, ...}
|
||||
{set3_val2, set3_val1, ...}
|
||||
{set4_val2, set4_val2, ...}
|
||||
|
||||
This produces the same result as the regular format example above.
|
||||
|
||||
@@ -320,8 +334,8 @@ The file template contains
|
||||
and the file `substitute` is
|
||||
|
||||
global {family=Kraimer}
|
||||
{first=Marty}
|
||||
{first=Irma}
|
||||
{first=Marty}
|
||||
{first=Irma}
|
||||
|
||||
The following is the output produced:
|
||||
|
||||
@@ -340,8 +354,8 @@ Let the command be:
|
||||
The file pattern contains
|
||||
|
||||
pattern {first,last}
|
||||
{Marty,Kraimer}
|
||||
{Irma,Kraimer}
|
||||
{Marty,Kraimer}
|
||||
{Irma,Kraimer}
|
||||
|
||||
and template is the same as the previous example:
|
||||
|
||||
@@ -365,16 +379,16 @@ Let the command be
|
||||
`xxx.substitutions` is
|
||||
|
||||
file template {
|
||||
pattern {first,last}
|
||||
{Marty,Kraimer}
|
||||
{Irma,Kraimer}
|
||||
pattern {last,first}
|
||||
{Smith,Bill}
|
||||
{Smith,Mary}
|
||||
pattern {first,last}
|
||||
{Marty,Kraimer}
|
||||
{Irma,Kraimer}
|
||||
pattern {last,first}
|
||||
{Smith,Bill}
|
||||
{Smith,Mary}
|
||||
}
|
||||
file template {
|
||||
{first=Marty,last=Kraimer}
|
||||
{first=Irma,last=Kraimer}
|
||||
{first=Marty,last=Kraimer}
|
||||
{first=Irma,last=Kraimer}
|
||||
}
|
||||
|
||||
`template` is the same as in the previous example.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
# This is a Makefile fragment, see src/ioc/Makefile.
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "devSup.h"
|
||||
#include "drvSup.h"
|
||||
#include "epicsRelease.h"
|
||||
#include "epicsConvert.h"
|
||||
#include "initHooks.h"
|
||||
#include "iocInit.h"
|
||||
#include "link.h"
|
||||
@@ -129,6 +130,16 @@ static int iocBuild_1(void)
|
||||
errlogPrintf("iocBuild: " ERL_ERROR " Aborting, bad database definition (DBD)!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
/* fall back to "old" decimal-only conversion if EPICS_DB_CONVERT_DECIMAL_ONLY
|
||||
is set and does not look like meaning no/false/0 */
|
||||
const char* dec_only = getenv("EPICS_DB_CONVERT_DECIMAL_ONLY");
|
||||
if (dec_only && *dec_only && !strchr("nNfF0", *dec_only)) {
|
||||
dbConvertBase = 10;
|
||||
}
|
||||
}
|
||||
|
||||
epicsSignalInstallSigHupIgnore();
|
||||
initHookAnnounce(initHookAtBeginning);
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ express that space character as an escaped character C<\x20> or C<\u0020> inside
|
||||
a quoted string, otherwise the space will mark the end of the channel name to
|
||||
the link parsing code inside the IOC.
|
||||
|
||||
=head4 Example Filters
|
||||
=head3 Example Filters
|
||||
|
||||
Given a record called C<test:channel> the following would all apply a channel
|
||||
filter C<f> to the VAL field of that record, giving the filter two numeric
|
||||
@@ -230,7 +230,9 @@ This filter is used for two purposes:
|
||||
|
||||
=head4 Parameters
|
||||
|
||||
=head4 No parameters (an empty pair of braces)
|
||||
=over
|
||||
|
||||
=item No parameters (an empty pair of braces)
|
||||
|
||||
Retrieve the record value as normal, but replace the timestamp with the time the
|
||||
value was fetched (or an update was sent). This is useful for clients that can't
|
||||
@@ -239,7 +241,7 @@ indicates when the record last processed, which could have been days or even
|
||||
weeks ago for some records, or set to the EPICS epoch if the record has never
|
||||
processed.
|
||||
|
||||
=head4 Numeric type C<"num">
|
||||
=item Numeric type C<"num">
|
||||
|
||||
The following values are accepted for this parameter:
|
||||
|
||||
@@ -262,7 +264,7 @@ The following values are accepted for this parameter:
|
||||
Note that C<epicsUInt32> cannot be transferred over Channel Access; in that
|
||||
case, the value will be converted to C<epicsFloat64>.
|
||||
|
||||
=head4 String type C<"str">
|
||||
=item String type C<"str">
|
||||
|
||||
The following values are accepted for this parameter:
|
||||
|
||||
@@ -275,7 +277,7 @@ The following values are accepted for this parameter:
|
||||
|
||||
=back
|
||||
|
||||
=head4 Epoch adjustment C<"epoch">
|
||||
=item Epoch adjustment C<"epoch">
|
||||
|
||||
The following values are accepted for this parameter:
|
||||
|
||||
@@ -288,6 +290,8 @@ The following values are accepted for this parameter:
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=head4 Examples
|
||||
|
||||
Hal$ caget -a 'test:invalid_ts.{"ts":{}}'
|
||||
|
||||
@@ -81,7 +81,7 @@ link(calc, lnkCalcIf)
|
||||
=head3 Calculation Link C<"calc">
|
||||
|
||||
A calculation link is an input link that can evaluate mathematical expressions
|
||||
on scalar (double-precision floating-point) values obtained from up to 12 child
|
||||
on scalar (double-precision floating-point) values obtained from up to 21 child
|
||||
input links, and returns a double-precision floating-point result. The
|
||||
expression is evaluated by the EPICS Calc engine, and the result is returned as
|
||||
the value of the link.
|
||||
@@ -95,7 +95,7 @@ record will be placed in C<LINK/MAJOR> alarm. If not and the C<minor> expression
|
||||
evaluates to non-zero the record will be placed in C<LINK/MINOR> alarm state.
|
||||
|
||||
A calculation link can also be an output link, with the scalar output value
|
||||
being converted to a double and provided to the expression as C<VAL>. Up to 12
|
||||
being converted to a double and provided to the expression as C<VAL>. Up to 21
|
||||
additional input links can also be read and provided to the expression as above.
|
||||
The result of the calculation is forwarded to a child output link specified in
|
||||
the link's C<out> parameter.
|
||||
@@ -127,7 +127,7 @@ An optional expression that returns non-zero to raise a minor alarm.
|
||||
=item args
|
||||
|
||||
A JSON list of up to 12 input arguments for the expression, which are assigned
|
||||
to the inputs C<A>, C<B>, C<C>, ... C<L>. Each input argument may be either a
|
||||
to the inputs C<A>, C<B>, C<C>, ... C<U>. Each input argument may be either a
|
||||
numeric literal or an embedded JSON link inside C<{}> braces. The same input
|
||||
values are provided to the two alarm expressions as to the primary expression.
|
||||
|
||||
@@ -149,7 +149,7 @@ result should be displayed. Equivalent to the C<PREC> field of a record.
|
||||
|
||||
=item time
|
||||
|
||||
An optional string containing a single upper or lower-case letter C<A> ... C<L>
|
||||
An optional string containing a single upper or lower-case letter C<A> ... C<U>
|
||||
which must correspond to an input provided in the C<args> parameter. When the
|
||||
record containing such a link has C<TSEL> set to -2 (epicsTimeEventDeviceTime)
|
||||
the record's timestamp field C<TIME> will be read from the indicated input link
|
||||
|
||||
@@ -177,7 +177,7 @@ static jlif_result lnkCalc_string(jlink *pjlink, const char *val, size_t len)
|
||||
if (clink->pstate == ps_time) {
|
||||
char tinp;
|
||||
|
||||
if (len != 1 || (tinp = toupper((int) val[0])) < 'A' || tinp > 'L') {
|
||||
if (len != 1 || (tinp = toupper((int) val[0])) < 'A' || tinp >= 'A' + CALCPERFORM_NARGS) {
|
||||
errlogPrintf("lnkCalc: Bad 'time' parameter \"%.*s\"\n", (int) len, val);
|
||||
return jlif_stop;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "alarm.h"
|
||||
#include "cantProceed.h"
|
||||
#include "epicsStdio.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbAccess.h"
|
||||
@@ -141,8 +142,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
if (pfunc) {
|
||||
pfunc(prec);
|
||||
} else {
|
||||
recGblRecordError(S_db_BadSub, (void *)prec,
|
||||
"aSubRecord::init_record - INAM subr not found");
|
||||
fprintf(stderr, "%s.INAM " ERL_ERROR " function '%s' not found\n",
|
||||
prec->name, prec->inam);
|
||||
return S_db_BadSub;
|
||||
}
|
||||
}
|
||||
@@ -153,8 +154,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
if (pfunc)
|
||||
prec->sadr = pfunc;
|
||||
else {
|
||||
recGblRecordError(S_db_BadSub, (void *)prec,
|
||||
"aSubRecord::init_record - SNAM subr not found");
|
||||
fprintf(stderr, "%s.SNAM " ERL_ERROR " function '%s' not found\n",
|
||||
prec->name, prec->snam);
|
||||
return S_db_BadSub;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ This flag controls value, log (archive) and alarm change events.
|
||||
The input links from where the values of A,...,U are fetched
|
||||
during record processing.
|
||||
|
||||
=fields INPA, INPB, INPC, INPD, INPE, INPF, INPG, INPH, INPI, INPJ, INPK, INPL, INPM, INPN, INPO, INPP, INPQ, INPR, INPS, INPT, INPU
|
||||
=fields INPA - INPU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -341,7 +341,7 @@ during record processing.
|
||||
Thse fields hold the scalar or array values fetched through the input links
|
||||
INPA,...,INPU.
|
||||
|
||||
=fields A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U
|
||||
=fields A - U
|
||||
|
||||
=cut
|
||||
|
||||
@@ -561,7 +561,7 @@ INPA,...,INPU.
|
||||
Field types of the input value fields.
|
||||
The choices can be found by following the link to the menuFtype definition.
|
||||
|
||||
=fields FTA, FTB, FTC, FTD, FTE, FTF, FTG, FTH, FTI, FTJ, FTK, FTL, FTM, FTN, FTO, FTP, FTQ, FTR, FTS, FTT, FTU
|
||||
=fields FTA - FTU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -742,7 +742,7 @@ Note that access to the C<NOT> field from C code must use the field name in
|
||||
upper case, e.g. C<< prec->NOT >> since the lower-case C<not> is a reserved
|
||||
word in C++ and cannot be used as an identifier.
|
||||
|
||||
=fields NOA, NOB, NOC, NOD, NOE, NOF, NOG, NOH, NOI, NOJ, NOK, NOL, NOM, NON, NOO, NOP, NOQ, NOR, NOS, NOT, NOU
|
||||
=fields NOA - NOU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -899,7 +899,7 @@ word in C++ and cannot be used as an identifier.
|
||||
These fields specify how many array elements the input value fields currently
|
||||
contain.
|
||||
|
||||
=fields NEA, NEB, NEC, NED, NEE, NEF, NEG, NEH, NEI, NEJ, NEK, NEL, NEM, NEN, NEO, NEP, NEQ, NER, NES, NET, NEU
|
||||
=fields NEA - NEU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -1035,7 +1035,7 @@ contain.
|
||||
The output links through which the VALA ... VALU field values are sent
|
||||
during record processing, provided the subroutine returned 0.
|
||||
|
||||
=fields OUTA, OUTB, OUTC, OUTD, OUTE, OUTF, OUTG, OUTH, OUTI, OUTJ, OUTK, OUTL, OUTM, OUTN, OUTO, OUTP, OUTQ, OUTR, OUTS, OUTT, OUTU
|
||||
=fields OUTA - OUTU
|
||||
|
||||
=cut
|
||||
field(OUTA,DBF_OUTLINK) {
|
||||
@@ -1149,7 +1149,7 @@ during record processing, provided the subroutine returned 0.
|
||||
These fields hold scalar or array data generated by the subroutine which will
|
||||
be sent through the OUTA ... OUTU links during record processing.
|
||||
|
||||
=fields VALA, VALB, VALC, VALD, VALE, VALF, VALG, VALH, VALI, VALJ, VALK, VALL, VALM, VALN, VALO, VALP, VALQ, VALR, VALS, VALT, VALU
|
||||
=fields VALA - VALU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -1369,7 +1369,7 @@ be sent through the OUTA ... OUTU links during record processing.
|
||||
The previous values of the output fields.
|
||||
These are used to determine when to post events if EFLG is set to C<ON CHANGE>.
|
||||
|
||||
=fields OVLA, OVLB, OVLC, OVLD, OVLE, OVLF, OVLG, OVLH, OVLI, OVLJ, OVLK, OVLL, OVLM, OVLN, OVLO, OVLP, OVLQ, OVLR, OVLS, OVLT, OVLU
|
||||
=fields OVLA - OVLU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -1526,7 +1526,7 @@ These are used to determine when to post events if EFLG is set to C<ON CHANGE>.
|
||||
Field types of the output value fields.
|
||||
The choices can be found by following a link to the menuFtype definition.
|
||||
|
||||
=fields FTVA, FTVB, FTVC, FTVD, FTVE, FTVF, FTVG, FTVH, FTVI, FTVJ, FTVK, FTVL, FTVM, FTVN, FTVO, FTVP, FTVQ, FTVR, FTVS, FTVT, FTVU
|
||||
=fields FTVA - FTVU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -1703,7 +1703,7 @@ The choices can be found by following a link to the menuFtype definition.
|
||||
|
||||
These fields specify how many array elements the output value fields may hold.
|
||||
|
||||
=fields NOVA, NOVB, NOVC, NOVD, NOVE, NOVF, NOVG, NOVH, NOVI, NOVJ, NOVK, NOVL, NOVM, NOVN, NOVO, NOVP, NOVQ, NOVR, NOVS, NOVT, NOVU
|
||||
=fields NOVA - NOVU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -1860,7 +1860,7 @@ These fields specify how many array elements the output value fields may hold.
|
||||
These fields specify how many array elements the output value fields currently
|
||||
contain.
|
||||
|
||||
=fields NEVA, NEVB, NEVC, NEVD, NEVE, NEVF, NEVG, NEVH, NEVI, NEVJ, NEVK, NEVL, NEVM, NEVN, NEVO, NEVP, NEVQ, NEVR, NEVS, NEVT, NEVU
|
||||
=fields NEVA - NEVU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -1996,7 +1996,7 @@ contain.
|
||||
These fields specify how many array elements the old value fields currently
|
||||
contain.
|
||||
|
||||
=fields ONVA, ONVB, ONVC, ONVD, ONVE, ONVF, ONVG, ONVH, ONVI, ONVJ, ONVK, ONVL, ONVM, ONVN, ONVO, ONVP, ONVQ, ONVR, ONVS, ONVT, ONVU
|
||||
=fields ONVA - ONVU
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -67,23 +67,29 @@ converted into engineering units and placed in the VAL field as follows:
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
RVAL is converted to a double and ROFF is added to it.
|
||||
|
||||
=item 2.
|
||||
|
||||
If ASLO is non-zero the value is multiplied by ASLO.
|
||||
|
||||
=item 3.
|
||||
|
||||
AOFF is added.
|
||||
|
||||
=item 4.
|
||||
|
||||
If LINR is C<NO CONVERSION> the units conversion is finished after the above
|
||||
steps.
|
||||
|
||||
=item 5.
|
||||
|
||||
If LINR is C<LINEAR> or C<SLOPE>, the value from step 3 above is multiplied by
|
||||
ESLO and EOFF is added to complete the units conversion process.
|
||||
|
||||
=item 6.
|
||||
|
||||
Any other value for LINR selects a particular breakpoint table to be used on the
|
||||
value from step 3 above.
|
||||
|
||||
|
||||
@@ -689,13 +689,17 @@ Routine process implements the following algorithm:
|
||||
|
||||
=over
|
||||
|
||||
=item 1. Check to see that the appropriate device support module
|
||||
=item 1.
|
||||
|
||||
Check to see that the appropriate device support module
|
||||
exists. If it doesn't, an error message is issued and processing is
|
||||
terminated with the PACT field set to TRUE. This ensures that processes
|
||||
will no longer be called for this record. Thus error storms will not
|
||||
occur.
|
||||
|
||||
=item 2. Check PACT: If PACT is FALSE call fetch_values and convert
|
||||
=item 2.
|
||||
|
||||
Check PACT: If PACT is FALSE call fetch_values and convert
|
||||
which perform the following steps:
|
||||
|
||||
=over
|
||||
@@ -742,20 +746,28 @@ calculated in, using the formula RVAL = (RVAL -AOFF) / ASLO - ROFF.
|
||||
|
||||
=back
|
||||
|
||||
=item 3. Check alarms: This routine checks to see if the new VAL causes
|
||||
=item 3.
|
||||
|
||||
Check alarms: This routine checks to see if the new VAL causes
|
||||
the alarm status and severity to change. If so, NSEV, NSTA and y are
|
||||
set. It also honors the alarm hysteresis factor (HYST). Thus the value
|
||||
must change by at least HYST before the alarm status and severity is
|
||||
reduced.
|
||||
|
||||
=item 4. Check severity and write the new value. See Invalid Alarm
|
||||
=item 4.
|
||||
|
||||
Check severity and write the new value. See Invalid Alarm
|
||||
Output Action for details on how invalid alarms affect output records.
|
||||
|
||||
=item 5. If PACT has been changed to TRUE, the device support write
|
||||
=item 5.
|
||||
|
||||
If PACT has been changed to TRUE, the device support write
|
||||
output routine has started but has not completed writing the new value.
|
||||
In this case, the processing routine merely returns, leaving PACT TRUE.
|
||||
|
||||
=item 6. Check to see if monitors should be invoked:
|
||||
=item 6.
|
||||
|
||||
Check to see if monitors should be invoked:
|
||||
|
||||
=over
|
||||
|
||||
@@ -772,7 +784,9 @@ monitors are invoked.
|
||||
|
||||
=back
|
||||
|
||||
=item 7. Scan forward link if necessary, set PACT and INIT FALSE, and
|
||||
=item 7.
|
||||
|
||||
Scan forward link if necessary, set PACT and INIT FALSE, and
|
||||
return.
|
||||
|
||||
=back
|
||||
|
||||
@@ -331,23 +331,25 @@ Routine process implements the following algorithm:
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
Check to see that the appropriate device support module exists. If it
|
||||
doesn't, an error message is issued and processing is terminated with
|
||||
the PACT field still set to TRUE. This ensures that processes will no
|
||||
longer be called for this record. Thus error storms will not occur.
|
||||
|
||||
=item 2.
|
||||
|
||||
C<readValue()> is called. See L<Input Records> for details.
|
||||
|
||||
=item 3.
|
||||
|
||||
If PACT has been changed to TRUE, the device support read routine has
|
||||
started but has not completed reading a new input value. In this case, the
|
||||
processing routine merely returns, leaving PACT TRUE.
|
||||
|
||||
=item 4.
|
||||
Convert.
|
||||
|
||||
=back
|
||||
Convert.
|
||||
|
||||
=over
|
||||
|
||||
@@ -368,17 +370,15 @@ if status is 2, set status = 0
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item 5.
|
||||
|
||||
Check alarms: This routine checks to see if the new VAL causes the alarm
|
||||
status and severity to change. If so, NSEV, NSTA and LALM are set. Note
|
||||
that if VAL is greater than 1, no checking is performed.
|
||||
|
||||
=item 6.
|
||||
Check if monitors should be invoked:
|
||||
|
||||
=back
|
||||
Check if monitors should be invoked:
|
||||
|
||||
=over
|
||||
|
||||
@@ -396,9 +396,8 @@ NSEV and NSTA are reset to 0.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item 7.
|
||||
|
||||
Scan forward link if necessary, set PACT FALSE, and return.
|
||||
|
||||
=back
|
||||
|
||||
@@ -21,7 +21,7 @@ the HIGH field is configured.
|
||||
|
||||
recordtype(bo) {
|
||||
|
||||
=head3 Scan Parameters
|
||||
=head2 Scan Parameters
|
||||
|
||||
The binary output record has the standard fields for specifying under what
|
||||
circumstances the record will be processed.
|
||||
@@ -29,7 +29,7 @@ These fields are described in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=fields SCAN, PHAS, EVNT, PRIO, PINI
|
||||
|
||||
=head3 Desired Output Parameters
|
||||
=head2 Desired Output Parameters
|
||||
|
||||
The binary output record must specify where its desired output originates.
|
||||
The desired output needs to be in engineering units.
|
||||
@@ -50,7 +50,7 @@ for information on hardware addresses and links.
|
||||
|
||||
=fields DOL, OMSL
|
||||
|
||||
=head3 Convert and Write Parameters
|
||||
=head2 Convert and Write Parameters
|
||||
|
||||
These parameters are used to determine where the binary output writes to
|
||||
and how to convert the engineering units to a raw signal. After VAL is set
|
||||
@@ -76,7 +76,7 @@ device back to 0 after I<N> number of seconds.
|
||||
|
||||
=fields DTYP, OUT, VAL, RVAL, HIGH, ZNAM, ONAM
|
||||
|
||||
=head3 Conversion Parameters
|
||||
=head2 Conversion Parameters
|
||||
|
||||
The ZNAM field has the string that corresponds to the 0 state, and the ONAM
|
||||
field holds the string that corresponds to the 1 state. These fields, other
|
||||
@@ -98,7 +98,7 @@ the device or link to 1, then changes it back to 0 after I<N> number of seconds.
|
||||
|
||||
=fields ZNAM, ONAM, HIGH
|
||||
|
||||
=head3 Output Specification
|
||||
=head2 Output Specification
|
||||
|
||||
The OUT field specifies where the binary output record writes its output.
|
||||
It must specify the address of an I/O card if the record sends its output
|
||||
@@ -116,7 +116,7 @@ for information on the format of the database and channel access addresses.
|
||||
Also, see L<Device Support For Soft Records> in this chapter for more on output
|
||||
to other records.
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
=head2 Operator Display Parameters
|
||||
|
||||
These parameters are used to present meaningful data to the operator, The
|
||||
C<get_enum_str()> record support routine can retrieve the state string
|
||||
@@ -129,7 +129,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields ZNAM, ONAM, NAME, DESC
|
||||
|
||||
=head3 Alarm Parameters
|
||||
=head2 Alarm Parameters
|
||||
|
||||
These parameters are used to determine the binary output's alarm condition
|
||||
and to determine the severity of that condition. The possible alarm
|
||||
@@ -147,7 +147,7 @@ common to all record types.
|
||||
|
||||
=fields ZSV, OSV, COSV, IVOA, IVOV
|
||||
|
||||
=head3 Run-Time Parameters
|
||||
=head2 Run-Time Parameters
|
||||
|
||||
These parameters are used by the run-time code for processiong the binary
|
||||
output. They are not configurable using a configuration tool. They
|
||||
@@ -178,7 +178,7 @@ The WPDT field is a private field for honoring seconds to hold HIGH.
|
||||
|
||||
=fields ORAW, MASK, RBV, ORBV, LALM, MLST, RPVT, WDPT
|
||||
|
||||
=head3 Simulation Mode Parameters
|
||||
=head2 Simulation Mode Parameters
|
||||
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
@@ -376,11 +376,9 @@ for more information on simulation mode and its fields.
|
||||
}
|
||||
|
||||
|
||||
=head2 Record Support
|
||||
=head2 Record Support Routines
|
||||
|
||||
=head3 Record Support Routines
|
||||
|
||||
=head2 C<init_record>
|
||||
=head3 C<init_record>
|
||||
|
||||
This routine initializes SIMM if SIML is a constant or creates a channel
|
||||
access link if SIML is PV_LINK. If SIOL is a PV_LINK a channel access link
|
||||
@@ -398,19 +396,19 @@ or initialzed to 0 if DOL is zero, and UDF is set to FALSE.
|
||||
If device support includes C<init_record()>, it is called. VAL is set using
|
||||
RVAL, and UDF is set to FALSE.
|
||||
|
||||
=head2 C<process>
|
||||
=head3 C<process>
|
||||
|
||||
See next section.
|
||||
|
||||
=head2 C<get_enum_str>
|
||||
=head3 C<get_enum_str>
|
||||
|
||||
Retrieves ASCII string corresponding to VAL.
|
||||
|
||||
=head2 C<get_enum_strs>
|
||||
=head3 C<get_enum_strs>
|
||||
|
||||
Retrieves ASCII strings for ZNAM and ONAM.
|
||||
|
||||
=head2 C<put_enum_str>
|
||||
=head3 C<put_enum_str>
|
||||
|
||||
Checks if string matches ZNAM or ONAM, and if it does, sets VAL.
|
||||
|
||||
@@ -418,96 +416,107 @@ Checks if string matches ZNAM or ONAM, and if it does, sets VAL.
|
||||
|
||||
Routine process implements the following algorithm:
|
||||
|
||||
=over 1
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
Check to see that the appropriate device support module exists. If it
|
||||
doesn't, an error message is issued and processing is terminated with
|
||||
the PACT field still set to TRUE. This ensures that processes will no
|
||||
longer be called for this record. Thus error storms will not occur.
|
||||
|
||||
=item 2.
|
||||
If PACT is FALSE
|
||||
|
||||
=back
|
||||
If PACT is FALSE
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
If DOL holds a link and OMSL is C<closed_loop>
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
get values from DOL
|
||||
|
||||
=item *
|
||||
|
||||
check for link alarm
|
||||
|
||||
=item *
|
||||
|
||||
force VAL to be 0 or 1
|
||||
|
||||
=item *
|
||||
|
||||
if MASK is defined
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
if VAL is 0 set RVAL = 0
|
||||
|
||||
=back
|
||||
|
||||
=item *
|
||||
|
||||
else set RVAL = MASK
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item 3.
|
||||
|
||||
Check alarms: This routine checks to see if the new VAL causes the alarm
|
||||
status and severity to change. If so, NSEV, NSTA, and LALM are set.
|
||||
|
||||
=item 4.
|
||||
|
||||
Check severity and write the new value. See L<Invalid Output Action Fields|dbCommonOutput/Invalid Output Action Fields>
|
||||
for more information on how INVALID alarms affect output.
|
||||
|
||||
=item 5.
|
||||
|
||||
If PACT has been changed to TRUE, the device support write output routine
|
||||
has started but has not completed writing the new value. in this case, the
|
||||
processing routine merely returns, leaving PACT TRUE.
|
||||
|
||||
=item 6.
|
||||
|
||||
Check WAIT. If VAL is 1 and WAIT is greater than 0, process again with a
|
||||
VAL=0 after WAIT seconds.
|
||||
|
||||
=item 7.
|
||||
|
||||
Check to see if monitors should be invoked.
|
||||
|
||||
=back
|
||||
|
||||
=over 1
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
Alarm monitors are invoked if the alarm status or severity has changed.
|
||||
|
||||
=item *
|
||||
|
||||
Archive and value change monitors are invoked if MLST is not equal to VAL.
|
||||
|
||||
=item *
|
||||
|
||||
Monitors for RVAL and for RBV are checked whenever other monitors are
|
||||
invoked.
|
||||
|
||||
=item *
|
||||
|
||||
NSEV and NSTA are reset to 0.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
=item 8.
|
||||
|
||||
=item 8
|
||||
Scan forward link if necessary, set PACT FALSE, and return
|
||||
|
||||
=back
|
||||
@@ -527,7 +536,7 @@ are primarily interested in the following fields:
|
||||
|
||||
Device support consists of the following routines:
|
||||
|
||||
=head4 long report(int level)
|
||||
=head4 C<long report(int level)>
|
||||
|
||||
This optional routine is called by the IOC command C<dbior> and is passed the
|
||||
report level that was requested by the user.
|
||||
@@ -537,7 +546,7 @@ information at higher levels, or to select different types of information with
|
||||
different levels.
|
||||
Level zero should print no more than a small summary.
|
||||
|
||||
=head4 long init(int after)
|
||||
=head4 C<long init(int after)>
|
||||
|
||||
This optional routine is called twice at IOC initialization time.
|
||||
The first call happens before any of the C<init_record()> calls are made, with
|
||||
@@ -545,41 +554,46 @@ the integer parameter C<after> set to 0.
|
||||
The second call happens after all of the C<init_record()> calls have been made,
|
||||
with C<after> set to 1.
|
||||
|
||||
=head2 C<init_record(precord)>
|
||||
=head4 C<init_record(precord)>
|
||||
|
||||
This routine is optional. If provided, it is called by record support
|
||||
This routine is optional. If provided, it is called by the record support's
|
||||
C<init_record()> routine. It should determine MASK if it is needed.
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
0: Success. RVAL modified (VAL will be set accordingly)
|
||||
|
||||
=item *
|
||||
|
||||
2: Success. VAL modified
|
||||
|
||||
=item *
|
||||
|
||||
other: Error
|
||||
|
||||
=back
|
||||
|
||||
=head2 C<get_ioint_info(int cmd, struct dbCommon *precord, IOSCANPVT *ppvt)>
|
||||
=head4 C<get_ioint_info(int cmd, struct dbCommon *precord, IOSCANPVT *ppvt)>
|
||||
|
||||
This routine is called by the ioEventScan system each time the record is
|
||||
added or deleted from an I/O event scan list. C<cmd> has the value (0,1) if
|
||||
the record is being (added to, deleted from) an I/O event list. It must be
|
||||
provided for any device type that can use the ioEvent scanner.
|
||||
|
||||
=head2 C<write_bo(precord)>
|
||||
=head4 C<write_bo(precord)>
|
||||
|
||||
This routine must output a new value. It returns the following values:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
0: Success
|
||||
|
||||
=item *
|
||||
|
||||
other: Error.
|
||||
|
||||
=back
|
||||
|
||||
@@ -159,9 +159,9 @@ static long special(DBADDR *paddr, int after)
|
||||
#define indexof(field) calcRecord##field
|
||||
|
||||
static long get_linkNumber(int fieldIndex) {
|
||||
if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L))
|
||||
if (fieldIndex >= indexof(A) && fieldIndex < indexof(A) + CALCPERFORM_NARGS)
|
||||
return fieldIndex - indexof(A);
|
||||
if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL))
|
||||
if (fieldIndex >= indexof(LA) && fieldIndex < indexof(LA) + CALCPERFORM_NARGS)
|
||||
return fieldIndex - indexof(LA);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ These fields are described in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=head3 Read Parameters
|
||||
|
||||
The read parameters for the Calc record consist of 12 input links INPA,
|
||||
INPB, ... INPL. The fields can be database links, channel access links, or
|
||||
The read parameters for the Calc record consist of 21 input links INPA -
|
||||
INPU. The fields can be database links, channel access links, or
|
||||
constants. If they are links, they must specify another record's field or a
|
||||
channel access link. If they are constants, they will be initialized with
|
||||
the value they are configured with and can be changed via C<dbPuts>. They
|
||||
@@ -45,7 +45,7 @@ See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on how to specify database links.
|
||||
|
||||
=fields INPA, INPB, INPC, INPD, INPE, INPF, INPG, INPH, INPI, INPJ, INPK, INPL
|
||||
=fields INPA - INPU
|
||||
|
||||
=head3 Expression
|
||||
|
||||
@@ -113,7 +113,7 @@ radians to degrees
|
||||
|
||||
The expression uses the values retrieved from the INPx links as operands,
|
||||
though constants can be used as operands too. These values retrieved from
|
||||
the input links are stored in the A-L fields. The values to be used in the
|
||||
the input links are stored in the A-U fields. The values to be used in the
|
||||
expression are simply referenced by the field letter. For instance, the
|
||||
value obtained from INPA link is stored in the field A, and the value
|
||||
obtained from INPB is stored in field B. The field names can be included in
|
||||
@@ -121,7 +121,7 @@ the expression which will operate on their respective values, as in A+B.
|
||||
Also, the RNDM nullary function can be included as an operand in the
|
||||
expression in order to generate a random number between 0 and 1.
|
||||
|
||||
=fields A, B, C, D, E, F, G, H, I, J, K, L
|
||||
=fields A - U
|
||||
|
||||
The keyword VAL returns the current contents of the VAL field (which can be
|
||||
written to by a CA put, so it might I<not> be the result from the last time
|
||||
@@ -492,12 +492,12 @@ modifiable at run-time. They are used to process the record.
|
||||
The LALM field is used to implement the hysteresis factor for the alarm
|
||||
limits.
|
||||
|
||||
The LA-LL fields are used to decide when to trigger monitors for the
|
||||
The LA-LU fields are used to decide when to trigger monitors for the
|
||||
corresponding fields. For instance, if LA does not equal the value A,
|
||||
monitors for A are triggered. The MLST and ALST fields are used in the same
|
||||
manner for the VAL field.
|
||||
|
||||
=fields LALM, ALST, MLST, LA, LB, LC, LD, LE, LF, LG, LH, LI, LJ, LK, LL
|
||||
=fields LALM, ALST, MLST, LA - LU
|
||||
|
||||
=cut
|
||||
|
||||
@@ -512,7 +512,7 @@ manner for the VAL field.
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_CALC)
|
||||
pp(TRUE)
|
||||
size(80)
|
||||
size(160)
|
||||
initial("0")
|
||||
}
|
||||
field(INPA,DBF_INLINK) {
|
||||
@@ -575,6 +575,60 @@ manner for the VAL field.
|
||||
promptgroup("42 - Input G-L")
|
||||
interest(1)
|
||||
}
|
||||
field(INPM,DBF_INLINK) {
|
||||
prompt("Input M")
|
||||
special(SPC_MOD)
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPN,DBF_INLINK) {
|
||||
prompt("Input N")
|
||||
special(SPC_MOD)
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPO,DBF_INLINK) {
|
||||
prompt("Input O")
|
||||
special(SPC_MOD)
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPP,DBF_INLINK) {
|
||||
prompt("Input P")
|
||||
special(SPC_MOD)
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPQ,DBF_INLINK) {
|
||||
prompt("Input Q")
|
||||
special(SPC_MOD)
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPR,DBF_INLINK) {
|
||||
prompt("Input R")
|
||||
special(SPC_MOD)
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPS,DBF_INLINK) {
|
||||
prompt("Input S")
|
||||
special(SPC_MOD)
|
||||
promptgroup("44 - Input S-U")
|
||||
interest(1)
|
||||
}
|
||||
field(INPT,DBF_INLINK) {
|
||||
prompt("Input T")
|
||||
special(SPC_MOD)
|
||||
promptgroup("44 - Input S-U")
|
||||
interest(1)
|
||||
}
|
||||
field(INPU,DBF_INLINK) {
|
||||
prompt("Input U")
|
||||
special(SPC_MOD)
|
||||
promptgroup("44 - Input S-U")
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup("80 - Display")
|
||||
@@ -733,6 +787,42 @@ manner for the VAL field.
|
||||
prompt("Value of Input L")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(M,DBF_DOUBLE) {
|
||||
prompt("Value of Input M")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(N,DBF_DOUBLE) {
|
||||
prompt("Value of Input N")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(O,DBF_DOUBLE) {
|
||||
prompt("Value of Input O")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(P,DBF_DOUBLE) {
|
||||
prompt("Value of Input P")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(Q,DBF_DOUBLE) {
|
||||
prompt("Value of Input Q")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(R,DBF_DOUBLE) {
|
||||
prompt("Value of Input R")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(S,DBF_DOUBLE) {
|
||||
prompt("Value of Input S")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(T,DBF_DOUBLE) {
|
||||
prompt("Value of Input T")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(U,DBF_DOUBLE) {
|
||||
prompt("Value of Input U")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(LA,DBF_DOUBLE) {
|
||||
prompt("Prev Value of A")
|
||||
special(SPC_NOMOD)
|
||||
@@ -793,6 +883,51 @@ manner for the VAL field.
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LM,DBF_DOUBLE) {
|
||||
prompt("Prev Value of M")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LN,DBF_DOUBLE) {
|
||||
prompt("Prev Value of N")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LO,DBF_DOUBLE) {
|
||||
prompt("Prev Value of O")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LP,DBF_DOUBLE) {
|
||||
prompt("Prev Value of P")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LQ,DBF_DOUBLE) {
|
||||
prompt("Prev Value of Q")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LR,DBF_DOUBLE) {
|
||||
prompt("Prev Value of R")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LS,DBF_DOUBLE) {
|
||||
prompt("Prev Value of S")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LT,DBF_DOUBLE) {
|
||||
prompt("Prev Value of T")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LU,DBF_DOUBLE) {
|
||||
prompt("Prev Value of U")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LALM,DBF_DOUBLE) {
|
||||
prompt("Last Value Alarmed")
|
||||
special(SPC_NOMOD)
|
||||
@@ -813,7 +948,7 @@ manner for the VAL field.
|
||||
prompt("Reverse Polish Calc")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("char rpcl[INFIX_TO_POSTFIX_SIZE(80)]")
|
||||
extra("char rpcl[INFIX_TO_POSTFIX_SIZE(160)]")
|
||||
}
|
||||
|
||||
=head2 Record Support
|
||||
@@ -911,7 +1046,7 @@ Archive and values change monitors are invoked if ADEL and MDEL conditions
|
||||
are met.
|
||||
|
||||
=item *
|
||||
Monitors for A-L are checked whenever other monitors are invoked.
|
||||
Monitors for A-U are checked whenever other monitors are invoked.
|
||||
|
||||
=item *
|
||||
NSEV and NSTA are reset to 0.
|
||||
|
||||
@@ -355,6 +355,15 @@ static long special(DBADDR *paddr, int after)
|
||||
case(calcoutRecordINPJ):
|
||||
case(calcoutRecordINPK):
|
||||
case(calcoutRecordINPL):
|
||||
case(calcoutRecordINPM):
|
||||
case(calcoutRecordINPN):
|
||||
case(calcoutRecordINPO):
|
||||
case(calcoutRecordINPP):
|
||||
case(calcoutRecordINPQ):
|
||||
case(calcoutRecordINPR):
|
||||
case(calcoutRecordINPS):
|
||||
case(calcoutRecordINPT):
|
||||
case(calcoutRecordINPU):
|
||||
case(calcoutRecordOUT):
|
||||
lnkIndex = fieldIndex - calcoutRecordINPA;
|
||||
plink = &prec->inpa + lnkIndex;
|
||||
@@ -406,9 +415,9 @@ static long special(DBADDR *paddr, int after)
|
||||
#define indexof(field) calcoutRecord##field
|
||||
|
||||
static long get_linkNumber(int fieldIndex) {
|
||||
if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L))
|
||||
if (fieldIndex >= indexof(A) && fieldIndex < indexof(A) + CALCPERFORM_NARGS)
|
||||
return fieldIndex - indexof(A);
|
||||
if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL))
|
||||
if (fieldIndex >= indexof(LA) && fieldIndex < indexof(LA) + CALCPERFORM_NARGS)
|
||||
return fieldIndex - indexof(LA);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user