Merge up changes from below

This commit is contained in:
Andrew Johnson
2018-01-20 19:17:35 -06:00
15 changed files with 303 additions and 83 deletions

2
README
View File

@@ -20,5 +20,5 @@ Additional information about EPICS including mailing list
archives and subscription instructions, documentation and
training materials, additional components, links to other
websites etc. is available on the EPICS home page at
http://www.aps.anl.gov/epics/
https://epics.anl.gov/

View File

@@ -40,11 +40,12 @@ configuration:
# Environment variables: compiler toolchain
environment:
matrix:
- TOOLCHAIN: 9.0
- TOOLCHAIN: 10.0
- TOOLCHAIN: 11.0
- TOOLCHAIN: 12.0
- TOOLCHAIN: 14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLCHAIN: 2017
- TOOLCHAIN: cygwin
- TOOLCHAIN: mingw
@@ -57,8 +58,6 @@ platform:
matrix:
exclude:
# VS Express installs don't have the 64 bit compiler
- platform: x64
TOOLCHAIN: 9.0
- platform: x64
TOOLCHAIN: 10.0

View File

@@ -1,6 +1,6 @@
:: Universal build script for AppVeyor (https://ci.appveyor.com/)
:: Environment:
:: TOOLCHAIN - toolchain version [9.0/10.0/11.0/12.0/14.0/cygwin/mingw]
:: TOOLCHAIN - toolchain version [10.0/11.0/12.0/14.0/2017/cygwin/mingw]
:: CONFIGURATION - determines EPICS build [dynamic/static]
:: PLATFORM - architecture [x86/x64]
::
@@ -57,10 +57,22 @@ if "%TOOLCHAIN%"=="mingw" (
)
set "VSINSTALL=C:\Program Files (x86)\Microsoft Visual Studio %TOOLCHAIN%"
if not exist "%VSINSTALL%\" set "VSINSTALL=C:\Program Files (x86)\Microsoft Visual Studio\%TOOLCHAIN%\Community"
if not exist "%VSINSTALL%\" goto MSMissing
set "MAKE=C:\tools\make"
echo [INFO] APPVEYOR_BUILD_WORKER_IMAGE=%APPVEYOR_BUILD_WORKER_IMAGE%
if "%OS%"=="64BIT" (
set EPICS_HOST_ARCH=windows-x64%ST%
:: VS 2017
if exist "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat" (
call "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat"
where cl
if !ERRORLEVEL! NEQ 0 goto MSMissing
goto MSFound
)
if exist "%VSINSTALL%\VC\vcvarsall.bat" (
call "%VSINSTALL%\VC\vcvarsall.bat" amd64
where cl
@@ -79,12 +91,19 @@ if "%OS%"=="64BIT" (
)
) else (
set EPICS_HOST_ARCH=win32-x86%ST%
:: VS 2017
if exist "%VSINSTALL%\VC\Auxiliary\Build\vcvars32.bat" (
call "%VSINSTALL%\VC\Auxiliary\Build\vcvars32.bat"
where cl
if !ERRORLEVEL! NEQ 0 goto MSMissing
goto MSFound
)
if exist "%VSINSTALL%\VC\vcvarsall.bat" (
call "%VSINSTALL%\VC\vcvarsall.bat" x86
where cl
if !ERRORLEVEL! NEQ 0 goto MSMissing
goto MSFound
)
)
if exist "%VSINSTALL%\VC\bin\vcvars32.bat" (
call "%VSINSTALL%\VC\bin\vcvars32.bat"
where cl

View File

@@ -65,6 +65,6 @@ if "%TOOLCHAIN%"=="mingw" (
)
echo [INFO] Installing Make 4.1
@powershell -Command "(new-object net.webclient).DownloadFile('https://www.aps.anl.gov/epics/download/tools/make-4.1-win64.zip', 'C:\tools\make-4.1.zip')"
curl -fsS --retry 3 -o C:\tools\make-4.1.zip https://epics.anl.gov/download/tools/make-4.1-win64.zip
cd \tools
"C:\Program Files\7-Zip\7z" e make-4.1.zip

View File

@@ -170,6 +170,10 @@ COMPILE.ctdt = $(CC) -c $(CPPFLAGS) $(CFLAGS_ctdt) $(INCLUDES) $(SOURCE_FLAG)
VXCPPFLAGS = $(filter-out $(OP_SYS_INCLUDE_CPPFLAGS),$(CPPFLAGS))
PREPROCESS.cpp = $(CPP) $(VXCPPFLAGS) $(INCLUDES) $< > $@
#--------------------------------------------------
# Use LEDLIB for command-line editing
COMMANDLINE_LIBRARY = LEDLIB
#--------------------------------------------------
# Allow site overrides
-include $(CONFIG)/os/CONFIG_SITE.Common.vxWorksCommon

View File

@@ -98,7 +98,7 @@
base/configure/os/CONFIG_SITE.Common.vxWorksCommon file or in one of its
target-specific overrides.</P>
<P>Consult the <a href="http://www.aps.anl.gov/epics/base/vxWorks6.php">vxWorks
<P>Consult the <a href="https://epics.anl.gov/base/vxWorks6.php">vxWorks
6.x</a> EPICS web pages and the vxWorks documentation for information
about configuring your vxWorks operating system for use with EPICS.</P>
@@ -128,7 +128,7 @@
<H3><A NAME="0_0_8"> Documentation</A></H3>
<BLOCKQUOTE>EPICS documentation is available through the
<a href="http://www.aps.anl.gov/epics/">EPICS website</a> at Argonne.
<a href="https://epics.anl.gov/">EPICS website</a> at Argonne.
<P>Release specific documentation can also be found in the base/documentation
directory of the distribution.</BLOCKQUOTE>

View File

@@ -53,6 +53,61 @@ than one should be ignored).</p>
<!-- Insert inherited items immediately below here ... -->
<h3>Restore use of ledlib for VxWorks command editing</h3>
<p>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
<a href="https://bugs.launchpad.net/bugs/1741578">bug #1741578</a>.</p>
<h3>Constant link types</h3>
<p>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.</p>
<h3>Upgraded the YAJL JSON Library</h3>
<p>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 <tt>size_t</tt> instead
<tt>unsigned int</tt> for string lengths, but it also uses <tt>long long</tt>
instead of <tt>long</tt> for JSON integer values, which was the main motivation
for the upgrade.</p>
<p>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
<tt>EPICS_YAJL_VERSION</tt> which is defined in the yajl_common.h header file
along with a brief description of the API changes.</p>
<h3>Timestamp support for the calc link type</h3>
<p>A new optional parameter can be given when specifying a calc JSON link. The
<tt>time</tt> parameter is a string containing a single letter <tt>A..L</tt>
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).</p>
<h3>Silence errors from puts to constant link types</h3>
<p>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.</p>
<h3>RSRV expanding large buffer causes crash</h3>
<p>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
<a href="https://bugs.launchpad.net/epics-base/+bug/1706703">bug
#1706703</a>.</p>
<h2 align="center">Changes made between 3.16.0.1 and 3.16.1</h2>

View File

@@ -652,7 +652,7 @@ not follow this pattern, but are still printable strings.
=item [1] R3.15 Channel Access Reference Manual by Jeffrey O. Hill
L<http://www.aps.anl.gov/epics/base/R3-15/2-docs/CAref.html>
L<https://epics.anl.gov/base/R3-15/5-docs/CAref.html>
=back

View File

@@ -34,6 +34,8 @@
*
* Two time intervals are measured. The time to queue and run each of
* the immediate callbacks, and the actual delay of the delayed callback.
*
* Slow callbacks no longer fail the test, they just emit a diagnostic.
*/
#define NCALLBACKS 169
@@ -108,7 +110,7 @@ MAIN(callbackParallelTest)
for (j = 0; j < 5; j++)
setupError[i][j] = timeError[i][j] = defaultError[j];
testPlan(4);
testPlan(2);
testDiag("Starting %d parallel callback threads", noCpus);
@@ -165,7 +167,8 @@ MAIN(callbackParallelTest)
}
}
testOk(faults == 0, "%d faults during callback setup", faults);
testOk(slowups <= 1, "%d slowups during callback setup", slowups);
if (slowups)
testDiag("%d slowups during callback setup", slowups);
slowups = 0;
for (i = 0; i < NCALLBACKS ; i++) {
@@ -182,7 +185,8 @@ MAIN(callbackParallelTest)
}
updateStats(timeError[i%NUM_CALLBACK_PRIORITIES], error);
}
testOk(slowups < 5, "%d slowups during callbacks", slowups);
if (slowups)
testDiag("%d slowups during callback setup", slowups);
testDiag("Setup time statistics");
printStats(setupError[0], "LOW");

