Practical EPICS Training�IOC Basics
erhtjhtyhy
Kevin Peterson
XSD-BC
January 20, 2023
Suggested line of text (optional):
WE START WITH YES.
Disclaimer
Target audience:
People who have used EPICS but never needed to know anything about IOCs
People who are new to EPICS
Goals:
Provide a foundation of IOC knowledge on which future trainings will build
Enable examination of existing IOCs with minimal confusion
2
What is an IOC?
An IOC:
An IOC is just an application running on a computer
3
Channel
Access
Serial
Ethernet
What is a Process Variable (PV)?
PV = record_name + . + field_name
4
13PS1:cam1:NumImages.VAL
kmp3:userCalcOut2.CALC
kmp3:m1.RBV
kmp3:scan1.P1PV
What is a record?
Records are the building blocks of EPICS
5
What is a record field?
A controllable or informative property of a record
6
How to learn more about record fields?
It isn’t easy and requires multiple sources
7
Records in synApps modules
8
Module | Records | Module | Records |
alive | alive | motor | motor |
asyn | asyn | optics | table |
busy | busy | scaler | scaler |
calc | acalcout, scalcout, sseq, swait, transform | sscan | sscan |
camac | camac | std | epid, timestamp, throttle |
lua | luascript | vac | digitel, vs |
mca | mca | vme | vme |
The SCAN, PROC & FLNK fields
Records can be processed multiple ways:
Records do nothing until they are processed
SCAN field options:
9
Record link types
Input Links
10
inlinkHelp is accessible from userTransform screens
Record link types
Output Links
11
outlinkHelp is accessible from userTransform & scaler screens
Record link types
Forward Links
12
What is a database?
A collection of related records of various types
13
How are databases loaded?
dbLoadRecords("$(IP)/db/ADAM_4018.db", "P=kmp:,R=adam1,PORT=serial1,A=01")
dbLoadRecords("$(IP)/db/ADAM_4018.db", "P=kmp:,R=adam2,PORT=serial1,A=02")
dbLoadTemplate(“substitutions/ADAM_4018.substitutions”, “P=kmp:”)
ADAM_4018.substitutions:
file "$(IP)/db/ADAM_4018.db"
{
pattern
{R, PORT, A}
{adam1, serial1, 01}
{adam2, serial1, 02}
}
dbLoadRecords or dbLoadTemplate
14
How does one create an IOC?
No one does it from scratch
15
IOC Layout
kmp
├── bin
│ └── rhel8-x86_64
├── configure
│ ├── O.Common
│ └── O.rhel8-x86_64
├── db
├── dbd
├── iocBoot
│ └── iockmp
│ ├── autosave
│ ├── iocsh
│ ├── softioc
│ │ └── commands
│ └── substitutions
├── kmpApp
│ ├── Db
│ │ ├── O.Common
│ │ └── O.rhel8-x86_64
│ ├── op
│ │ ├── adl
│ │ └── ui
│ │ └── autoconvert
│ └── src
│ ├── O.Common
│ └── O.rhel8-x86_64
└── lib
└── rhel8-x86_64
16
IOC Layout
kmp
├── bin
│ └── rhel8-x86_64
├── configure
│ ├── O.Common
│ └── O.rhel8-x86_64
├── db
├── dbd
├── iocBoot
│ └── iockmp
│ ├── autosave
│ ├── iocsh
│ ├── softioc
│ │ └── commands
│ └── substitutions
Build configuration
├── kmpApp
│ ├── Db
│ │ ├── O.Common
│ │ └── O.rhel8-x86_64
│ ├── op
│ │ ├── adl
│ │ └── ui
│ │ └── autoconvert
│ └── src
│ ├── O.Common
│ └── O.rhel8-x86_64
└── lib
└── rhel8-x86_64
17
IOC Layout
kmp
├── bin
│ └── rhel8-x86_64
├── configure
│ ├── O.Common
│ └── O.rhel8-x86_64
├── db
├── dbd
├── iocBoot
│ └── iockmp
│ ├── autosave
│ ├── iocsh
│ ├── softioc
│ │ └── commands
│ └── substitutions
Intermediate build dirs
├── kmpApp
│ ├── Db
│ │ ├── O.Common
│ │ └── O.rhel8-x86_64
│ ├── op
│ │ ├── adl
│ │ └── ui
│ │ └── autoconvert
│ └── src
│ ├── O.Common
│ └── O.rhel8-x86_64
└── lib
└── rhel8-x86_64
18
IOC Layout
kmp
├── bin
│ └── rhel8-x86_64
├── configure
│ ├── O.Common
│ └── O.rhel8-x86_64
├── db
├── dbd
├── iocBoot
│ └── iockmp
│ ├── autosave
│ ├── iocsh
│ ├── softioc
│ │ └── commands
│ └── substitutions
Build products
├── kmpApp
│ ├── Db
│ │ ├── O.Common
│ │ └── O.rhel8-x86_64
│ ├── op
│ │ ├── adl
│ │ └── ui
│ │ └── autoconvert
│ └── src
│ ├── O.Common
│ └── O.rhel8-x86_64
└── lib
└── rhel8-x86_64
19
IOC Layout
kmp
├── bin
│ └── rhel8-x86_64
├── configure
│ ├── O.Common
│ └── O.rhel8-x86_64
├── db
├── dbd
├── iocBoot
│ └── iockmp
│ ├── autosave
│ ├── iocsh
│ ├── softioc
│ │ └── commands
│ └── substitutions
Run-time configuration
├── kmpApp
│ ├── Db
│ │ ├── O.Common
│ │ └── O.rhel8-x86_64
│ ├── op
│ │ ├── adl
│ │ └── ui
│ │ └── autoconvert
│ └── src
│ ├── O.Common
│ └── O.rhel8-x86_64
└── lib
└── rhel8-x86_64
20
IOC Layout
kmp
├── bin
│ └── rhel8-x86_64
├── configure
│ ├── O.Common
│ └── O.rhel8-x86_64
├── db
├── dbd
├── iocBoot
│ └── iockmp
│ ├── autosave
│ ├── iocsh
│ ├── softioc
│ │ └── commands
│ └── substitutions
Start scripts
├── kmpApp
│ ├── Db
│ │ ├── O.Common
│ │ └── O.rhel8-x86_64
│ ├── op
│ │ ├── adl
│ │ └── ui
│ │ └── autoconvert
│ └── src
│ ├── O.Common
│ └── O.rhel8-x86_64
└── lib
└── rhel8-x86_64
21
How does support get into an IOC?
A quick overview
22
st.cmd
< envPaths
dbLoadDatabase("../../dbd/iockmpLinux.dbd")
iockmpLinux_registerRecordDeviceDriver(pdbbase)
### Databases are loaded
### Drivers are initialized/configured here
iocInit
### Sequence programs & autosave are started here
dbl > dbl-all.txt
date
The startup script, simplified
23
autosave
Mostly automatic when mkioc is used
iockmp
├── auto_positions.req
├── auto_settings.req
├── autosave/
│ ├── built_positions.req
│ └── built_settings.req
├── common.iocsh
├── envPaths
├── iocsh/
├── settings.iocsh
├── softioc/
├── st.cmd.Linux
└── substitutions/
24
How to build & clean a Linux IOC
25
Running an IOC
# 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}
# Start caQtDM
$ kmp caqtdm &
# Start the IOC (in the background using screen or procServ)
$ kmp start
# Confirm the IOC is running
$ kmp status
kmp is running (pid=1281733) in a screen session (pid=1281732)
Use the script
26
Connecting to an IOC’s shell
# Manually connect to an IOC running in screen from the IOC’s host
$ screen -x kmp
# 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
# Manually connect to an IOC running in procServ from the IOC’s subnet
$ telnet s100bcda 53127
There are many ways to do it
27
Disconnecting from an IOC’s shell
There are not many ways to do it
28
IOC shell commands
help [command] - shows available commands or syntax of specified command
dbpr record_name [0-9] - displays fields and values for a given record
dbl - lists all records in an IOC
dbl record_type - lists all records of a specific type in an IOC
dbl record_type "field_list" - lists specified fields (space-separated list) of records of a specific type in an IOC
dbpf pv_name value - change a PV’s value – analogous to caput
dbgf pv_name - read a PV’s value – analogous to caget
epicsEnvShow - prints environment variables
seqShow - shows running sequence programs
seqStop - stops a running sequence program
29
CA command-line utilities
caget - get the value of one of more PVs
caput - change the value of a PV
camonitor - monitor the value of one or more PVs
cainfo - print info about a PV, including which host is running the IOC
Example:
$ caget kmp3:m1.{DESC,RTYP,DTYP,VAL}
kmp3:m1.DESC motor 1
kmp3:m1.RTYP motor
kmp3:m1.DTYP asynMotor
kmp3:m1.VAL 60
CA = Channel Access
30
Graphical User Interfaces (GUIs)
MEDM & caQtDM
31
Where does EPICS support reside at the APS?
/APSshare (read-only)
└── epics
├── base-X.Y.Z
└── synApps_X_Y
└── support
/net/s##dserv/xorApps (read-write)
└── epics
└── synApps_X_Y
├── ioc
│ └── ## beamline IOCs are deployed here
└── support
└── Local support modules are deployed here
On the dserv, historically
32
How to add streamDevice support to an IOC
33
Questions?
35