EPICS TCL/TK Interface

Bob Daly

Table of Contents

Argonne National Laboratory
Advanced Photon Source
Accelerator Systems Division/Controls Group
August 1998

1. Introduction

This document describes the tcl command (pv) and command operations (link, linkw, get, getw, put, putq, mon, umon,  cmon, info, stat, vset, vset, and vmap) which are used to interface  with EPICS. The tcl package  libraries upon which et is built include tk and blt.  This release of et has been tested using shared libraries from the tcl release 8.0p2,  the tk package release 8.0p2, and the blt package release blt2.4c.  The Makefile.Vx  supports building a shared library for the epics interface package ( and an interpreter (et_wish). The reader of this document is assumed to be familiar with tcl/tk/blt.

2. Running et

Start interactive use of et interpreter by typing:

 In a script, the first line identifies the interpreter for the script.
 #!<full path name>et_wish
 Remember that on many UNIX systems the first line is limited to 32 characters.

3. Command Syntax

The command syntax consists of three or more words, with the first three words having the same meaning in each command. The words after the first three words are dependent on the type of command issued. A command example follows:
  pv link {ai1 ai2 ai3} {IOC:ai1 IOC:ai2 IOC:ai3}
Examples of all supported operations:
  •   pv link {c0 ai1 ai2 ai3 ai4} {T:calc T:ai1 T:ai2 T:ai3 T:ai4}
  •   pv unlink ai1
  •   pv get c0
  •   pv getw ai1 11.1
  •   pv put ai1
  •   pv putw ai2
  •   pv putq ai3
  •   pv info {c0 ai1 ai2 ai3 ai4} {state status severity time units}
  •   pv stat ai1
  •   pv mon {c0 ai3 ai4} {puts "I can execute a script for you"}
  •   pv umon ai1
  •   pv cmon ai1
  •   <<<<start multi-element (vector) record oriented operations>>>>>>>>>
  •   pv link {wf wf1} {vong:xy566WaveformCh0 vong:xy566WaveformCh1}
  •   pv vdef {wf wf1} {0 256 5}
  •   pv vset wf
  •   pv vset wf { 1 2 33 }
  •   pv vmap wf wfvector
  • 4. pv Command Operations

    link, linkw, unlink

       pv link(w) tclVars iocVars <optional timeout>
    Description: Establish a link at run-time between tcl variables and process variables in existing IOC databases. The tcl variables are automatically created during the operation. For string and enum process variables, the tcl type created will be a string.(1) For float and double process variable types, the tcl variable type created is a double. For all other process variable types the tcl variable type is  integer. A tcl variable may be subsequently linked with a different process variable (i.e. relinked). When relinked the old link is completely removed. A tcl variable may also be unlinked.


     Comments: The user must always check the state of the link after link and linkw type commands, using either the `stat' or `info' command types. The state must be `OK' (see stat and info type commands) before further operations on the tcl or process variable(s) are made. When the link(w) is first issued `state' is set to `IO'. If a link to a database process variable is successful the state changes to `OK'. If the link was unsuccessful the state will be something other than `IO" or `OK', i.e. NC (Never Connected), LC (Lost Connection), RD (No Read Access), WR (No Write Access). For blocking links, i.e. linkw, the state can be checked immediately after the linkw command is issued. For non-blocking links, i.e. link, the state may still be in the `IO' state after the link command is issued and subsequently (asynchronously) change to another state. For the non-blocking command it is up to the user code to wait until a `state' transition or timeout has occurred. I recommend using blocking links because of their coding simplicity.

     Examples of correct forms of link(w), unlink

  •   pv link ai1 IOC:beamVoltage
  •   pv linkw {ai1 ao1 bi1} {IOC:beamCurrent IOC:outputCurrent IOC:beamStatus}
  •   set varList{ai1 ao1 bi1}
  •   set iocList {IOC:beamCurrent IOC:outputCurrent IOC:beamStatus}
  •   pv linkw $varList $iocList
  •   pv link $varList $iocList
  •   if { [pv linkw ai1 IOC:beamVoltage] == 1} puts stdout $errorCode
  •   pv unlink ai1
  •   pv unlink $varList

    get, getw

      pv get(w) tclvars <optional timeout>
    Description: Update the linked tcl variables to the current values stored in the IOC databases.


    Comments: The user should always check state of the link after get and getw type commands using either the `stat' or `info' command types. The state must be `OK'. Additionally the severity of the process variable should be checked to, at least, make sure that it is not INVALID. I recommend using the `stat' command type for checking.

     Examples of correct forms of get(w):

  •   set varList {ai1 ao1 bi1}
  •   set iocList {IOC:beamCurrent IOC:outputCurrent IOC:beamStatus}
  •   pv link $varList $iocList
  •   pv get $varList
  •   pv getw $varList
  •   pv get {ai1 ao1}
  •   pv getw {ao1 bi1}
  •   pv get bi1
  •   pv getw bi1
  • put, putw, putq

      pv put(w,q) tclvars <optional timeout>
    Description: Update the current process variable values stored in the IOC databases to the linked tcl variable values. The put and putw types require notification from the IOC that record processing has completed for all the linked variables in the command. The putw blocks until all notifications have been received. The putq returns to the application as soon as the proper requests have been forwarded to the IOC. I recommend using the putq type unless there is a compelling reason for wanting to wait for record processing associated with a process variable to complete.


    Comments: User should always check state of the link after put, putw, and putq type commands. The state must be `OK'. I recommend using the `stat' command.

     Examples of correct forms of put(w,q):

  •  set varList {ai1 ao1 bi1}
  •  set iocList {IOC:beamCurrent IOC:outputCurrent IOC:beamStatus}
  •  pv link $varList $iocList
  •  pv put ao1
  •  pv putw ao1
  •  pv putq ao1
  •  pv put {ai1 ao1 bi1}
  •  pv putw {ai1 ao1 bi1}
  •  pv putq {ai1 ao1 bi1}
  •  pv put $varList
  •  pv putw $varList
  •  pv putq $varList
  • mon, umon, cmon

  •   pv mon tclVars <optional script>
  •   pv umon tclVars <optional script>
  •   pv cmon tclVars



    Description: Establish/Clear an EPICS database monitor for the linked tcl variable(s). The linked tcl variable is updated immediately with umon.  The use of umon is convenient when TK widgets are used to display the value of a variable. However, with mon, the linked tcl variable is updated only when the tcl variable is read. An optional tcl script, when defined in the command, will be executed whenever a monitored event is received from an IOC. Using the optional script, the user can implement an completely event driven application.


    Examples of correct forms of mon umon, and cmon:
  •   set varList {ai1 ao1 bi1}
  •   set iocList {IOC:beamCurrent IOC:outputCurrent IOC:beamStatus}
  •   pv link $varList $iocList
  •   pv link {c0 ai1 ai2 ai3 ai4} {T:calc T:ai1 T:ai2 T:ai3 T:ai4}
  •   pv mon $varList
  •   pv mon $varList {puts "Print this every event"}
  •   pv mon $varList tclProcedureName
  •   pv umon ai1
  •   pv umon ai1 {puts "Print this every event"}
  •   pv mon ai1 tclProcedureName
  •   pv mon {ai1 bi1}
  •   pv mon {ai1 bi1} {puts "Print this every event"}
  •   pv mon {ai1 bi1} tclProcedureName
  •   pv cmon $varList
  •   pv cmon ai1
  •   pv cmon {ai1 bi1}
  • info

      pv info tclVars requestedInfo
    Description: Obtain information in the form of a list of lists about linked tcl variables stored in the interface. Any or all of the following information may be requested in any order. Information is available for:
      Examples of correct forms of info:
  •  set varList {ai1 ao1 bi1}
  •  set iocList {IOC:beamCurrent IOC:outputCurrent IOC:beamStatus}
  •  pv link $varList $iocList
  •  pv link {c0 ai1 ai2 ai3 ai4} {T:calc T:ai1 T:ai2 T:ai3 T:ai4}
  •  pv getw $varList
  •  pv info ai1 state
  •  pv info ai1 {state ioc name units severity status}
  •  pv info ai1 {units state name ioc}
  •  pv info $varList {state severity status time}
  •  pv info $varList severity
  •  pv info {ai1 bi1} {name choices hopr lopr precision units lo lolo ioc access}
  • stat

      pv stat tclVar associative_array_name
    Description: Obtain state, status, severity, and time information about a single process variable as elements (state, status, severity and time) of an tcl associative array named in command. The array is created if it doesn't exist.


    Comments: In tcl scripts `stat' provides a more convenient command type than `info'.

     Examples of correct forms of stat:

  •  set varList {ai1 ao1 bi1}
  •  set iocList {IOC:beamCurrent IOC:outputCurrent IOC:beamStatus}
  •  pv link $varList $iocList
  •  pv link {c0 ai1 ai2 ai3 ai4} {T:calc T:ai1 T:ai2 T:ai3 T:ai4}
  •  pv getw $varList
  •  pv stat ai1 arrayName1
  •  pv stat bi1 arrayName2
  •  pv stat ao1 arrayName3
  •  set arrayName1(state)
  •  set arrayName2(severity)
  • set arrayName3(status)
  • <<<<start multi-element (vector) record oriented operations>>>>>>>>>


  •   pv linkw s et:256ushort
  •   pv linkw d et:512double
  •   set varList { d s }
  •   pv vmap s svec
  •   pv vmap d dvec
  •   pv vmap $varList { dvec svec }



    Description:  Specify the names of  BLT vectors (svec,dvec in syntax examples ) to be mapped to tcl variables (s,d in syntax examples) which were previously linked (link(w)) to multi-element process variables (et:256ushort, et:512double). The vector will be automatically created. Also, the vector will be reset and updated whenever the mapped tcl variable is read either by a get(w) or a monitor.  The tcl variable will only reflect the first element  data value while the vector will contain all the element data values. The vector data can  be operated upon by all the vector  operations supported by BLT. The vector data will be sent to the process variable whenever a put, putw, or putq operation is performed on the mapped tcl variable.  If the vector is resized by one of the BLT operations in tcl code only the minimum of --the size of the vector or the number of elements in the process variable -- will be sent to the process variable via a put(w).  If the tcl variable is unlinked, the vector is destroyed.

    The BLT graph command can use a vector as one of its coordinates and the graph will automatically be updated whenever the vector changes. This provides an especially efficient method to graph 2-D data.


    Example :

    # et:256ushort is a 256 element waveform record of unsigned shorts
    #  consult BLT documentation for how to use vectors in tcl code

  •  pv linkw s et:256ushort
  •  pv info s state
  •  pv vmap s svector
  •  svector seq 0 255 1
  •  pv put s
  •  pv get s
  •  set svector(100:111) 11
  •  pv put s
  •  blt::create x
  •  x seq -128 128 1
  •  svector expr { abs(x(0:255)) * 2 }
  •  pv put s



    NOTE: the following two operations vdef and vset are still suported but it is recommended to use the vmap operation described above.

    vdef, vset

  •   pv vdef tclVars {base size precision}
  •   pv vset tclVars {list of values to be written to tclVars}
  •   pv vvec tclVars bltVectors



    Description: Both of these operations  are used to deal with multi-element and waveform records. For multi-element and single element records the link, get, put, and mon command types operate the same and transfer all the process variable elements into an internal et interface buffer. However, for multi-element process variables the linked tcl variable only reflects the value of the first element. The user can read and write multi-element data stored in the interface buffer using a "view" mechanism. A view is a defined subset of a multi-element record which will be subsequently used for accessing data from the record.

      Examples of correct forms of vdef and vset:
  •  pv link {wf1 wf} {vong:xy566WaveformCh0 vong:xy566WaveformCh1}
  •  pv get {wf1 wf}
  •  pv vdef wf1{100 50 2}
  •  pv vset wf1
  •  pv vset wf1 {1 2 33 56.4 987.56 1.01}
  •  pv vdef wf1 {150 50 5 }

    5. Variable Mapping : EPICS Native->TCL

    string  string 
    enum( with string elements) enum string
    enum( no string elements defined) value string
    char long
    integer long
    long long
    float float
    double double

    6. Usage

    There are typically only three steps needed to communicate with an EPICS database:
      The user must keep in mind that command types link, get, and put involve transferring data over a network which means that the user must check that the network operation has successfully completed. The return result (either 0 or 1) of these command types together with the stat/info command type are used to insure that the operation was successful. In addition, when the command type is a get the user must insure that the data is valid (the network operation might have succeeded but the GPIB instrument timed out during a GPIB read). The stat/info command type is also used to check the validity of data.

     The user must keep in mind that both the process variable in an IOC and the tcl linked variable can change at any time and are only synchronized only during a get or put type command.

     Use of lists is encouraged in link, get, put and mon types to improve the efficiency of the network communications.

     Use of mon types is encouraged for process variables which change infrequently (at least less frequently than referenced in script) and for applications which are designed to be event driven.

     When checking the state, status, severity, and time in scripts, it is usually easier to use the stat command type. Info works well for interactive use.

     The put and putw command types require notification from the IOC that the record has processed before completion. It is much better to rely on readback process variables to ensure that a put operation has successfully completed. With a readback available use of putq is preferred. The putq does not require IOC notification before completing.

     When using asynchronous forms of link, get and put, the application must give the X-event loop time to process before each check on completion. The tcl/tk event loop processes whenever user code is not running, or whenever certain tck/tk command are issued as described in the tcl/tk documentation. Otherwise, the application code will end up in an endless loop testing for something (state, status, severity, time) that never gets updated.

     In the script associated with monitors, THE SYNCHRONOUS COMMAND TYPES LINKW, PUTW and GETW SHOULD NOT BE USED (this is a network software limitation related to code reentrancy).


    For ENUM database process variables which DO NOT have strings defined, use of numbers is supported.
    `state' is a two-character string, whose possible values are: NC->NeverConnected, LC->LostConnection, RD->NoReadAccess, WR->NoWriteAccess, IO->I/OinProgress, OK->OK
    When a list of values to be written is not included as the final word of the vset command type, vset returns a list of values (defined by vdef).