areaDetector / pvaDriver

An EPICS areaDetector driver for importing an EPICSv4 NTNDArray via pvAccess into an areaDetector IOC.
https://areadetector.github.io/master/pvaDriver/pvaDriver.html
Other
1 stars 5 forks source link

connectPv exception on IOC start up #1

Closed GDYendell closed 7 years ago

GDYendell commented 7 years ago

I am currently trying to update DLS to ADCore 2-6, plus the other dependencies that come with that.

I have two IOCs, one with a SimDetector and pvaPlugin, the other with a pvaDriver, PosPlugin and HDF5Plugin. It works OK with our most recent internal ADCore 2-4 release. (We imported pvaDriver at this commit https://github.com/dls-controls/ADCore/commit/834944c827b43f0948f1364caddb41c50ccc78a7). The PvName is set, reports up and I am able to get frames and capture an image.

When testing the pvaDriver in its new repository I got the following error:

2017/04/05 16:09:17.358 pvaDriver::connectPv exception initializing monitor: 0 or empty channel name
2017/04/05 16:09:17.359 MAP-DI-TEST-01:CAM:PvName devAsynOctet::writeIt failed pvaDriver:writeOctet: status=3, function=87, value=

and on start up, the PvName is empty and reports as Down and I can't get any frames through. Here is the console output where I have added some debug statements; PvName and 4 numbers throughout the connectPv function and the value asked to set in the writeOctet function.

 > bin/linux-x86_64/sttestPVDriver.sh 
# This file was automatically generated on Tue 04 Apr 2017 16:50:49 BST from
# source: /dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/etc/makeIocs/testPVDriver.xml
# 
# *** Please do not edit this file: edit the source file instead. ***
# 
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
epicsEnvSet "EPICS_TS_MIN_WEST", '0'
# Loading libraries
# -----------------
# Device initialisation
# ---------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadDatabase "dbd/testPVDriver.dbd"
testPVDriver_registerRecordDeviceDriver(pdbbase)
# pvaDriverConfig(portName, pvName, maxBuffers, maxMemory, priority, stackSize)
pvaDriverConfig("SIM.CAM", TESTPV1, 50, 0, 0, 0)
PV Name: TESTPV1
1
2
3
4
# NDPosPluginConfigure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory, priority, stackSize)
NDPosPluginConfigure("SIM.POS", 2, 0, "SIM.CAM", 0, 50, 0, 0, 0)
# NDFileHDF5Configure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory)
NDFileHDF5Configure("SIM.HDF", 1000, 0, "SIM.POS", 0, 50, 0)
# Final ioc initialisation
# ------------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadRecords 'db/testPVDriver_expanded.db'
iocInit
Starting iocInit
############################################################################
## EPICS R3.14.12.3 $Date: Mon 2012-12-17 14:11:47 -0600$
## EPICS Base built Mar 18 2015
############################################################################
Writing Octet ''
Writing Octet ''
PV Name: 
1
2
2017/04/05 16:37:48.285 pvaDriver::connectPv exception initializing monitor: 0 or empty channel name
2017/04/05 16:37:48.285 MAP-DI-TEST-01:CAM:PvName devAsynOctet::writeIt failed pvaDriver:writeOctet: status=3, function=87, value=
cas warning: Configured TCP port was unavailable.
cas warning: Using dynamically assigned TCP port 38347,
cas warning: but now two or more servers share the same UDP port.
cas warning: Depending on your IP kernel this server may not be
cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)
iocRun: All initialization complete
epics>

I tried playing with the pvaDriver source to find the problem and it seems like, between pvaDriverConfig() and connectPv() being called a second time, something is calling writeOctet to set PvName to a blank string. I added a check to refuse to set PvName if the value is blank and that seems to fix the issue. The PvName is blank, but reports up and I can get frames and capture an image.

I tried checking out the ADCore 2-6 and pvaDriver 1-1 releases, alongside the DLS configure/ folder and I get the same issue.

 > bin/linux-x86_64/sttestPVDriver.sh 
# This file was automatically generated on Tue 04 Apr 2017 16:50:49 BST from
# source: /dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/etc/makeIocs/testPVDriver.xml
# 
# *** Please do not edit this file: edit the source file instead. ***
# 
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
epicsEnvSet "EPICS_TS_MIN_WEST", '0'
# Loading libraries
# -----------------
# Device initialisation
# ---------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadDatabase "dbd/testPVDriver.dbd"
testPVDriver_registerRecordDeviceDriver(pdbbase)
# pvaDriverConfig(portName, pvName, maxBuffers, maxMemory, priority, stackSize)
pvaDriverConfig("SIM.CAM", TESTPV1, 50, 0, 0, 0)
# NDPosPluginConfigure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory, priority, stackSize)
NDPosPluginConfigure("SIM.POS", 2, 0, "SIM.CAM", 0, 50, 0, 0, 0)
# NDFileHDF5Configure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory)
NDFileHDF5Configure("SIM.HDF", 1000, 0, "SIM.POS", 0, 50, 0)
# Final ioc initialisation
# ------------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadRecords 'db/testPVDriver_expanded.db'
iocInit
Starting iocInit
############################################################################
## EPICS R3.14.12.3 $Date: Mon 2012-12-17 14:11:47 -0600$
## EPICS Base built Mar 18 2015
############################################################################
2017/04/05 16:40:03.678 pvaDriver::connectPv exception initializing monitor: 0 or empty channel name
2017/04/05 16:40:03.678 MAP-DI-TEST-01:CAM:PvName devAsynOctet::writeIt failed pvaDriver:writeOctet: status=3, function=87, value=
cas warning: Configured TCP port was unavailable.
cas warning: Using dynamically assigned TCP port 45807,
cas warning: but now two or more servers share the same UDP port.
cas warning: Depending on your IP kernel this server may not be
cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)
iocRun: All initialization complete
epics>

