asynDriver: Asynchronous Driver Support - Release Notes

Release 4-12

August 19, 2009


A problem was introduced in R4-11 by not starting the autoconnect process until iocInit(), and operations that do not use the XXXSyncIO functions thus fail before iocInit(). This means, for example, that calls to asynSetOption() to set serial port parameters fail if done in a startup script before iocInit(). R4-12 fixes this problem by decoupling autoconnect operations from iocInit(). NOTE: The first call to the pasynCommon->connect() function now happens almost immediately after pasynManager->registerInterface() is called for the asynCommon interface. This timing is different from all previous asyn releases, and it means that port drivers must initialize everything required by asynCommon->connect() before they register the asynCommon interface. This may require minor re-ordering of the initialization sequence in some drivers.


Requests to set end-of-string values or serial port parameters are accepted even when the port is not connected. The request takes effect when the port is connected. This makes IOC startup more robust in the face of network or USB to serial adapters that may be unavailable on startup.

asynInt32Average, asynFloat64Average

If record is processed before new data have arrived (numAverage==0) set record to UDF/INVALID, set UDF to TRUE and leave value unchanged.

Release 4-11

June 16, 2009


asynReport at detail level 0 now reports only disconnected subaddresses.

The autoconnect code has undergone considerable modification. When a port is registered with autoConnect true, or whenever a port disconnect exception is raised on an autoConnect port, an attempt at connection occurs immediately followed by retry attempts at 20 second intervals. Attempts to queue requests to a disconnected port (even an autoConnect port) will be rejected. These changes have been made to reduce the occurences of 'connection flurries' and to ensure that requests do not languish in the queue when connections are broken.

Setting the trace mask or trace I/O mask for a port now also sets the trace mask or trace I/O mask for every device associated with that port.

Passing a NULL pasynUser argument to the setTraceMask and setTraceIOMask will set the asynBase (default) trace mask or trace I/O mask. To do this from the iocsh pass a zero length portName string to the iocsh commands asynSetTraceMask or asynSetTraceIOMask.


Add new version macros (ASYN_VERSION, ASYN_REVISION and ASYN_MODIFICATION). These are guaranteed to be numeric.

Add new asynStatus codes, asynDisconnected and asynDisabled. Attempts to queue a request to a disconnected or disabled port return these codes, respectively. Future changes to record support may propogate these to the record alarm status field.


Increased the size of the input buffer from 600 to 2048 bytes.


Fix from Takashi Asakawa, Yokogawa Electric Corporation, Japan to allow link identifiers with a value of zero.

devEpics (devAsynInt32, devAsynFloat64, devAsynUInt32Digital)


Add some cleanup code to eliminate memory/socket leaks.


The asynOctetSyncIO openSocket method will be removed in the next release. This method is redundant since it is no different than calling the connect method with the port name from a previous drvAsynIPPortConfigure command.


A new C++ base class called asynPortDriver from which real asyn port drivers can be derived. It greatly simplifies the code required to write a new asyn port driver. It is documented here.


A new test application to demonstrate the use of the new asynPortDriver C++ class. This driver simulates a simple digital oscilloscope, and includes a C++ driver, EPICS database, medm screen, and an example iocBoot directory in ioctestAsynPortDriver. It is described in the documentation for asynPortDriver.

Release 4-10

Sept. 2, 2008


Ths asynOctet writeRaw and readRaw methods have been removed. In most cases, if your code now calls readRaw or writeRaw it should be safe to simply change these calls to their non-Raw equivalent. If you're paranoid about someone interposing the end-of-string processing layer you could add something like the following to ensure that there is no end-of-string to match:


If you need to switch to 'raw' mode for a while and then back to 'eos mode', you can use code similar to that in devGpib.c:readArbitraryBlockProgramData:

char saveEosBuf[5];
int saveEosLen;
status = pasynOctet->getInputEos(asynOctetPvt,pasynUser,saveEosBuf,sizeof saveEosBuf,&saveEosLen);
if (status != asynSuccess) {
    epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,"Device EOS too long!");
    return -1;
if (saveEosLen)
if (saveEosLen)

When compiling your code against this new version of asyn you should pay particular attention to warning messages of the form "warning: initialization from incompatible pointer type". These are a good indication that you're initializing an asynOctet structure with the old-style I/O methods.


Add a strStatus method to convert an asynStatus code to a string.


Cleaned up timeout handling.

Fix memory leak (one epicsAtExit entry was allocated for every connect).

asynReport no longer reports as connected a port which has successfully disconnected.

Improved diagnostic messages.


Fixed bugs that caused the thread that listened for new connections to exit when errors occurred. Such errors included too many simultaneous connections.