View File

@@ -34,6 +34,8 @@
*
* Two time intervals are measured. The time to queue and run each of
* the immediate callbacks, and the actual delay of the delayed callback.
*
* Slow callbacks no longer fail the test, they just emit a diagnostic.
*/
#define NCALLBACKS 169
@@ -108,7 +110,7 @@ MAIN(callbackTest)
for (j = 0; j < 5; j++)
setupError[i][j] = timeError[i][j] = defaultError[j];
testPlan(4);
testPlan(2);
callbackInit();
epicsThreadSleep(1.0);
@@ -162,7 +164,8 @@ MAIN(callbackTest)
}
}
testOk(faults == 0, "%d faults during callback setup", faults);
testOk(slowups <= 1, "%d slowups during callback setup", slowups);
if (slowups)
testDiag("%d slowups during callback setup", slowups);
slowups = 0;
for (i = 0; i < NCALLBACKS ; i++) {
@@ -179,7 +182,8 @@ MAIN(callbackTest)
}
updateStats(timeError[i%NUM_CALLBACK_PRIORITIES], error);
}
testOk(slowups < 5, "%d slowups during callbacks", slowups);
if (slowups)
testDiag("%d slowups during callback setup", slowups);
testDiag("Setup time statistics");
printStats(setupError[0], "LOW");

