Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FINDLSTN via E5810a #16

Open
fluteze opened this issue Sep 29, 2016 · 15 comments
Open

FINDLSTN via E5810a #16

fluteze opened this issue Sep 29, 2016 · 15 comments

Comments

@fluteze
Copy link

fluteze commented Sep 29, 2016

How do I issue the command FINDLSTN to the ethernet<->gpib converter (Agilent E5810a) to list all active listeners?

I've read the source code and it isn't apparent how to accomplish this.

An attempt produces this:

import vxi11
i=vxi11.Instrument("*************","gpib0")
i.ask("FINDLSTN")
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 664, in ask
return self.read(num, encoding)
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 652, in read
return self.read_raw(num).decode(encoding).rstrip('\r\n')
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 622, in read_raw
raise Vxi11Exception(error, 'read')
vxi11.vxi11.Vxi11Exception: 17: IO error [read]

or

import vxi11
i=vxi11.Instrument("*************") # No gpib0 (in hopes to enumerate com port as well
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 663, in ask
self.write(message, encoding)
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 648, in write
self.write_raw(str(message).encode(encoding))
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 560, in write_raw
self.open()
File "/usr/lib/python3.5/site-packages/vxi11/vxi11.py", line 530, in open
raise Vxi11Exception(error, 'open')
vxi11.vxi11.Vxi11Exception: 3: Device not accessible [open]

@alexforencich
Copy link
Contributor

Eh, there isn't a very good way to do that at the moment. I need to add support for some of the GPIB specific 'out of band' commands. The problem is the command has to be interpreted by the converter itself. There are extensions on the base VXI-11 protocol that support stuff like that, but it's currently not implemented in python-vxi11. It's on my to-do list, but it might be a little while before I get a chance to implement that.

@fluteze
Copy link
Author

fluteze commented Oct 7, 2016

Can you point me to some documentation on the E5810a for the out-of-band (rpc calls perhaps) instructions? I'll see if I can write the code.

@alexforencich
Copy link
Contributor

Alright, so I have been doing some reading on the VXI-11 spec and on that command. Apparently that isn't a command that is directly supported by a GPIB controller, it's an algorithm implemented in the GPIB driver. So that means it would have to be implemented in python somewhere. The real, proper solution would be to reorganize the python-vxi11 code so there are separate 'instrument' and 'controller' modules, possibly both inheriting from a common parent 'device' class, and then implement the low-level stuff (like find_listeners, which would be the 'pythonic' name) in the 'controller' module. It looks like the actual API call required is already there, device_docmd, it's just a matter of writing the high-level wrappers to perform the commands listed in the VXI-11 spec.

@alexforencich
Copy link
Contributor

Just committed an initial implementation of the VXI-11 level commands to interface with a VXI-11 to GPIB unit. Next step is to implement the high level API - parallel polling, find listeners, etc.

@alexforencich
Copy link
Contributor

Well, it has been a productive evening. I found a bug in the ICS 8065 firmware that results in truncated response packets. Hopefully they will fix that in the firmware as I don't want to have to further break the VXI-11 RPC code to work around it. So the code doesn't work on an ICS 8065 on any firmware version. But it does work on the E2050A. Also, apparently there is something wrong with the 'standard' implementation for findlstn. Not sure why, but if I don't send the talk address of the controller, the routine only detects the controller. The GPIB devices do pick up that they are being addressed, they just don't seem to assert the NDAC signal. If I don't follow the spec and send the controller talk address as well as the 'test' listen addresses, then it seems to work correctly. Anyway, try it and let me know what you think. I'll look in to implementing some of the other high level commands.

@fluteze
Copy link
Author

fluteze commented Oct 11, 2016

Generally works with Agilent E5810a. Must specify "gpib0" instead of the default "inst0" in the call to InterfaceDevice().

An oddity in the response system:
If the list sent to find_listeners() starts with a non 0 (zero) item and that item is responsive on the gpib bus (i.e. address 10), the return string runs through ((10,1),(10,2),(10,3)...(10,30), 16,17,21,27, etc.) with the non-tupled items being actual active item on the bus. If the first item is non-zero and non-active, all seems to be well. When no list is supplied the default of range(31) seems to work OK. My particular setup appears to have a ghost on address 21. FINDLSNT reports the device but all physically connected devices are accounted.

Note for Aglient E5810a users: This converter will timeout other concurrent sessions on the bus while doing this scan. Also note, this converter will HARD lockup if nmap is run against it.

@alexforencich
Copy link
Contributor