Added three new array interfaces, asynInt8Array, asynInt16Array, and asynFloat32Array. asynInt8Array and asynInt16Array are the same as asynInt32Array except that the data types are for epicsInt8 and epicsInt16 respectively. asynFloat32Array is the same as asynFloat64Array except that the data type is for epicsFloat32.

Added asyn(XXX)ArraySyncIO for synchronous I/O to all array interfaces.

Added new asynGenericPointer interface. The datatype for this interface is void*, so it can be used to pass a pointer to anything. Includes asynGenericPointerSyncIO for synchronous I/O.

Added asynStandardInterfaces.h and asynStandardInterfacesBase.c to simplify driver initialization when using the standard asyn interfaces defined in asyn/interfaces (common, octet, int32, etc.)


Undid the change that was done in R4-9 with direct calls to dbScanLock and process in the interrupt callback functions. This could lead to deadlocks in some circumstances. The original reason for changing from scanIoRequest to (dbScanLock, process) was because callback values would be lost if the callbacks came so close together in time that the single callback value stored in device support was overwritten before scanIoRequest could process the record. This problem has been fixed by adding a FIFO (ring buffer) to the device support for the scalar interfaces asynInt32, asynUInt32Digital, and asynFloat64. The ring buffer is only created when the record is put into I/O Intr scan, so the storage is not allocated for records that are not I/O Intr scanned. The ring buffer default size is 10 values, but this can be changed on a per-record basis using the dbInfo string "FIFO" with a value such as "100".

Added support for bi and bo records for asynInt32 interface. Previously these records were only supported for the asynUInt32Digital interface.

Added waveform record device support for the asynInt8Array, asynInt16Array, and asynFloat32Array interfaces. These are the same as devAsynInt32Array and devAsynFloat64Array with changes to the data types.


Remove duplicate windows function decorations.


Improved diagnostic messages.


Fixed timeout bug introduced in R4-6 when timeouts of 0.0 and -1.0 were defined.

Release 4-9

October 19, 2007


Replaced scanIoRequest with direct call to rset->process in interrupt callback routines in all device support. Without this fix if another interrupt occurred before the first scanIoRequest was complete bad things could happen. The data from the first interrupt would be lost, and the read function in the driver would be called when it should not have been.


Added support for 28,800 baud for those architectures which support this unusual speed.

Added stub routines for WIN32 so that a separate DBD file is no longer needed.


Added short delay in cleanup routine so sockets would close cleanly.


Fixed bug which caused asynOctetRead() to return prematurely with eomReason=ASYN_EOM_CNT if the port driver returned 600 bytes in readRaw().


Build driver for Greensprings IP-488 if IPAC is defined in configure/RELEASE.


Added stub routines for WIN32 so that a separate DBD file is no longer needed.


Avoid duplicate clnt_destroy operations.

Release 4-8

April 28, 2007


Added support for link specification of


in addition to the previous support for


This allows device support to work with drivers that cannot return meaningful values in pasynInt32->getBounds because they do not know the range of the device. This is true, for example of Modbus ADCs. The nbits parameter is defined as follows:

  nbits > 0  Device is unipolar with a range from 0 to 2^nbits-1
  nbits < 0  Device is bipolar with a range from -2^(abs(nbits)-1) to 2^((abs(nbits)-1)-1
           Values returned on the asynInt32 interface will be sign extended
           using the sign bit (e.g. bit abs(nbits)-1 starting at bit 0).

devEpics/devAsynInt32Array, devAsynFloat64Array

Added support for callbacks from driver to device support. This allows waveform records to have I/O Intr scanning, as already supported for other records in devEpics.


Changed parser so it requires an exact match to "asyn(" or "asynMask(". Previously it tolerated other characters before the "(", and in particular it accepted "asynMask(" when "asyn(" was expected. Note that this change could cause problems with database files if they did not follow the documented syntax, which has no white space between "asyn" or "asynMask" and the "(" character.


Fix errors in format strings for asynPrint.

Temporary fix to asynReport thread for Cygwin. If the amount of output is small the thread exists for a very short time, and this causes a crash. The fix is a short wait, but it should really be fixed in base/src/libCom/osi/os/posix/osdThread.c.


Fix problem with Makefile.


Add more SCPI commands to devGpib template.


Close sockets on application exit. This is very important for vxWorks, otherwise sockets are not closed cleanly which often leads to problems when the IOC reboots.


Hold off SRQ callbacks until iocInit.

Release 4-7

February 28, 2007


Clean up operation on POSIX/termios systems (everything but vxWorks). The old mechanism was prone to polling during read operations rather than using the termios read timeout mechanism.


asynRecord sets line-buffering on trace file.

Peter Mueller provided code to remove/restore a device from/to the SRQ polling list.


Clean up dangling 'default' statement.


Fixed error in GPIBACMD operations.


Patches from Gasper Jansa to improve option handling.


Fixed null pointer dereference for all device support when SCAN=I/O Intr and asyn port could not be found.


Fixed buffer overflow error when NRRD>40 and IFMT=ASCII.


Read method now sets return status and *eomReason properly.


*eomReason now set to ASYN_EOM_CNT when read count has been satisfied.

Fix timeout settings on RTEMS.

Add support for UDP broadcasts. Specify "UDP*" and the network broadcast address in the port configuration command:
drvAsynIPPortConfigure("L0", " UDP*", 0, 0, 0)


Full support for new timeout semantics (timeout<0 means "wait forever for characters to arrive", timeout=0 means "return characters immediately available", timeout>0 means "return a timeout status if no characters are received within the specified number of seconds").

Release 4-6


Fixed NULL pointer dereference.


Previous versions of drvAsynIPPort.c (1.29 and earlier, asyn R4-5 and earlier) attempted to allow 2 things:

  1. Use an EPICS timer to time-out an I/O operation, such as send(), recv() and connect().
  2. Periodically check (every 5 seconds) during a long I/O operation to see if the operation should be cancelled.

Item 1) above was not really implemented because there is no portable robust way to abort a pending I/O operation. So the timer set a flag which was checked after the poll() was complete to see if the timeout had occured. This was not robust, because there were competing timers (timeout timer and poll) which could fire in the wrong order.

