Difference between revisions of "RRM 3-14 Array Subroutine"

From EPICSWIKI
Line 170: Line 170:
internally by record processing and do not concern the user.  
internally by record processing and do not concern the user.  


<tr><td>NEA,..., NEU<td>
<tr><td>NEA,..., NEU<td>Num. elements in field<td>Num. elements in field


<tr><td>NEVA,..., NEVU<td>
<tr><td>NEVA,..., NEVU<td>Num. elements in field<td>Num. elements in field
</table>
</table>



Revision as of 19:46, 10 September 2009

aSub - Array Subroutine

The aSub record is a variant of the 'sub' (subroutine) record with array-valued input and output fields, whose types are user specifiable at database-configure time, and associated input and output links.

The routine to be called at process time can be changed dynamically after the database has been loaded. The name of the routine can either be fetched in over a link from another record or written directly into the SNAM field.

The user can configure the record to decide when events will be posted for the output fields. This can be: Never, Always or just when any element of an array changes value.

The VAL field holds the value returned from the routine called during record processing.

Field Summary

FieldTypeDCTInitialAccessModifyRecProcMonitorPP


VALLONGNo0YesYesYesNo
OVALLONGNo0YesYesNoNo
SADRLONGNo0YesNoYesNo
OSADLONGNo0YesNoNoNo
LFLGRECCHOICEYesIgnoreYesYesNoNo
EFLGRECCHOICEYesAlwaysYesYesNoNo
SUBLINLINKYes0NoNoNANo
INAMSTRINGYesNullYesNoNoNo
SNAMSTRINGYesNullYesYesNoNo
ONAMSTRINGYesNullYesNoNoNo
STYPSHORTNo0YesNoNoNo
BRSVGBLCHOICEYes0YesYesNoYes
PRECSHORTYes0YesYesNoNo
INPAINLINKYes0NoNoNANo
INPBINLINKYes0NoNoNANo
........................
INPUINLINKYes0NoNoNANo
ANOACCESSNo0NoYesNoNo
BNOACCESSNo0NoYesNoNo
........................
UNOACCESSNo0NoYesNoNo
FTAGBLCHOICEYesDOUBLEYesNoNoNo
FTBGBLCHOICEYesDOUBLEYesNoNoNo
........................
FTUGBLCHOICEYesDOUBLEYesNoNoNo
NOAULONGYes1YesNoNoNo
NOBULONGYes1YesNoNoNo
........................
NOUULONGYes1YesNoNoNo
OUTAOUTLINKYes0NoNoNANo
OUTBOUTLINKYes0NoNoNANo
........................
OUTUOUTLINKYes0NoNoNANo
VALANOACCESSNo0NoYesYesNo
VALBNOACCESSNo0NoYesYesNo
........................
VALUNOACCESSNo0NoYesYesNo
OVLANOACCESSNo0NoNoNoNo
OVLBNOACCESSNo0NoNoNoNo
........................
OVLUNOACCESSNo0NoNoNoNo
FTVAGBLCHOICEYesDOUBLEYesNoNoNo
FTVBGBLCHOICEYesDOUBLEYesNoNoNo
........................
FTVUGBLCHOICEYesDOUBLEYesNoNoNo
NOVAULONGYes1YesNoNoNo
NOVBULONGYes1YesNoNoNo
........................
NOVUULONGYes1YesNoNoNo
TOVAULONGYes0YesNoNoNo
TOVBULONGYes0YesNoNoNo
........................
TOVUULONGYes0YesNoNoNo
NEAULONGYes1YesNoNoNo
NEBULONGYes1YesNoNoNo
........................
NEUULONGYes1YesNoNoNo
NEVAULONGYes1YesNoNoNo
NEVBULONGYes1YesNoNoNo
........................
NEVUULONGYes1YesNoNoNo

Field Descriptions

NameSummaryDescription
VALValue returned from process routineThis field holds the value returned from the user defined

process routine.

OVALOld VALPrevious VAL, used to decide when to post events.
SADRSubroutine Address The address of the routine called at process time.
OSADOld SADRPrevious SADR, used to decide when to post events.
LFLGLink FlagTells the record whether to read or ignore the SUBL link. If

the value is READ, then the name of the subroutine to be called at process time is read from SUBL. If the value is IGNORE, the name of the subroutine is that currently held in SNAM.

