6. Variables within e3¶
Lesson Overview¶
In this lesson, you will learn how to do the following:
Understand variables and parameters within an IOC.
Run commands to access variables and parameters from within an IOC.
Understand EPICS and e3 environment variables used when a module is configured.
Combine variable commands to access path or files of any module within an IOC.
Running an IOC¶
The following variables are defined when an IOC is running from within startup and iocsh scripts.
General iocsh
variables¶
REQUIRE_IOC
: A unique name of the IOC that can be used to track certain variables in a certain IOC. For example, an e3 IOC will generate on startup a number of PVs of the form$(REQUIRE_IOC):MODULES
that list the modules that are loaded in a given IOC. :::{note} IfIOCNAME
is defined in the environment prior to the IOC starting, thenREQUIRE_IOC
will be a (possibly truncated) copy of that. Otherwise, it will be a name which depends on the process ID for the running IOC and so will not be consistent from one run to the next of the IOC. :::E3_CMD_TOP
: The absolute path to the startup script (cmd file), if one exists.E3_IOCSH_TOP
: The absolute path to whereiocsh
was executed from; equivalent to runningpwd
.IOCSH_PS1
: The IOC Prompt String. Defaults to$HOSTNAME-$PID >
.
Variables created by require¶
Whenever an e3 module is dynamically loaded, require generates a number of
module-specific variables that are useful in scripts. For mrfioc2
these would
be
mrfioc2_VERSION
- The version ofmrfioc2
that was loaded.mrfioc2_DIR
- The absolute path wheremrfioc2
is located. Useful for loading.iocsh
snippets and other files installed with the module.mrfioc2_DB
- The absolute path where the database, template, protocol, and substitutions files formrfioc2
have been installed.
Let us see these in action. Copy the following into a new ch6.cmd
file.
require iocstats
iocInit
epicsEnvShow E3_IOCSH_TOP
epicsEnvShow E3_CMD_TOP
epicsEnvShow iocstats_DIR
epicsEnvShow iocstats_VERSION
epicsEnvShow iocstats_DB
[iocuser@host:e3training/workbook]$ iocsh ch6.cmd
# --- snip snip ---
Starting iocInit
############################################################################
## EPICS R7.0.6.1-E3-7.0.6.1-patch
## Rev. 2021-03-15T09:48+0100
############################################################################
iocRun: All initialization complete
epicsEnvShow E3_IOCSH_TOP
E3_IOCSH_TOP=/home/iocuser/data/git/e3.pages.esss.lu.se
epicsEnvShow E3_CMD_TOP
E3_CMD_TOP=/home/iocuser/data/git/e3.pages.esss.lu.se
epicsEnvShow iocstats_DIR
iocstats_DIR=/epics/base-7.0.6.1/require/4.0.0/siteMods/iocstats/3.1.16+0/
epicsEnvShow iocstats_VERSION
iocstats_VERSION=3.1.16+0
epicsEnvShow iocstats_DB
iocstats_DB=/epics/base-7.0.6.1/require/4.0.0/siteMods/iocstats/3.1.16+0/db/
# --- snip snip ---
As stated before, these variables are needed if you want to use database or
protocol files that have been installed with a given module. For example,
StreamDevice uses a variable STREAM_PROTOCOL_PATH
when searching for
.proto
files, and so a common idiom in a startup script is a line such as
epicsEnvSet("STREAM_PROTOCOL_PATH", "$(mymodule_DB)")
Note however that if a module depends on StreamDevice, then this variable is automatically set by require when the module is loaded.
Exercise:
Modify the above startup script to add some other modules, and look at the resulting paths. For example, load
stream
and see what pathsmodule_DIR
are available within the IOC shell.
EPICS variables, parameters, and environment variables¶
You can see EPICS parameters and environment variables from within an IOC using
epicsParamShow
(or epicsPrtEnvParams
) and epicsEnvShow
.
localhost-15716 > epicsParamShow
localhost-15716 > epicsEnvShow
Exercises:
How do we print only one variable - for example
TOP
?What is the difference between
$(TOP)
and${TOP}
? Is it the same inside of the IOC shell as in UNIX?
In the IOC shell, run var
. This provides a list of variables that are defined
within the IOC environment; these can be modified or set by running var <variable> <value>
.
localhost-15716 > var
CASDEBUG = 0
PDBProviderDebug = 0
asCaDebug = 0
asCheckClientIP = 0
atExitDebug = 0
boHIGHlimit = 100000
boHIGHprecision = 2
calcoutODLYlimit = 100000
calcoutODLYprecision = 2
callbackParallelThreadsDefault = 2
dbAccessDebugPUTF = 0
dbBptNotMonotonic = 0
dbConvertStrict = 0
dbJLinkDebug = 0
dbQuietMacroWarnings = 0
dbRecordsAbcSorted = 0
dbRecordsOnceOnly = 0
dbTemplateMaxVars = 100
dbThreadRealtimeLock = 1
exprDebug = 0
histogramSDELprecision = 2
lnkDebug_debug = 0
logClientDebug = 0
pvaLinkNWorkers = 1
requireDebug = 0
runScriptDebug = 0
seqDLYlimit = 100000
seqDLYprecision = 2
Note that there are four UNIX commands that can be used from within the IOC
shell: date
, pwd
, cd
, and echo
.
Note
For more information about EPICS functions, check out the App Developers Guide.
As described in the design documentation,
require is used to dynamically load EPICS modules during the startup of an
IOC. This is what the line require iocstats
does above; iocstats
can be
replaced with any other EPICS module that is installed in your e3 environment.
First, let us start up an IOC that has iocstats loaded in it as before. You can do this in one of two ways:
[iocuser@host:~]$ iocsh ch6.cmd
or
[iocuser@host:~]$ iocsh -r iocstats
Exercise:
What is the difference between these two commands? Take a look at the output of the IOC shell as it starts up.
As a second experiment, try to load iostats a second time as follows.
[iocuser@host:~]$ iocsh -r iocstats -r iocstats
# --- snip snip ---
require iocstats
Module iocstats version 3.1.16+4 found in /epics/base-7.0.6.1/require/4.0.0/siteMods/iocstats/3.1.16+4/
Module iocstats depends on calc 3.7.4+1
# --- snip snip ---
Calling function iocstats_registerRecordDeviceDriver
Loading module info records for iocstats
require iocstats
Module iocstats version 3.1.16+4 already loaded
# --- snip snip ---
Nothing happens due to the fact that require will only load a module a single
time. It is possible to have multiple configured instances of a module (for
example, an IOC can control multiple copies of the same device) by loading the
appropriate .iocsh
snippet with different parameters, but that is a topic for
another time.
Next, in the running IOC, let us try to load the recsync module. Run
localhost-15965 > require recsync
Error! Modules can only be loaded before iocIint!
require cannot load modules after iocInit
has been called. This is due to the
fact that a lot of setup and initialisation must be done before the call to
iocInit
.
It can be useful to see a bit of extra information when require is loading a
module to understand exactly where it is coming from (and to see why it loads
the version that it does). Create a new file, ch6-2.cmd
, with the following
contents:
var requireDebug 1
require recsync
and then load it with iocsh
:
[iocuser@host:~]$ iocsh ch6-2.cmd
# --- snip snip ---
iocshLoad 'ch6-2.cmd',''
var requireDebug 1
require recsync
require: putenv("T_A=linux-x86_64")
require: putenv("EPICS_HOST_ARCH=linux-x86_64")
require: putenv("EPICS_RELEASE=7.0.6")
require: putenv("OS_CLASS=Linux")
require: versionstr = ""
require: module="recsync" version="(null)" args="(null)"
require: searchpath=/epics/base-7.0.6.1/require/4.0.0/siteMods
require: no recsync version loaded yet
require: trying /epics/base-7.0.6.1/require/4.0.0/siteMods
require: found directory /epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/
require: checking version 1.4.0+0 against required (null)
require: compareVersions(found=1.4.0+0, request=(null))
require: compareVersions: MATCH empty version requested
require: recsync 1.4.0+0 may match (null)
require: directory /epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/lib/linux-x86_64/
exists
require: recsync 1.4.0+0 looks promising
Module recsync version 1.4.0+0 found in /epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/
require: looking for dependency file
require: file /epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/lib/linux-x86_64/recsync.dep
exists, size 31 bytes
require: parsing dependency file /epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/lib/linux-x86_64/recsync.dep
require: looking for library file
require: file /epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/lib/linux-x86_64/librecsync.so
exists, size 114720 bytes
Loading library /epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/lib/linux-x86_64/librecsync.so
Loaded recsync version 1.4.0+0
require: compare requested version (null) with loaded version 1.4.0+0
require: compareVersions(found=1.4.0+0, request=(null))
require: compareVersions: MATCH empty version requested
require: file /epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/dbd/recsync.dbd
exists, size 207 bytes
Loading dbd file /epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/dbd/recsync.dbd
Calling function recsync_registerRecordDeviceDriver
require: registerModule(recsync,1.4.0+0,/epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/)
require: putenv("MODULE=recsync")
require: putenv("recsync_VERSION=1.4.0+0")
require: putenv("recsync_DIR=/epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/")
require: putenv("SCRIPT_PATH=.:/epics/base-7.0.6.1/require/4.0.0/siteMods/recsync/1.4.0+0/:/epics/base-7.0.6.1/require/4.0.0/")
Loading module info records for recsync
# --- snip snip ---
As you can see, there is a lot of output that describes, for example, the search process for the requested module as well as information about which environment variables are set during the loading process.
It should be noted that requireDebug
(as its name suggests) is a variable
defined within the require module. Other modules have similar functionality.
Exercise:
Find at least one other modules installed in the core specification that has a debug variable.
Note
Like any well-behaved shell, you should be able to use the up/down arrows to re-run previous commands.
Building a module or an application¶
Back in Chapter 3 we looked at the two e3 variables
E3_MODULE_VERSION
and EPICS_MODULE_TAG
. As you will see, there are many
more environment variables that are used by e3 for configuring and installing
modules.
e3 environment variables¶
You can print out all environment variables of a module with the rule make vars
:
[iocuser@host:e3-caputlog]$ make vars
------------------------------------------------------------
>>>> Current EPICS and E3 Environment Variables <<<<
------------------------------------------------------------
E3_MODULES_INSTALL_LOCATION = /epics/base-7.0.6.1/require/4.0.0/siteMods/caputlog/3.7.0+0
E3_MODULES_INSTALL_LOCATION_BIN = /epics/base-7.0.6.1/require/4.0.0/siteMods/caputlog/3.7.0+0/bin
E3_MODULES_INSTALL_LOCATION_DB = /epics/base-7.0.6.1/require/4.0.0/siteMods/caputlog/3.7.0+0/db
E3_MODULES_INSTALL_LOCATION_INC = /epics/base-7.0.6.1/require/4.0.0/siteMods/caputlog/3.7.0+0/include
E3_MODULES_INSTALL_LOCATION_LIB = /epics/base-7.0.6.1/require/4.0.0/siteMods/caputlog/3.7.0+0/lib
E3_MODULES_PATH = /epics/base-7.0.6.1/require/4.0.0/siteMods
E3_MODULE_MAKEFILE = caPutLog.Makefile
E3_MODULE_MAKE_CMDS = make -C caPutLog -f caPutLog.Makefile LIBVERSION="3.7.0+0"
PROJECT="caputlog"
EPICS_MODULES="/epics/base-7.0.6.1/require/4.0.0/siteMods"
EPICS_LOCATION="/epics/base-7.0.6.1" BUILDCLASSES="Linux"
E3_SITEMODS_PATH="/epics/base-7.0.6.1/require/4.0.0/siteMods"
caputlog_E3_GIT_DESC="7.0.6.1-4.0.0/3.7.0-20f7c82-20220210T112335-2-gaab774b"
caputlog_E3_GIT_STATUS="[ ]"
caputlog_E3_GIT_URL="git@gitlab.esss.lu.se:e3/wrappers/core/e3-caPutLog.git"
E3_MODULE_NAME = caputlog
E3_MODULE_SRC_PATH = caPutLog
E3_MODULE_VERSION = 3.7.0+0
E3_REQUIRE_CONFIG = /epics/base-7.0.6.1/require/4.0.0/configure
E3_REQUIRE_TOOLS = /epics/base-7.0.6.1/require/4.0.0/tools
EPICS_MODULE_NAME = caPutLog
EPICS_MODULE_TAG = R3.7
EPICS_SHORT_VERSION = 7.0.6.1
EPICS_VERSION_NUMBER = 7.0.6.1
EPICS_VERSION_STRING = "EPICS Version 7.0.6.1"
EXPORT_VARS = E3_MODULES_INSTALL_LOCATION_LIB TEMP_CELL_PATH EPICS_HOST_ARCH EPICS_BASE
MSI E3_MODULE_NAME E3_MODULE_VERSION E3_SITEMODS_PATH E3_REQUIRE_MAKEFILE_INPUT_OPTIONS
E3_REQUIRE_NAME E3_REQUIRE_CONFIG E3_REQUIRE_DB E3_REQUIRE_LOCATION
E3_REQUIRE_DBD E3_REQUIRE_VERSION E3_REQUIRE_TOOLS E3_REQUIRE_INC E3_REQUIRE_LIB
E3_REQUIRE_BIN QUIET
MSI = /epics/base-7.0.6.1/bin/linux-x86_64/msi
REQUIRE_CONFIG = /epics/base-7.0.6.1/require/4.0.0/configure
Many of these variables fall into one of several different categories: EPICS environment variables, e3 environment variables, and e3 module-related variables.
e3 environment variables¶
These are variables generated by require or EPICS base and are used to reference important paths for modules and for builds.
EPICS_*VERSION*
: Version of EPICS baseE3_MODULES_PATH
: Installation path for modules.E3_REQUIRE_CONFIG
: require configure path.E3_REQUIRE_TOOLS
: require tools path.REQUIRE_CONFIG
: require configuration path used for by module configurations. It is typically the same asE3_REQUIRE_CONFIG
, but is defined beforeE3_REQUIRE_CONFIG
.
e3 module/application core environment variables¶
These are variables that related to a given e3 module. Most of these are set in
CONFIG_MODULE
, and some of them are generated by require.
The following are set in CONFIG_MODULE
in the wrapper directory.
EPICS_MODULE_NAME
: The module name of the community module. See alsoE3_MODULE_NAME
.EPICS_MODULE_TAG
: A string representing a valid git reference to the version of the module that will be built. :::{note} This can be any valid git reference, but best practice is that this is a commit hash or even better a tag. Mutable references should be avoided. :::E3_MODULE_NAME
: The module name used require to install and to load the module. :::{note} This is usually the same asEPICS_MODULE_NAME
. However, there are two additional restrictions:Only lower-case characters, numbers, and underscores are allowed.
The resulting string must be a valid C identifier :::
E3_MODULE_SRC_PATH
: Location of the module code within the wrapper repository.E3_MODULE_VERSION
: Module version used for installing and loading the module.E3_MODULE_MAKEFILE
: Name of the module/application makefile.
The following variables are set by require.
E3_MODULES_INSTALL_LOCATION
: Parent path to installation directories.E3_MODULES_INSTALL_LOCATION_BIN
: Binary installation path.E3_MODULES_INSTALL_LOCATION_DB
: Database installation path.E3_MODULES_INSTALL_LOCATION_INC
: Include installation path.E3_MODULES_INSTALL_LOCATION_LIB
: Library installation path.
Assignments¶
Use the command
iocsh -r asyn
to load asyn into a fresh IOC. From the IOC shell, print out all of the database files that are included with asyn. Hint: There is a command that lets you run an external shell command within an IOC. See chapter 2.Can you find out which file it is that allows us to run
make vars
within the e3 building system? Try adding the--debug
flag when executingmake
.