Tcl-IOC provides a Tcl shell for an EPICS R3.14 IOC. It is a replacement for iocsh that comes with EPICS base. This adds the full capability of a scripting programming language to EPICS iocCore. Access to registered EPICS functions and variables is supported similar to iocsh.
Tcl is required and TclX is recommended for its capability to switch from scripting mode to interactive mode. Alternatively, wish, the graphical extension to the Tcl shell, can be used. To build Tcl-IOC, the sources or the development rpm of Tcl (tcl-devel) is required (i.e. the header file tcl.h is needed). To run Tcl-IOC, a run time installation of Tcl and TclX is sufficient.
EPICS R3.14.7 is required (higher versions might also work).
Download the tclioc.tgz package. See below how to install it.
Tcl-IOC has been tested on the following systems:
Operating System | EPICS Release | Compiler | Tcl Version |
---|---|---|---|
Redhat Linux 6.2 | R3.14.7 | gcc egcs-2.91.66 | 8.0 |
Redhat Linux 7.3 | R3.14.7 | gcc 2.96 | 8.3 |
Scientific Linux 3.0.5 | R3.14.7 | gcc 3.2.3 | 8.3 |
Fedora Core 3 | R3.14.7 | gcc 3.4.3 | 8.4 |
It has not yet been tested on Windows systems. If you make it run on other systems, feedback is welcome.
Tcl-IOC consistes of a shared library that can be linked with an IOC application and loaded into any Tcl shell (tclsh, tcl, wish, wishx, bltwish, ...) with the load command. Loading the library automatically adds iocCore, including all EPICS functions and variables to the Tcl shell.
For each registered EPICS function, a Tcl command with the same name is created. Thus, any EPICS function available in iocsh can be called from the Tcl shell. Since iocsh functions have void results, the corresponding Tcl commands normally return an empty string. Many EPICS functions write to stdout, but input and output can be redirected:
< filename
> filename
>> filename
2> filename
2>> filename
<@ fileId
open
and
socket
)
>@ fileId
open
and
socket
)
2>@ fileId
open
and
socket
)
>$ varName
>>$ varName
2>$ varName
2>>$ varName
>$$
2>$$
Note that most EPICS functions also write error messages to stdout instead of stderr.
Each registered EPICS variable is mapped to a global Tcl variable with
the same name.
Reading and writing of those Tcl variables is redirected
to the corresponding EPICS variable.
EPICS variables cannot be
unset
.
Tcl-IOC comes as a BaseApp-style EPICS R3.14 project. It contains the following files:
tclioc |-- Makefile |-- myTclIocApp | |-- Makefile | |-- example.subs | |-- example.template | |-- exampleiocsh.tcl | |-- myTclIocAppInclude.dbd | `-- simpleiocsh.tcl `-- src |-- Makefile |-- README |-- iocUtil.c `-- iocsh.cpp
Unpack the project it in a <TOP> location and run make. This will create a loadable library and an example application. For further information on EPICS projects and <TOP> directories, please refer to the EPICS IOC Application Developer's Guide (download PDF), Chapter 4.
A Tcl-IOC application is similar to any other EPICS IOC application. The differences are in the Makefile and the startup script. An example application can be found in the myTclIocApp subdirectory.
PROD
executable, create a
LOADABLE_LIBRARY
.PROD = myApplication
LOADABLE_LIBRARY = myApplication
PROD_SRCS
, etc. by
LIBS_SRCS
or myApplication_SRCS
.
$(EPICS_BASE_IOC_LIBS)
,
link it to tclioc
.myApplication_LIBS += $(EPICS_BASE_IOC_LIBS)
myApplication_LIBS += tclioc
Differences to a standard application Makefile are marked blue.
TOP=../.. include $(TOP)/configure/CONFIG LOADABLE_LIBRARY = myApplication DBD += myApplication.dbd myApplication_SRCS += myApplication_registerRecordDeviceDriver.cpp myApplication_LIBS += tclioc include $(TOP)/configure/RULES
/usr/bin/tcl
(or wherever TclX is installed)
as the interpreter. That means the first line should be#!/usr/bin/tcl
load libmyApplication.so tclioc
dbLoadDatabase
,
myApplication_registerRecordDeviceDriver
,
dbLoadTemplate
or dbLoadRecords
,
iocInit
), it is possible to use Tcl language constructs.
This allows loops and conditionals, access to variables, etc.
commandloop -prompt1 {puts -nonewline "epics> "}
#!/usr/bin/tcl load libmyApplication.so tclioc dbLoadDatabase myApplication.dbd myApplication_registerRecordDeviceDriver #create records using TCL programming set scan "1 second" for {set n 1} {$n <= 100} {incr n} { dbLoadRecords example.template "number=$n,scan=$scan" } #set an EPICS variable set asCaDebug 1 #some EPICS commands with output redirection set logfile iocboot.log iocInit > $logfile dbnr 1 >> $logfile dbl >> $logfile # go interactive commandloop -prompt1 {puts -nonewline "epics> "}