Epics@GSI Webhome

Epics Tips And Tricks And Examples

Introduction

Collection of Apps, Tricks and Tipps

<div style="text-align:right"><a style="font-size:smaller" href="/edit/Epics/SeqRecordsDelayTimingAndProcessing">edit</a></div>

seq Records Delay Timing and Processing

    seq-record.png

    • The calc record serves as a 10Hz Time reference.
    • The seq record:
      • is scanned every 10 s
      • each of the LNKx get its input value from the calc reference, delayed by DLYx
    • alert the seq record stays active until all LNKs have been processed.
    • alert the nested second, delayed, and "PPed" seq record "seq2" doesn't delay the execution of LNK4
    • alert LNK5 to a dummy record introduces an addditional delay, before "ai5" is "FLNKed" (Listing 1)
      otherwise (LNK5 undefined) "ai4" and "ai5" do get the (almost) same time (Listing 2)

    Listing 1
    > camonitor ai1 ai2 ai3 ai4 ai5 ai6
    ai1                            <undefined> 0 UDF INVALID
    ai2                            <undefined> 0 UDF INVALID
    ai3                            <undefined> 0 UDF INVALID
    ai4                            <undefined> 0 UDF INVALID
    ai5                            <undefined> 0 UDF INVALID
    ai6                            <undefined> 0 UDF INVALID
    
    ai1                            2015-06-12 11:20:43.537023 10.4  
    ai2                            2015-06-12 11:20:45.532220 12.4  
    ai3                            2015-06-12 11:20:45.927412 12.8  
    ai4                            2015-06-12 11:20:46.723239 13.6  
    ai5                            2015-06-12 11:20:50.718449 17.6  
    ai6                            2015-06-12 11:20:51.422657 18.3  
    
    ai1                            2015-06-12 11:20:53.548024 20.5  
    
    Listing 2
    > camonitor ai1 ai2 ai3 ai4 ai5 ai6
    ai1                            2015-06-12 11:34:01.036987 10.4  
    ai2                            2015-06-12 11:34:03.032172 12.4  
    ai3                            2015-06-12 11:34:03.427368 12.8  
    ai4                            2015-06-12 11:34:04.222552 13.6  
    ai5                            2015-06-12 11:34:04.222568 13.6  
    ai6                            2015-06-12 11:34:08.923422 18.3  
    
    ai1                            2015-06-12 11:34:11.037168 20.4  
    

-- PeterZumbruch - 2017-03-31

<div style="text-align:right;font-size:smaller">EpicsTipsAndTricksMultipleIOCs <a href="/edit/Epics/EpicsTipsAndTricksMultipleIOCs">(edit)</a></div>

multiple IOCs

To have one PC / Computer per IOC/Server seems to be an annoying situation.
Solution would be to be able to have several IOCs running on a PC. But you will be faced by the following Problems
(taken from talk of Kenneth Evans: "_Channel Access in Depth_", Kenneth Evans, Jr., March 8, 2005 as Part of the EPICS “Getting Started” Lecture Series, p15):

Multiple Servers on the Same Host
  • Used to not be possible at all (Base 3.13)
  • Now, it can be done, but there are problems
  • Will get message
    • cas warning: Configured TCP port was unavailable. Using dynamically assigned TCP port 45003, but now two or more servers share the same UDP port. Depending on your IP kernel this server may not be reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)
  • First part means clients will establish their circuit on another port than the default 5064.
    • Not a problem
  • Second part means unicast search requests may not get to both servers
    • UDP deficiency, similar to the CaRepeater problem
    • May be a problem when EPICS_CA_ADDR_LIST is used

    Solution 1: EPICS_CA_ADDR_LIST

    EPICS_CA_ADDR_LIST
    • Determines where to search
    • Is a list (separated by spaces)
      • “123.45.1.255 123.45.2.14 123.45.2.108”
    • Default is broadcast addresses of all interfaces on the host
      • Works when servers are on same subnet as clients
    • Broadcast address
      • Goes to all servers on a subnet
      • Example: 123.45.1.255
      • Use ifconfig –a on UNIX to find it (or ask an administrator)

By setting the EPICS_CA_ADDR_LIST, the EPICS Channel Access (Client) Address List on the client site.
E.g. for MEDM:
  1. export EPICS_CA_ADDR_LIST and start medm in the same session
    $> export EPICS_CA_ADDR_LIST && medm &

    Solution 2: make use of more EPICS environment variables to allow inter IOC communication

    Following the thread in tech-talk Multiple IOC from 2007:
       It was fixed by setting the CAS Beacon Address List to the address and ports of the other IOC's CA repeater port.
    
       IOC1
    
       EPICS_CAS_BEACON_ADDR_LIST=nnn.nnn.nnn.nnn:5071
       EPICS_CA_ADDR_LIST=nnn.nnn.nnn.nnn:5070
    
       IOC2
    
       EPICS_CA_Server_Port=5070
       EPICS_CAS_Server_Port=5070
       EPICS_CA_Repeater_Port=5071
       EPICS_CAS_BEACON_ADDR_LIST=nnn.nnn.nnn.nnn:5065
       EPICS_CA_ADDR_LIST=nnn.nnn.nnn.nnn:5064
    
    

