StreamDevice: Setup

1. Prerequisites

StreamDevice requires EPICS base R3.14.6, R3.14.7, or R3.14.8. Since StreamDevice comes with an interface to asynDriver as the underlying driver layer, you should have asynDriver installed first. The current StreamDevice version works with asynDriver version 4-3 or 4-4. Make sure that the asyn library can be found, e.g. by adding a line like this to your <top>/configure/RELEASE file:

ASYN=/home/epics/asyn/4-4

Please refer to the IOC Application Developer's Guide chapter 4: EPICS Build Facility.

2. Build the StreamDevice Library

Unpack the file StreamDevice-2-0.tgz in a <top> directory of your application build area. (You might probably have done this already.) Go to the newly created subdirectory StreamDevice-2-0 and run make (or gmake). This will create and install the library stream and the stream.dbd file. The sources of the StreamDevice library are in the StreamDevice-2-0/src directory.

3. Build an Application

To use StreamDevice, your application must be built with the stream and asyn libraries and must load stream.dbd and asyn.dbd.

Include the following lines in your application Makefile:

PROD_LIBS += stream
PROD_LIBS += asyn

Include the following lines in your xxxAppInclude.dbd file to use stream and asyn with serial lines and IP sockets:

include "base.dbd"
include "stream.dbd"
include "asyn.dbd"
registrar(drvAsynIPPortRegisterCommands)
registrar(drvAsynSerialPortRegisterCommands)

You can find an example application in StreamDevice-2-0/streamApp.

4. The Startup Script

StreamDevice is based on protocol files. To tell StreamDevice where to search for protocol files, set the environment variable STREAM_PROTOCOL_PATH to a list of directories to search. On Unix systems, directories are separated by :, on Windows systems by ;. The default value is STREAM_PROTOCOL_PATH=., i.e. the current directory.

Also configure the buses (in asynDriver terms: ports) you want to use with StreamDevice. You can give the buses any name you want, like COM1 or socket, but I recommend to use names related to the connected device.

Example:

A power supply with serial communication (9600 baud, 8N1) is connected to /dev/ttyS1. The name of the power supply is PS1. Protocol files are either in the current working directory or in the ../protocols directory.

Then the startup script must contain lines like this:

epicsEnvSet ("STREAM_PROTOCOL_PATH", ".:../protocols")

drvAsynSerialPortConfigure ("PS1","/dev/ttyS1")
asynSetOption ("PS1", 0, "baud", "9600")
asynSetOption ("PS1", 0, "bits", "8")
asynSetOption ("PS1", 0, "parity", "none")
asynSetOption ("PS1", 0, "stop", "1")

5. The Protocol File

For each different type of hardware, create a protocol file which defines protocols for all needed functions of the device. The file name is arbitrary, but I recommend that it contains the device type. It must not contain spaces and should be short. During iocInit, streamDevice loads and parses the required protocol files. If the files contain errors, they are printed on the IOC shell. Put the protocol file in one of the directories listed in STREAM_PROTOCOL_PATH.

Example:

PS1 is an ExamplePS power supply. It communicates via ASCII strings which are terminated by <carriage return> <line feed> (ASCII codes 13, 10). The output current can be set by sending a string like "CURRENT 5.13". When asked with the string "CURRENT?", the device returns the last set value in a string like "CURRENT 5.13 A".

Normally, an analog output record should write its value to the device. But during startup, the record should be initialized from the the device. The protocol file ExamplePS.proto defines the protocol setCurrent.

Terminator = CR LF;

setCurrent {
    out "CURRENT %.2f";
    @init { 
        out "CURRENT?";
        in "CURRENT %f A";
    }
}

Reloading the Protocol File

During development, the protocol files might change frequently. To prevent restarting the IOC all the time, it is possible to reload the protocol file of one or all records with the shell function streamReload("record"). If "record" is not given, all records using StreamDevice reload their protocols. Furthermore, the streamReloadSub function can be used with a subroutine record to reload all protocols.

Reloading the protocol file aborts currently running protocols. This might set SEVR=INVALID and STAT=UDF. If a record can't reload its protocol file (e.g. because of a syntax error), it stays INVALID/UDF until a valid protocol is loaded.

See the next chapter for protocol files in depth.

6. Configure the Records

To make a record use StreamDevice, set its DTYP field to "stream". The INP or OUT link has the form "@file protocol bus [address [parameters]]".

Here, file is the name of the protocol file and protocol is the name of a protocol defined in this file. If the protocol requires arguments, specify them enclosed in parentheses: protocol(arg1,arg2,...).

The communication channel is specified with bus and addr. If the bus does not have addresses, addr is dispensable. Optional parameters are passed to the bus driver.

Example:

Create an output record to set the current of PS1. Use protocol setCurrent from file ExamplePS.proto. The bus is called PS1 like the device.

record (ao, "PS1:I-set")
{
    field (DESC, "Set current of PS1")
    field (DTYP, "stream")
    field (OUT,  "@ExamplePS.proto setCurrent PS1")
    field (EGU,  "A")
    field (PREC, "2")
    field (DRVL, "0")
    field (DRVH, "60")
    field (LOPR, "0")
    field (HOPR, "60")
}

Next: Protocol File

Dirk Zimoch, 2006