EFLGEvent FlagTells the record when to post events on the output fields

VALA,...,VALU. If the value is NEVER, events are never posted. If the value is ALWAYS, events are posted everytime the record processes. If the value is ON CHANGE, events are posted when any element of an array changes value. Archiving and Value Change events are posted in each case.

SUBLSubroutine LinkWhere to get the subroutine name from.
INAMInitialisation Routine This is the name of the initialisation routine to be called once,

at iocInit.

SNAMProcess RoutineThis is the name of the routine to be called when the record

processes. Note, this can be overwritten by the SUBL link, if LFLG is set to READ.

ONAMProcess RoutineOld process subroutine name.
STYPSubroutine Symbol Type Filled in by record processing.
BRSVSeverity for a subroutine return value less than 0. Specifies the Alarm severity.
PRECDisplay Precision Specifies the number of decimal places with which to display

the values of the fields VALA,...,VALU.

INPA,..., INPUInput Link A,..., Input Link U The input links from where the values of A,...,U are fetched

during record processing.

A,...,UInput Fields The input fields which hold the scalar values or arrays fetched

in across the input links INPA,...,INPU.

FTA,..., FTUField Type of A Field Type of U Field types of the input values. These can be CHAR,

STRING, DOUBLE, LONG, etc.

NOA..., NOUNumber of elements in A,.. Number of elements in U The number of elements in each input field. Default is 1

(scalar value). An array is specified by setting this field to greater than 1.

OUTA,..., OUTUOutput Link A,.. Output Link U The output links on which the scalars or arrays located at

VALA,...,VALU are placed during record processing.

VALA,.., VALUOutput Fields The output fields which hold the scalar values or arrays

pushed out across the output links OUTA,...,OUTU.

FTVA,..., FTVUField Type of VALA Field Type of VALU Field types of the output values. These can be CHAR,

STRING, DOUBLE, LONG, etc.

OVLA,.., OVLUPrevious Outputs The previous values of the outputs. These are used to decide

when to post events if EFLG is set to ON CHANGE.

NOVA,..., NOVUNumber of elements in VALA Number of elements in VALU The number of elements in each output field. Default is 1

(scalar value). An array is specified by setting this field to greater than 1.

TOVA,..., TOVUTotal Number of bytes in VALA Total Number of bytes in VALU The total number of bytes in each output field. These are used

internally by record processing and do not concern the user.

NEA,..., NEUNum. elements in fieldNum. elements in field
NEVA,..., NEVUNum. elements in fieldNum. elements in field

Record Support Routines

init_record

This routine is called twice at iocInit. On the first call it does the following:

  • Look for any user functions defined in the fields UFA-UFU and UFVA-UFVU. If they have been defined, call them to get the size of the structure which is to passed across the link. If they are not defined, no routine is called.
  • Calloc sufficient space to hold the number of input scalars and/or arrays defined by the settings of the fields FTA-FTU and NOA-NOU. If a user function has been defined, calloc the space required by the multiple of the number of elements and size returned from the user function.
  • Calloc sufficient space to hold the number of output scalars and/or arrays defined by the settings of the fields FTVA-FTVU and NOVA-NOVU. If a user function has been defined, calloc the space required by the multiple of the number of elements and size returned from the user function. For the output fields, also calloc space to hold the previous value of a field. This is required when the decision is made on whether or not to post events.

On the second call, it does the following:

  • Initializes SUBL if it is a constant link.
  • Initializes each constant input link.
  • If the field INAM is set, look-up the address of the routine and call it.
  • If the field LFLG is set to IGNORE and SNAM is defined, look-up the address of

the process routine.

process

This routine implements the following algorithm:

  • If PACT is FALSE, perform normal processing
  • If PACT is TRUE, perform asynchronous-completion processing