OK, the default should now be 'gpib0' instead of 'inst0' for the InterfaceDevice object.

I presume 21 is the address of the E5810A. I modified the code to skip the unit address when scanning the complete bus. Not sure what's going on with address 0 though. I have not been able to duplicate that behavior with my setup. I am using an E2050A, though I'm not sure if that would make a difference. I also don't have any other sessions running in parallel.

I also added lock/unlock around the find_listeners call. However, it doesn't appear that the locks are necessarily implemented correctly on the devices - i.e. you can get a lock on a device and on the interface device at the same time, which makes no sense. Really, there should be 32 locks - one per device and one for the interface, and you can't get the interface lock if ANY devices are locked, and you can't get ANY device lock if the interface is locked. However, it seems like it doesn't work this way on either the E2050 or the ICS 8065 box. The E2050 lets me lock the interface and a device at the same time, but it doesn't let the device link do I/O when the interface is locked. Which is very strange because supposedly the device link has the lock. The ICS 8065 seems to be completely disjoint - you can get an interface lock and a device lock at the same time, and it doesn't do anything to prevent a device link from performing I/O when the interface is locked. Seems like there are more bug reports to file.

@fluteze
Copy link
Author

fluteze commented Oct 12, 2016

The Agilent E5810a with firmware A.01.02 does not really honor locks in an anticipated manner either. Sometimes things are great, no problem, then random glitches appear in the data returned to a query command running on another system from the one running FINDLSTN. I would have guessed the E5810a would lock all devices on the buss when the buss is locked, but nope.

The net effect is the second process running a .ask(":meas:volt:dc?") etc. receives a null response without any error code from the E5810a.

Connecting to the instrument (i.e. gpib0,3) and locking it before checking FINDLSTN on the buss/address seems to work if the instrument & lock time-outs are long enough on the .ask application and the address is responsive. If the address isn't responsive in 5 seconds or so, it will generate an error to the other processes.

Feels awkward to do it this way, but the enumeration does work.

@fluteze
Copy link
Author

fluteze commented Oct 12, 2016

Here's the code I've found the greatest success:

import vxi11
adapter="***************_" # E5810a address/name
l=[]
f=[]
d=vxi11.InterfaceDevice(adapter,'gpib0')
for n in range(30):
try:
inst=vxi11.Instrument(adapter,'gpib0,{0}'.format(n))
inst.open()
inst.lock()
f=d.find_listeners([n]) # if I do the whole range at once it will interfere...
if f != []:
print("Address: {0}\t{1}".format(n,inst.ask("_IDN?")))
l.append(f[0])
inst.unlock()
inst.close()
del inst
except:
e=sys.exc_info()[0]
print("Error on inst no.: {0}\n{1}".format(n,e))
del inst
print(l)
print("Done.")

@alexforencich
Copy link
Contributor

alexforencich commented Oct 12, 2016

