IOC 101
What is an IOC
For a basic description, see Epics 101
How does one create an IOC?
There are multiple ways to create an IOC, but no one does it from scratch:
The EPICS base approach
It creates a bare bones IOC but requires more knowledge of the EPICS build system to get started:
makeBaseApp.pl
- Must be run multiple times
- Creates IOC contents in the current directory
- synApps support needs to be added manually
The synApps approach
It is based on the xxx module and designed to give you a usable IOC with as little effort as possible:
mkioc
- A single command leaves you with an IOC you can build:
$/APSshare/bin/mkioc -n -f -s 6-2-1 kmp Usage: mkioc [options] ioc_name -h print this message -v print the version -f create a fresh git repo without an xxx remote -g default to creating gitlab repo and pushing ioc -n default to not creating gitlab repo and pushing ioc -s <version> use a specific synApps version
- Creates a top-level IOC directory in the current directory
- Common synApps support is included by default
- mkioc will ask you questions if you run it without options
Note: The BCDA convention is to name development IOCs using the developer's initials (here we will use either xxx or kmp).
IOC Layout
Overview
The IOC layout can be overwhelming and confusing to those who aren’t yet familiar with it. The EPICS build system creates many directories, making it harder to find the important directories.
Important files are often buried multiple directories down from the top-level. It is helpful to look at subsets of the IOC directory.
Note:
- build: building an IOC is the action generating the binary
bin/rhel#-x86_64/xxxApp
(plus other build products as described below) by using the commandmake
. - run: running an IOC is the action of running the binary along with a startup script of iocsh commands (usually called
st.cmd
)
Build configuration
Orange folders:
xxx/configure
:
- contains the files that specify which versions of EPICS base and EPICS modules should be used when building the IOC.
xxx/xxxApp/Db
:
- contains local databases (and associated autosave files) and protocol files used by the IOC.
xxx/xxxApp/src
:
- contains the Makefile that determines all of the software that gets built into the IOC binary. ; local sequence programs and other EPICS support that needs to be compiled go here.
Intermediate build directories
Grey folders:
The EPICS build system will generate O.
files (Common, EPICS HOST and TARGET architectures) in the configure, Db, and src directory. These directories are not needed after the IOC is built and can be removed with the make clean
command. If they are not removed, they can be safely ignored. It is highly unlikely that you will ever need to look at any of the files in them.
Build products
Red folders:
The EPICS build system creates top level bin, db, dbd, and lib directories:
xxx/bin/rehl8-x86_64
:
- contains the architecture-specific IOC binary (or munch file for VxWorks IOCs).
xxx/db
:
- contains installed database files which may or may not be used, since many IOCs reference the databases in the
Db
directory instead.
xxx/dbd
:
- contains a single database definition file to be loaded by the IOC.
xxx/lib/rehl8-x86_64
:
- contains architecture-specific files for EPICS modules, but should be empty for the IOC.
The build system creates an envPaths
file in the startup directory iocBoot/iocxxx
, which contains the locations of the modules defined in the RELEASE
file.
Startup directory
Green folders:
The iocxxx
directory is referred to as the startup directory. It contains the st.cmd
file, which is the runtime configuration for the IOC (i.e. what the IOC needs to know to start).
The IOC’s config is often broken into separate .iocsh
(or .cmd
) files so that support can be more easily commented out and to improve readability; substitutions
and iocsh
files usually reside in subdirectories to reduce clutter in the startup directory.
Startup scripts
Blue folders:
The top-level IOC directory xxx
contains scripts that start medm & caQtDM.
The softioc
subdirectory of the startup dir contains a bash script which simplifies managing the IOC on Linux.
Windows IOCs: the startup directory contains batch files to start the IOC.
Note: The startup directory can reside elsewhere.
How does support get into an IOC?
Quick overview
configure/RELEASE
:- Defines the locations of EPICS base and EPICS modules
- Often includes other RELEASE files
xxxApp/src/Makefile
:- Specifies which database definitions (dbd) to include
- Specifies which libraries should be included in the IOC binary
- Specifies which local code should be included in the IOC binary
- Libraries will not be included unless an associated dbd file is included
- The order of the libraries is important (single-pass linker)
iocBoot/iocxxx/st.cmd
:- The primary IOC config file that is sourced when the IOC is started
- Name can vary slightly based on how the IOC was created
Startup script st.cmd
Legacy IOCs often have monolithic st.cmd
files. Newer IOCs source more .iocsh
files from EPICS modules, which makes it easier to keep an IOC's config up-to-date.
< envPaths dbLoadDatabase("../../dbd/iocxxxLinux.dbd") iocxxxLinux_registerRecordDeviceDriver(pdbbase) ### Databases are loaded ### Drivers are initialized/configured here iocInit ### Sequence programs & autosave are started here dbl > dbl-all.txt date
We can break it up into 3 functional zones:
- Zone 1: before
dbLoadDatabase
. Usually this is where environment variables and paths are defined. - Zone 2: after
dbLoadDatabase
& beforeiocInit
. Databases can are loaded here (and can only be loaded here). - Zone 3: after
iocInit
. This zone is mostly empty thanks todoAfterIocInit
from thestd
module (sequence programs and autosave get initialized here, but the calls that do the initializing appear much earlier in the startup)
Note: PVs are available during iocInit
, even though the IOC is still starting up.
Autosave
autosave
is a synApps module that provides seamless reboot functionality. It is mostly automatic when mkioc is used.
PVs are saved while the IOC is running and loaded during iocInit
.
Autosaved values overwrite database defaults.
Databases with associated req files (_settings.req
) are automatically added to built_*.req
by autosaveBuild.
Multiple .sav
files can be created:
- Default:
.sav
&.savB
- actually restored
- Periodic:
.sav0
,.sav1
,.sav2
, …- overwritten cyclically
- Dated:
.sav-230109-134502
- written once at boot time
The 1st half of common.iocsh
sets up autosave:
https://github.com/epics-modules/xxx/blob/master/iocBoot/iocxxx/common.iocsh#L1-L46
How to build & clean a Linux IOC
- Confirm the RHEL version
uname -r → 3.10.0-1160.62.1.el7.x86_64
cat /etc/redhat-release → Red Hat Enterprise Linux Server release 7.9
- Set
EPICS_HOST_ARCH
environment variable- bash:
export EPICS_HOST_ARCH=rhel7-x86_64
- tcsh:
setenv EPICS_HOST_ARCH rhel7-x86_64
- bash:
- Initiate the build in the top-level IOC directory
make
- Remove intermediate build dirs (for the current
EPICS_HOST_ARCH
)make clean
- Remove all intermediate build dirs and top-level build directories
make distclean
- Show all make options
make help
Running an IOC
Use the script
Create an alias
Create an alias for the script (assuming PWD = IOC’s top-level dir)
$ alias kmp=${PWD}/iocBoot/iockmp/softioc/kmp.sh
$ kmp
Usage: kmp.sh {console|restart|run|start|caqtdm|medm|status|stop|usage}
Noteworthy arguments:
run
: Runs the IOC in the current terminal (doesn't return the command prompt). Useful for troubleshooting. Problematic for normal operation.start
: Runs the IOC in the background (returns the command prompt) using screen or procServ.status
: Tells you if the IOC is running and refuses to start if it is.
Note:
- Use the full path to the IOC’s start script so the alias can be run from any directory (bash syntax shown).
EPICS_HOST_ARCH
needs to still be set otherwise the IOC will not start (unless theEPICS_HOST_ARCH
is hard-coded in the start script).
Start caQtDM
kmp caqtdm &
Note: the ampersand is needed for synApps_6_2_1 IOCs, but it won’t be needed in the future because it was added to the start_caQtDM_xxx
script.
Start the IOC
Starts the IOC in the background (using screen or procServ):
kmp start
IOCs are usually run in screen or procServ so that:
- the window in which they’re started can be closed
- multiple people can connect to them
- [procServ] allows other user accounts to restart an IOC
- [procServ] allows users to connect to Windows IOCs
Confirm the IOC is running
kmp status
kmp is running (pid=1281733) in a screen session (pid=1281732)
Note: bugs in the deployed copy of xxx.sh
may prevent it from detecting an IOC is running.
Connecting to an IOC’s shell
There are many ways to do it:
- Manually connect to an IOC running in screen from the IOC’s host
$ screen -x kmp
- The -x option will connect even if someone is already connected to the screen session.
- The -r option only succeeds if no one is connected to the session.
- Connect to an IOC running in screen or procServ from the IOC’s host
$ kmp console
- Connect to an IOC running in screen or procServ with logging from any host
$ /APSshare/bin/iocConsole.py iockmp
- Note: iocConsole.py requires ssh access which beamline accounts don't have by default
- Manually connect to an IOC running in procServ from the IOC’s subnet
$ telnet s100bcda 53127
Disconnecting from an IOC’s shell
- Close the terminal that is connected to the screen or procServ session
- Disconnects from both screen & procServ
- Kills an IOC running outside of screen & procServ
Ctrl+a
,Ctrl+d
- Disconnects from both screen & procServ
- Kills an IOC running outside of screen & procServ
Ctrl+a, d
- Only disconnects from screen