IOC 101

From Beam Line Controls
Jump to navigation Jump to search

What is an IOC

For a basic description, see Epics 101

EPICS basics PV diagram.png

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

Not recommended: it creates a bare bones IOC but requires more knowledge of the EPICS build system to get started:
  • 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:

  • 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 (common records/modules such as alive, sscan, calc...)
  • 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


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.


  • build: building an IOC is the action of compiling i.e. generating the binary bin/rhel#-x86_64/xxxApp (plus other build products as described below) by using the command make.
  • run: running an IOC is the action of running the binary along with a startup script of iocsh commands (usually called st.cmd)


  • Any change in the build configuration (Orange folders) requires to recompile the IOC by issuing a make.
  • Any change in the runtime configuration (Green folders) requires to reboot the IOC.

xxx IOC tree

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 directories (orange directories). 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. all the files the IOC needs to load to run/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 startup directory softioc subdirectory 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

EPICS basics linking diagrams.png
  • configure/RELEASE:
    • Defines the locations of EPICS base and EPICS modules
    • Often includes other RELEASE files
    • Note: already included when using mkioc
  • 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)
    • Note: unless you are adding a non-synApps module or an uncommon motor driver, you should not need to modify the Makefile
  • iocBoot/iocxxx/st.cmd:
    • That is the runtime configuration file, i.e. the primary IOC config file that is sourced when the IOC is started: determines all the things that gets loaded (e.g. I want 7 motor records, with these names, and this resolution, etc...)
    • Name can vary slightly based on how the IOC was created
    • Note: this is the file that you will very likely modify

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


### Databases are loaded
### Drivers are initialized/configured here


### Sequence programs & autosave are started here

dbl > dbl-all.txt


We can break it up into 3 functional zones:

  • Zone 1 - before dbLoadDatabase: it is usually dedicated to setting-up the environment (e.g. defines environment variables and paths to EPICS modules).
  • Zone 2 - after dbLoadDatabase & before iocInit: this is were most of the software is loaded (e.g. databases and substitutions template are loaded here, drivers are initialized and configured).
  • Zone 3 - after iocInit: this zone is mostly empty thanks to doAfterIocInit from the std 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 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.

IOC autosave.jpg

In xxx-based IOCs, created using mkioc, autosave is included by default: common.iocsh contains all the necessary configuration, and you will only need to modify it if you want to customize something. It also includes an autosaveBuild feature: every loaded database with associated req files (_settings.req) are automatically added to autosave/built_position.req and autosave/built_settings.req, so long as they use the correct naming convention, i.e. the _settings.req uses the same prefix as the database.
The legacy request files, autosave_position.req and autosave_settings.req (that live outside the autosave directory) are reserved for things added manually (often empty). Multiple .sav files can be created:

  • Default:
    • .sav & .savB
    • actually restored when the IOC restarts
  • Periodic:
    • .sav0, .sav1, .sav2, …
    • overwritten cyclically; if the default one do not exist, those ones get restored.
  • Dated:
    • .sav-230109-134502
    • written once at boot time

The 1st half of common.iocsh sets up autosave:

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
  • 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 to start fresh:
    • 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
Usage: {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.


  • 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 the EPICS_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 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/ iockmp
Note: 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

IOC shell commands

See EPICS Cheat Sheet

Where does EPICS support reside at the APS

IOC Support.jpg

What's next?

For step by step instructions to create your own IOC, go to IOC Deployment & Troubleshooting.