Getting Started
Getting Started with EPICS
Contents
Installation on Linux/UNIX/Darwin (Mac)
1. Installing EPICS. What is it about?
We assume that you know more or less what EPICS is. Here we want to start
from scratch and get to the point where we have a working server, offering some
PVs for reading (caget
or pvget
) and writing
(caput
or pvput
), and we read and write on them from
another terminal, either on the same machine or on another one in the same
network. If you are going to use two different machines, you will have to
repeat the steps for installing EPICS for both of them.
2. Prepare your system
You need make, c++ and libreadline to compile from source. On macOS these
dependencies can be installed by using e.g. homebrew
. On Linux you
can use apt-get install
.
3. Install EPICS
mkdir $HOME/EPICS cd $HOME/EPICS git clone --recursive https://github.com/epics-base/epics-base.git cd epics-base make
After compiling you should put the path into $HOME/.profile
or
into $HOME/.bashrc
by adding the following to either one of those
files:
export EPICS_BASE=${HOME}/EPICS/epics-base export EPICS_HOST_ARCH=$(${EPICS_BASE}/startup/EpicsHostArch) export PATH=${EPICS_BASE}/bin/${EPICS_HOST_ARCH}:${PATH}
EpicsHostArch is a program provided by EPICS that returns the architecture
of your system. Thus the code above should be fine for every architecture.
4. Test EPICS
Now log out and log in again, so that your new path is set correctly.
Alternatively, you can execute the three lines above beginning with export
directly from the terminal.
Run softIoc
and, if everything is ok, you should see an EPICS
prompt.
softIoc epics>
You can exit with ctrl-c or by typing exit.
VoilĂ .
Ok, that is not very impressive, but at least you know that EPICS is
installed correctly. So now let us try something more complex, which will
hopefully suggest how EPICS works.
In whatever directory you like, prepare a file test.db
that
reads like
record(ai, "temperature:water") { field(DESC, "Water temperature in the fish tank") }
This file defines a record instance called temperature:water, which
is an analog input (ai) record. As you can imagine DESC stays for
Description. Now we start softIoc
again, but this time using this
record database.
softIoc -d test.db
Now, from your EPICS prompt, you can list the available records with thedbl
command and you will see something like
epics> dbl temperature:water epics>
Open a new terminal (we call it nr. 2) and try the command line toolscaget
and caput
. You will see something like
your prompt> caget temperature:water temperature:water 0 your prompt> caget temperature:water.DESC temperature:water.DESC Water temperature in the fish tank your prompt> caput temperature:water 21 Old : temperature:water 0 New : temperature:water 21 your prompt> caput temperature:water 24 Old : temperature:water 21 New : temperature:water 24 your prompt> caget temperature:water temperature:water 24 ... etc.
Now open yet another terminal (nr. 3) and try camonitor
as
camonitor temperature:water
First, have a look at what happens when you change the temperature:water
value from terminal nr. 2 using caput
. Then, try to change the
value by some tiny amounts, like 15.500001, 15.500002, 15.500003… You will
see that camonitor
reacts but the readings do not change. If you
wanted to see more digits, you could run
camonitor -g8 temperature:water
For further details on the Channel Access protocol, including documentation
on the caput
, caget
, camonitor
…
command line tools, please refer to the Channel Access Reference Manual.
In real life, however, it is unlikely that the 8 digits returned by your
thermometer (in this example) are all significant. We should thus limit the
traffic to changes of the order of, say, a hundredth of a degree. To do this,
we add one line to the file test.db
, so that it reads
record(ai, "temperature:water") { field(DESC, "Water temperature in Lab 10") field(MDEL, ".01") }
MDEL stands for Monitor Deadband. If you now run
softIoc -d test.db
with the new test.db
file, you will see thatcamonitor
reacts only to changes that are larger than 0.01.
This was just a simple example. Please refer to the Record Reference Manual for further
information.
5. Create a demo/test ioc to test ca and pva
mkdir -p $HOME/EPICS/TEST/testIoc cd $HOME/EPICS/TEST/testIoc makeBaseApp.pl -t example testIoc makeBaseApp.pl -i -t example testIoc make cd iocBoot/ioctestIoc chmod u+x st.cmd ioctestIoc> ./st.cmd #!../../bin/darwin-x86/testIoc < envPaths epicsEnvSet("IOC","ioctestIoc") epicsEnvSet("TOP","/Users/maradona/EPICS/TEST/testIoc") epicsEnvSet("EPICS_BASE","/Users/maradona/EPICS/epics-base") cd "/Users/maradona/EPICS/TEST/testIoc" ## Register all support components dbLoadDatabase "dbd/testIoc.dbd" testIoc_registerRecordDeviceDriver pdbbase ## Load record instances dbLoadTemplate "db/user.substitutions" dbLoadRecords "db/testIocVersion.db", "user=junkes" dbLoadRecords "db/dbSubExample.db", "user=junkes" #var mySubDebug 1 #traceIocInit cd "/Users/maradona/EPICS/TEST/testIoc/iocBoot/ioctestIoc" iocInit Starting iocInit ############################################################################ ## EPICS R7.0.1.2-DEV ## EPICS Base built Mar 8 2018 ############################################################################ cas warning: Configured TCP port was unavailable. cas warning: Using dynamically assigned TCP port 52907, cas warning: but now two or more servers share the same UDP port. cas warning: Depending on your IP kernel this server may not be cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST) iocRun: All initialization complete 2018-03-09T13:07:02.475 Using dynamically assigned TCP port 52908. ## Start any sequence programs #seq sncExample, "user=maradona" epics> dbl maradona:circle:tick maradona:compressExample maradona:line:b maradona:aiExample maradona:aiExample1 maradona:ai1 maradona:aiExample2 ... etc. ... epics>
Now in another terminal, one can try command line tools like
caget
,caput
,camonitor
,cainfo
(Channel Access)pvget
,pvput
,pvlist
,eget
… (PVAccess)
6. Add the asyn package
cd $HOME/EPICS mkdir support cd support git clone https://github.com/epics-modules/asyn.git cd asyn
Edit $HOME/EPICS/support/asyn/configure/RELEASE
and setEPICS_BASE
like
EPICS_BASE=${HOME}/EPICS/epics-base
Comment IPAC=...
and SNCSEQ=...
, as they are not
needed for the moment. The whole file should read:
#RELEASE Location of external products HOME=/Users/maradona SUPPORT=$(HOME)/EPICS/support -include $(TOP)/../configure/SUPPORT.$(EPICS_HOST_ARCH) # IPAC is only necessary if support for Greensprings IP488 is required # IPAC release V2-7 or later is required. #IPAC=$(SUPPORT)/ipac-2-14 # SEQ is required for testIPServer #SNCSEQ=$(SUPPORT)/seq-2-2-5 # EPICS_BASE 3.14.6 or later is required EPICS_BASE=$(HOME)/EPICS/epics-base -include $(TOP)/../configure/EPICS_BASE.$(EPICS_HOST_ARCH)
Now, run
make
7. Install StreamDevice (by Dirk Zimoch, PSI)
StreamDevice does not come with its own top location andtop/configure
directory. It expects to be put into an already
existing top directory structure. We can simply create one withmakeBaseApp.pl
cd $HOME/EPICS/support mkdir stream cd stream/ makeBaseApp.pl -t support git clone https://github.com/paulscherrerinstitute/StreamDevice.git cd StreamDevice/ rm GNUmakefile
Now we must edit the$HOME/EPICS/support/stream/configure/RELEASE
. The not-commented
lines must read
# Variables and paths to dependent modules: MODULES = ${HOME}/EPICS/support # If using the sequencer, point SNCSEQ at its top directory: #SNCSEQ = $(MODULES)/seq-ver # EPICS_BASE should appear last so earlier modules can override stuff: EPICS_BASE = ${HOME}/EPICS/epics-base # These lines allow developers to override these RELEASE settings # without having to modify this file directly. -include $(TOP)/../RELEASE.local #-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local -include $(TOP)/configure/RELEASE.local ASYN=$(MODULES)/asyn
Remember that $(NAME)
works if it is defined within the same
file, but ${NAME}
with curly brackets must be used if a shell
variable is meant. It is possible that the compiler does not like some of the
substitutions. In that case, replace the ${NAME}
variables with
full paths, like /Users/maradona/EPICS...
.
Finally run make
(we are in the directory...EPICS/support/stream/StreamDevice
)
Creation of an Input/Output Controller (IOC)
An IOC allows to talk to devices e.g. via ethernet. Create a directory for
the IOCs. For example $HOME/EPICS/IOCs
cd $HOME/EPICS; mkdir IOCs; cd IOCs
Create a top for an IOC called sampleIOC
mkdir sampleIOC; cd sampleIOC makeBaseApp.pl -t example sampleIOC makeBaseApp.pl -i -t example sampleIOC Using target architecture darwin-x86 (only one available) The following applications are available: sampleIOC What application should the IOC(s) boot? The default uses the IOC's name, even if not listed above. Application name? (just return)
Now, by running make
, a sample IOC like the demo/test IOC is
built. Next, we want to add asyn and StreamDevice to the IOC. For this, we add
the stream and asyn libraries to the Makefile. EditsampleIOCApp/src/Makefile
and add the block
#add asyn and streamDevice to this IOC production libs sampleIOC_LIBS += stream sampleIOC_LIBS += asyn
The application must also load asyn.dbd
andstream.dbd
to use StreamDevice . This can be put into a generated
dbd, e.g into xxxSupport.dbd
which already gets included by the
Makefile. So the xxxSupport.dbd
now reads:
cat sampleIOCApp/src/xxxSupport.dbd include "xxxRecord.dbd" device(xxx,CONSTANT,devXxxSoft,"SoftChannel") # include "stream.dbd" include "asyn.dbd" registrar(drvAsynIPPortRegisterCommands) registrar(drvAsynSerialPortRegisterCommands) registrar(vxi11RegisterCommands)
To find the dbd files, you have to add the paths to these files inconfigure/RELEASE
:
... # Build variables that are NOT used in paths should be set in # the CONFIG_SITE file. # Variables and paths to dependent modules: SUPPORT = ${HOME}/EPICS/support ASYN=$(SUPPORT)/asyn STREAM=$(SUPPORT)/stream # If using the sequencer, point SNCSEQ at its top directory: #SNCSEQ = $(MODULES)/seq-ver ...
If make
was done before, make distclean
is
probably required. Anyway, then make
. The newly created IOC can be
run with:
cd iocBoot/iocsampleIOC/ chmod u+x st.cmd ./st.cmd
Not very interesting yet, because there is no database file nor a protocol
file.
ls -la sampleIOCApp/Db/ total 56 drwxr-xr-x 11 maradona staff 374 Jun 1 16:47 . drwxr-xr-x 5 maradona staff 170 Jun 1 12:46 .. -rw-r--r-- 1 maradona staff 523 Jun 1 12:46 Makefile drwxr-xr-x 2 maradona staff 68 Jun 1 16:47 O.Common drwxr-xr-x 3 maradona staff 102 Jun 1 16:47 O.darwin-x86 -rw-r--r-- 1 maradona staff 1761 Jun 1 12:46 circle.db -rw-r--r-- 1 maradona staff 1274 Jun 1 12:46 dbExample1.db -rw-r--r-- 1 maradona staff 921 Jun 1 12:46 dbExample2.db -rw-r--r-- 1 maradona staff 286 Jun 1 12:46 dbSubExample.db -rw-r--r-- 1 maradona staff 170 Jun 1 12:46 sampleIOCVersion.db -rw-r--r-- 1 maradona staff 307 Jun 1 12:46 user.substitutions
Note that this is a Db
directory and not the db
directory that is in ./sampleIOC . For MDOxxxx scopes by Tektronix, the
database (.db
) and protocol (.proto
) file can look
something like
cat MDO.db record(stringin, $(P)$(R)idn){ field(DESC, "Asks for info blabla") field(DTYP, "stream") field(INP, "@MDO.proto getStr(*IDN,99) $(PORT) $(A)") field(PINI, "YES") } cat MDO.proto Terminator = LF; getStr{ out "$1?"; in "%s"; @replytimeout {out "$1?"; in "%s";} }
Now, we add to sampleIOCApp/Db/Makefile
the information that
these files must be included in the compilation. So
cat sampleIOCApp/Db/Makefile TOP=../.. include $(TOP)/configure/CONFIG #---------------------------------------- # ADD MACRO DEFINITIONS BELOW HERE # Install databases, templates & substitutions like this DB += circle.db DB += dbExample1.db DB += dbExample2.db DB += sampleIOCVersion.db DB += dbSubExample.db DB += user.substitutions DB += MDO.db DB += MDO.proto # If .db template is not named *.template add # _TEMPLATE = include $(TOP)/configure/RULES #---------------------------------------- # ADD EXTRA GNUMAKE RULES BELOW HERE
Again, make
in directory sampleIOC. Finally, we add IP port
configuration, setting the Stream path and loading the database to thest.cmd
file. The st.cmd
should read:
cat st.cmd #!../../bin/darwin-x86/sampleIOC #- You may have to change sampleIOC to something else #- everywhere it appears in this file < envPaths epicsEnvSet ("STREAM_PROTOCOL_PATH","$(TOP)/db") cd "${TOP}" ## Register all support components dbLoadDatabase "dbd/sampleIOC.dbd" sampleIOC_registerRecordDeviceDriver pdbbase ## Load record instances dbLoadTemplate "db/user.substitutions" dbLoadRecords "db/sampleIOCVersion.db", "user=UUUUUU" dbLoadRecords "db/dbSubExample.db", "user=UUUUUU" #IF if the user also defines EPICS_CAS_INTF_ADDR_LIST then beacon address #list automatic configuration is constrained to the network interfaces specified #therein, and therefore only the broadcast addresses of the specified LAN interfaces, #and the destination addresses of all specified point-to-point links, will be automatically configured. #epicsEnvSet ("EPICS_CAS_INTF_ADDR_LIST","aaa.aaa.aaa.aaa") # connect to the device ... IP-Address ! Port 2025 used by textronix, see manual drvAsynIPPortConfigure("L0","bbb.bbb.bbb.bbb:pppp",0,0,0) ## Load record instances dbLoadRecords("db/MDO.db", "P=UUUUUU:,PORT=L0,R=MDO:,L=0,A=0") #- Set this to see messages from mySub #var mySubDebug 1 #- Run this to trace the stages of iocInit #traceIocInit cd "${TOP}/iocBoot/${IOC}" iocInit ## Start any sequence programs #seq sncExample, "user=UUUUUU"
In here, you have to replace UUUUUU with the user name that runs
the EPICS IOC (you?). bbb.bbb.bbb.bbb is the IP of the device (e.g.
the scope) and pppp the port on which it listens.
EPICS_CAS_INTF_ADDR_LIST can be used if there are two network
interfaces (e.g. wlan and eth0).
The following commands might be necessary with multiple network
interfaces:
export EPICS_CA_ADDR_LIST=ccc.ccc.ccc.ccc << Broadcast address of the network export EPICS_CA_AUTO_ADDR_LIST=NO