Creating a SoftIoc - acquaman/acquaman GitHub Wiki
SoftIocs host EPICs PVs in a distributed fashion. Each PV can contain a set of subfields, which themselves can either be pure data, or PVs themselves. Each PV simply stores some state of a control, and a softIoc may host a database file which contains a number of PVs (more often than not related to each other in some way). In order to create a softIoc file for a set of PVs then, we are simply going to create a database file, and then invoke the EPICs softIoc command with the created database.
Create a file using your favourite text editor with the name BL<number>-ID-<identifier>-<title>.db
where <number>
is the beamline identifying number, <identifier>
is a unique identifier for that beamline, and <title>
is some title that describes the common link between the PVs to contained. For example the SGM hexapod PV db file is named BL1611-ID-1-HexapodAddon.db
.
Within this file a number of PVs will need to be created. There is often a semi standard format for common types of PV, which means if they follow this structure interfacing with them in Acquaman is much easier. These include:
- A simple read PV ~ Just contains a feedback PV
- A read/write PV ~ Contains a setpoint PV which is written to, and a feedback PV which is read from
- PV with status ~ Contains a setpoint PV which is written to, a feedback PV which is read from, and a status PV which enumerates through standard values representing states (see below).
Each of these PVs is given a unique name, which also follows a standard format:
Type | Style | Example | EPICs field type |
---|---|---|---|
setpoint | <device_type><beamline_number>-<room_number>-I10-<device_identifier>:<component>:<units> |
HXPD1611-4-I10-01:X:mm | ao |
feedback | <device_type><beamline_number>-<room_number>-I10-<device_identifier>:<component>:<units>:fbk |
HXPD1611-4-I10-01:X:mm:fbk | ao |
status | <device_type><beamline_number>-<room_number>-I10-<device_identifier>:<component>:status |
HXPD1611-4-I10-01:X | mbbi |
Each of these types are created using one of two of EPICs' standard field types:
- ao ~ Analog output. Used for storing double values.
- mbbi ~ Multi bit binary input. Used for representing an enumeration.
NOTE: There are many more EPICs field types, and information for them can be found here
The analog output field stores a double precision floating point value, which can be read from and written to. It contains a number of sub-field types:
Type | Description | Example |
---|---|---|
VAL | Value field. Stores the actual double value. Takes the default value to which the field will be initialized on starting the softIoc. |
field( VAL, "0" ) - A VAL field which will be initialized to 0 |
DRVH | Drive high. A ceiling value for the VAL field. Writing a higher value than this to the VAL field will cause it to take on the value of DRVH |
field( DRVH, "17.0001") - A DRVH field which will be initialized to 17.0001. |
DRVL | Drive low. A floor value for the VAL field. Writing a lower value than this to the VAL field will cause it to take on the value of DRVL |
field( DRVL, "-17.0001" ) - A DRVL field which will be initialized to -17.0001. |
EGU | Engineering units. Denotes the units in which the VAL field is measured |
field( EGU "mm" ) - An EGU field which will be initialized to mm. |
MDEL | Signaling behaviour. A value of -1 indicates that a signal to indicate editing should be emitted even when the same value has been written. This should be included in all records | field( MDEL, "-1" ) |
Analog output records for the setpoint and feedback can therefore be created with the following format:
record( ao, "HXPD1611-4-I10-01:Z:mm" )
{
field( VAL, "0" )
field( DRVH, "6.5001" )
field( DRVL, "-6.5001" )
field( EGU, "mm" )
field( MDEL, "-1" )
}
A setpoint record for a PV with the name HXPD1611-4-I10-01:X:mm
which will be initialized with a VAL of 0, a DRVH of 6.5001, a DRVL of -6.5001, EGUs of mm and ....
record( ao, "HXPD1611-4-I10-01:Z:mm:fbk" )
{
field( VAL, "0" )
field( EGU, "mm" )
}
A feedback record for a PV with the name 'HXPD1611-4-I10-01"x"mm:fbk` which will be initialized with a VAL of 0 and EGUs of mm.
The mbbi fields store a set of enumerated values which the field can take, and the string equivalents which these values represent. It contains a number of sub-field types, including:
Type | Description | Example |
---|---|---|
VAL | Value. The value which the enumerator currently stores. |
field( VAL, "0" ) - A VAL field which will be initialized to 0 |
ZRST | Zero String. The string which a value of zero represents. |
field( ZRST, "MOVE DONE" ) - A ZRST field which denotes that the ZRVL field corresponds to the string "MOVE DONE". |
ZRVL | Zero Value. The value which the zeroth enumerated value corresponds with, in hexadecimal |
field( ZRVL, "0x00" ) - A ZRVL field which indicates that the zeroth position of the enumerator corresponds with the value 0. |
|
Each of these nString and nValue fields are repeated up until 15, allowing for a maximum enumeration of 16 different values which the field can take. The names of these fields are as follows:
Value Field Name | String Field Name | Enumeration Position |
---|---|---|
ZRVL | ZRST | Zero |
ONVL | ONST | One |
TWVL | TWST | Two |
THVL | THST | Three |
FRVL | FRST | Four |
FVVL | FVST | Five |
SXVL | SXST | Six |
SVVL | SVST | Seven |
EIVL | EIST | Eight |
NIVL | NIST | Nine |
TEVL | TEST | Ten |
ELVL | ELST | Eleven |
TVVL | TVST | Twelve |
TTVL | TTST | Thirteen |
FTVL | FTST | Fourteen |
FFVL | FFST | Fifteen |
mbbi records can therefore be created for the status PV with the following format:
record( mbbi, "HXPD1611-4-I10-01:X:status" )
{
field( VAL, "0" )
field( ZRST, "MOVE DONE" )
field( ZRVL, "0x00" )
field( ONST, "MOVE ACTIVE" )
field( ONVL, "0x01" )
field( TWST, "AT LIMIT" )
field( TWVL, "0x02" )
field( THST, "FORCED STOP" )
field( THVL, "0x03" )
field( FRST, "ERROR" )
field( FRVL, "0x04" )
}
A status PV which can take on the values MOVE DONE, MOVE ACTIVE, AT LIMIT, FORCED STOP and ERROR
Therefore for a PV which is to have a setpoint, feedback and status the db file would contain the following:
record( ao, "HXPD1611-4-I10-01:Z:mm" )
{
field( VAL, "0" )
field( DRVH, "6.5001" )
field( DRVL, "-6.5001" )
field( EGU, "mm" )
field( MDEL, "-1" )
}
record( ao, "HXPD1611-4-I10-01:Z:mm:fbk" )
{
field( VAL, "0" )
field( EGU, "mm" )
}
record( mbbi, "HXPD1611-4-I10-01:Z:status" )
{
field( VAL, "0" )
field( ZRST, "MOVE DONE" )
field( ZRVL, "0x00" )
field( ONST, "MOVE ACTIVE" )
field( ONVL, "0x01" )
field( TWST, "AT LIMIT" )
field( TWVL, "0x02" )
field( THST, "FORCED STOP" )
field( THVL, "0x03" )
field( FRST, "ERROR" )
field( FRVL, "0x04" )
}
NOTE: A single db file could contain multiple records for related PVs (in this above example it could also contain the X, Y, U, V and W fields for the hexapod also).
Now that a database file has been created it is possible to host that PV over the network by invoking the epics softIoc command with the -d parameter and the db filename:
softIoc -d BL1611-ID-1-HexapodAddon.db
The PVs contained within the db file will then be available for the length of time which the softIoc process is active.
Access to the PVs served by the softIoc are available across VLans, however when moving from one VLan to the next it has to cross an EPICs gateway. Passing through the EPICs gateway introduces an additional point of failure, and as such it is highly recommended to host the PVs from within the VLan from which they are likely to be accessed.
Testing of PVs can be done with the caget, caput and camonitor commands.
Command | Description | Example |
---|---|---|
caget | Obtain the value stored in the provided PV |
caget HXPD1611-4-I10-01:Z:mm - Obtain the value stored in the provided PV |
caput | Writes a value to the provided PV |
caput HXPD1611-4-I10-01:Z:mm 0.5 - Write the value of 0.5 to the provided PV |
camonitor | Listens for changes to the provided PV |
camonitor HXPD1611-4-I10-01:Z:mm:status - Outputs the altered value of the provided PV each time it changes |