add streamReinit function
This commit is contained in:
@ -9,10 +9,10 @@ BUILDCLASSES += Linux
|
|||||||
|
|
||||||
DOCUDIR = documentation
|
DOCUDIR = documentation
|
||||||
|
|
||||||
ifdef EPICSVERSION
|
|
||||||
ifndef RECORDTYPES
|
|
||||||
PCRE=1
|
PCRE=1
|
||||||
ASYN=1
|
ASYN=1
|
||||||
|
ifdef EPICSVERSION
|
||||||
|
ifndef RECORDTYPES
|
||||||
include src/CONFIG_STREAM
|
include src/CONFIG_STREAM
|
||||||
export RECORDTYPES BUSSES FORMATS
|
export RECORDTYPES BUSSES FORMATS
|
||||||
endif
|
endif
|
||||||
@ -44,5 +44,10 @@ export DBDFILES = streamSup.dbd
|
|||||||
streamSup.dbd:
|
streamSup.dbd:
|
||||||
@echo Creating $@ from $(RECORDTYPES)
|
@echo Creating $@ from $(RECORDTYPES)
|
||||||
$(PERL) ../src/makedbd.pl $(RECORDTYPES) > $@
|
$(PERL) ../src/makedbd.pl $(RECORDTYPES) > $@
|
||||||
|
ifdef BASE_3_14
|
||||||
|
ifdef ASYN
|
||||||
|
echo "registrar(AsynDriverInterfaceRegistrar)" >> $@
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
@ -54,9 +54,9 @@ its <code>SEVR</code> field set to <code>INVALID</code> and its
|
|||||||
<dl>
|
<dl>
|
||||||
<dt><code>TIMEOUT</code></dt>
|
<dt><code>TIMEOUT</code></dt>
|
||||||
<dd>
|
<dd>
|
||||||
The device could not be locked (<code>LockTimeout</code>) or the
|
The device could not be locked (<code>LockTimeout</code>) because
|
||||||
device did not reply in time
|
other records are keeping the device busy or the device did not reply
|
||||||
(<a href="protocol.html#sysvar"><code>ReplyTimeout</code></a>).
|
in time (<a href="protocol.html#sysvar"><code>ReplyTimeout</code></a>).
|
||||||
</dd>
|
</dd>
|
||||||
<dt><code>WRITE</code></dt>
|
<dt><code>WRITE</code></dt>
|
||||||
<dd>
|
<dd>
|
||||||
@ -96,13 +96,14 @@ will be set according to the original error.
|
|||||||
<a name="init"></a>
|
<a name="init"></a>
|
||||||
<h2>2. Initialization</h2>
|
<h2>2. Initialization</h2>
|
||||||
<p>
|
<p>
|
||||||
Often, it is required to initialize records from the hardware after
|
Often, it is useful to initialize records from the hardware after
|
||||||
booting the IOC, especially output records.
|
booting the IOC, especially output records.
|
||||||
For this purpose, initialization is formally handled as an
|
For this purpose, initialization is formally handled as an
|
||||||
<a href="protocol.html#except">exception</a>.
|
<a href="protocol.html#except">exception</a>.
|
||||||
The <code>@init</code> handler is called as part of the
|
The <code>@init</code> handler is called as part of the
|
||||||
<code>initRecord()</code> function during <code>iocInit</code>
|
<code>initRecord()</code> function during <code>iocInit</code>
|
||||||
before any scan task starts.
|
before any scan task starts <span class="new">and may be re-run
|
||||||
|
later under circumstances listed below</span>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
In contrast to <a href="#proc">normal processing</a>, the protocol
|
In contrast to <a href="#proc">normal processing</a>, the protocol
|
||||||
@ -120,7 +121,7 @@ If the handler fails, the record remains uninitialized:
|
|||||||
The <code>@init</code> handler has nothing to do with the
|
The <code>@init</code> handler has nothing to do with the
|
||||||
<code>PINI</code> field.
|
<code>PINI</code> field.
|
||||||
The handler does <u>not</u> process the record nor does it trigger
|
The handler does <u>not</u> process the record nor does it trigger
|
||||||
forward links or other PP links.
|
forward links or any links with the <code>PP</code> flag.
|
||||||
It runs <u>before</u> <code>PINI</code> is handled.
|
It runs <u>before</u> <code>PINI</code> is handled.
|
||||||
If the record has <code>PINI=YES</code>, the <code>PINI</code>
|
If the record has <code>PINI=YES</code>, the <code>PINI</code>
|
||||||
processing is a <a href="#proc">normal processing</a> after the
|
processing is a <a href="#proc">normal processing</a> after the
|
||||||
@ -147,19 +148,33 @@ read from a constant <code>INP</code> or <code>DOL</code> field,
|
|||||||
or restored from a bump-less reboot system
|
or restored from a bump-less reboot system
|
||||||
(e.g. <em>autosave</em> from the <em>synApps</em> package).
|
(e.g. <em>autosave</em> from the <em>synApps</em> package).
|
||||||
</p>
|
</p>
|
||||||
<p class="new">
|
<p>
|
||||||
The <code>@init</code> handler is called again in the following situations:
|
The <code>@init</code> handler is called in the following situations:
|
||||||
|
<ul>
|
||||||
|
<li>At startup by <code>iocInit</code> during record initialization
|
||||||
|
as described above.
|
||||||
|
<li class="new">When the IOC is resumed with <code>iocRun</code> (after
|
||||||
|
beeing paused with <code>iocPause</code>) before the scan tasks
|
||||||
|
restart and before records with <code>PINI=RUN</code> are processed.
|
||||||
|
<li class="new">When the protocol is
|
||||||
|
<a href="setup.html#reload">reloaded</a></span> for example with
|
||||||
|
<code>streamReload ["<var>recordname</var>"]</code>.
|
||||||
|
<li class="new">When <em>StreamDevice</em> detects that the device has
|
||||||
|
reconnected (after being disconnected). This includes the case that
|
||||||
|
the device was disconnected when the IOC started.
|
||||||
|
Be aware that some drivers test the connection only periodically,
|
||||||
|
e.g. the <em>asynIPPort</em> driver tests it every few seconds.
|
||||||
|
Thus there may be a small delay between the device being online
|
||||||
|
and the record re-initializing.
|
||||||
|
<li class="new">When <code>streamReinit
|
||||||
|
"<var>asynPortname</var>"[,<var>addr</var>]</code> is called
|
||||||
|
(if using an <em>asynDriver</em> port).
|
||||||
|
<li class="new">When the "magic value" <code>2</code> is written to the
|
||||||
|
<code>.PROC</code> field of the record.
|
||||||
|
In this case the record is processed and thus its <code>FLNK</code>
|
||||||
|
and links with the <code>PP</code> flag are triggered.
|
||||||
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
<ul class="new">
|
|
||||||
<li>The device driver informs <em>StreamDevice</em> that the device has
|
|
||||||
reconnected after it had been disconnected. This is only detectable for
|
|
||||||
some types of busses.
|
|
||||||
<li>The IOC is resumed with <code>iocRun</code> after it had
|
|
||||||
been paused with <code>iocPause</code>. This requires EPICS 3.14.11 or higher.
|
|
||||||
<li>The record protocol has been <a href="setup.html#reload">reloaded</a>
|
|
||||||
using the shell function <code>streamReload</code> or the subroutine
|
|
||||||
record funtion <code>streamReloadSub</code>.
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<a name="iointr"></a>
|
<a name="iointr"></a>
|
||||||
<h2>3. I/O Intr</h2>
|
<h2>3. I/O Intr</h2>
|
||||||
|
@ -558,15 +558,8 @@ There is a fixed set of exception handler names starting with
|
|||||||
Not really an exception but formally specified in the same syntax.
|
Not really an exception but formally specified in the same syntax.
|
||||||
This handler can be used to initialize an output record with a value read from
|
This handler can be used to initialize an output record with a value read from
|
||||||
the device.
|
the device.
|
||||||
Also see chapter <a href="processing.html#init">Record Processing</a>.
|
See also chapter <a href="processing.html#init">Record Processing</a>.
|
||||||
|
|
||||||
It is called at startup by <code>iocInit</code> during record
|
|
||||||
initialization <span class="new">and again whenever <em>StreamDevice</em>
|
|
||||||
detects that the device has reconnected after a disconnect or when the
|
|
||||||
IOC is resumed with <code>iocRun</code> after beeing paused or
|
|
||||||
when the protocol has been <a href="setup.html#reload">reloaded</a></span>
|
|
||||||
or when the "magic value" <code>2</code> is written to the <code>.PROC</code>
|
|
||||||
field.
|
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<h3>Example:</h3>
|
<h3>Example:</h3>
|
||||||
|
@ -32,6 +32,8 @@ extern "C" {
|
|||||||
#include "epicsAssert.h"
|
#include "epicsAssert.h"
|
||||||
#include "epicsTime.h"
|
#include "epicsTime.h"
|
||||||
#include "epicsTimer.h"
|
#include "epicsTimer.h"
|
||||||
|
#include "epicsStdioRedirect.h"
|
||||||
|
#include "iocsh.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "asynDriver.h"
|
#include "asynDriver.h"
|
||||||
@ -1558,3 +1560,53 @@ handleTimeout()
|
|||||||
clientName(), toStr(ioAction));
|
clientName(), toStr(ioAction));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" long streamReinit(const char* portname, int addr)
|
||||||
|
{
|
||||||
|
if (!portname)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: streamReinit \"portname\", [addr]\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
asynUser* pasynUser = pasynManager->createAsynUser(NULL, NULL);
|
||||||
|
if (!pasynUser)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't create asynUser\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
asynStatus status = pasynManager->connectDevice(pasynUser, portname, addr);
|
||||||
|
if (status == asynSuccess)
|
||||||
|
status = pasynManager->exceptionDisconnect(pasynUser);
|
||||||
|
if (status == asynSuccess)
|
||||||
|
status = pasynManager->exceptionConnect(pasynUser);
|
||||||
|
if (status != asynSuccess)
|
||||||
|
fprintf(stderr, "%s\n", pasynUser->errorMessage);
|
||||||
|
pasynManager->disconnect(pasynUser);
|
||||||
|
pasynManager->freeAsynUser(pasynUser);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef EPICS_3_13
|
||||||
|
static const iocshArg streamReinitArg0 =
|
||||||
|
{ "portname", iocshArgString };
|
||||||
|
static const iocshArg streamReinitArg1 =
|
||||||
|
{ "[addr]", iocshArgInt };
|
||||||
|
static const iocshArg * const streamReinitArgs[] =
|
||||||
|
{ &streamReinitArg0, &streamReinitArg1 };
|
||||||
|
static const iocshFuncDef streamReinitDef =
|
||||||
|
{ "streamReinit", 2, streamReinitArgs };
|
||||||
|
|
||||||
|
void streamReinitFunc(const iocshArgBuf *args)
|
||||||
|
{
|
||||||
|
streamReinit(args[0].sval, args[1].ival);
|
||||||
|
}
|
||||||
|
static void AsynDriverInterfaceRegistrar ()
|
||||||
|
{
|
||||||
|
iocshRegister(&streamReinitDef, streamReinitFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
epicsExportRegistrar(AsynDriverInterfaceRegistrar);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -87,6 +87,9 @@ streamReferences: ../CONFIG_STREAM
|
|||||||
# create stream.dbd from all RECORDTYPES
|
# create stream.dbd from all RECORDTYPES
|
||||||
$(COMMON_DIR)/$(LIBRARY_DEFAULT).dbd: ../CONFIG_STREAM
|
$(COMMON_DIR)/$(LIBRARY_DEFAULT).dbd: ../CONFIG_STREAM
|
||||||
$(PERL) ../makedbd.pl $(RECORDTYPES) > $@
|
$(PERL) ../makedbd.pl $(RECORDTYPES) > $@
|
||||||
|
ifdef ASYN
|
||||||
|
echo "registrar(AsynDriverInterfaceRegistrar)" >> $@
|
||||||
|
endif
|
||||||
|
|
||||||
$(LIBRARY_DEFAULT).dbd$(DEP): ../CONFIG_STREAM
|
$(LIBRARY_DEFAULT).dbd$(DEP): ../CONFIG_STREAM
|
||||||
echo $(LIBRARY_DEFAULT).dbd: $< > $@
|
echo $(LIBRARY_DEFAULT).dbd: $< > $@
|
||||||
|
Reference in New Issue
Block a user