Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
493dc19d8b | |||
3b64242ffd | |||
280cb7765a | |||
835e68bd76 | |||
92903361d0 | |||
fb937316aa | |||
ae6ebc4106 | |||
0f0dd31a0d | |||
189e61bbe8 | |||
d8f88c340a | |||
2ef5c47f19 | |||
cb4d490fb6 | |||
da281ebf97 | |||
c832efbcb6 | |||
b7b3bc0af0 | |||
4a42c3d43a | |||
624cc0134a | |||
d9d5d5f55d | |||
53ea75dc80 | |||
b1f4c2a7d9 | |||
d87e9cedd2 | |||
32d93d9028 | |||
3d30827798 | |||
b688f14c22 | |||
9e972d3f33 | |||
f5da2ea6b3 | |||
4edd2f2eff | |||
846b884eb5 | |||
3f1918ed2d | |||
1d753366d8 | |||
047f18d113 | |||
26c5b012a7 | |||
4f33600a0f | |||
2077dfb0a6 |
@ -32,9 +32,8 @@ HEADERS += StreamError.h
|
|||||||
StreamCore.o StreamCore.d: streamReferences
|
StreamCore.o StreamCore.d: streamReferences
|
||||||
|
|
||||||
# Update version string (contains __DATE__ and __TIME__)
|
# Update version string (contains __DATE__ and __TIME__)
|
||||||
# each time make runs.
|
# each time anything changes.
|
||||||
StreamVersion.o: FORCE
|
StreamVersion.o: $(filter-out StreamVersion.o stream_exportAddress.o,$(LIBOBJS))
|
||||||
FORCE:
|
|
||||||
|
|
||||||
streamReferences:
|
streamReferences:
|
||||||
$(PERL) ../src/makeref.pl Interface $(BUSSES) > $@
|
$(PERL) ../src/makeref.pl Interface $(BUSSES) > $@
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# StreamDevice
|
# StreamDevice
|
||||||
|
|
||||||
_StreamDevice_ is a generic [EPICS](https://www.aps.anl.gov/epics)
|
_StreamDevice_ is a generic [EPICS](https://epics.anl.gov/)
|
||||||
device support for devices with a "byte stream" based
|
device support for devices with a "byte stream" based
|
||||||
communication interface.
|
communication interface.
|
||||||
That means devices that can be controlled by sending and receiving
|
That means devices that can be controlled by sending and receiving
|
||||||
|
@ -14,14 +14,21 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
|||||||
# define INSTALL_LOCATION_APP here
|
# define INSTALL_LOCATION_APP here
|
||||||
#INSTALL_LOCATION_APP=<fullpathname>
|
#INSTALL_LOCATION_APP=<fullpathname>
|
||||||
|
|
||||||
|
# For SynApps:
|
||||||
|
RELEASE=
|
||||||
|
|
||||||
EPICS_BASE=/usr/local/epics/base-3.16.1
|
EPICS_BASE=/usr/local/epics/base-7.0.1
|
||||||
ASYN=~/top-3.16/asyn4-30
|
ASYN=~/top-7/asyn4-33
|
||||||
CALC=~/top-3.16/SynApps/calc-2-8
|
CALC=~/top-7/SynApps/calc-2-8
|
||||||
PCRE=~/top-3.16/pcre-7-2
|
PCRE=~/top-7/pcre-7-2
|
||||||
PCRE_INCLUDE_SL6-x86=/usr/include
|
|
||||||
PCRE_INCLUDE_SL6-x86_64=/usr/include
|
#EPICS_BASE=/usr/local/epics/base-3.16.1
|
||||||
PCRE_INCLUDE_SL6-x86_64-clang=/usr/include
|
#ASYN=~/top-3.16/asyn4-30
|
||||||
|
#CALC=~/top-3.16/SynApps/calc-2-8
|
||||||
|
#PCRE=~/top-3.16/pcre-7-2
|
||||||
|
#PCRE_INCLUDE_SL6-x86=/usr/include
|
||||||
|
#PCRE_INCLUDE_SL6-x86_64=/usr/include
|
||||||
|
#PCRE_INCLUDE_SL6-x86_64-clang=/usr/include
|
||||||
|
|
||||||
#EPICS_BASE=/usr/local/epics/base-3.15.5
|
#EPICS_BASE=/usr/local/epics/base-3.15.5
|
||||||
#ASYN=~/top-3.15/asyn4-30
|
#ASYN=~/top-3.15/asyn4-30
|
||||||
|
@ -53,7 +53,7 @@ RegisterConverter(MyConverter,"Q");
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<a name="theory"></a>
|
<a name="theory"></a>
|
||||||
<h2>Theroy of Operation</h2>
|
<h2>Theory of Operation</h2>
|
||||||
|
|
||||||
<a name="registration"></a>
|
<a name="registration"></a>
|
||||||
<h3>Registration </h3>
|
<h3>Registration </h3>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<h2>What is <em>StreamDevice</em>?</h2>
|
<h2>What is <em>StreamDevice</em>?</h2>
|
||||||
<p>
|
<p>
|
||||||
<em>StreamDevice</em> is a generic
|
<em>StreamDevice</em> is a generic
|
||||||
<a href="https://www.aps.anl.gov/epics" target="ex">EPICS</a>
|
<a href="https://epics.anl.gov/" target="ex">EPICS</a>
|
||||||
device support for devices with a "byte stream" based
|
device support for devices with a "byte stream" based
|
||||||
communication interface.
|
communication interface.
|
||||||
That means devices that can be controlled by sending and
|
That means devices that can be controlled by sending and
|
||||||
@ -96,11 +96,11 @@ come in a predictible order to be parsable by <em>StreamDevice</em>.
|
|||||||
<h2>Recommended Readings</h2>
|
<h2>Recommended Readings</h2>
|
||||||
<p>
|
<p>
|
||||||
IOC Application Developer's Guide:
|
IOC Application Developer's Guide:
|
||||||
<a href="https://www.aps.anl.gov/epics/base/R3-14/12-docs/AppDevGuide"
|
<a href="https://epics.anl.gov/base/R3-14/12-docs/AppDevGuide/"
|
||||||
target="ex">R3.14.12</a>,
|
target="ex">R3.14.12</a>,
|
||||||
<a href="https://www.aps.anl.gov/epics/base/R3-16/1-docs/AppDevGuide"
|
<a href="https://epics.anl.gov/base/R3-15/6-docs/AppDevGuide/AppDevGuide.html"
|
||||||
target="ex">R3.15.5</a>,
|
target="ex">R3.15.5</a>,
|
||||||
<a href="https://www.aps.anl.gov/epics/base/R3-15/5-docs/AppDevGuide"
|
<a href="https://epics.anl.gov/base/R3-16/1-docs/AppDevGuide/AppDevGuide.html"
|
||||||
target="ex">R3.16.1</a>
|
target="ex">R3.16.1</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
@ -23,7 +23,7 @@ written or read value.
|
|||||||
<dd>
|
<dd>
|
||||||
Not allowed.
|
Not allowed.
|
||||||
</dd>
|
</dd>
|
||||||
<dt>LONG format (e.g. <code>%i</code>):</dt>
|
<dt>LONG <span class=new>or ENUM</span> format (e.g. <code>%i</code>):</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>If any of <code>ZRVL</code> ... <code>FFVL</code> is set
|
<dt>If any of <code>ZRVL</code> ... <code>FFVL</code> is set
|
||||||
@ -41,17 +41,12 @@ written or read value.
|
|||||||
</dd>
|
</dd>
|
||||||
<dt>If none of <code>ZRVL</code> ... <code>FFVL</code> is set
|
<dt>If none of <code>ZRVL</code> ... <code>FFVL</code> is set
|
||||||
(all are <code>0</code>):</dt>
|
(all are <code>0</code>):</dt>
|
||||||
<dd>
|
<dd class=new>
|
||||||
<u>Output:</u> <code><i>x</i>=VAL</code><br>
|
<u>Output:</u> <code><i>x</i>=(VAL<<SHFT)&MASK</code><br>
|
||||||
<u>Input:</u> <code>VAL=<i>x</i></code><br>
|
<u>Input:</u> <code>VAL=(RBV=(<i>x</i>&MASK))>>SHFT</code><br>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</dd>
|
</dd>
|
||||||
<dt>ENUM format (e.g. <code>%{</code>):</dt>
|
|
||||||
<dd>
|
|
||||||
<u>Output:</u> <code><i>x</i>=VAL</code><br>
|
|
||||||
<u>Input:</u> <code>VAL=<i>x</i></code><br>
|
|
||||||
</dd>
|
|
||||||
<dt>STRING format (e.g. <code>%s</code>):</dt>
|
<dt>STRING format (e.g. <code>%s</code>):</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<u>Output:</u> Depending on <code>VAL</code>, one of <code>ZRST</code>
|
<u>Output:</u> Depending on <code>VAL</code>, one of <code>ZRST</code>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<h2>1. Normal Processing</h2>
|
<h2>1. Normal Processing</h2>
|
||||||
<p>
|
<p>
|
||||||
<em>StreamDevice</em> is an asynchronous device support
|
<em>StreamDevice</em> is an asynchronous device support
|
||||||
(see <a href="http://www.aps.anl.gov/epics/base/R3-14/8-docs/AppDevGuide.pdf"
|
(see <a href="http://www.aps.anl.gov/epics/base/R3-14/12-docs/AppDevGuide.pdf"
|
||||||
target="ex">IOC Application Developer's Guide</a> chapter 12:
|
target="ex">IOC Application Developer's Guide</a> chapter 12:
|
||||||
Device Support).
|
Device Support).
|
||||||
Whenever the record is processed, the <a href="protocol.html">protocol</a>
|
Whenever the record is processed, the <a href="protocol.html">protocol</a>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<p>
|
<p>
|
||||||
<b>Note:</b> The scalcout record is part of the <i>calc</i> module of
|
<b>Note:</b> The scalcout record is part of the <i>calc</i> module of
|
||||||
the <a target="ex"
|
the <a target="ex"
|
||||||
href="http://www.aps.anl.gov/aod/bcda/synApps/index.php"
|
href="https://www.aps.anl.gov/BCDA/synApps"
|
||||||
><em>synApps</em></a> package.
|
><em>synApps</em></a> package.
|
||||||
Device support for scalcout records is only available for <i>calc</i>
|
Device support for scalcout records is only available for <i>calc</i>
|
||||||
module release 2-4 or higher.
|
module release 2-4 or higher.
|
||||||
|
@ -388,7 +388,7 @@ The <code>INP</code> or <code>OUT</code> link has the form
|
|||||||
<code>"@<var>filename protocol</var>[(<var>arg1</var>,<var>arg2</var>,...)] </var>bus</var> [<var>address</var> [<var>parameters</var>]]"</code>.
|
<code>"@<var>filename protocol</var>[(<var>arg1</var>,<var>arg2</var>,...)] </var>bus</var> [<var>address</var> [<var>parameters</var>]]"</code>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
(Elements in <code>[]</code> are optional. To not type the <code>[]</code>).
|
(Elements in <code>[]</code> are optional. Do not type the <code>[]</code>).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Here, <code><var>filename</var></code> is the name of the protocol file and
|
Here, <code><var>filename</var></code> is the name of the protocol file and
|
||||||
|
@ -74,7 +74,7 @@ CPPFLAGS += -DUSE_TYPED_RSET
|
|||||||
-include $(TOP)/configure/RULES
|
-include $(TOP)/configure/RULES
|
||||||
|
|
||||||
# Update version string whenever something changes
|
# Update version string whenever something changes
|
||||||
StreamVersion$(OBJ): ../*.c ../*.h ../*.cc ../CONFIG_STREAM
|
StreamVersion$(OBJ): $(filter-out StreamVersion.o,$(LIBOBJS)$(LIBRARY_OBJS))
|
||||||
|
|
||||||
# Add references to all registrars to main file to avoid
|
# Add references to all registrars to main file to avoid
|
||||||
# missing initialization.
|
# missing initialization.
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
{init(NULL, size);}
|
{init(NULL, size);}
|
||||||
|
|
||||||
~StreamBuffer()
|
~StreamBuffer()
|
||||||
{if (buffer != local) delete buffer;}
|
{if (buffer != local) delete [] buffer;}
|
||||||
|
|
||||||
// operator (): get char* pointing to index
|
// operator (): get char* pointing to index
|
||||||
const char* operator()(ssize_t index=0) const
|
const char* operator()(ssize_t index=0) const
|
||||||
|
@ -1315,12 +1315,12 @@ normal_format:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case StreamProtocolParser::skip:
|
case StreamProtocolParser::skip:
|
||||||
// ignore next input byte
|
// ignore next input byte (if exists)
|
||||||
consumedInput++;
|
if (consumedInput < inputLine.length()) consumedInput++;
|
||||||
break;
|
break;
|
||||||
case StreamProtocolParser::whitespace:
|
case StreamProtocolParser::whitespace:
|
||||||
// any number of whitespace (including 0)
|
// any number of whitespace (including 0)
|
||||||
while (isspace(inputLine[consumedInput])) consumedInput++;
|
while (consumedInput < inputLine.length() && isspace(inputLine[consumedInput])) consumedInput++;
|
||||||
break;
|
break;
|
||||||
case esc:
|
case esc:
|
||||||
// escaped literal byte
|
// escaped literal byte
|
||||||
|
@ -534,11 +534,11 @@ long streamInitRecord(dbCommon* record, const struct link *ioLink,
|
|||||||
streamIoFunction readData, streamIoFunction writeData)
|
streamIoFunction readData, streamIoFunction writeData)
|
||||||
{
|
{
|
||||||
long status;
|
long status;
|
||||||
char filename[80];
|
char filename[256];
|
||||||
char protocol[80];
|
char protocol[256];
|
||||||
char busname[80];
|
char busname[256];
|
||||||
int addr = -1;
|
int addr = -1;
|
||||||
char busparam[80];
|
char busparam[256];
|
||||||
memset(busparam, 0 ,sizeof(busparam));
|
memset(busparam, 0 ,sizeof(busparam));
|
||||||
|
|
||||||
debug("streamInitRecord(%s): SEVR=%d\n", record->name, record->sevr);
|
debug("streamInitRecord(%s): SEVR=%d\n", record->name, record->sevr);
|
||||||
@ -720,7 +720,7 @@ parseLink(const struct link *ioLink, char* filename,
|
|||||||
if (0 >= sscanf(ioLink->value.instio.string+n1, " %[^ \t(] %n", protocol, &n2))
|
if (0 >= sscanf(ioLink->value.instio.string+n1, " %[^ \t(] %n", protocol, &n2))
|
||||||
{
|
{
|
||||||
error("%s: Missing protocol name\n"
|
error("%s: Missing protocol name\n"
|
||||||
" expect \"@file protocol[(args)] bus [addr] [params]\"\n"
|
" expect \"@file protocol[(arg1,...)] bus [addr] [params]\"\n"
|
||||||
" in \"@%s\"\n", name(),
|
" in \"@%s\"\n", name(),
|
||||||
ioLink->value.instio.string);
|
ioLink->value.instio.string);
|
||||||
return S_dev_badInitRet;
|
return S_dev_badInitRet;
|
||||||
@ -728,15 +728,14 @@ parseLink(const struct link *ioLink, char* filename,
|
|||||||
n1+=n2;
|
n1+=n2;
|
||||||
if (ioLink->value.instio.string[n1] == '(')
|
if (ioLink->value.instio.string[n1] == '(')
|
||||||
{
|
{
|
||||||
strcat(protocol, "(");
|
n2 = 0;
|
||||||
n1++;
|
|
||||||
sscanf(ioLink->value.instio.string+n1, " %[^)] %n", protocol+strlen(protocol), &n2);
|
sscanf(ioLink->value.instio.string+n1, " %[^)] %n", protocol+strlen(protocol), &n2);
|
||||||
n1+=n2;
|
n1+=n2;
|
||||||
if (ioLink->value.instio.string[n1++] != ')')
|
if (ioLink->value.instio.string[n1++] != ')')
|
||||||
{
|
{
|
||||||
error("%s: Missing ')' after protocol '%s': '%s'\n"
|
error("%s: Missing ')' after protocol arguments '%s'\n"
|
||||||
" expect \"@file protocol(args) bus [addr] [params]\"\n"
|
" expect \"@file protocol(arg1,...) bus [addr] [params]\"\n"
|
||||||
" in \"@%s\"\n", name(), protocol, ioLink->value.instio.string+n1-1,
|
" in \"@%s\"\n", name(), protocol,
|
||||||
ioLink->value.instio.string);
|
ioLink->value.instio.string);
|
||||||
return S_dev_badInitRet;
|
return S_dev_badInitRet;
|
||||||
}
|
}
|
||||||
@ -745,7 +744,7 @@ parseLink(const struct link *ioLink, char* filename,
|
|||||||
if (0 >= sscanf(ioLink->value.instio.string+n1, "%s %i %99c", busname, addr, busparam))
|
if (0 >= sscanf(ioLink->value.instio.string+n1, "%s %i %99c", busname, addr, busparam))
|
||||||
{
|
{
|
||||||
error("%s: Missing bus name\n"
|
error("%s: Missing bus name\n"
|
||||||
" expect \"@file protocol[(args)] bus [addr] [params]\"\n"
|
" expect \"@file protocol[(arg1,...)] bus [addr] [params]\"\n"
|
||||||
" in \"@%s\"\n", name(),
|
" in \"@%s\"\n", name(),
|
||||||
ioLink->value.instio.string);
|
ioLink->value.instio.string);
|
||||||
return S_dev_badInitRet;
|
return S_dev_badInitRet;
|
||||||
@ -832,7 +831,7 @@ initRecord(const char* filename, const char* protocol,
|
|||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
debug("Stream::initRecord %s: initialized. %s\n",
|
debug("Stream::initRecord %s: initialized. %s\n",
|
||||||
name(), convert==2 ?
|
name(), convert == DO_NOT_CONVERT ?
|
||||||
"convert" : "don't convert");
|
"convert" : "don't convert");
|
||||||
return convert;
|
return convert;
|
||||||
}
|
}
|
||||||
@ -844,6 +843,7 @@ process()
|
|||||||
debug("Stream::process(%s)\n", name());
|
debug("Stream::process(%s)\n", name());
|
||||||
if (record->pact || record->scan == SCAN_IO_EVENT)
|
if (record->pact || record->scan == SCAN_IO_EVENT)
|
||||||
{
|
{
|
||||||
|
record->proc = 0;
|
||||||
if (status != NO_ALARM)
|
if (status != NO_ALARM)
|
||||||
{
|
{
|
||||||
debug("Stream::process(%s) error status=%s (%d)\n",
|
debug("Stream::process(%s) error status=%s (%d)\n",
|
||||||
@ -855,7 +855,7 @@ process()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
debug("Stream::process(%s) ready. %s\n",
|
debug("Stream::process(%s) ready. %s\n",
|
||||||
name(), convert==2 ?
|
name(), convert == DO_NOT_CONVERT ?
|
||||||
"convert" : "don't convert");
|
"convert" : "don't convert");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -869,11 +869,15 @@ process()
|
|||||||
debug("Stream::process(%s) start\n", name());
|
debug("Stream::process(%s) start\n", name());
|
||||||
status = NO_ALARM;
|
status = NO_ALARM;
|
||||||
convert = OK;
|
convert = OK;
|
||||||
if (!startProtocol(record->proc==2 ? StreamCore::StartInit : StreamCore::StartNormal))
|
if (!startProtocol(record->proc == 2 ? StreamCore::StartInit : StreamCore::StartNormal))
|
||||||
{
|
{
|
||||||
debug("Stream::process(%s): could not start %sprotocol, status=%d\n",
|
debug("Stream::process(%s): could not start %sprotocol, status=%s (%d)\n",
|
||||||
name(), record->proc==2 ? "@init " : "", status);
|
name(), record->proc == 2 ? "@init " : "",
|
||||||
|
status >= 0 && status < ALARM_NSTATUS ?
|
||||||
|
epicsAlarmConditionStrings[status] : "ERROR",
|
||||||
|
status);
|
||||||
(void) recGblSetSevr(record, status ? status : UDF_ALARM, INVALID_ALARM);
|
(void) recGblSetSevr(record, status ? status : UDF_ALARM, INVALID_ALARM);
|
||||||
|
record->proc = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
debug("Stream::process(%s): protocol started\n", name());
|
debug("Stream::process(%s): protocol started\n", name());
|
||||||
@ -921,7 +925,7 @@ scan(format_t *format, void* value, size_t maxStringSize)
|
|||||||
currentValueLength = scanValue(*format->priv, *(double*)value);
|
currentValueLength = scanValue(*format->priv, *(double*)value);
|
||||||
break;
|
break;
|
||||||
case DBF_STRING:
|
case DBF_STRING:
|
||||||
currentValueLength = scanValue(*format->priv, (char*)value, size);
|
currentValueLength = scanValue(*format->priv, (char*)value, size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("INTERNAL ERROR (%s): Illegal format type %d\n",
|
error("INTERNAL ERROR (%s): Illegal format type %d\n",
|
||||||
@ -1084,7 +1088,7 @@ getFieldAddress(const char* fieldname, StreamBuffer& address)
|
|||||||
// FIELD in this record or VAL in other record
|
// FIELD in this record or VAL in other record
|
||||||
StreamBuffer fullname;
|
StreamBuffer fullname;
|
||||||
fullname.print("%s.%s", name(), fieldname);
|
fullname.print("%s.%s", name(), fieldname);
|
||||||
if (dbNameToAddr(fullname(), &dbaddr) != OK)
|
if (dbNameToAddr(fullname(), &dbaddr) != OK || strcmp(((dbFldDes*)dbaddr.pfldDes)->name, fieldname) != 0)
|
||||||
{
|
{
|
||||||
// VAL in other record
|
// VAL in other record
|
||||||
fullname.clear().print("%s.VAL", fieldname);
|
fullname.clear().print("%s.VAL", fieldname);
|
||||||
|
@ -32,7 +32,6 @@ extern "C" {
|
|||||||
|
|
||||||
#define STREAM_MAJOR 2
|
#define STREAM_MAJOR 2
|
||||||
#define STREAM_MINOR 8
|
#define STREAM_MINOR 8
|
||||||
#define STREAM_PATCHLEVEL 0
|
|
||||||
|
|
||||||
#ifndef OK
|
#ifndef OK
|
||||||
#define OK 0
|
#define OK 0
|
||||||
|
@ -116,17 +116,11 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
if ((length = streamScanfN(record, format,
|
if ((length = streamScanfN(record, format,
|
||||||
(char *)aai->bptr, aai->nelm)) == ERROR)
|
(char *)aai->bptr, aai->nelm)) == ERROR)
|
||||||
{
|
{
|
||||||
memset(aai->bptr, 0, aai->nelm);
|
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
if (lval < (ssize_t)aai->nelm)
|
if (length < (ssize_t)aai->nelm)
|
||||||
{
|
{
|
||||||
memset(((char*)aai->bptr)+lval , 0, aai->nelm-lval);
|
((char*)aai->bptr)[length] = 0;
|
||||||
lval++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
((char*)aai->bptr)[aai->nelm-1] = 0;
|
|
||||||
}
|
}
|
||||||
aai->nord = (long)length;
|
aai->nord = (long)length;
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -108,22 +108,16 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
case DBF_CHAR:
|
case DBF_CHAR:
|
||||||
case DBF_UCHAR:
|
case DBF_UCHAR:
|
||||||
{
|
{
|
||||||
ssize_t length;
|
ssize_t length;
|
||||||
aao->nord = 0;
|
aao->nord = 0;
|
||||||
if ((length = streamScanfN(record, format,
|
if ((length = streamScanfN(record, format,
|
||||||
(char *)aao->bptr, aao->nelm)) == ERROR)
|
(char *)aao->bptr, aao->nelm)) == ERROR)
|
||||||
{
|
{
|
||||||
memset(aao->bptr, 0, aao->nelm);
|
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
if (length < (ssize_t)aao->nelm)
|
if (length < (ssize_t)aao->nelm)
|
||||||
{
|
{
|
||||||
memset(((char*)aao->bptr)+lval , 0, aao->nelm-lval);
|
((char*)aao->bptr)[length] = 0;
|
||||||
lval++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
((char*)aao->bptr)[aao->nelm-1] = 0;
|
|
||||||
}
|
}
|
||||||
aao->nord = (long)length;
|
aao->nord = (long)length;
|
||||||
goto end_no_check;
|
goto end_no_check;
|
||||||
|
@ -23,30 +23,27 @@
|
|||||||
static long readData(dbCommon *record, format_t *format)
|
static long readData(dbCommon *record, format_t *format)
|
||||||
{
|
{
|
||||||
lsiRecord *lsi = (lsiRecord *)record;
|
lsiRecord *lsi = (lsiRecord *)record;
|
||||||
|
ssize_t length;
|
||||||
|
|
||||||
if (format->type == DBF_STRING)
|
if (format->type != DBF_STRING) return ERROR;
|
||||||
|
if ((length = streamScanfN(record, format, lsi->val, (long)lsi->sizv)) == ERROR)
|
||||||
{
|
{
|
||||||
long len;
|
return ERROR;
|
||||||
if ((len = streamScanfN(record, format, lsi->val, lsi->sizv) == ERROR))
|
|
||||||
{
|
|
||||||
lsi->len = 0;
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
lsi->len = len;
|
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
return ERROR;
|
if (length < (ssize_t)lsi->sizv)
|
||||||
|
{
|
||||||
|
lsi->val[length] = 0;
|
||||||
|
}
|
||||||
|
lsi->len = length;
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long writeData(dbCommon *record, format_t *format)
|
static long writeData(dbCommon *record, format_t *format)
|
||||||
{
|
{
|
||||||
lsiRecord *lsi = (lsiRecord *)record;
|
lsiRecord *lsi = (lsiRecord *)record;
|
||||||
|
|
||||||
if (format->type == DBF_STRING)
|
if (format->type != DBF_STRING) return ERROR;
|
||||||
{
|
return streamPrintf(record, format, lsi->val);
|
||||||
return streamPrintf(record, format, lsi->val);
|
|
||||||
}
|
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long initRecord(dbCommon *record)
|
static long initRecord(dbCommon *record)
|
||||||
|
@ -24,17 +24,19 @@
|
|||||||
static long readData(dbCommon *record, format_t *format)
|
static long readData(dbCommon *record, format_t *format)
|
||||||
{
|
{
|
||||||
lsoRecord *lso = (lsoRecord *)record;
|
lsoRecord *lso = (lsoRecord *)record;
|
||||||
long len;
|
ssize_t length;
|
||||||
unsigned short monitor_mask;
|
unsigned short monitor_mask;
|
||||||
|
|
||||||
if (format->type != DBF_STRING)
|
if (format->type != DBF_STRING) return ERROR;
|
||||||
return ERROR;
|
if ((length = streamScanfN(record, format, lso->val, lso->sizv)) == ERROR)
|
||||||
if ((len = streamScanfN(record, format, lso->val, lso->sizv) == ERROR))
|
|
||||||
{
|
{
|
||||||
lso->len = 0;
|
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
lso->len = len;
|
if (length < (ssize_t)lso->sizv)
|
||||||
|
{
|
||||||
|
lso->val[length] = 0;
|
||||||
|
}
|
||||||
|
lso->len = length;
|
||||||
if (record->pact) return OK;
|
if (record->pact) return OK;
|
||||||
/* In @init handler, no processing, enforce monitor updates. */
|
/* In @init handler, no processing, enforce monitor updates. */
|
||||||
monitor_mask = recGblResetAlarms(record);
|
monitor_mask = recGblResetAlarms(record);
|
||||||
@ -60,11 +62,8 @@ static long writeData(dbCommon *record, format_t *format)
|
|||||||
{
|
{
|
||||||
lsoRecord *lso = (lsoRecord *)record;
|
lsoRecord *lso = (lsoRecord *)record;
|
||||||
|
|
||||||
if (format->type == DBF_STRING)
|
if (format->type != DBF_STRING) return ERROR;
|
||||||
{
|
return streamPrintf(record, format, lso->val);
|
||||||
return streamPrintf(record, format, lso->val);
|
|
||||||
}
|
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long initRecord(dbCommon *record)
|
static long initRecord(dbCommon *record)
|
||||||
|
@ -33,11 +33,12 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
{
|
{
|
||||||
case DBF_ULONG:
|
case DBF_ULONG:
|
||||||
case DBF_LONG:
|
case DBF_LONG:
|
||||||
|
case DBF_ENUM:
|
||||||
{
|
{
|
||||||
if (streamScanf(record, format, &val) == ERROR) return ERROR;
|
if (streamScanf(record, format, &val) == ERROR) return ERROR;
|
||||||
|
if (mbbo->mask) val &= mbbo->mask;
|
||||||
mbbo->rbv = val;
|
mbbo->rbv = val;
|
||||||
mbbo->rval = val;
|
mbbo->rval = val;
|
||||||
if (mbbo->mask) val &= mbbo->mask;
|
|
||||||
if (mbbo->shft > 0) val >>= mbbo->shft;
|
if (mbbo->shft > 0) val >>= mbbo->shft;
|
||||||
/* read VAL or RBV? Look if any value is defined */
|
/* read VAL or RBV? Look if any value is defined */
|
||||||
if (mbbo->sdef)
|
if (mbbo->sdef)
|
||||||
@ -56,17 +57,12 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
mbbo->val = (epicsEnum16)val;
|
mbbo->val = (epicsEnum16)val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DBF_ENUM:
|
|
||||||
{
|
|
||||||
if (streamScanf(record, format, &val) == ERROR) return ERROR;
|
|
||||||
mbbo->val = (epicsEnum16)val;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DBF_STRING:
|
case DBF_STRING:
|
||||||
{
|
{
|
||||||
char buffer[sizeof(mbbo->zrst)];
|
char buffer[sizeof(mbbo->zrst)];
|
||||||
if (streamScanfN(record, format, buffer, sizeof(buffer)) == ERROR)
|
if (streamScanfN(record, format, buffer, sizeof(buffer)) == ERROR)
|
||||||
return ERROR;
|
return ERROR;
|
||||||
|
mbbo->val = 65535; /* initalize to unknown state*/
|
||||||
for (val = 0; val < 16; val++)
|
for (val = 0; val < 16; val++)
|
||||||
{
|
{
|
||||||
if (strcmp ((&mbbo->zrst)[val], buffer) == 0)
|
if (strcmp ((&mbbo->zrst)[val], buffer) == 0)
|
||||||
@ -75,6 +71,7 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return ERROR;
|
return ERROR;
|
||||||
@ -82,12 +79,21 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
if (record->pact) return DO_NOT_CONVERT;
|
if (record->pact) return DO_NOT_CONVERT;
|
||||||
/* In @init handler, no processing, enforce monitor updates. */
|
/* In @init handler, no processing, enforce monitor updates. */
|
||||||
monitor_mask = recGblResetAlarms(record);
|
monitor_mask = recGblResetAlarms(record);
|
||||||
|
if (mbbo->val > 15) {
|
||||||
|
recGblSetSevr(record, STATE_ALARM, mbbo->unsv);
|
||||||
|
} else {
|
||||||
|
recGblSetSevr(record, STATE_ALARM, (&(mbbo->zrsv))[mbbo->val]);
|
||||||
|
}
|
||||||
|
mbbo->lalm = mbbo->val;
|
||||||
|
if (mbbo->val != mbbo->lalm) {
|
||||||
|
if (!recGblSetSevr(record, COS_ALARM, mbbo->cosv)) mbbo->lalm = mbbo->val;
|
||||||
|
}
|
||||||
if (mbbo->mlst != mbbo->val)
|
if (mbbo->mlst != mbbo->val)
|
||||||
{
|
{
|
||||||
monitor_mask |= (DBE_VALUE | DBE_LOG);
|
monitor_mask |= (DBE_VALUE | DBE_LOG);
|
||||||
mbbo->mlst = mbbo->val;
|
mbbo->mlst = mbbo->val;
|
||||||
}
|
}
|
||||||
if (monitor_mask){
|
if (monitor_mask) {
|
||||||
db_post_events(record, &mbbo->val, monitor_mask);
|
db_post_events(record, &mbbo->val, monitor_mask);
|
||||||
}
|
}
|
||||||
if (mbbo->oraw != mbbo->rval) {
|
if (mbbo->oraw != mbbo->rval) {
|
||||||
@ -110,39 +116,38 @@ static long writeData(dbCommon *record, format_t *format)
|
|||||||
switch (format->type)
|
switch (format->type)
|
||||||
{
|
{
|
||||||
case DBF_ULONG:
|
case DBF_ULONG:
|
||||||
|
case DBF_ENUM:
|
||||||
/* print VAL or RVAL ? */
|
/* print VAL or RVAL ? */
|
||||||
val = mbbo->val;
|
val = mbbo->val;
|
||||||
|
if (mbbo->shft > 0) val <<= mbbo->shft;
|
||||||
if (mbbo->sdef) for (i=0; i<16; i++)
|
if (mbbo->sdef) for (i=0; i<16; i++)
|
||||||
{
|
{
|
||||||
if ((&mbbo->zrvl)[i])
|
if ((&mbbo->zrvl)[i])
|
||||||
{
|
{
|
||||||
/* any values defined ? */
|
/* any values defined ? */
|
||||||
val = mbbo->rval;
|
val = mbbo->rval;
|
||||||
if (mbbo->mask) val &= mbbo->mask;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mbbo->mask) val &= mbbo->mask;
|
||||||
return streamPrintf(record, format, val);
|
return streamPrintf(record, format, val);
|
||||||
case DBF_LONG:
|
case DBF_LONG:
|
||||||
{
|
{
|
||||||
/* print VAL or RVAL ? */
|
/* print VAL or RVAL ? */
|
||||||
val = (epicsInt16)mbbo->val;
|
val = (epicsInt16)mbbo->val;
|
||||||
|
if (mbbo->shft > 0) val <<= mbbo->shft;
|
||||||
if (mbbo->sdef) for (i=0; i<16; i++)
|
if (mbbo->sdef) for (i=0; i<16; i++)
|
||||||
{
|
{
|
||||||
if ((&mbbo->zrvl)[i])
|
if ((&mbbo->zrvl)[i])
|
||||||
{
|
{
|
||||||
/* any values defined ? */
|
/* any values defined ? */
|
||||||
val = (epicsInt32)mbbo->rval;
|
val = (epicsInt32)mbbo->rval;
|
||||||
if (mbbo->mask) val &= mbbo->mask;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mbbo->mask) val &= mbbo->mask;
|
||||||
return streamPrintf(record, format, val);
|
return streamPrintf(record, format, val);
|
||||||
}
|
}
|
||||||
case DBF_ENUM:
|
|
||||||
{
|
|
||||||
return streamPrintf(record, format, mbbo->val);
|
|
||||||
}
|
|
||||||
case DBF_STRING:
|
case DBF_STRING:
|
||||||
{
|
{
|
||||||
if (mbbo->val >= 16) return ERROR;
|
if (mbbo->val >= 16) return ERROR;
|
||||||
|
@ -42,7 +42,7 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
case DBF_LONG:
|
case DBF_LONG:
|
||||||
case DBF_UONG:
|
case DBF_ULONG:
|
||||||
case DBF_ENUM:
|
case DBF_ENUM:
|
||||||
{
|
{
|
||||||
long lval;
|
long lval;
|
||||||
@ -72,7 +72,7 @@ static long writeData(dbCommon *record, format_t *format)
|
|||||||
return streamPrintf(record, format, sco->oval);
|
return streamPrintf(record, format, sco->oval);
|
||||||
}
|
}
|
||||||
case DBF_LONG:
|
case DBF_LONG:
|
||||||
case DBF_UONG:
|
case DBF_ULONG:
|
||||||
case DBF_ENUM:
|
case DBF_ENUM:
|
||||||
{
|
{
|
||||||
return streamPrintf(record, format, (long)sco->oval);
|
return streamPrintf(record, format, (long)sco->oval);
|
||||||
|
@ -117,21 +117,15 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
if ((length = streamScanfN(record, format,
|
if ((length = streamScanfN(record, format,
|
||||||
(char *)wf->bptr, wf->nelm)) == ERROR)
|
(char *)wf->bptr, wf->nelm)) == ERROR)
|
||||||
{
|
{
|
||||||
memset(wf->bptr, 0, wf->nelm);
|
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
if (length < (ssize_t)wf->nelm)
|
if (length < (ssize_t)wf->nelm)
|
||||||
{
|
{
|
||||||
memset(((char*)wf->bptr)+lval , 0, wf->nelm-lval);
|
((char*)wf->bptr)[length] = 0;
|
||||||
lval++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
((char*)wf->bptr)[wf->nelm-1] = 0;
|
|
||||||
}
|
}
|
||||||
wf->nord = (long)length;
|
wf->nord = (long)length;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
errlogSevPrintf(errlogFatal,
|
errlogSevPrintf(errlogFatal,
|
||||||
"readData %s: can't convert from string to %s\n",
|
"readData %s: can't convert from string to %s\n",
|
||||||
|
@ -54,8 +54,6 @@ set debug 0
|
|||||||
startioc
|
startioc
|
||||||
|
|
||||||
# Some formats give different results on 32 bit and 64 bit machines.
|
# Some formats give different results on 32 bit and 64 bit machines.
|
||||||
# This occurs when printing negative numbers with unsigned formats.
|
|
||||||
# This is normal. E.g. -1 HAS a different number of 1 bits.
|
|
||||||
# Specify the width field in the format if this is a problem.
|
# Specify the width field in the format if this is a problem.
|
||||||
|
|
||||||
put DZ:percent 1
|
put DZ:percent 1
|
||||||
@ -75,17 +73,9 @@ assure "12345 12345 012345 3039 003039 11000000111001 11000000111001 111001 !!..
|
|||||||
put DZ:lo 2147483647
|
put DZ:lo 2147483647
|
||||||
assure "2147483647 2147483647 2147483647 7fffffff FFFFFF 1111111111111111111111111111111 1111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
assure "2147483647 2147483647 2147483647 7fffffff FFFFFF 1111111111111111111111111111111 1111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
||||||
put DZ:lo -1
|
put DZ:lo -1
|
||||||
if {$tcl_platform(machine) == "x86_64"} {
|
|
||||||
assure "-1 -1 -00001 ffffffffffffffff FFFFFF 1111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
|
||||||
} else {
|
|
||||||
assure "-1 -1 -00001 ffffffff FFFFFF 11111111111111111111111111111111 11111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
assure "-1 -1 -00001 ffffffff FFFFFF 11111111111111111111111111111111 11111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
||||||
}
|
|
||||||
put DZ:lo -1234
|
put DZ:lo -1234
|
||||||
if {$tcl_platform(machine) == "x86_64"} {
|
|
||||||
assure "-1234 -1234 -01234 fffffffffffffb2e FFFB2E 1111111111111111111111111111111111111111111111111111101100101110 1111111111111111111111111111111111111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n"
|
|
||||||
} else {
|
|
||||||
assure "-1234 -1234 -01234 fffffb2e FFFB2E 11111111111111111111101100101110 11111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n"
|
assure "-1234 -1234 -01234 fffffb2e FFFB2E 11111111111111111111101100101110 11111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n"
|
||||||
}
|
|
||||||
put DZ:lo 255
|
put DZ:lo 255
|
||||||
assure "255 255 000255 ff 0000FF 11111111 11111111 111111 !!!!!!!! !!!!!!!!\n"
|
assure "255 255 000255 ff 0000FF 11111111 11111111 111111 !!!!!!!! !!!!!!!!\n"
|
||||||
put DZ:lo 65535
|
put DZ:lo 65535
|
||||||
|
Reference in New Issue
Block a user