Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  <20032004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  <20032004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
<== Date ==> <== Thread ==>

Subject: EPICS PV aliases? (rather long-winded)
From: "Hoff, Lawrence" <>
Date: Fri, 24 Oct 2003 10:30:12 -0400

For some time, I've been thinking about the subject of aliases. I regret now not bringing up the subject at the Collaboration meeting last week. I think there could have been good dialog. My excuse for bringing it up here and now is that ICALEPCS piqued my interest again. My real question is whether the idea of aliases is one that has already been discussed and settled, or whether there is interest in pursuing the idea. I especially hope its not just an existing feature that I am unaware of. We can, of course, bring it up at the next Collaboration Meeting. Here's my take on the subject:

	The RHIC control system supports aliases in the client-side
directory services. We find this useful for two general categories of
situations; transition between names, and multiplexing records. The
former uses aliases only during the transition period. The latter makes
permanent use of aliases.

	There are a couple situations that create the need for
transitioning between names:

	1) The naming standard changes, or was not correctly understood
when the PVs were first named and deployed. Perhaps there are EDM
screens or other applications deployed as well as the IOC. In order
to change the PV names to the "correct" values, the IOC must be rebooted
at the same time the new EDM screens are released (and old EDM screens
reloaded). The coordination needed for this type of release often leads
to "old" names living longer than desired. Using aliases, both "old"
and "new" names can co-exist for a transition period while old EDM
screens continue to be supported, and new screen are rolled out.

	2) The mission of the PV changes over time. E.g. today the
digitizer/scope/timing trigger is connected to one beam diagnostic
system, but next month it is connected to a different system. Another
variation on this theme is the idea of deploying/testing IOCs before
the final "mission" of the H/W is specified. For RHIC we took advantage
of that by deploying digitizers and function generators with "generic
names" (funcGen1, funcGen2, adc1, adc2) for testing purposes, well ahead
of when the PS group was ready to provide detailed wiring diagrams.
As the "mission" was being finalized, we used aliases to assign mission-
specific names to signals while retaining the "generic name" in case the
PS group changed their minds as they wired up the signals.

	The idea of multiplexing records has cropped up at SNS, which
is my real impetus behind thinking about aliases.....

	There is a "virtual scope" application in use at SNS. It is a
very sophisticated application, designed for high performance, and
flexible configuration. One feature of this application is that it can
display signals with different time bases (sample frequency, trigger
times). It does this by associating time-PVs with the signal-PV. This
association is done via the PV name. I.e. if the signal-PV has a name
like "LINAC_BPM_004", the trigger time PV must have a name like
"LINAC_BPM_004_trigger". The trouble with this scheme is that there
can be dozens of signals that all share the same time base. To support
the virtual scope, there needs to be one set of time-PVs for every
signal-PV, even though they all contain identical values. Of course,
this could be corrected in the virtual scope by configuring it to use
specific time-PVs, rather than making constructions based on the name
of the PV, but then the application loses its generality.

	Having a set of aliases which support the virtual scope, but all
of which refer to the same underlying record removes duplication and
preserves generality.

	OK, assuming that aliases are therefore "a good thing", what
are the potential pitfalls, and how could one implement them in a
server-side context, rather than in a directory service?

	Our RHIC experience indicates that there still should be one
and only one "canonical" name for a record. I.e. as silly as it sounds
when you ask "record, what is your name?" you should get the same answer
whether you are using an alias or not. Otherwise one cannot do
meaningful save/compare/restore operations before/during/after a
transition period.

	Existing diagnostic tools should act in a natural way. I.e.
a tool which should print out all the records in an IOC should not
print out duplicates just because aliases are in effect for that record.
However, tools which search for records by name should work with either
the canonical name or the alias.

	Alias should be easy to configure and manage. There must be
diagnostic tools which allow one to print out the set of aliases in

	OK, with all that in mind, is it still possible/reasonable
to implement aliases on the server-side (putting aside for the moment
the question of whether it is a good idea to do so)? I believe the
answer is "Yes, it is trivially easy to do so." For those who care about
details, I'll support this claim with detailed explanation of how I
think it can be done, and even some source code with a "reference
implementation" at the end of this message.

	For now, I'll show some examples of how it might work.
Suppose there is a function called "addPvAlias" which takes two
arguments. The first is the name of an existing record. The second
is an alias name. Suppose there is also a diagnostic function "dbla"
which prints out all the aliases on an IOC. Here's how it might work:

value = 0 = 0x0
value =  = 0x0

HOST>caget "larryTest1.NAME"
 larryTest2.NAME --- Invalid channel name

VXWORKS> addPvAlias "BNL_test:iocsns170:Time", "larryTest1"
value = 33542248 = 0x1ffd068 = dbla + 0xa8
value = 0 = 0x0
alias: larryTest1, name: BNL_test:iocsns170:Time
value = 1 = 0x1
VXWORKS> dbpr "larryTest1"
ASG:                DESC: The current time                  DISA: 0
DISP: 0             DISV: 1             NAME: BNL_test:iocsns170:Time
RVAL: 0             SEVR: NO_ALARM      STAT: NO_ALARM      TPRO: 0
VAL: OCT 24 10:18:52
value = 0 = 0x0

HOST>caget "larryTest1.NAME"
larryTest1.NAME               BNL_test:iocsns170:Time

The source code which follows implements this by adding elements to the "PV directory", which point to existing records. I.e. it supports the idea of 1->N mapping between records and directory entries on the IOC, rather than a 1->1 mapping. This allows name lookup to work correctly, without changing the actual record count on the IOC. A separate list is maintained of aliases which have been successfully added to the IOC.

Here is the (hacked up) source code. This module can be compiled
and loaded to a running EPICS system. To properly implement aliases,
similar code would be implemented with the PV directory module in
IOC core.


-- Larry

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char *strdup(const char *s){

  char *dup = (char *) malloc(strlen(s)+1);
  if(dup) strcpy(dup, s);
  return dup;

/* #include <libCom/ellLib.h> */
struct ELLNODE {
  struct ELLNODE  *next;
  struct ELLNODE  *previous;

typedef struct ELLNODE ELLNODE;

struct ELLLIST {
  ELLNODE  node;
  int   count;

typedef struct ELLLIST ELLLIST;

extern ELLNODE *ellNext (ELLNODE *pNode);

/* #include <dbStatis/dbStaticPvt.h> */
struct dbRecordType; typedef struct dbRecordType dbRecordType;
struct dbBase; typedef struct dbBase dbBase;

extern dbBase *pdbbase;

/* #include <dbStatis/dbBase.h> */

typedef struct dbRecordNode {
        ELLNODE         node;
        void            *precord;
        char            *recordname;
        int             visible; /* 0 */

typedef struct{
        ELLNODE         node;
        dbRecordType    *precordType;
        dbRecordNode    *precnode;

static ELLLIST aliasList; /* automatically initialized to 0 */

typedef struct {
  ELLNODE node;
  const char *name;
  const char *alias;
} aliasNode;

extern PVDENTRY *dbPvdFind(dbBase *pdbbase,char *name,int lenName);

extern PVDENTRY *dbPvdAdd(dbBase *pdbbase,dbRecordType *precordType,dbRecordNode

PVDENTRY *addPvAlias(char *name, const char *alias){

if(!name || !alias) { errno = -1; return NULL; }

  PVDENTRY *enode = dbPvdFind(pdbbase, name, strlen(name));

if(!enode) { errno = -1; return NULL; }

  dbRecordNode *recnode = (dbRecordNode *) calloc(sizeof(dbRecordNode), 1);

if(!recnode) { errno = -2; return NULL; }

  recnode->precord = enode->precnode->precord;
  recnode->recordname = strdup(alias);

  PVDENTRY *retval = dbPvdAdd(pdbbase, enode->precordType, recnode);
  if(!retval) { errno = -3; return NULL; }

    aliasNode *anode = calloc(sizeof(aliasNode),1);
    if(!anode) { errno = -4; return NULL; }

    anode->name = enode->precnode->recordname;
    anode->alias = recnode->recordname;
    ellAdd(&aliasList, anode);

unsigned long dbla(void){

aliasNode *enode = (aliasNode *);


printf("alias: %s, name: %s\n", enode->alias, enode->name);

enode = (aliasNode *) enode->;


return aliasList.count;


Re: EPICS PV aliases? (rather long-winded) Bob Dalesio

Navigate by Date:
Prev: Re: EPICS PV aliases? (rather long-winded) Bob Dalesio
Next: Re: EPICS PV aliases? (rather long-winded) Alan K Biocca
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  <20032004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
Navigate by Thread:
Prev: What channel access method in EDM Liyu, Andrei
Next: Re: EPICS PV aliases? (rather long-winded) Bob Dalesio
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  <20032004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
ANJ, 10 Aug 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·