VxWorks global symbol device support

This document describes the unbundled version of the symbol support that is intended for use with EPICS Base R3.14.4 and later. Earlier versions of this device support were included with EPICS Base.

Overview

VxWorks gives the programmer access to a library of symbol table support routines and provides a global symbol table which contains all external variable and function references in the system. The device support module described here allow selected record types to read and write variables referenced by name. This capability allows EPICS to monitor and influence VxWorks-runnable code which was written without any knowledge of EPICS; the code needs only to have its critical variables declared externally, that is, left non-static outside any function definitions in the usual `C' manner.

Adding to an application

IOC applications using this module should have a line like this in their configure/RELEASE file:

SYMB=/path/to/installed/symb

Database Definition file entries for the device support are given in the installed file dbd/symb.dbd. This must be linked into the application with the following entry in an appropriate appInclude.dbd file:

include "symb.dbd"

The device support routines described below are compiled into an object library lib/<arch>/libSymb.a. This file must be searched when building the binary object for the IOC by adding it to the application's Makefile as follows:

myapp_LIBS_vxWorks += Symb

Description

Device support is provided for most of the standard input and output record types. These provide the ability to read and write double (ai, ao), long (bi, bo, mbbi, mbbo, longin, longout), and char * (stringin, stringout) variable types. Waveform records use the TYPE field to select which variable type to read.

The device type "vxWorks Variable" is defined for each of the above record types in the symb.dbd file. Within a database the name of the VxWorks symbol desired is obtained one of two ways, depending on whether the LINK field type is a CONSTANT or INST_IO.

CONSTANT
The name of the vxWorks global variable is derived from the record name by stripping off any prefix ending with the first ":" and any suffix starting with the last ";". An underscore is automatically prefixed if required by the particular target architecture.

For example: "ppp:fred;sss" refers to the vxWorks global variable "fred".

The intention is that the prefix would refer to the IOC and the suffix would distinguish references within an IOC. Suffixes and prefixes are optional.

INST_IO
The string value of the link field is assumed to be of the form:
[ "*" ] name [ "[" index "]" ]

where quoted items are literal and square brackets imply optional items. White space is ignored. The leading "*", if specified, implies that the variable in question is a pointer containing the address of the desired data. The name is the name of the vxWorks global variable (a leading underscore is added if required by the target architecture). The optional array index is multipled by the data element size (e.g. sizeof(char), sizeof(long) or sizeof(double)) and applied as an offset to the data address.

For example:

DIRECT
"fred" refers to the value of the vxWorks global variable "fred"

INDIRECT
"*fred" refers to the value whose address is given in the vxWorks global pointer "fred". The value of the pointer will be read at run-time rather than initialisation, allowing it to be changed dynamically.

INDEXED
"fred[1]" states that the vxWorks global variable "fred" is an array and refers to its second element

INDIRECT + INDEXED
"*fred[1]" states that the vxWorks global pointer "fred" contains the address of an array, and refers to the second element of that array

Note that the interpretation of the "*" operator is not the same as in C. For example, "fred" and "fred[0]" produce the same result, but "*fred" and "fred[0]" are different.

Finally note that strings are not treated any differently from longs or doubles in that the address returned from this routine is simply the address of the data. "fred" is the entire string. "fred[2]" starts at the third character of the string.

Symbol table lookup is performed only at record init time; the resulting pointer is stored in the DPVT field. (The indirection, if present, is resolved at run time.) If the symbol is not found an illegal NAME field error is posted and DPVT is set to NULL. Processing consists of reading or writing the VAL field using the pointer, unless the pointer is NULL, in which case the device support module exits immediately.

Other than for the multi-bit raw support no value conversions are performed; it is assumed that the symbol refers to a variable of the same type as the record's VAL field. String operations are restricted to the 40 character size of the string record VAL fields and null termination is enforced.

No exclusion or interlocking with other code using the referenced variable is provided, other than locking interrupts while reading or writing the value. Synchronization must be provided by the appliation on a case-by-case basis. Typically the vxWorks code will poll for its input variables (set by output record types) and EPICS will poll the code's output variables with suitable SCAN field values (using input record types).


Updated Andrew Johnson, 1999 & 2003