Item 2) was not implemented, because asyn has no mechanism to issue a cancel request to a driver which is blocked on an I/O operation.

Since neither of these mechanisms was working as designed, the driver has been re-written to simplify it. If one or both of these are to be implemented in the future the code as of version 1.29 should be used as the starting point.

If pasynUser->timeout < 0 an infinite timeout is now used.

Fixed bug so that ports connected with a file descriptor in pasynUser->reason execute code to set timeouts.

Fixed bug to return error if pasynCommon->connect is called when port already connected.


Added two new functions which are related to pasynTrace->print and pasynTrace->printIO the way vprintf is related to printf.


Changed pasynManager->connectDevice for ports which have the properties autoConnect=1 and isConnected=0. In this case a request is queued to call asynCommon->connect for that port. This ensures that ports that have a pasynUser connected to them will report being connected even if no I/O has yet been done. Previously such ports reported a disconnected state until the first I/O or operation such as setTraceMask. This was confusing.

Clarify documentation on meaning of pasynUser->timeout. Previously there was no documented method of specifying an "infinite" timeout to a driver, and the meaning of timeout=0.0 was not defined. The new definitions are:

> 0.0 Wait for up to timeout seconds for the I/O to complete

= 0.0 Peform any I/O that can be done without blocking. Return timeout error if no I/O can be done without blocking.

< 0.0 Infinite timeout. Wait forever for I/O to complete.


Fixed bugs with asynFloat64Average device support. The wrong interrupt function was being called, and UDF was not being cleared.

Release 4-5


memMalloc was allocating the amount of memory the caller requested rather than the amount required for the freeList. If memFree was called and the memory reallocated to a user requesting a larger size, memory corruption occured. This is fixed.

SyncIO routines

If the connect call fails the asynUser is no longer freed. Instead a message is put into asynUser.errorMessage. The caller must call disconnect in order to free the storage for the asynUser.

The SyncIO routines no longer call asynPrint if there is an error and there is a valid asynUser available. Rather they return an error message in pasynUser->errorMessage. The SyncIO*Once functions still call asynPrint for errors, because they do not have a way of returning an error message.

Serial, TCP/UDP/IP

Handle 0-length write requests.


Added drvAsynIPServerPort to support TCP and UDP socket servers.

Added iocBoot/testIPServer to test TCP server support.

drvAsynIPPort now closes TCP sockets when remote system closes connection.

drvAsynIPPort connect function now uses pasynUser->reason as a file descriptor if it is > 0. This allows drvAsynIPServerPort to re-use asyn ports it creates.

Made drvAsynIPPort add null byte at end of input if there is room.

Made drvAsynIPPort:readRaw set eomReason to 0. It was not setting eomReason at all previously.


Made drvAsynSerialPort add null byte at end of input if there is room.

Made drvAsynSerialPort:readRaw set eomReason to 0. It was not setting eomReason at all previously.


Added asynCommonSyncIO for synchronous support of the asynCommon interface.


Add delay loops to get these boards to work with faster VME CPU modules.

Release 4-4


Better support was provided for VXI-11.3 controllers, i.e. talking directly to an ethernet port on an instrument. In particular a TDS3054B was tested.

WARNING: The VXI-11.1 ansd VXI-11.3 standards do NOT allow access to GPIB lines, i.e. conmmands like Untalk/Unlisten are not possible. The previous support issued these commands after each read or write. Some really old GPIB devices may fail. If so the device specific code must be modified to sent these commands separately.