-- PeterZumbruch - 2018-01-08

<div style="text-align:right;font-size:smaller">EpicsTipsAndTricksCrisAxisAddtionForSeveralEpicsApplications <a href="/edit/Epics/EpicsTipsAndTricksCrisAxisAddtionForSeveralEpicsApplications">(edit)</a></div>

cris-axis addition for several EPICS applications

HOWTO build flex (libfl) for cris-axis crisv32-axis

Since some of the EPICS extensions and modules rely on libfl flex and the standard distribution of AXIS SDK doesn't contain the libfl.a this has to be added:
Prerequisites
  • Axis SDK
  • cross compiler

Build & Installation

  1. set some helper variables:
    export SRC_DIR=<Source Directory>
    export DOWNLOAD_DIR=<Download Directory>
    # provided cross compiler and SDK are installed here export ETRAX_DIR=<ETRAX Tools Directory>
  2. download sources from http://sourceforge.net/projects/flex/ (version 2.5.35) via direct link to $DOWNLOAD_DIR
    mkdir -p ${DOWNLOAD_DIR:?undefined} &&
    wget http://prdownloads.sourceforge.net/flex/flex-2.5.35.tar.bz2?download
  3. unpack to $SRC_DIR
    mkdir -p ${SRC_DIR:?undefined} &&
    cd SRC_DIR &&
    tar -jxvf flex-2.5.35.tar.bz
  4. Source cris-axis-setup.sh ,defining environment variables, e.g. AXIS_TOP_DIR, and extending PATH, needs ETRAX_DIR to be defined. or just take its main code:
    oldpwd=$OLDPWD
    base=$(pwd)
    cd ${ETRAX_DIR:?undefined)/SDK && cd $(ls --color=never -t -1 -d devbo* | head -n 1) && . ./init_env
    cd $base
    cd ${ETRAX_DIR:?undefined)/ETRAX/compiler && . ./setup.sh
    cd $oldpwd
    cd $base
    unset scriptname base oldpwd epicsDir
  5. Change to source directory $SRC_DIR
    cd ${SRC_DIR:?undefined}
  6. Since configure automatically sets for cross-compilers 'ac_cv_func_malloc_0_nonnull' and 'ac_cv_func_realloc_0_nonnull' to 'no', (since it cannot check it) those have to be configured by hand:
    1. cris-axis
      1. export myTARGET=cris-axis-linux-gnu
      2. make clean
      3. ./configure --prefix=${AXIS_TOP_DIR:?undefined}/target/${myTARGET:?defined}/usr --host=${myTARGET} --build=i686-pc-linux-gnu ac_cv_func_realloc_0_nonnull=yes ac_cv_func_malloc_0_nonnull=yes
      4. make
      5. make install
    2. crisv32-axis
      1. export myTARGET=crisv32-axis-linux-gnu
      2. make clean
      3. ./configure --prefix=${AXIS_TOP_DIR:?undefined}/target/${myTARGET:?defined}/usr --host=${myTARGET} --build=i686-pc-linux-gnu ac_cv_func_realloc_0_nonnull=yes ac_cv_func_malloc_0_nonnull=yes
      4. make
      5. make install

    Compact
      export SRC_DIR=<Source Directory>
      export DOWNLOAD_DIR=<Download Directory>
      # provided cross compiler and SDK are installed here
      export ETRAX_DIR=<ETRAX Tools Directory>

      mkdir -p ${DOWNLOAD_DIR:?undefined} &&
      wget http://prdownloads.sourceforge.net/flex/flex-2.5.35.tar.bz2?download

      mkdir -p ${SRC_DIR:?undefined} &&
      cd SRC_DIR &&
      tar -jxvf flex-2.5.35.tar.bz

      oldpwd=$OLDPWD
      base=$(pwd)
      cd ${ETRAX_DIR:?undefined)/SDK && cd $(ls --color=never -t -1 -d devbo* | head -n 1) && . ./init_env
      cd $base
      cd ${ETRAX_DIR:?undefined)/ETRAX/compiler && . ./setup.sh
      cd $oldpwd
      cd $base
      unset scriptname base oldpwd epicsDir

      # crisv-axis
      export myTARGET=cris-axis-linux-gnu
      cd ${SRC_DIR:?undefined} &&
      make clean
      ./configure --prefix=${AXIS_TOP_DIR:?undefined}/target/${myTARGET:?defined}/usr --host=${myTARGET} --build=i686-pc-linux-gnu ac_cv_func_realloc_0_nonnull=yes ac_cv_func_malloc_0_nonnull=yes &&
      make && make install

      # crisv32-axis
      export myTARGET=crisv32-axis-linux-gnu
      cd ${SRC_DIR:?undefined} &&
      make clean
      ./configure --prefix=${AXIS_TOP_DIR:?undefined}/target/${myTARGET:?defined}/usr --host=${myTARGET} --build=i686-pc-linux-gnu ac_cv_func_realloc_0_nonnull=yes ac_cv_func_malloc_0_nonnull=yes &&
      make && make install