View File

@@ -1,11 +1,11 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne
* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* Author: Eric Norum Date: 12DEC2001 */
/* Author: Eric Norum */
#include <stdio.h>
#include <stdlib.h>
@@ -15,8 +15,15 @@
#include "envDefs.h"
#include "epicsReadline.h"
/* Basic command-line input, no editing or history: */
#define EPICS_COMMANDLINE_LIBRARY_EPICS 0
/* OS-specific command-line editing and/or history: */
#define EPICS_COMMANDLINE_LIBRARY_LIBTECLA 1
#define EPICS_COMMANDLINE_LIBRARY_LEDLIB 1
#define EPICS_COMMANDLINE_LIBRARY_OTHER 1
/* GNU readline, or Apple's libedit wrapper: */
#define EPICS_COMMANDLINE_LIBRARY_READLINE 2
#define EPICS_COMMANDLINE_LIBRARY_READLINE_CURSES 2
#define EPICS_COMMANDLINE_LIBRARY_READLINE_NCURSES 2
@@ -38,18 +45,17 @@ static void osdReadlineEnd(struct readlineContext *);
#if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_EPICS
static void osdReadlineBegin(struct readlineContext * c) {}
static char * osdReadline(const char *prompt, struct readlineContext * c) { return NULL; }
static void osdReadlineEnd(struct readlineContext * c) {}
static void osdReadlineBegin(struct readlineContext *rc) {}
static char * osdReadline(const char *prompt, struct readlineContext *rc)
{
return NULL;
}
static void osdReadlineEnd(struct readlineContext *rc) {}
#elif EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE
# include "gnuReadline.c"
#else
# if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE
# include "gnuReadline.c"
# else
# include "osdReadline.c"
# endif
# include "osdReadline.c"
#endif
/*
@@ -58,15 +64,15 @@ static void osdReadlineEnd(struct readlineContext * c) {}
void * epicsShareAPI
epicsReadlineBegin(FILE *in)
{
struct readlineContext *readlineContext = calloc(1, sizeof(*readlineContext));
struct readlineContext *rc = calloc(1, sizeof(*rc));
if (readlineContext) {
readlineContext->in = in;
readlineContext->line = NULL;
if (rc) {
rc->in = in;
rc->line = NULL;
if (!envGetConfigParamPtr(&IOCSH_HISTEDIT_DISABLE))
osdReadlineBegin(readlineContext);
osdReadlineBegin(rc);
}
return readlineContext;
return rc;
}
/*
@@ -75,19 +81,19 @@ epicsReadlineBegin(FILE *in)
char * epicsShareAPI
epicsReadline (const char *prompt, void *context)
{
struct readlineContext *readlineContext = context;
struct readlineContext *rc = context;
FILE *in;
char *line;
int c; /* char is unsigned on some archs, EOF is -ve */
int linelen = 0;
int linesize = 50;
if (readlineContext->osd)
return osdReadline(prompt, readlineContext);
if (rc->osd)
return osdReadline(prompt, rc);
free(readlineContext->line);
readlineContext->line = NULL;
if ((in = readlineContext->in) == NULL) {
free(rc->line);
rc->line = NULL;
if ((in = rc->in) == NULL) {
in = stdin;
if (prompt) {
fputs(prompt, stdout);
@@ -125,7 +131,7 @@ epicsReadline (const char *prompt, void *context)
line[linelen++] = c;
}
line[linelen] = '\0';
readlineContext->line = line;
rc->line = line;
return line;
}
@@ -136,13 +142,13 @@ void epicsShareAPI
epicsReadlineEnd (void *context)
{
if (context) {
struct readlineContext *readlineContext = context;
struct readlineContext *rc = context;
if (readlineContext->osd)
osdReadlineEnd(readlineContext);
else
free(readlineContext->line);
free(readlineContext);
if (rc->osd)
osdReadlineEnd(rc);
else
free(rc->line);
free(rc);
}
}

View File

@@ -33,7 +33,7 @@ struct osdContext {
static void
osdReadlineBegin(struct readlineContext *context)
{
struct osdContext osd = malloc(sizeof *osd);
struct osdContext *osd = malloc(sizeof *osd);
if (osd != NULL) {
osd->ledId = (LED_ID) ERROR;

View File

@@ -11,6 +11,7 @@
#include "dbStaticLib.h"
#include "dbTest.h"
#include "dbUnitTest.h"
#include "epicsThread.h"
#include "errlog.h"
#include "registryFunction.h"
#include "subRecord.h"
@@ -39,10 +40,10 @@ void doProcess(const char *rec)
testdbPutFieldOk(proc, DBR_CHAR, 1);
}
/* Group 0 are all soft-channel input records with INP being a DB link
/* Group 0 are soft-channel input records with INP being a DB or CA link
* to the PV 'source'. Their VAL fields all start out with the default
* value for the type, i.e. 0 or an empty string. Triggering record
* processing should read the integer value from the 'source' PV.
* processing reads the value from the 'source' PV.
*/
static
@@ -50,14 +51,22 @@ void testGroup0(void)
{
const char ** rec;
const char * records[] = {
"ai0", "bi0", "di0", "ii0", "li0", "lsi0", "mi0", "si0", NULL
"ai0", "bi0", "di0", "ii0", "li0", "lsi0", "mi0", "si0",
"ai0c", "bi0c", "di0c", "ii0c", "li0c", "lsi0c", "mi0c", "si0c",
NULL
};
testDiag("============ Starting %s ============", EPICS_FUNCTION);
testdbPutFieldOk("source", DBR_LONG, 1);
/* The above put sends CA monitors to all of the CA links, but
* doesn't trigger record processing (the links are not CP/CPP).
* How could we wait until all of those monitors have arrived,
* instead of just waiting for an arbitrary time period?
*/
epicsThreadSleep(1.0); /* FIXME: Wait here? */
for (rec = records; *rec; rec++) {
if (strcmp(*rec, "lsi0") != 0)
if (strncmp(*rec, "lsi0", 4) != 0)
testdbGetFieldEqual(*rec, DBR_LONG, 0);
checkDtyp(*rec);
doProcess(*rec);
@@ -65,6 +74,7 @@ void testGroup0(void)
}
testdbPutFieldOk("source", DBR_LONG, 0);
epicsThreadSleep(1.0); /* FIXME: Wait here as above */
for (rec = records; *rec; rec++) {
doProcess(*rec);
testdbGetFieldEqual(*rec, DBR_LONG, 0);
@@ -129,6 +139,7 @@ static
long destSubr(subRecord *prec)
{
dest = prec->val;
prec->val = -1;
return 0;
}
@@ -138,20 +149,25 @@ void checkOutput(const char *rec, int value)
testDiag("Checking record '%s'", rec);
testdbPutFieldOk(rec, DBR_LONG, value);
/* Even with a local CA link, the dest record gets processed in
* the context of this thread (i.e. immediately). TPRO confirms.
*/
testOk(dest == value, "value %d output -> %d", value, dest);
}
/* Group 3 are all soft-channel output records with OUT being a DB link
* to the PV 'dest' with PP. Putting a value to the record writes that
* value to 'dest' and processes it.
/* Group 3 are all soft-channel output records with OUT being a DB or
* local CA link to the subRecord 'dest'; DB links have the PP flag,
* for CA links the VAL field is marked PP. Putting a value to the
* output record writes that value to 'dest'.
*/
static
void testGroup3(void)
{
const char ** rec;
const char * records[] = {
"ao0", "bo0", "io0", "lo0", "lso0", "mo0", "so0", NULL,
"ao3", "bo3", "io3", "lo3", "lso3", "mo3", "so3",
"ao3c", "bo3c", "io3c", "lo3c", "lso3c", "mo3c", "so3c",
NULL,
};
testDiag("============ Starting %s ============", EPICS_FUNCTION);
@@ -160,13 +176,16 @@ void testGroup3(void)
checkOutput(*rec, 1);
checkDtyp(*rec);
}
checkOutput("do0.B0", 1);
checkDtyp("do0");
checkOutput("do3.B0", 1);
checkDtyp("do3");
checkOutput("do3c.B0", 1);
checkDtyp("do3c");
for (rec = records; *rec; rec++) {
checkOutput(*rec, 0);
}
checkOutput("do0.B0", 0);
checkOutput("do3.B0", 0);
checkOutput("do3c.B0", 0);
}
/* Group 4 are all soft-channel output records with OUT being empty
@@ -177,7 +196,7 @@ void testGroup4(void)
{
const char ** rec;
const char * records[] = {
"ao1", "bo1", "do1.B0", "io1", "lo1", "lso1", "mo1", "so1", NULL,
"ao4", "bo4", "do4.B0", "io4", "lo4", "lso4", "mo4", "so4", NULL,
};
testDiag("============ Starting %s ============", EPICS_FUNCTION);
@@ -189,9 +208,10 @@ void testGroup4(void)
void recTestIoc_registerRecordDeviceDriver(struct dbBase *);
MAIN(softTest)
{
testPlan(163);
testPlan(266);
testdbPrepare();
testdbReadDatabase("recTestIoc.dbd", NULL, NULL);

View File

@@ -59,6 +59,60 @@ record(stringin, "si0") {
field(INP, "source")
}
record(ai, "ai0c") {
field(DTYP, "Soft Channel")
field(INP, "source CA")
}
record(bi, "bi0c") {
field(DTYP, "Soft Channel")
field(INP, "source CA")
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(int64in, "ii0c") {
field(DTYP, "Soft Channel")
field(INP, "source CA")
}
record(longin, "li0c") {
field(DTYP, "Soft Channel")
field(INP, "source CA")
}
record(mbbiDirect, "di0c") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(INP, "source CA")
}
record(mbbi, "mi0c") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(INP, "source CA")
field(ZRST, "Zero")
field(ONST, "One")
field(TWST, "Two")
field(THST, "Three")
field(FRST, "Four")
field(FVST, "Five")
field(SXST, "Six")
field(SVST, "Seven")
field(EIST, "Eight")
field(NIST, "Nine")
field(TEST, "Ten")
field(ELST, "Eleven")
field(TWST, "Twelve")
field(TTST, "Thirteen")
field(FTST, "Fourteen")
field(FFST, "Fifteen")
}
record(lsi, "lsi0c") {
field(DTYP, "Soft Channel")
field(SIZV, 40)
field(INP, "source CA")
}
record(stringin, "si0c") {
field(DTYP, "Soft Channel")
field(INP, "source CA")
}
# Group 1 are all soft-channel input records with INP being a non-zero
# "const" JSON-link, 9 for most records, 1 for the binary. Their VAL
@@ -171,38 +225,39 @@ record(mbbi, "mi2") {
}
# Group 3 are all soft-channel output records with OUT being a DB link
# to the PV 'dest' with PP. Putting a value to the record writes that
# value to 'dest' and processes it.
# Group 3 are all soft-channel output records with OUT being a DB or
# CA link to the PV 'dest' with PP. Putting a value to the record
# under test writes the value to 'dest' and processes it.
record(sub, "dest") {
field(SNAM, "destSubr")
field(VAL, -1)
}
record(ao, "ao0") {
record(ao, "ao3") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
}
record(bo, "bo0") {
record(bo, "bo3") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(int64out, "io0") {
record(int64out, "io3") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
}
record(longout, "lo0") {
record(longout, "lo3") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
}
record(mbboDirect, "do0") {
record(mbboDirect, "do3") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(OUT, "dest PP")
}
record(mbbo, "mo0") {
record(mbbo, "mo3") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(OUT, "dest PP")
@@ -223,39 +278,93 @@ record(mbbo, "mo0") {
field(FTST, "Fourteen")
field(FFST, "Fifteen")
}
record(lso, "lso0") {
record(lso, "lso3") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
field(SIZV, 40)
}
record(stringout, "so0") {
record(stringout, "so3") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
}
record(ao, "ao3c") {
field(DTYP, "Soft Channel")
field(OUT, "dest CA")
}
record(bo, "bo3c") {
field(DTYP, "Soft Channel")
field(OUT, "dest CA")
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(int64out, "io3c") {
field(DTYP, "Soft Channel")
field(OUT, "dest CA")
}
record(longout, "lo3c") {
field(DTYP, "Soft Channel")
field(OUT, "dest CA")
}
record(mbboDirect, "do3c") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(OUT, "dest CA")
}
record(mbbo, "mo3c") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(OUT, "dest CA")
field(ZRST, "Zero")
field(ONST, "One")
field(TWST, "Two")
field(THST, "Three")
field(FRST, "Four")
field(FVST, "Five")
field(SXST, "Six")
field(SVST, "Seven")
field(EIST, "Eight")
field(NIST, "Nine")
field(TEST, "Ten")
field(ELST, "Eleven")
field(TWST, "Twelve")
field(TTST, "Thirteen")
field(FTST, "Fourteen")
field(FFST, "Fifteen")
}
record(lso, "lso3c") {
field(DTYP, "Soft Channel")
field(OUT, "dest CA")
field(SIZV, 40)
}
record(stringout, "so3c") {
field(DTYP, "Soft Channel")
field(OUT, "dest CA")
}
# Group 4 are all soft-channel output records with OUT being empty
# (i.e. a CONSTANT link). Putting a value to the record must succeed.
record(ao, "ao1") {
record(ao, "ao4") {
field(DTYP, "Soft Channel")
}
record(bo, "bo1") {
record(bo, "bo4") {
field(DTYP, "Soft Channel")
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(int64out, "io1") {
record(int64out, "io4") {
field(DTYP, "Soft Channel")
}
record(longout, "lo1") {
record(longout, "lo4") {
field(DTYP, "Soft Channel")
}
record(mbboDirect, "do1") {
record(mbboDirect, "do4") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
}
record(mbbo, "mo1") {
record(mbbo, "mo4") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(ZRST, "Zero")
@@ -275,10 +384,10 @@ record(mbbo, "mo1") {
field(FTST, "Fourteen")
field(FFST, "Fifteen")
}
record(lso, "lso1") {
record(lso, "lso4") {
field(DTYP, "Soft Channel")
field(SIZV, 40)
}
record(stringout, "so1") {
record(stringout, "so4") {
field(DTYP, "Soft Channel")
}

View File

@@ -18,8 +18,8 @@ use POSIX qw(strftime);
use strict;
# RFC 8601 date+time w/ zone (eg "2014-08-29T09:42:47-0700")
my $tfmt = '%Y-%m-%dT%H:%M:%S';
# RFC 8601 date+time w/ zone (eg "2014-08-29T09:42-0700")
my $tfmt = '%Y-%m-%dT%H:%M';
$tfmt .= '%z' unless $^O eq 'MSWin32'; # %z returns zone name on Windows
my $now = strftime($tfmt, localtime);