Changes were made to allow asyn to build on native Windows (win32-x86) architecture.

There are two asyn components that do not yet work on win32-x86.

  1. Local serial ports. The asyn uses the "termios" API for serial ports, and termios is not available for native Windows.
  2. VXI-11. The asyn VXI-11 support uses the Sun XDR API, which is not available for native Windows.

Users who want to use local serial ports or VXI-11 on Windows can use the Cygwin EPICS build (cygwin-x86).

devGpib: devGpibConvertExample

An example of how to implement convert routines for devGpib support modules is available in asyn/devGpib/devGpibConvertExample.c


The UDF field is now set FALSE when the VAL field is updated.

Release 4-3



The cancelInterruptUser methods of all interfaces has been changed from

    asynStatus (*cancelInterruptUser)(void *registrarPvt, asynUser *pasynUser);


    asynStatus (*cancelInterruptUser)(void *drvPvt, asynUser *pasynUser,
                                      void *registrarPvt);


The length and size arguments now have type size_t.


Several improvements were made to devSupportGpib.c. All changes should be transparent to code that uses devGpib.


The maxchars argument to callInterruptUsers has been removed.


The filename argument has been removed.


For asynAoFloat64 it now uses oval instead of val.

asynFloat64Array, asynInt32Array, asynOctet, asynOctetSyncIO

All length and size arguments now have type size_t.

asynFloat64SyncIO, asynInt32SyncIO, asynOctetSyncIO, and asynUInt32DigitalSyncIO

These all use lockPort/unlockPort instead of queueRequest.

Release 4-2-1


Device support was not returning 2 (do not convert) for ai records when it should. This meant that the VAL field was being set back to 0 by the record after device support wrote to it. This bug is fixed.


The record sometimes did not read the current input and output EOS values from the driver when it connected. This bug is fixed.

Release 4-2


Yevgeny A. Gusev has again reported some hard to recognize bugs. He must have spent many hours looking at the code. His extra set of very good eyes are much appreciated!!. He also thought of the way to handle support that uses one addressing scheme but wants to use support that has a different addressing scheme. For example support for mult-drop serial that wants to use the standard serial support

Release 4-2


If read reads maxchars, it forced the last character to be 0 and returned asynOverflow if it wasn't. This is fixed.

drvAsynSerialPort,drvAsynIPPort - Error reporting

These did not properly set an error message in asynUser.errorMessage when they returned asynError. This is fixed.

drvAsynSerialPort - serial port options

Changes were made to the way serial port options are handled.

asynRecord - Serial Port Options

This has a new option to set Modem Control.

Release 4-1

The only code change was to fix the drvAsynIPPort and drvAsynSerialPort segmentation faults on cygwin-x86.

Release 4-0

Incompatible Changes.

APOLOGY: Many interfaces have changed since release 3-3. This is the reason this release is called 4-0.

New Features

Release 3-3

Incompatible Changes.

Major New Features


The following changes have been made


Removed the GOPT field. This is no longer necessary because the port options are automatically read whenever connecting to a port. "special" requests are now queued without changing the state of the record, using the new duplicateAsynUser, memMalloc(), and memFree() methods. This means that there is no longer a possibility of a special request being rejected because the record is busy. It is no longer possible to cancel a special request.




Flushes input only.


The EOS read method now calls the low-level read method only once and returns as many characters as the low-level method supplies. This makes the EOS read semantics match those of the low-level serial and IP drivers.


vxi11SetRpcTimeout - now handles fractions of a second properly


A new field has beem added, AQR (Abort Queue Request)

The semantics have been changed as follows: process is responsible for all and only for I/O operations. Only I/O operations cause the alarm status and severity to change. Special is responsible for all other operations performed by asynRecord.

Release 3-2

Changed and obsolete features

Major New Features

Release 3-1

Changed and obsolete features

Release 2-1

Major New Features

Changed and obsolete features

Release 1-2

Release 1-1

This release includes support for the following:

Modifications include:

  1. Added asynSetPortOption and asynGetPortOption to manipulate port options.
  2. Changed serial support to use asynSetPortOption/asynGetPortOption.
  3. Added devGPIB GPIBCVTIO commmand type to allow custom conversion routine to perform all I/O operations.
  4. Changed rules for return value from devGPIB custom conversion routines.
  5. Added dbior support.
  6. Changed devGPIB to no longer cache EOS.

Release 1-0alpha2

Support Provided in addition to asynDriver and asynGpib

Future Support


The vxi11 support has been tested on the following platforms: Solaris, Linux (redhat 9), Darwin, Windows XP (Cygwin), and vxWorks. It has been tested with the following vxi11 controllers:

The generic serial support has been tested with the following:

Two Device Support modules have been converted from the 3.13 gpib support: DG535 and TDS3014B Scope.