The problem with that is a transaction to a DIFFERENT address on the same bus at the wrong time will mess up the find_listeners routine. Really, you need to lock out ALL of the other devices on the bus while performing the scan, otherwise things are likely to interfere. It looks like interface locking is completely useless (actually, I would say worse than useless...having no locks at all is one thing, but having locks that don't work gives you a false sense of security) on most of the existing GPIB to LAN boxes.

It's dissapointing that the spec does not cover this...what the boxes really need to implement is 32 locks, one per device and one for the bus. The bus lock can either be held by an interface link, or by the controller. To get a device lock, the controller has to first acquire the bus lock. The controller then cannot release the bus lock until all of the other device locks have been released. It should not even be possible to acquire a bus lock until the instrument locks have been released, nor should it be possible to acquire an instrument lock while an interface link holds the bus lock.

@fluteze
Copy link
Author

fluteze commented Oct 12, 2016

Yeah, that's what I thought. Kinda an awkward situation. Either way, the
FINDLSTN function is returning useable data, the other processes didn't
appear to cause it any issues.

@Jay-Berg
Copy link

Jay-Berg commented May 12, 2017

Actually the 8065 and 9065 ICS VXI-11.2 gateway devices have a maximum of 64 locks, not just 32 locks.

However there is a problem in regards to locks in relation to a VXI-11.2 gateway device in that the VXI-11 specification fails to define the result of an Interface level lock in regards to device level operations. This is left to the implementer as to what happens based on his/her understanding of the VXI-11 specification.

In the case of the ICS VXI-11.2 devices it was felt that the VXI-11 definition of locks requires locking of only the resource defined by the link and does not extend to impacting resources defined by other links. As a result the locking of the interface link does not directly impact operations based on a device level link.

Furthermore implementing a "bus lock" is not possible under the VXI-11 specification since the GPIB bus is not a resource (can not be named specifically) and thus can not have a link created. Remember that the interface itself is a resource only insofar as the VXI-11 commands that affect the resource and that the GPIB bus is not a part of the interface resource.

Another issue to remember is that secondary GPIB addresses may exist on the GPIB bus. Thus locking of resource GPIB0,2 will not lock GPIB0,2,1. Since it is unknown whether any given resource exists let alone whether secondary resources exist, a much larger pool than just 32 (primary) GPIB resources would need to be locked to ensure no GPIB bus operations. Each and every potential GPIB resource would need locking, including all potential secondary resources.

The FINDLSTN client side operation is but one example of VXI-11 locking limitations. Unfortunately there is no perfect solution to be found within the VXI-11 specification. Remember what the VXI-11 specification itself says.

"The communications and programming paradigms supported by this specification are similar in nature to the techniques supported by IEEE 488.2."

@alexforencich
Copy link
Contributor

My point is that when an interface link attempts to acquire a lock, it won't be able to if ANY other locks are currently active. In other words, if you want to lock the interface link, ALL of the other locks must be released. And on the flip side, attempting to acquire a device link lock will fail if the interface lock has been acquired. Otherwise the interface lock is just about totally useless. Good point about primary vs. secondary addresses - I didn't realize that you could have an arbitrary number of levels of sub-addresses. This is probably not very common, though.

I think it's important to note that the interface link can be used to 'forge' requests to any device on the bus. Say, if you lock GPIB0,2, the interface link can directly read and write GPIB0,2 despite the lock. I don't think this is really the same situation as locking GPIB0,2 and then accessing GPIB0,2,1 - it is a sub-address, but it is a distinct address and I think it's reasonable for it to fall under a different lock.

The other issue with FINDLSTN is that it tends to put devices into remote mode. Some older devices go in to remote mode as soon as they are addressed. Unfortunately, there probably isn't a clean way to avoid that in general.

@Jay-Berg
Copy link

Your design thoughts are of interest, but I fear that they would violate the VXI-11 specification. The specification defines four possible errors for the device_lock. If in your design the GPIB0 resource was locked, what error would the device_lock return if an attempt is made to lock a device resource? Using error-11 would be tempting, but wrong in that it would say that the device resource was locked, which is not the case.

Furthermore the specification allows for the exclusive ownership of a device through locking of the device without ever unlocking it since no time limit is defined for lock ownership. Using your design would mean that the GPIB0 resource would never be able to be locked if a device is locked and never unlocked.

While it is not explicitly defined, the VXI-11 specification has an implied rule that resources are independent of other resources. As such an action directed to a specific resource should not impact any other resource. However as has been pointed out in this thread, some GPIB0 level functions do have the ability to impact other resources through bus manipulation.

Given how the device_lock (and locking in general) is defined in the specification, much discussion has been done as to how to implement it. I know that ICS and Agilent invested many emails and phone calls discussing this single point. However no consensus was ever reached and there are small differences between the two companies in their VXI-11 implementations.

I can only explain how ICS designed locking and why the design choices were made.

@Jay-Berg
Copy link

A side note should be made at this point regarding the usage of GPIB-32.DLL in a dedicated GPIB controller (such as a PCI card).

Assume the case where two different applications are executing on the PC, with each application having GPIB control capabilities. Application-1 executes a FINDLSTN GPIB-32.DLL command, with application-2 executing an ib_wrt function at the same time. The FINDLSTN begins the binary search for listeners but the ib_wrt function also begins the writing to a specific device (which results in a specific LSTN address). Obviously there would be a conflict which would invalidate one, or the other unless there was locking implemented within the GPIB-32.DLL) itself. Since such locking is not done, one or the other command will be corrupted and fail to properly execute and invalidate the result. While it could be said that a well designed GPIB-32.DLL should block other GPIB operations while the FINDLSTN is active, other bus operations can be performed which could result in conflict. Imagine application-1 using IBCMD to issue a specific LSTN command sequence, with application-2 then issuing an IBWRT which changes the active LSTN address, then a second application-1 function would execute on the wrong device.

If GPIB operations are done exclusively through VISA, then locking can be done which would prevent such issues. However there is nothing preventing applications from using GPIB-32.DLL functions and therefore invalidating any VISA locking.

As you can see, this issue of locking of (or rather inability to lock) resources is not exclusive to VXI-11, but rather exists even with a dedicated GPIB controller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants