Hi Oleg,
What you are trying to do is not supported in the drvAsynIPPort driver. In order for a record with SCAN=I/O Intr to process, the driver must register
itself as a source of interrupt callbacks with asynManager, and then do those callbacks to all registered clients. Some drivers do register themselves as interrupt sources, and will do callbacks to device support like you are trying.
For example this is a record from the areaDetector ADBase.template:
record(stringin, "$(P)$(R)PortName_RBV")
{
field(DTYP, "asynOctetRead")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))PORT_NAME_SELF")
field(VAL, "Unknown")
field(SCAN, "I/O Intr")
}
This works because the areaDetector driver registers as a source of interrupt callbacks on the asynOctet interface. Note that it uses the drvInfo field
PORT_NAME_SELF which specifies exactly what piece of information this record is requesting from the driver. Interrupt callbacks can work in this case.
However, the drvAsynIPPort driver cannot do interrupt callbacks. The reason is pretty clear if you think about it. What if your IOC had another record
in it like this, which is identical to your record, but with SCAN=”1 second”. Now if the IOC receives input, what should happen? Should the data go to the I/O Intr scanned record, or the periodically scanned record?
record(waveform,"devWfAsynReadPeriodic")
{
field(DTYP,"asynOctetRead")
field(INP,"@asyn($(PORT),$(ADDR),$(TMO))")
field(NELM,"255")
field(FTVL,"CHAR")
field(TSE, "$(TSE)")
field(SCAN,"1 second")
}
Note that StreamDevice DOES support I/O Intr scanned records with asynOctet. But I think it does this by frequent polling and then calling the I/O Intr
scanned record if no other record has consumed the data.
Mark
From: Oleg A. Makarov [mailto:[email protected]]
Sent: Tuesday, November 26, 2013 12:16 PM
To: Mark Rivers
Cc: '[email protected]'
Subject: Re: Anyone using StreamDevice with local serial ports on Windows?
Mark,
I have an AsynOctet problem on Linux IOC: waveform PV does not get updated with a scan field set to "I/O Intr".
Below are the results of an IOC test with serial port /dev/ttyS2 connected to the PMAC motion controller.
IOC has two waveform PVs:
record(waveform,"devWfAsynWrite")
{
field(DTYP,"asynOctetWrite")
field(INP,"@asyn($(PORT),$(ADDR),$(TMO))")
field(NELM,"255")
field(FTVL,"CHAR")
}
record(waveform,"devWfAsynRead")
{
field(DTYP,"asynOctetRead")
field(INP,"@asyn($(PORT),$(ADDR),$(TMO))")
field(NELM,"255")
field(FTVL,"CHAR")
field(TSE, "$(TSE)")
field(SCAN,"I/O Intr")
}
with the request (dbpf devWfAsynWrite "version<cr>") written to the devWfAsynWrite PV one would expect devWfAsynRead PV will get an answer value from PMAC motion controller in a fraction of a second, but this does not happen. Then after a 5-second delay with
"dbpf devWfAsynRead.PROC 1" command forcing devWfAsynRead PV to process, it gets value supplied by the PMAC motion controller (1.940 \r\006\006).
Am I missing some settings in /dev/ttyS2 setup or is there a bug in AsynOctet?
Oleg Makarov
> ./st.cmd
#!../../bin/linux-x86_64/fsen
## You may have to change fsen to something else
## everywhere it appears in this file
< envPaths
epicsEnvSet("ARCH","linux-x86_64")
epicsEnvSet("IOC","iocfsen")
epicsEnvSet("TOP","/mnt/share3/gmca/epics_synApps/synApps_5_6/f_sens")
epicsEnvSet("ASYN","/mnt/share3/gmca/epics_synApps/synApps_5_6/asyn-4-22")
epicsEnvSet("EPICS_BASE","/usr/local/epics/base")
epicsEnvSet EPICS_CAS_BEACON_ADDR_LIST "164.54.103.63"
cd /mnt/share3/gmca/epics_synApps/synApps_5_6/f_sens
## Register all support components
dbLoadDatabase dbd/fsen.dbd
fsen_registerRecordDeviceDriver pdbbase
## drvAsynSerialPortConfigure portName ttyName priority noAutoConnect noProcessEos
drvAsynSerialPortConfigure Serial2 "/dev/ttyS2" 0 0 0
## asynSetOption portName addr key value
asynSetOption Serial2 -1 baud "38400"
asynSetOption Serial2 -1 bits "8"
asynSetOption Serial2 -1 parity none
asynSetOption Serial2 -1 stop "1"
asynSetOption Serial2 -1 clocal Y
asynSetOption Serial2 -1 crtscts "Y"
## asynOctetSetOutputEos portName addr eos
"synOctetSetOutputEos Serial2 -1 "
## asynOctetSetInputEos portName addr eos
asynOctetSetInputEos Serial2 -1 ""
## asynSetTraceFile portName addr filename
asynSetTraceFile Serial2 -1 ""
# traceMask definitions
#ASYN_TRACE_ERROR 0x0001
#ASYN_TRACEIO_DEVICE 0x0002
#ASYN_TRACEIO_FILTER 0x0004
#ASYN_TRACEIO_DRIVER 0x0008
#ASYN_TRACE_FLOW 0x0010
#ASYN_TRACE_WARNING 0x0020
## asynSetTraceMask portName addr mask
asynSetTraceMask Serial2 -1 0x018
# traceIO mask definitions
#ASYN_TRACEIO_NODATA 0x0000
#ASYN_TRACEIO_ASCII 0x0001
#ASYN_TRACEIO_ESCAPE 0x0002
#ASYN_TRACEIO_HEX 0x0004
## asynSetTraceIOMask portName addr mask
asynSetTraceIOMask Serial2 -1 0x2
# traceInfo mask definitions
#ASYN_TRACEINFO_TIME 0x0001
#ASYN_TRACEINFO_PORT 0x0002
#ASYN_TRACEINFO_SOURCE 0x0004
#ASYN_TRACEINFO_THREAD 0x0008
## asynSetTraceInfoMask portName addr mask
asynSetTraceInfoMask Serial2 -1 0x5
## Load record instances
## dbLoadRecords 'file name' substitutions
dbLoadRecords db/fsen.db "P=23d:,PORT=Serial2,ADDR=-1,TMO=1,TSE=0"
cd /mnt/share3/gmca/epics_synApps/synApps_5_6/f_sens/iocBoot/iocfsen
iocInit
Starting iocInit
############################################################################
## EPICS R3.14.12.3 $Date: Mon 2012-12-17 14:11:47 -0600$
## EPICS Base built Aug 29 2013
############################################################################
2013/11/26 11:36:32.113 [../../asyn/devEpics/devAsynOctet.c:235] devWfAsynRead devAsynOctet::getIoIntInfo registering interrupt
2013/11/26 11:36:32.113 [../../asyn/interfaces/asynOctetBase.c:302] Serial2 -1 registerInterruptUser
iocRun: All initialization complete
epicsThreadSleep 2
asynReport
Serial2 multiDevice:No canBlock:Yes autoConnect:Yes
Serial line /dev/ttyS2: Connected
epicsThreadSleep 2
"bpf devWfAsynWrite "version
2013/11/26 11:36:36.615 [../../asyn/asynDriver/asynManager.c:1509] Serial2 addr -1 queueRequest priority 1 not lockHolder
" ]: "version
epicsThreadSleep 5
2013/11/26 11:36:36.615 [../../asyn/asynDriver/asynManager.c:855] asynManager::portThread port=Serial2 callback
2013/11/26 11:36:36.615 [../../asyn/drvAsynSerial/drvAsynSerialPort.c:627] /dev/ttyS2 write.
2013/11/26 11:36:36.615 [../../asyn/drvAsynSerial/drvAsynSerialPort.c:629] /dev/ttyS2 write 10
version\r\000\r
2013/11/26 11:36:36.615 [../../asyn/drvAsynSerial/drvAsynSerialPort.c:697] wrote 10 to /dev/ttyS2, return asynSuccess
dbpf devWfAsynRead.PROC 1
2013/11/26 11:36:41.615 [../../asyn/asynDriver/asynManager.c:1509] Serial2 addr -1 queueRequest priority 1 not lockHolder
DBR_UCHAR: 1 0x1
2013/11/26 11:36:41.615 [../../asyn/asynDriver/asynManager.c:855] asynManager::portThread port=Serial2 callback
2013/11/26 11:36:41.615 [../../asyn/drvAsynSerial/drvAsynSerialPort.c:715] /dev/ttyS2 read.
2013/11/26 11:36:41.615 [../../asyn/drvAsynSerial/drvAsynSerialPort.c:795] /dev/ttyS2 read 10
1.940 \r\006\006
2013/11/26 11:36:41.615 [../../asyn/drvAsynSerial/drvAsynSerialPort.c:827] /dev/ttyS2 read 10, return 0
epics>
On 11/25/2013 6:31 PM, Mark Rivers wrote:
I found and fixed a problem in drvAsynSerialPortWin32.c. When pasynUser->timeout was 0 for a read operation, and the number of characters available to read was 0, it was returning asynSuccess. This is incorrect, it should return asynTimeout.
Dirk also found a problem that when pasynUser->timeout was 0 it was not returning immediately.
With these fixes StreamDevice works correctly with local serial ports on WIN32.
These fixes will be in the next release of asyn, R4-23.
Mark
From: Mark Rivers
Sent: Sunday, November 24, 2013 12:25 PM
To: [email protected]
Subject: Anyone using StreamDevice with local serial ports on Windows?
Folks,
I am trying to use StreamDevice with a local serial port on win32-x86. It is not working. I’d like to know if the problem is specific to my setup.
Has anyone else used StreamDevice with local serial ports on win32-x86 or windows-x64?
Thanks,
Mark