Normal processing:

  • Set PACT to TRUE.
  • If the field LFLG is set to READ, get the subroutine name from the SUBL link. If the name is not NULL and it is not the same as the previous subroutine name, lookup the subroutine address. Set the old subroutine name, ONAM, equal to the current name, SNAM.
  • Fetch the values from the input links.
  • Set PACT to FALSE
  • If all input-link fetches succeeded, call the routine specified by SNAM.
  • Set VAL equal to the return value from the routine specified by SNAM.
  • If the SNAM routine set PACT to TRUE, then return. In this case, we presume the routine has arranged that process will be called at some later time for asynchronous completion.
  • Set PACT to TRUE.
  • Write the output values using the output links.
  • Get the time of processing and put it into the timestamp field.
  • If VAL has changed, post a change-of value and log event for this field. If EFLG is set to ALWAYS, post change-of-value and log events for every output field. If EFLG is set to ON CHANGE, post change-of-value and log events for every output field which has changed. In the case of an array, an event will be posted if any single element of the array has changed. If EFLG is set to NEVER, no change-of-value or log events are posted for the output fields.
  • Process the record on the end of the forward link, if one exists.
  • Set PACT to FALSE.

Asynchronous-completion processing:

  • Call the routine specified by SNAM.
  • Set VAL equal to the return value from the routine specified by SNAM.
  • Set PACT to TRUE.
  • Write the output values using the output links.
  • Get the time of processing and put it into the timestamp field.
  • If VAL has changed, post a change-of value and log event for this field. If EFLG is set to ALWAYS, post change-of-value and log events for every output field. If EFLG is set to ON CHANGE, post change-of-value and log events for every output field which has changed. In the case of an array, an event will be posted if any single element of the array has changed. If EFLG is set to NEVER, no change-of-value or log events are posted for the output fields.
  • Process the record on the end of the forward link, if one exists.
  • Set PACT to FALSE.

get_value

Fills in the values of struct valueDes so that they refer to VAL.

get_precision

Sets the display precision to the value of PREC for any of the output fields VALA,..., VALU. This routine could be called for any of these fields.

cvt_dbaddr

The purpose of this routine is to fill in the struct dbAddr for the field of the record for which it has been called. Typically, the number of elements in the field, the field type and the size of the field will be set in this routine. For arrays, this record support routine is essential.

get_array_info

This routine returns the current number of elements and the offset of the first value for an array. For this record, the offset field is always 0.

put_array_info

This routine is called after new values have been placed in an array.

special

This routine is called whenever the SNAM field changes. It is called twice, once before the change and once after. On the first call, the routine simply returns. On the second call, after SNAM has changed, it implements the following algorithm:

  • If LFLG is set to IGNORE and SNAM is not NULL, then look-up the address of the routine specified by SNAM. Set the SADR field equal to the subroutine address.
  • Post change-of-value and log events for the SADR field, if this has changed.

Use of the aSub Record

Two aSub records can be used to transfer data between one another. These records can be located in the same IOC or in separate IOC's. The data can be a scalar of any type, an array, a user defined structure or an array of user defined structures.

Let us name the aSub record which is sending data, record A, and the aSub record which is receiving the data, record B. There are some fields which must be set-up correctly in each record before the data transfer can occur without error. The output field types and the number of elements in the output fields of record A must match the input field types and number of elements in the input fields of record B. Thus, combining the two records is rather like a jigsaw. Let us take an example.

If 5 doubles are to be passed from the VALA field of record A to the A field of record B, then the following settings are necessary:

Record A should have: FTVA = DOUBLE, NOVA = 5. Record B should have: FTA = DOUBLE, NOA = 5.


Dynamically Changing the User Routine called during Record Processing

The aSub record allows the user to dynamically change which routine is called when the record processes. This can be done in two ways:

  • The LFLG field can be set to READ so that the name of the routine is read from the SUBL link. Thus, whatever is feeding this link can change the name of the routine before the aSub record is processed. In this case, the record looks in the symbol table for the symbol name whenever the name of routine fetched from the link changes.
  • The LFLG field can be set to IGNORE. In this case, the routine called during record processing is that specified in the SNAM field. Under these conditions, the SNAM field can be changed by a Channel Access write to that field. Thus, during development work, when it is often required to run a modified version of the routine, it will no longer be a requirement to reboot the IOC and reload the database. A new routine will be called during record processing if the routine is loaded with the vxWorks ld command, and cau is used to put the name of the routine into the record's SNAM field. After the SNAM field has been changed, the record automatically looks up the symbol name in the symbol table. Note that, if the same routine name is used, this is not a problem. The record finds the latest version of the code which has been loaded. Obviously, one needs to take care of the amount of memory used in the system, if the vxWorks unld command is never used.