Fixed problem with UDP broadcast sockets. Previously sending broadcast messages worked correctly, but any responses from clients to those messages were rejected by the IOC system. This is because connect() and send() were being called. This is not correct, in this case connect() should not be called and sendto() should be called rather than send(). Also changed the code to call recvfrom() rather than recv()for UDP sockets. This returns the source address information, which is now printed with the source message length and contents if ASYN_TRACEIO_DRIVER is set.
New test application, testOutputReadbackApp. Tests that the initial values of output records are set correctly.
New test application directory, testBroadcastApp. It has 2 applications for sending broadcasts and reading responses. One uses asyn, and the other native OS calls. The native OS call version only builds on Linux. This is used for testing the UDP broadcast problem fixed in this release.
The source code repository was moved from https://svn.aps.anl.gov/epics/asyn to https://github.com/epics-modules/asyn. This will make it much easier for others to collaborate in the development of asyn.
drvAsynIPPortConfigure("portName","hostInfo",priority,noAutoConnect,noProcessEos)
to
drvAsynIPPortConfigure("portName","hostInfo",priority,noAutoConnect,userFlags)
info(asyn:READBACK, "1")
Fixed 2 bugs:
Added optional support for ring buffers with waveform records. Ring buffers were added to asyn device support for scalar (non-array) records in R4-10. To enable ring buffer support on a waveform record the record info tag FIFO can be set to a value greater than 0. For example this line in a db file for a waveform record sets a ring buffer size of 20 elements.
info("FIFO", "20")
Ring buffers are only used when records have SCAN=I/O Intr. They allow the record to process all of the arrays from a rapid burst of callbacks from the driver. However, because Channel Access does not provide any buffering for arrays, even if the record processes for each new array callback, Channel Access will not necessarily send events for each value, because it just sends the current record value when the CA callbacks are done.
A new test application, testArrayRingBufferApp was added to test this array ring buffer support. A new iocBoot/ioctestRingBuffer directory was also added.
Added new asynOptionSyncIO interface. This interface is needed so that the asynOption interface can be called synchronously when it is OK to block.
It has always been asserted that except for devEpics asyn only really depends on libCom from EPICS base. People who are interested in using asyn drivers from other control systems, want to minimize the dependencies of libraries from EPICS base. The following lines have been added to asyn/configure/CONFIG_SITE:
------------------------------------------------------------------------------- # If you want to build asyn so the only dependency on EPICS base is libCom then set the following flag #EPICS_LIBCOM_ONLY=YES -------------------------------------------------------------------------------
If EPICS_LIBCOM_ONLY is YES then the build is done so that only libCom is needed. This does the following:
A new C++ class was added, asyn/asynPortClient/asynPortClient.cpp. This class makes it easy to write a C++ application that starts existing asyn port drivers and communicates with them over standard asyn interfaces without running an IOC.
A new test application directory was added testAsynPortClient. This tests running
C++ applications that communicate with asyn port drivers without running an IOC.
This currently contains a single test application, testAsynIPPortClient.cpp. This
program creates an asynIPPort driver, and uses the command line arguments to set
the hostInfo string, a single command string to send to the server, and optionally
the input and output EOS. It then prints out the response from the server. There
are 3 example shell scipts that show how to use testAsynIPPortClient to communicate
with a Web server, XPS motor controller, and a telnet host respectively.
Bruno Martins found and fixed a problem with data transfers that spanned multiple USB packets.
Added capability to specify the local port that the server should use for the connection. Normally the local host choses a random local port that it binds to and passes to the server. There are a few servers that only accept a specific local port or range of local ports, for which this capability is required. The new syntax is:
<host>:<port>[:localPort] [protocol]
For example
164.54.160.100:5000:10101 UDP
where 10101 is the optional local port number.
Fixed all initialization routines so that if there is an error they do the following:
Thanks to Nick Rees for these fixes.
Fixed problem with location of #define epicsExportSharedSymbols and/or #include <epicsExport.h>. In previous versions these were placed immediately before the #include statements defining symbols for that source file . However, this was incorrect, they must be placed before all of the #include statements defining symbols for that DLL . This mistake causes the same symbol being defined with both dllExport and dllImport when building the DLL. The Visual Studio compiler does not even warn about this error, but it produces a fatal error with the GCC compiler under Cygwin.
Fixed a bug in pasynManager->memMalloc. It could return a pointer that was not a multiple of 8 bytes. This led to subtle problems on some architectures (e.g. ARM) if a double was stored in the memory returned by memMalloc. Fixed the code so the pointer is always a multiple of 16 bytes (for future safety).
Fixed bug: the port was not always being disconnected when the OS returned serious errors. This was preventing USB serial devices from disconnecting and reconnecting properly.
Fixed 2 bugs in pasynOctet->read() when pasynUserTimeout=0:
Fixed several 32/64 bit issues.
Added support for UDP servers, in addition to TCP servers. Thanks to Helge Brands and Dirk Zimoch from PSI for this.
Fix to Makefile to link with system libgpib library.
Sign-extend positive or unsigned values as well as negative values when DTYP=asynInt32 and asynMask value is non-zero.
Apply mask to longin and longout records.
Undid the change in R4-22 that changed the asynStdInterfaces from protected to private. That change was not compatible with areaDetector R1-9-1.
Removed paramList.h and paramList.cpp, put the code into asynPortDriver.cpp. These two classes had many interdependencies, so needed to include each other's header files. This was difficult when building dynamically on Windows, where imported and exported symbols need to be distinguished.
Added links to asynPortDriver.html to detailed tutorial on how to write a driver using asynPortDriver.
Fixed a bug that could cause the values of *nbytesOut, *nbytesIn, and *eomReason to be garbage if an I/O error occurred.
Handled exporting symbols consistently, which is important when building dynamically for Windows with Visual Studio. Eliminated all references to epicsSharedSymbols, now just #include <epicsexport.h> just before the #include for the header file that defines symbols for this file, and after all other #include statements. Thanks to Peter Heesterman for the initial version of this fix.
Updated the files in the configure directory to the versions from EPICS base 3.14.12.3. Paths to EPICS base and other modules are still defined in configure/RELEASE. However, other configuration values, such as LINUX_GPIB and DRV_USBTMC are now defined in configure/CONFIG_SITE, not in RELEASE.
Added support functions for setting timestamps in asyn port drivers. These can be used to set the timestamp when the port driver received data. The driver can then set the asynUser->timeStamp field to this value for all input records on read and callback operations. Records that have TSE=-2 will have this timestamp. There is support for registering a user-supplied function to provide the timestamp, which will override the default source that just calls epicsTimeGetCurrent().
Added the following new functions to pasynManager for timestamp support.
asynStatus (*registerTimeStampSource)(asynUser *pasynUser, void *userPvt, timeStampCallback callback); asynStatus (*unregisterTimeStampSource)(asynUser *pasynUser); asynStatus (*updateTimeStamp)(asynUser *pasynUser); asynStatus (*getTimeStamp)(asynUser *pasynUser, epicsTimeStamp *pTimeStamp); asynStatus (*setTimeStamp)(asynUser *pasynUser, const epicsTimeStamp *pTimeStamp);
Added the following shell commands for timestamp support.
asynRegisterTimeStampSource(const char *portName, const char *functionName); asynUnregisterTimeStampSource(const char *portName);
Added a new bit to asynTraceMask, ASYN_TRACE_WARNING. This is intended to be used for messages that are less serious than ASYN_TRACE_ERROR, but more serious than ASYN_TRACE_FLOW.
Added new asynTraceInfoMask. This mask controls the information printed at the beginning of each message by asynPrint and asynPrintIO. Thanks to Ulrik Pedersen for help with this. The mask is defined with the following bits:
#define ASYN_TRACEINFO_TIME 0x0001 #define ASYN_TRACEINFO_PORT 0x0002 #define ASYN_TRACEINFO_SOURCE 0x0004 #define ASYN_TRACEINFO_THREAD 0x0008
Added a new shell command to control this mask.
asynSetTraceInfoMask port,addr,mask
Added asynTrace information to the output of asynReport if details >=1.
Use simple lock/unlock operations rather than queueLockPort/queueUnlockPort for end-of-string manipulations (setInputEos, getInputEos, setOutputEos, getOutputEos). This ensures that these operations can take place even with the device disconnected.
Finished the support for setting the record TIME field for input records, both for read operations and for callback operations (i.e. records with SCAN=I/O Intr). This work was begun in R4-20, but it was not complete. Fixes were made in devAsynOctet, devAsynInt32, devAsynFloat64, and devAsynUInt32Digital.
Changed the ring buffer overflow messages that are printed in devAsynInt32, devAsynFloat64, and devAsynUInt32Digital. These now use the new ASYN_TRACE_WARNING mask. Prior to asyn R4-20 these used ASYN_TRACE_ERROR, and in asyn R4-20 and R4-21 they used ASYN_TRACEIO_DEVICE.
Fixed a bug in calling poll(). Previously the status return from poll() was not being checked; it was assumed that when poll() returned the port either had new data or had timed out. This is not correct, because poll() can return prematurely with errno=EINTR if a Posix signal occurs before data is received or the timeout expires. This can happen, for example, when the Posix high-resolution timer routines (timer_create, etc.) are used in the IOC. The Prosilica vendor library uses the Posix timer routines, and there were problems using asyn IP ports in IOCs that were also running Prosilica cameras. The problem was fixed by calling poll() again if it returns EINTR and the desired timeout time has not expired since poll() was first called.
Added support for AF_UNIX sockets on systems that provide them.
Support for all baud rates supported by the operating system.
Fix for XON/XOFF support from Dirk Zimoch.
Removed include of asyn.dbd, from drvAsynSerialPort.dbd, drvAsynIPPort.dbd, drvVxi11.dbd, and drvGsIP488.dbd.
Fixed Makefile rule for vxi11intr.h for parallel builds.
Fixes for eomReason and EOS handling from Dirk Zimoch.
Removed the openSocket() function from this interface. This method really did not belong in this interface, since it just wrapped the call to drvAsynIPPortConfigure().
Added 4 additional baud rates to the BAUD field (460800, 576000, 921600, 1152000). However, the BAUD field can still only support 16 fixed baud rates because it is type DBF_ENUM.
Added a new LBAUD (long baud rate) field of type DBF_LONG. This allows selection of any baud rate, not just those in the BAUD menu. Changing the BAUD field changes the LBAUD field. Changing the LBAUD field changes the BAUD field to the appropriate selection if it is a supported value, or to "Unknown" if not.
Added support for ASYN_TRACE_WARNING and asynTraceInfoMask, including the opi screens.
Added new virtual methods to support Eos operations on the asynOctet interface. These are setInputEosOctet(), getInputEosOctet(), setOutputEosOctet(), getOutputEosOctet(). Changed the report() method to print the current values of the inputEos and outputEos.
Added new virtual methods for timestamp support. These are updateTimeStamp(), setTimeStamp(), getTimeStamp().
Added new function getAsynStdInterfaces() to access the asynStdInterfaces structure, which is now private.
Changed the functions that do callbacks when callParamCallbacks() is called to call pasynManager->getTimeStamp() and set the pasynUser->timestamp field to this value in the callbacks.
Changed the base class readXXX() functions (e.g. readInt32(), readFloat64(), etc.) to call pasynManager->getTimeStamp() and set the pasynUser->timestamp field to this value. The readXXX() functions in derived classes should also do this, so that records with TSE=-2 will get the timestamp from the driver.
Added an example of a user-supplied timestamp source.
Added calls to lock() and unlock() in simTask. This was previously a serious omission in this example driver. Thanks to Kay Kasemir for spotting this.
Restored the original versions of pasynManager->lockPort and unlockPort that were used in asyn prior to R4-14. These versions just call epicsMutexLock and epicsMutexUnlock. In R4-14 these versions were replaced with versions that queued requests to lock the port. The R4-14 versions fixed a problem with the interfaces/asynXXXSyncIO functions, but it has become clear that the original versions are useful in some circumstances. The change was done as follows:
Changed the report() function so that if details<0 then asynManager does not print information for each device (address). It calls pasynCommon->report(-details) in this case so driver report functions will not be affected.
Changed the asynTrace print, printIO, vprint, vprintIO functions so they use EPICS_PRINTF_STYLE. This causes the GCC (version 3.0 and higher) and clang compilers to check the agreement of format strings with function arguments when using asynPrint() and asynPrintIO(), just as they do with printf(). This is very helpful in finding errors, and uncovered a number in asyn itself, which have been fixed.
Changed event code readback to support both the original 'short' VAL field (EPICS 3.14 and earlier) and the new 'string' VAL field (EPICS 3.15 and later).
Added support for DSET_AIRAW and DSET_AORAW definitions.
Replace strcpy with strncpy in devCommonGpib.c to reduce possibility of errors. Use NELEMENTS macro in devSkeletonGpib.c rather than hardcoding. Thanks to Andrew Johnson for these.
Improved the initMbboDirect function in devAsynUInt32Digital.c. If an initial value is read successfully from the driver it now sets the .Bn fields in the record. It also sets VAL rather than RVAL and returns 2 rather than 0. Thanks to Andrew Johnson for this.
Fixed a bug in devAsynUInt32Digital.c, which was missing a call to epicsMutexLock in interruptCallbackInput. Thanks to Angus Gratton for this fix.
Fixed a bug in devAsynXXXArray.h to handle case of multiple interrupt callbacks between record processing. Previously this would result in a call to the asynXXXArray->read() in the driver, which is not correct. The asynXXXArray device support does not have a ring buffer, so multiple interrupt callbacks between processing results in data being "lost", i.e. the record processes more than once with the same data. This is not really an error, but we now issue an ASYN_TRACEIO_DEVICE warning. This is analogous to ring buffer overflow for non-array data types.
Changed the "ring buffer overflow" messages from "ASYN_TRACE_ERROR" to "ASYN_TRACEIO_DEVICE", for devAsynFloat64. This was done for other device support in R4-20, but float64 was overlooked.
Added writeRead and writeReadOnce functions to the asynGenericPointer interface. Thanks to Florian Feldbauer for this addition.
Fixed a bug in asynCommonSyncIO that could cause a crash if the connect() function returned an error.
Added support for the asynOption interface. Added code to demonstrate and test this to the testErrors test application.
Added new method asynPortDriver::flushOctet(), which implements asynOctet::flush(). The base class implementation reproduces the behavior of asynOctetBase.c::flushIt, i.e. it calls pasynOctet->read() repeatedly with a timeout of 0.05 seconds until it gets no data back. But now drivers can implement their own version of flush() if a different behavior is desired, which was not previously possible.
Changed the code so that the length of string parameters returned in readOctet and octetCallback is now strlen(string)+1, rather than strlen(string). The length thus now includes the terminating nil. This fixes problems with clients that request long strings or subscribe to monitors with a length of 0, but don't check for a nil terminator.
Changed the meaning of the "details" argument in the asynPortDriver::report() function. The new meaning is:
Changed the connect() and disconnect() methods to return an error if the device address specified by the pasynUser is invalid (i.e. <-1 or >MAX_ADDR-1).
Fixed problem that was causing dynamic builds (e.g. SHARED_LIBRARIES=YES) to fail on Windows.
Changes to allow compiling with the old vxWorks Tornado 2.0.2.1 compiler. Thanks to Dirk Zimoch for this fix.
Many minor changes to avoid compiler warnings on Linux, vxWorks, and WIN32. Thanks to Dirk Zimoch for many of these.
Fixed a bug that caused a deadlock if pasynManager->lockPort was called multiple times without calling pasynManager->unlockPort in between. Thanks to Sebastian Marsching from "aquenos GmbH" for this fix.
Added support for setting the record timestamp from the driver, using a new field, pasynUser->timeStamp. The driver can set this field in read and callback operations.
Fixed a long-standing bug in devAsynXXXArray support for input waveform records with SCAN=I/O Intr. The data were being copied to the record without using dbScanLock. This meant that the data could change while the record was processing.
Changed the "ring buffer overflow" messages from "ASYN_TRACE_ERROR" to "ASYN_TRACEIO_DEVICE", so they do not appear by default. These messages are not really errors, but warnings that record processing it not keeping up with the rate of driver callbacks for records with SCAN=I/O Intr.
Fixed a bug when adding a parameter that already existed. Thanks to Hinko Kocevar for fixing this.
Added new document "HowToDoSerial_StreamDevice.html".
Added new test program, testConnectApp. It uses asynPortDriver, and has a polling thread that sends a user-defined string to a device and reads the response. It can be used to test the behavior when the device is disconnected and then reconnects, etc.
Added a rule in asyn/Makefile to fix a problem that could cause parallel make to fail.
Added a new interface, asynEnum. This interface is designed to allow drivers to set the strings, values, and severities for record enum fields. This can be done both at iocInit(), in init_record() with the pasynEnumSyncIO->read() function, and after iocInit via callbacks to device support.
Added support for the new asynEnum interface for bo, bi, mbbo, and mbbi records in the asynInt32 and asynUInt32Digital device support. These records now attempt to read the initial values of the strings, values (mbbo and mbbi only) and severities for the enum fields. They also support callbacks on the asynEnum interface, so that enum values can be set dynamically at run-time.
Improved the support for setting the alarm status of records. Previously for records that were not I/O Intr scanned STAT was always to READ_ALARM or WRITE_ALARM, and SEVR was set to INVALID_ALARM. A new function, pasynEpicsUtils->asynStatusToEpicsAlarm() was added that converts asynStatus values to EPICS alarm values. This allows records to have STAT=TIMEOUT_ALARM, DISABLE_ALARM, etc. More values of STAT can be supported in the future by adding more values to the asynStatus enum.
Previously it was not possible for input records with SCAN=I/O Intr to have their alarm status set at all. This support has been added. Device support now uses the pasynUser->auxStatus field in the pasynUser passed to the callback function. If auxStatus != asynSuccess then the record alarm STAT and SEVR are set to values based on the asynStatus. asyn port drivers can now signal error status to clients in callback functions by setting pasynUser->auxStatus to asynSuccess, asynTimeout, asynError, etc. This change should be backwards compatible with all drivers because the pasynUser that is used for the callbacks is private to the callback function, and the auxStatus field is initialized to 0, which is asynSuccess.
Added new waveform record device support, asynInt32TimeSeries and asynFloat64TimeSeries. These use callbacks from the driver on those respective interfaces to collect a time series of values in a waveform record. Added new medm file asynTimeSeries.adl for this, and added an example waveform record to testEpics/Db/devInt32.db.
Fixed bugs that caused crashes if SCAN=I/O Intr was set at iocInit.
Added support for I/O redirection to the "dbior" and "asynPrint" commands.
Added support for the new asynEnum interface described above.
Added support in asynPortDriver for passing status information to clients in callbacks. Each parameter in the parameter library now has an associated asynStatus variable. New functions setParamStatus() and getParamStatus() are provided to access this variable. For example, if setParamStatus(paramIndex, asynError) is called then callParamCallbacks() will cause any input records with SCAN=I/O Intr to go into alarm state.
Moved asynPortDriver from the miscellaneous directory to its own directory. Improved the internals, but did not change the API. Thanks to John Hammonds for this.
Added a new test application, testErrorsApp. This application uses a driver based on asynPortDriver to test error handling for all interfaces and all records support by the asyn standard device support (asyn/devEpics). It can be used to test error handling of records with both periodic scanning and I/O Intr scanning. It also tests the new asynEnum interface for setting enum strings, values, and severities at iocInit.
Removed the newline terminator from all messages in pasynUser->errorMessage. This formatting does not belong in the error message. Thanks to Lewis Muir for this.
drvAsynIPServerPort. Added call to epicsSocketEnableAddressReuseDuringTimeWaitState which fixes problems when the IOC is restarted and the port is still in TIME_WAIT state. Thanks to Lewis Muir for this.
Changes to avoid compiler warnings on 64-bit Darwin.
Changes to avoid compiler warnings and errors on older Solaris compiler.
Changed non-standard __VAR_ARGS__ to __VA_ARGS__ in asynPrint macro.
Added titles to EDM screens.
Added CSS BOY screens.
Fixed build problem. It was rebuilding the VXI11 code with rpcgen each time make was run, even if nothing had changed.
Cleaned up logic for callbacks on asynUInt32Digital interface. It was not doing callbacks if the value had not changed but an interrupt had occured for bits in the mask. This would happen when interrupts were only enabled on the falling or rising edges but not both. Added an additional form of setUIntDigitalParam that takes an interruptMask argument. In the previous releases drivers were calling setUInt32Interrupt for callbacks which is not correct. That function should only be called by device support to tell the driver which interrupts to recognize. These problems made the quadEM not work correctly with the ipUnidig.
Bug fix on WIN32. It was waiting forever when timeout=0 when it should return whatever characters are available without waiting at all.
Fixed asynRecord.dbd to include promptgroup for fields that need it. Removed the SOCK field and asynSocketSetup.adl; the record no longer supports creating sockets, which can easily be done with the iocsh drvAsynIPPortConfigure command.
Added IXON, IXOFF, and IXANY fields for new XON/XOFF support on serial ports. These fields were added to the asynSerialPortSetup.adl medm screen.
For waveform output records the device support was always writing NELM elements, rather than NORD elements.
Added missing include file, which caused asyn not to build on EPICS base versions before 3.14.10.
Removed unneeded declarations of 'register int32_t *buf' from many functions. Removed register keyword from remaining instances, because address was being taken, which is illegal in C, and was causing errors on vxWorks Pentium cross-compiler.
Added a global function, findAsynPortDriver(const char *portName), that returns a pointer to an asynPortDriver object given the asyn port name.
Added 3 new asynPortDriver methods: setUInt32DigitalInterrupt, clearUInt32Interrupt, getUInt32Interrupt. These were needed to complete the asynUInt32Digital support.
The asynOctetSetInputEos, asynOctetSetOutputEos, asynOctetShowInputEos and asynOctetShowOutputEos commands now take effect even if the port is not connected. This makes startup scripts more robust in the face of devices that are not accessible at IOC startup. Removed the unused "drvInfo" parameter from each of these functions.
Host name lookup is now deferred until port connection time. This makes startup scripts robust in the face of a device that is offline at IOC startup and has been offline for so long that it's DNS entry has been deleted.
Prevent reconnects during IOC shutdown. The IP Port exithandler runs before record scanning stops. In that interval, if a record is scanned then it will trigger a reconnect, and new connection can be shutdown without sending data, or without waiting for a reply. Some embedded TCP/IP stacks have problems dealing with this. Thanks to Michael Davidsaver for this fix.
Added support for local serial ports on Windows, i.e.win32-x86 and windows-x64 architectures. Previously Windows local serial ports were only supported on the cygwin-x86 architecture.
Added support for serial line software handshake flags (ixon/ixoff/xany) on most architectures (e.g. Linux, Cygwin, Darwin, WIN32; see: man stty) and vxWorks (ixon only). Thanks to Dirk Zimoch for this.
Changed asyn/Makefile to fix build dependencies for rpcgen of vxi11. Thanks to Michael Davidsaver for this fix.
Support has been added for terminal servers which support the TELNET RFC 2217`protocol. To communicate with such devices specify "COM" as the protocol in the drvAsynIPPortConfigure command. This allows port parameters (speed, parity, etc.) to be set using an asynRecord or asynSetOption commands just as for local serial ports.
Fix from Benjamin Franksen to fix problem with reconnection.
The 'timeout' argument to vxi11Configure has been changed from double to string. This allows vxi11Configure to be called directly from the vxWorks shell.
The third argument to the vxi11Configure command is now a bit-map. The least significant bit (value 0x1) remains the 'recover with IFC' control. The next-to-least significant bit (value 0x2) when set will cause all devices to be locked when a connection is made. This allows for cooperative exclusive access to devices.
Fixed memory leak in lockPort() when an error occured, was not calling freeAsynUser(). Thanks to Andrew Starritt for finding this.
Bug fix for devAsynInt32 and devAsynFloat64: it was not freeing the mutex in processAiAverage if numAverage==0, i.e. there had been no callbacks from the driver since the record last processed. This would hang the next thread that tried to take the mutex, typically the driver callback thread.
Bug fix for devAsynXXXArray: it was calling drvUserCreate in the port driver even if there was no userParam in the link, which could crash the driver.
Changes to allow building dynamically on WIN32 (i.e. making DLLs).
Changes to allow building on Cygwin 1.7.x or 1.5.x; replaced rpc with $(CYGWIN_RPC_LIB),
which allows it to link with rpc on 1.5.x and tirpc on 1.7.x. You need to add one
of the following 2 lines to base/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86
For Cygwin 1.7.x: CYGWIN_RPC_LIB = tirpc For Cygwin 1.5.x CYGWIN_RPC_LIB = rpc
Fixed bugs in connection management. Releases 4-11 through 4-13 had the following problems:
These problems were fixed by doing the following:
Fixed problems with the SyncIO calls, which were caused by the implementation of pasynManager->lockPort():
Fixed a bug in driver initialization. The driver had not completed all required initialization before it called pasynGpib->registerPort. Because pasynGpib->registerPort registers the asynCommon interface, that now normally triggers an immediate callback to vxiConnect, and the driver was not yet properly initialized to handle that callback.
Added an additional example driver, asynPortTest, that uses asynPortDriver. It implements the asynInt32, asynFloat64, and asynOctet interfaces to communicate with the echo server using asynOctetSyncIO calls. This tests nested SyncIO calls. Added a new startup script, database and medm screen for testing this new driver.
Added a call to asynOctet->flush() just before the call to asynOctet->write() operation when doing write/read operations. This eliminates any stale input that may have already been sent by the device and would otherwise be incorrectly returned by the read operation.
Now behaves properly even when eomReason is NULL.
Changed ipEchoServer2.c to eliminate the epicsThreadSleep(0.01) in the listener thread. This sleep is no longer necessary because of the change to lockPort described above, so the example program was changed to test and demonstrate this.
Fixed bug in getXXXParam. It was not returning error status when a parameter was undefined. This caused device support to use undefined values for output records, because the initial read from the driver during device support initialization did not return an error it should have.
Change some dependencies to fix parallel (-j) make problem.
A return of 0 from a read of a TCP stream is treated as an END condition rather than as an error. This makes it easier to handle devices that close the connection at the end of a reply.
Support has been added for devices such as web servers that require a connect at the beginning of each transaction. To enable this behaviour, specify "http" as the protocol in the drvAsynIPPortConfigure command and ensure that each transaction ends with a read that detects the broken connection from the device. Note that the device will always appear connected. The connect/disconnect around each transaction is handled within the drvAsynIPPort driver.
Corrected the documentation to state that only the TCP/IP protocol is supported, not UDP.
Fix problem with NULL-pointer dereferences.
Bug fix from Benjamin Franksen for devices that don't support IRQ.
The ring buffer code in devAsynFloat64.c, devAsynInt32.c and devAsynUInt32Digital.c has been improved. Previously when ring buffer overflow occurred during a callback the new value was simply discarded. This meant that when the record processed at the end of a rapid burst of callbacks it would not contain the most recent value. Now when overflow occurs the oldest value is removed from from the ring buffer and the new value is added, so that the record will contain the most recent callback value after a burst.
asynUInt32Digital: asynMask values implying shifts greater than 16 bits are now supported.
Fixed bug which caused an error when writing or reading in binary format if the driver did not implement the get(Input/Output)Eos functions. This bug was introduced when readRaw and writeRaw were removed from asynOctet in release 4-10.
makeSupport.pl -t streamSCPI <name> creates skeleton stream protocol and database files for a SCPI (IEEE-488.2) device.
Fixed bug in readInt32Array, not taking lock where needed.
Added drvInfo strings to parameter lists, and new methods to support this: createParam(), findParam(), getParamName(). The report functions now print out the drvInfo strings, which is very useful. The base class drvUserCreate() method can now be used without reimplementing in derived classes, because the parameter names are now available to the base class. Removed asynParamString_T and drvUserCreateParam(), which are no longer needed. The testAsynPortDriver test application has been updated to use these new features.
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.
If record is processed before new data have arrived (numAverage==0) set record to UDF/INVALID, set UDF to TRUE and leave value unchanged.
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.
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.
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:
pasynOctet->setInputEos(asynOctetPvt,pasynUser,NULL,0);
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) pasynOctet->setInputEos(asynOctetPvt,pasynUser,NULL,0); . . . . if (saveEosLen) pasynOctet->setInputEos(asynOctetPvt,pasynUser,saveEos,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.
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.
Added support for link specification of
@asynMask(portName,addr,nbits,timeout)drvParams
in addition to the previous support for
@asyn(portName,addr,timeout)drvParams
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).
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.
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", "192.168.1.255:1234 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").
Fixed NULL pointer dereference.
Previous versions of drvAsynIPPort.c (1.29 and earlier, asyn R4-5 and earlier) attempted to allow 2 things:
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.
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.
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.
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.
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.
Users who want to use local serial ports or VXI-11 on Windows can use the Cygwin EPICS build (cygwin-x86).
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.
The names have been changed and now these methods only work for asynchronous ports. An error is returned if blockProcessCallback is called for a synchronous port.
These are new asynManager methods. They can be used in place of queueRequest if the caller can block. They have been added to make it easier to implement a driver with one addressing scheme that is a asynUser of a driver with a different addressing scheme. For example a multi-drop serial driver can be implemented that calls a standard serial driver.
This is a new interface for driver's that call other drivers.
The cancelInterruptUser methods of all interfaces has been changed from
asynStatus (*cancelInterruptUser)(void *registrarPvt, asynUser *pasynUser);
to
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.
All length and size arguments now have type size_t.
These all use lockPort/unlockPort instead of queueRequest.
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.
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
If read reads maxchars, it forced the last character to be 0 and returned asynOverflow if it wasn't. This is fixed.
These did not properly set an error message in asynUser.errorMessage when they returned asynError. This is fixed.
Changes were made to the way serial port options are handled.
Previosly defaults were assigned for all options. Now the initial values are fetched from either the termios (POSIX) or sioLib (vxWorks).
The vxWorks sioLib uses clocal for what POSIX calls crtscts. The new serial support for vxWorks accepts both clocal and crtscts to specify RTSCTS (Request to send, Clear to send).
This has a new option to set Modem Control.
The only code change was to fix the drvAsynIPPort and drvAsynSerialPort segmentation faults on cygwin-x86.
APOLOGY: Many interfaces have changed since release 3-3. This is the reason this release is called 4-0.
Blanks no longer appear in the menu choices. For example.
device(ai,INST_IO,devAiAsynInt32,"asyn Int32")is now
device(ai,INST_IO,asynAiInt32,"asynInt32")
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.
respond2Writes
field, if greater than 0, are now seconds rather than milliseconds. This change
was made so that all time values set in the instrument support initialization routine
are specified uniformly in units of seconds. Very few instrument support files are
likely to be affected by this changeThis release includes support for the following:
Modifications include:
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:
It's vxiName must start with "hpib" rather than "gpib".
When communicating with the Ethernet port it acts like a VXI-11.2 rather than a VXI-11.3 device. It seems to just accept any GPIB address. SRQs did not work when connecting via the ethernet port but did when communicating via a LAN/GPIB gateway.
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.