and with my check

 > bin/linux-x86_64/sttestPVDriver.sh 
# This file was automatically generated on Tue 04 Apr 2017 16:50:49 BST from
# source: /dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/etc/makeIocs/testPVDriver.xml
# 
# *** Please do not edit this file: edit the source file instead. ***
# 
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
epicsEnvSet "EPICS_TS_MIN_WEST", '0'
# Loading libraries
# -----------------
# Device initialisation
# ---------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadDatabase "dbd/testPVDriver.dbd"
testPVDriver_registerRecordDeviceDriver(pdbbase)
# pvaDriverConfig(portName, pvName, maxBuffers, maxMemory, priority, stackSize)
pvaDriverConfig("SIM.CAM", TESTPV1, 50, 0, 0, 0)
PV Name: TESTPV1
1
2
3
4
# NDPosPluginConfigure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory, priority, stackSize)
NDPosPluginConfigure("SIM.POS", 2, 0, "SIM.CAM", 0, 50, 0, 0, 0)
# NDFileHDF5Configure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory)
NDFileHDF5Configure("SIM.HDF", 1000, 0, "SIM.POS", 0, 50, 0)
# Final ioc initialisation
# ------------------------
cd "/dls_sw/work/R3.14.12.3/support/IOCTestSuite/MappingBuilder/iocs/testPVDriver"
dbLoadRecords 'db/testPVDriver_expanded.db'
iocInit
Starting iocInit
############################################################################
## EPICS R3.14.12.3 $Date: Mon 2012-12-17 14:11:47 -0600$
## EPICS Base built Mar 18 2015
############################################################################
Writing Octet ''
Writing Octet ''
Not changing PV Name from 'TESTPV1' to ''
PV Name: TESTPV1
1
2
3
4
cas warning: Configured TCP port was unavailable.
cas warning: Using dynamically assigned TCP port 46015,
cas warning: but now two or more servers share the same UDP port.
cas warning: Depending on your IP kernel this server may not be
cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)
iocRun: All initialization complete
epics> 

Any idea what the problem is?

MarkRivers commented 7 years ago

It sounds like perhaps autosave is restoring a blank string. Do you have the PvName is your auto_settings.req file?

Mark

ajgdls commented 7 years ago

I don't think @GDYendell is using autosave. There looks like no sign of autosave calls in the startup script.

Cheers, Alan

brunoseivam commented 7 years ago

In pvaDriver.template try setting PvName's PINI field to "NO"

GDYendell commented 7 years ago

That stops it @brunoseivam . No error message and the PvName is correct and reports up. Is this the fix to make, or is it just to diagnose the issue?

I guess it would make more sense to just remove the PINI entry. I have this fix on a branch, it would be good if it could be merged into master unless there is a better solution. I am happy to make a PR.

brunoseivam commented 7 years ago

That's what I think, too. Since the PV name is passed in the constructor, there's no need to have it set again on record loading.

A PR would be welcome!

GDYendell commented 7 years ago

PR here #2

GDYendell commented 7 years ago

If removing the PINI field will break autosave restoring, then perhaps a better solution would be to stop it overriding the *Config value unless it is explicitly set in autosave. Is this possible?

MarkRivers commented 7 years ago

It seems to me that the problem is really that the are 2 ways to configure the value at iocInit. The first is by an argument to the costructor and the second is via a record which the user could configure in the database. Why have both?

brunoseivam commented 7 years ago

@MarkRivers We could in principle get rid of the configuration by passing a PV name to the constructor. But that is an API breakage... This driver is the way it is right now because at first it didn't support changing the PV name at runtime. This functionality was added later.

I took a deeper look into it. I think the correct fix is what @GDYendell suggested at first: refusing blank PV names. The monitor creation code already does that check for us and throws an exception when it gets an invalid PV name.

The way it is right now, pvaDriver blindly accepts anything as a PV name and tries to create a monitor with it. However, if the monitor creation fails, it doesn't reject the input.

I am preparing a pull request that will check if the monitor creation succeeds first before setting the internal parameters. So having PINI=YES with a blank VAL field will be harmless.

MarkRivers commented 7 years ago

That sounds like a good solution.

brunoseivam commented 7 years ago

See #3