Merge branch '7.0' into PSI-7.0
This commit is contained in:
@@ -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":{}}'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -88,7 +88,7 @@ If SELM is C<Mask>, then SELN will be treated as a bit mask. If bit zero
|
||||
OUTB will be written to, and so on. Thus when SELN==5, both OUTC and OUTA
|
||||
will be written to.
|
||||
|
||||
=fields SELL, SELM, SELN, OUTA, OUTB, OUTC, OUTD, OUTE, OUTF, OUTG, OUTH
|
||||
=fields SELL, SELM, SELN, OUTA - OUTH
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ via dbPuts.
|
||||
The Fanout record also has the standard scanning fields common to all records.
|
||||
These fields are listed in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=fields SELM, SELN, SELL, OFFS, SHFT, LNK0, LNK1, LNK2, LNK3, LNK4, LNK5, LNK6, LNK7, LNK8, LNK9, LNKA, LNKB, LNKC, LNKD, LNKE, LNKF
|
||||
=fields SELM, SELN, SELL, OFFS, SHFT, LNK0 - LNK9, LNKA - LNKF
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ determine VAL as follows:
|
||||
|
||||
Each of the fields, B0-BF and B10-B1F, represents one bit of the word.
|
||||
|
||||
=fields VAL, INP, RVAL, SHFT, B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, BA, BB, BC, BD, BE, BF, B10, B11, B12, B13, B14, B15, B16, B17, B18, B19, B1A, B1B, B1C, B1D, B1E, B1F
|
||||
=fields VAL, INP, RVAL, SHFT, B0 - B9, BA - BF, B10 - B1F
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ initialization if the record is still undefined (UDF) after DOL has been read
|
||||
and the device support initialized but at least one of the B0-B1F fields is
|
||||
non-zero, the VAL field will be set from those fields and UDF will be cleared.
|
||||
|
||||
=fields B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, BA, BB, BC, BD, BE, BF, B10, B11, B12, B13, B14, B15, B16, B17, B18, B19, B1A, B1B, B1C, B1D, B1E, B1F
|
||||
=fields B0 - B9, BA - BF, B10 - B1F
|
||||
|
||||
=head3 Convert and Write Parameters
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ NaN to another value in order to define the link and its field. Note that all
|
||||
undefined links must be recognized as such if the selection algorithm is to work
|
||||
as expected.
|
||||
|
||||
=fields INPA, INPB, INPC, INPD, INPE, INPF, INPG, INPH, INPI, INPJ, INPK, INPL, A, B, C, D, E, F, G, H, I, J, K, L
|
||||
=fields INPA - INPL, A - L
|
||||
|
||||
=head3 Select Parameters
|
||||
|
||||
@@ -156,7 +156,7 @@ The LA-LL fields are used to implement the monitors for each of the value
|
||||
fields, A-L. They represent previous input values. For example, unless LA is not
|
||||
equal to A, no monitor is invoked for A.
|
||||
|
||||
=fields VAL, LALM, ALST, MLST, LA, LB, LC, LD, LE, LF, LG, LH, LI, LJ, LK, LL
|
||||
=fields VAL, LALM, ALST, MLST, LA - LL
|
||||
|
||||
=head2 Record Support
|
||||
|
||||
|
||||
@@ -58,11 +58,11 @@ constant value, and may subsequently be changed via dbPuts.
|
||||
|
||||
=head4 Desired Output Link Fields
|
||||
|
||||
=fields DOL0, DOL1, DOL2, DOL3, DOL4, DOL5, DOL6, DOL7, DOL8, DOL9, DOLA, DOLB, DOLC, DOLD, DOLE, DOLF
|
||||
=fields DOL0 - DOL9, DOLA - DOLF
|
||||
|
||||
=head4 Desired Output Value Fields
|
||||
|
||||
=fields DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DOA, DOB, DOC, DOD, DOE, DOF
|
||||
=fields DO0 - DO9, DOA - DOF
|
||||
|
||||
=head3 Output Parameters
|
||||
|
||||
@@ -72,7 +72,7 @@ output link (LNK0-LNKF). These output links can be database links or channel
|
||||
access links; they cannot be device addresses. There are sixteen output links, one
|
||||
for each desired output link. Only those that are defined are used.
|
||||
|
||||
=fields LNK0, LNK1, LNK2, LNK3, LNK4, LNK5, LNK6, LNK7, LNK8, LNK9, LNKA, LNKB, LNKC, LNKD, LNKE, LNKF
|
||||
=fields LNK0 - LNK9, LNKA - LNKF
|
||||
|
||||
=head3 Selection Algorithm Parameters
|
||||
|
||||
@@ -178,7 +178,7 @@ DOL1, DOV1, and LNK1 fields for three seconds. That is, the desired output value
|
||||
will not be fetched and written to the output link until three seconds have
|
||||
lapsed.
|
||||
|
||||
=fields DLY0, DLY1, DLY2, DLY3, DLY4, DLY5, DLY6, DLY7, DLY8, DLY9, DLYA, DLYB, DLYC, DLYD, DLYE, DLYF
|
||||
=fields DLY0 - DLY9, DLYA - DLYF
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ link.
|
||||
DOL can also be a constant, in which case VAL will be initialized to the
|
||||
constant value. However to be interpreted as a constant instead of a CA link
|
||||
the constant can only be numeric, so string output records are best initialized
|
||||
by dirctly setting the VAL field. Note that if DOL is a constant, OMSL
|
||||
by directly setting the VAL field. Note that if DOL is a constant, OMSL
|
||||
cannot be C<<< closed_loop >>>.
|
||||
|
||||
=fields VAL, DOL, OMSL
|
||||
|
||||
@@ -108,7 +108,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
/* convert the initialization subroutine name */
|
||||
psubroutine = (SUBFUNCPTR)registryFunctionFind(prec->inam);
|
||||
if (psubroutine == 0) {
|
||||
recGblRecordError(S_db_BadSub, (void *)prec, "Init subroutine (INAM)");
|
||||
fprintf(stderr, "%s.INAM " ERL_ERROR " function '%s' not found\n",
|
||||
prec->name, prec->inam);
|
||||
return S_db_BadSub;
|
||||
}
|
||||
/* invoke the initialization subroutine */
|
||||
@@ -122,7 +123,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
}
|
||||
prec->sadr = (SUBFUNCPTR)registryFunctionFind(prec->snam);
|
||||
if (prec->sadr == NULL) {
|
||||
recGblRecordError(S_db_BadSub, (void *)prec, "Proc subroutine (SNAM)");
|
||||
fprintf(stderr, "%s.SNAM " ERL_ERROR " function '%s' not found\n",
|
||||
prec->name, prec->snam);
|
||||
return S_db_BadSub;
|
||||
}
|
||||
prec->mlst = prec->val;
|
||||
@@ -186,8 +188,8 @@ static long special(DBADDR *paddr, int after)
|
||||
prec->sadr = (SUBFUNCPTR)registryFunctionFind(prec->snam);
|
||||
if (prec->sadr) return 0;
|
||||
|
||||
recGblRecordError(S_db_BadSub, (void *)prec,
|
||||
"subRecord(special) registryFunctionFind failed");
|
||||
fprintf(stderr, "%s " ERL_ERROR " subRecord::special - SNAM = '%s' not found\n",
|
||||
prec->name, prec->snam);
|
||||
return S_db_BadSub;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ the constant value and the field's value can be changed at run-time via dbPuts.
|
||||
Otherwise, the values for (A-F) are fetched from the input links when the record
|
||||
is processed.
|
||||
|
||||
=fields INPA, INPB, INPC, INPD, INPE, INPF, INPG, INPH, INPI, INPJ, INPK, INPL, A, B, C, D, E, F, G, H, I, J, K, L
|
||||
=fields INPA - INPL, A - L
|
||||
|
||||
=head3 Subroutine Connection
|
||||
|
||||
@@ -119,7 +119,7 @@ The rest of these fields--LALM, ALST, MLST, and the LA-LL fields--are used to
|
||||
implement the monitors. For example, when LA is not equal to A, the value-change
|
||||
monitors are called for that field.
|
||||
|
||||
=fields VAL, SADR, LALM, ALST, MLST, LA, LB, LC, LD, LE, LF, LG, LH, LI, LJ, LK, LL
|
||||
=fields VAL, SADR, LALM, ALST, MLST, LA - LL
|
||||
|
||||
=head2 Record Support
|
||||
|
||||
|
||||
@@ -29,4 +29,3 @@ softIoc_LIBS = $(EPICS_BASE_IOC_LIBS)
|
||||
DB += softIocExit.db
|
||||
|
||||
CLEANS += epicsInstallDir.h
|
||||
|
||||
|
||||
@@ -51,6 +51,14 @@ namespace {
|
||||
|
||||
bool verbose = false;
|
||||
|
||||
enum coloration {NONE, CMD, REM};
|
||||
|
||||
void verbose_out(coloration color, const std::string& message) {
|
||||
if (!verbose) return;
|
||||
const char *ansi[] = {ANSI_ESC_RESET, ANSI_ESC_BOLD, ANSI_ESC_BLUE};
|
||||
std::cout << ansi[color] << message << ansi[NONE] << std::endl;
|
||||
}
|
||||
|
||||
static void exitSubroutine(subRecord *precord) {
|
||||
epicsExitLater((precord->a == 0.0) ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
@@ -109,13 +117,11 @@ void lazy_dbd(const std::string& dbd_file) {
|
||||
if(lazy_dbd_loaded) return;
|
||||
lazy_dbd_loaded = true;
|
||||
|
||||
if (verbose)
|
||||
std::cout<<"dbLoadDatabase(\""<<dbd_file<<"\")\n";
|
||||
verbose_out(CMD, std::string("dbLoadDatabase(\"") + dbd_file + "\")");
|
||||
errIf(dbLoadDatabase(dbd_file.c_str(), NULL, NULL),
|
||||
std::string("Failed to load DBD file: ")+dbd_file);
|
||||
|
||||
if (verbose)
|
||||
std::cout<<"softIoc_registerRecordDeviceDriver(pdbbase)\n";
|
||||
verbose_out(CMD, "softIoc_registerRecordDeviceDriver(pdbbase)");
|
||||
errIf(softIoc_registerRecordDeviceDriver(pdbbase),
|
||||
"Failed to initialize database");
|
||||
registryFunctionAdd("exit", (REGISTRYFUNCTION) exitSubroutine);
|
||||
@@ -166,15 +172,14 @@ int main(int argc, char *argv[])
|
||||
epicsExit(2);
|
||||
return 2;
|
||||
case 'a':
|
||||
lazy_dbd(dbd_file);
|
||||
if (!macros.empty()) {
|
||||
if (verbose)
|
||||
std::cout<<"asSetSubstitutions(\""<<macros<<"\")\n";
|
||||
verbose_out(CMD, std::string("asSetSubstitutions(\"")
|
||||
+ macros + "\")");
|
||||
if(asSetSubstitutions(macros.c_str()))
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
if (verbose)
|
||||
std::cout<<"asSetFilename(\""<<optarg<<"\")\n";
|
||||
verbose_out(CMD, std::string("asSetFilename(\"")
|
||||
+ optarg + "\")");
|
||||
if(asSetFilename(optarg))
|
||||
throw std::bad_alloc();
|
||||
break;
|
||||
@@ -186,12 +191,10 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
case 'd':
|
||||
lazy_dbd(dbd_file);
|
||||
if (verbose) {
|
||||
std::cout<<"dbLoadRecords(\""<<optarg<<"\"";
|
||||
if(!macros.empty())
|
||||
std::cout<<", \""<<macros<<"\"";
|
||||
std::cout<<")\n";
|
||||
}
|
||||
verbose_out(CMD, std::string("dbLoadRecords(\"")
|
||||
+ optarg + "\"" + ( !macros.empty() ?
|
||||
(std::string(", \"") + macros + "\"") : std::string() )
|
||||
+ ")");
|
||||
errIf(dbLoadRecords(optarg, macros.c_str()),
|
||||
std::string("Failed to load: ")+optarg);
|
||||
loadedDb = true;
|
||||
@@ -211,9 +214,8 @@ int main(int argc, char *argv[])
|
||||
lazy_dbd(dbd_file);
|
||||
xmacro = "IOC=";
|
||||
xmacro += optarg;
|
||||
if (verbose) {
|
||||
std::cout<<"dbLoadRecords(\""<<exit_file<<"\", \""<<xmacro<<"\")\n";
|
||||
}
|
||||
verbose_out(CMD, std::string("dbLoadRecords(\"")
|
||||
+ exit_file + "\", \"" + xmacro + "\")");
|
||||
errIf(dbLoadRecords(exit_file.c_str(), xmacro.c_str()),
|
||||
std::string("Failed to load: ")+exit_file);
|
||||
loadedDb = true;
|
||||
@@ -227,20 +229,17 @@ int main(int argc, char *argv[])
|
||||
// run script
|
||||
// ignore any extra positional args (historical)
|
||||
|
||||
if (verbose)
|
||||
std::cout<<"# Begin "<<argv[optind]<<"\n";
|
||||
verbose_out(REM, std::string("# Begin ") + argv[optind]);
|
||||
errIf(iocsh(argv[optind]),
|
||||
std::string("Error in ")+argv[optind]);
|
||||
if (verbose)
|
||||
std::cout<<"# End "<<argv[optind]<<"\n";
|
||||
verbose_out(REM, std::string("# End ") + argv[optind]);
|
||||
|
||||
epicsThreadSleep(0.2);
|
||||
ranScript = true; /* Assume the script has done any necessary initialization */
|
||||
}
|
||||
|
||||
if (loadedDb) {
|
||||
if (verbose)
|
||||
std::cout<<"iocInit()\n";
|
||||
verbose_out(CMD, "iocInit()");
|
||||
if(iocInit()) {
|
||||
std::cerr<<ERL_ERROR " during iocInit()"<<std::endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user