-- PeterZumbruch - 09 Apr 2009

-- PeterZumbruch - 2017-03-31

<div style="text-align:right;font-size:smaller">EpicsTipsAndTricksNewIocCommand <a href="/edit/Epics/EpicsTipsAndTricksNewIocCommand">(edit)</a></div>

new IOC command

The general way how to add a new IOC command, which can be used inside the IOC Shell is described in Chapter 18.3 IOC Shell - IOC Shell Programming of the IOC Application Developer's Guide (3.14.9).

Here is an example (with the help of BK) to make the command dumpTable(mbo, dac, channel, type) available at the IOC shell.

  • application.c
      #include <epicsExport.h>
      
      /* ... */ 
      
      /***************************************************************************/
      static void dumpTable(int mbo, int dac, int channel, short type)
      {
        /* some function code */
        /* ... */ 
      }
      /***************************************************************************/
      
      /* Information needed by iocsh */
      /* Argument definition */
      static const iocshArg  dumpTableArg0 = {"mbo number",     iocshArgInt};
      static const iocshArg  dumpTableArg1 = {"dac number",     iocshArgInt};
      static const iocshArg  dumpTableArg2 = {"channel number", iocshArgInt};
      static const iocshArg  dumpTableArg3 = {"table type",     iocshArgInt};
      static const iocshArg  *dumpTableArgs[] = 
      {
        &dumpTableArg0,
        &dumpTableArg1,
        &dumpTableArg2,
        &dumpTableArg3
      };
      /* Function definition */
      static const iocshFuncDef dumpTableFuncDef = {"dumpTable", 4, dumpTableArgs};
      
      /* Wrapper called by iocsh, selects the argument types that dumpTable needs */
      static void dumpTableCallFunc(const iocshArgBuf *args) {
        dumpTable(args[0].ival, args[1].ival, args[2].ival, args[3].ival);
      }
      
      /* Registration routine, runs at startup */
      static void dumpTableRegister(void) {
          iocshRegister(&dumpTableFuncDef, dumpTableCallFunc);
      }
      epicsExportRegistrar(dumpTableRegister);
      

  • application.dbd
      variable(mySubDebug)
      ...
      registrar(dumpTableRegister)
      
-- PeterZumbruch - 08 May 2008

-- PeterZumbruch - 2018-01-08

<div style="text-align:right;font-size:smaller">EpicsTipsAndTricksUseOfMsiWithMultipleTempleateFiles <a href="/edit/Epics/EpicsTipsAndTricksUseOfMsiWithMultipleTempleateFiles">(edit)</a></div>

use of msi with multiple template files

To produce a single db file from multiple template files it is sufficient to include in the Makefile in the app/Db directory the line with the name of the db. This should be a not existing file (because it will be produced). Existing must be the corresponding substitutions file and the template file(s). In case that the substitutions file calls to a multiple template files is necessary to have an independent name from them, otherwise the generated db file will be only based on the same name template file.

Be aware that none of the template files should have the same name as the substitutions file.

Example: To make a db called vulom_1.db use a file vulom_1.substitutions which references for instance vulom.template, vulomreg.template, and vulomreg1.template

vulom_1.substitutions:
    file vulom.template {
    { PRE=HAD, NN="0", MM="1"}
    }
    file vulomreg.template {
    { PRE=HAD, NN="0", MM="1", CC="Del_0", AA="0", LIM="49.5", GAIN="3.3", LLIM="0"}
    { PRE=HAD, NN="0", MM="1", CC="Del_1", AA="1", LIM="49.5", GAIN="3.3", LLIM="0"}
    }
    file vulomreg1.template {
    { PRE=HAD, NN="0", MM="1", CC="Down_0", AA="7", LIM="15", GAIN="1"}
    { PRE=HAD, NN="0", MM="1", CC="Down_1", AA="8", LIM="15", GAIN="1"}
    }
    

The Makefile should contain a line
    DB += vulom_1.db
    

additional Dependencies

Adding the line in the Makefile
    vulom_1_DEPENDS ?= $(shell perl -n -e 'if (/file\s+(\w+.template)/) {print "$$1 \n";}' vulom_1.substitutions )
    
right after the previous
    DB += vulom_1.db
    
enables EPICS to check for dependencies (q.v. IOC Application Developer's Guide - 3.14.9 Chapter 4.6.4):
    If a <name> substitutions file contains "file" references to other input files, these referenced files should be made dependencies of the created <name>.db by adding a dependency definition line:
    <name>_DEPENDS = <filename1> <filename2> ...
-- PeterZumbruch - 09 May 2008

-- MartinMitkov - 2017-03-31

-- PeterZumbruch - 2018-01-08


-- PeterZumbruch - 2017-03-31
-- PeterZumbruch - 2017-03-31

This topic: Epics > WebHome > DevelopersCorner > EpicsTipsAndTricksAndExamples
Topic revision: 2017-03-31, PeterZumbruch
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding GSI Wiki? Send feedback | Legal notice | Privacy Policy (german)