Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

always VI_ERROR_RSRC_BUSY on reads, can't recover

No success, but incremental increase in understanding what's going on here...

I downloaded Scott Weston's patch and first tried manually installing that over pyusb v. 0.3.5, figuring that any improvements between 0.3.1 and 0.3.5 would be nice to keep. The patch & recompile went smoothly, and I manually followed his code (more or less), but when I tried a bulkWrite(), I got the error message "usb.USBError: could not detach kernel driver from interface 0: No data available" Tried diving down through the C source to see if I could figure out what was causing this, but gave up a few levels down. The call tree is:
bulkWrite() calls Py_usb_DeviceHandle_bulkWrite() in pyusb.c. That calls a number of formatting & parsing routines, but the meat of the function is usb_bulk_write(). That calls the libusb.c function usb_urb_transfer(), which I had trouble following; it calls a number of low-level routines. Presumably one of them tries to detach the kernel driver (again), but I don't know why / where.

So I went back up and applied the patch to pyusb v. 0.3.1 as recommended. During install, gcc generated some warnings similar to "pointer targets in assignment differ in signedness", which seems to be a complaint about an effecting type-casting from unsigned char * to signed char * (or vice versa). Figure that _probably_ isn't a big issue, since these characters are presumably being passed byte-wise, rather than being used in arithmetic. Unfortunately, I still get the "could not detach kernel driver" bit when I call bulkWrite().

The one happy achievement of all this is that I realized python casts bytes of the form 0x01 to 16-bit integers unless specifically told not to do so - which may be causing problems with the (assumed) byte-wise scope communication. The hack is to use chr() for every element of the byte-list, and to use chr((~self.bTag)&(0xff)) to take the inverse of bTag. For what its worth, I've attached some sample code. I usually run it from within python with "import testing" (Strip the .txt extension after dowload of testing.py.txt)

One other bit that confuses me: there's an oddity in the USBTMC spec: bTag is restricted to 1<=bTag<=255, and incrementing after each transfer. Presumably when it reaches 255, it rolls over to 0... or maybe to 1, but either way it seems like a minor violation of the spec. I haven't yet seen any explicit accounting for what's supposed to happen in the transfer _after_ #255. Maybe it's outlined in the USB spec; I haven't checked there yet.

Hope this helps.
Sarah Messer
gamer, physicist, programmer
0 Kudos
Message 11 of 32
(5,251 Views)
I just used a normal unpatched version of PyUSB 0.3.5. I think that detach stuff is "special" for that particular application in the example. AFAIK I'm not using any other driver except for the USB controller drivers since I am accessing the device directly. Therefore I probably don't want to detach it.

I commented it out and my code worked.
e.g.

def open(self):
    if self.handle:
        self.handle = None
        self.handle = self.dev.open()
#        self.handle.detachKernelDriver(0)
#        self.handle.detachKernelDriver(1)
        self.handle.setConfiguration(self.conf)
        self.handle.claimInterface(self.intf)
        self.handle.setAltInterface(self.intf)

I didn't worry too much about the bTag (yet) because the last thing I was focussed on was trying to work out what the init sequence was before sending the bulk write and bulk read.

I've looked at what my code does on the USB monitor and it looks exactly the same as the NI VISA code, so I'm not sure what I am missing.


0 Kudos
Message 12 of 32
(5,239 Views)
Good news & bad news today:

1) I finally got my writes to work consistently. Essentially, use the testing.py I posted before, but insert a self.handle.reset() right after the self.dev.open(), and remove the calls to detachKernelInterface() and setConfiguration(). Calling setConfiguration() seems to ruin the connection every time I call it, no matter the context. (I'm using the standard pyusb-0.3.5 here.)

2) Reads are still a mess.

3) Errors don't always get flagged immediately. setConfiguration(), for example, changes some state so that subsequent calls are much more likely to generate errors. _Usually_ I can recover the happy-oscilloscope state with some combination of reset(), clearHalt(), resetEndpoint(), and releaseInterface() & claimInterface() calls.

4) It doesn't seem to make a difference whether I import visa or not - except that sometimes both pyvisa and pyusb try to talk to the scope, and one locks the other out.

If I read your posts right, this is approximately your status as well...

Tomorrow I plan to dive into the source for libusb to sort out my error messages. My most common error result is "usb.USBError: No error", which I find particularly frustrating and uninformative.

What do you use for USB sniffing?
Sarah Messer
gamer, physicist, programmer
0 Kudos
Message 13 of 32
(5,202 Views)


@SMesser wrote:
Good news & bad news today:

1) I finally got my writes to work consistently. Essentially, use the testing.py I posted before, but insert a self.handle.reset() right after the self.dev.open(), and remove the calls to detachKernelInterface() and setConfiguration(). Calling setConfiguration() seems to ruin the connection every time I call it, no matter the context. (I'm using the standard pyusb-0.3.5 here.)
Can you confirm that you are able to: disable all NI-VISA software (no NI modules loaded, no NI processes running in the background), power up the scope, connect to the scope with your software, and perform a write?

3) Errors don't always get flagged immediately. setConfiguration(), for example, changes some state so that subsequent calls are much more likely to generate errors. _Usually_ I can recover the happy-oscilloscope state with some combination of reset(), clearHalt(), resetEndpoint(), and releaseInterface() & claimInterface() calls.
I'm unable to continue work on this problem for the moment, but it looks like you might be getting there.

4) It doesn't seem to make a difference whether I import visa or not - except that sometimes both pyvisa and pyusb try to talk to the scope, and one locks the other out.

If I read your posts right, this is approximately your status as well...
Similar, but I still require PyVISA to do something which I couldn't identify or see on the USB monitor.



Tomorrow I plan to dive into the source for libusb to sort out my error messages. My most common error result is "usb.USBError: No error", which I find particularly frustrating and uninformative.
That's the one that I get 20% of the time when it is working.


What do you use for USB sniffing?

There are several free Windows versions, but since I'm running Windows XP in a vmware session on Ubuntu Linux I prefer to use a Linux based sniffer - usbmon.
see /usr/src/linux/Documentation/usb/usbmon.txt for information. It takes some setting up, but works fairly well.

e.g. bulk write/read
--------- write *idn? -------------------
db1f6dc0 953816004 S Bo:056:06 -115 20 = 0102fd00 07000000 01000000 2a69646e 3f0d0a00
db1f6dc0 953817524 C Bo:056:06 0 20 >
------- read? -----------------
d48e3140 965376993 S Bo:056:06 -115 12 = 0203fc00 00500000 00000000
d8e7d1c0 965377017 S Bi:056:05 -115 8192 <
d48e3140 965378849 C Bo:056:06 0 12 >
d8e7d1c0 965389850 C Bi:056:05 0 60 = 0203fc00 30000000 01000000 54454b54 524f4e49 582c5444 53203230 3134422c

Fields for first line are:
URB tag, timestamp, S - submit, Bo - Bulk Out, 056 - Device Address, 06 - Endpoint, -115 = see /usr/include/linux/errno.h , 20 - data length, data = the request array for *idn?
C - callback, Bi = bulk in, Ci = Control In, etc ...

My scan of the PyVISA control setup is:
db1f6dc0 924398942 S Ci:056:00 s 80 06 0300 0000 0004 4 <
db1f6dc0 924400241 C Ci:056:00 0 4 = 04030904
db1f6dc0 924400883 S Ci:056:00 s 80 06 0303 0409 0002 2 <
db1f6dc0 924403238 C Ci:056:00 0 2 = 1003
db1f6dc0 924403275 S Ci:056:00 s 80 06 0303 0409 0010 16 <
db1f6dc0 924406236 C Ci:056:00 0 16 = 10034300 30003100 30003900 31003500
db1f6dc0 924406380 S Ci:056:00 s a1 07 0000 0000 0018 24 <
db1f6dc0 924409245 C Ci:056:00 0 24 = 01000001 00010000 00000000 00010707 00000000 00000000
db1f6dc0 924412671 S Ci:056:00 s a1 a0 0001 0000 0001 1 <
db1f6dc0 924416241 C Ci:056:00 0 1 = 01

By the way, I received a reply from Tektronix support. They acknowledged the lockup if the read times out.
i.e.
"Request Resolution:
I have verified this behavior and passed the information on to our VISA
software engineering team. They have entered it as a bug in the software and
will be trying to get this behavior repaired by the next release of TekVISA
which is expected first quarter 2007."


0 Kudos
Message 14 of 32
(5,196 Views)
Okay, time for the progress report:

I can confirm that I didn't need any of NI-VISA's components to access the scope using pyusb. I used both "lsmod | grep -i ni" and "ps -A | grep -i ni" to scan for NI stuff. I went on to uninstall NI-VISA and reboot.

N.B.: The UNINSTALL script that comes with the Linux version of NI-VISA doesn't get it completely off the system; after reboot, several NI components were loaded, but UNINSTALL did not detect them when I ran it a second time. I used modprobe -r and kill to get rid of them, then deleted /usr/local/natinst to get rid of the files. After that, I had to go into /etc/init.d and its subdirectories to manually delete the dangling soft links pointing to the (deleted) /usr/local/natinst files. After that I rebooted again; this time the system came up clean. After that, I recompiled, in order, libusb, pyusb, and my own convenience scripts - just to make sure there weren't any links to defunct NI libraries or daemons.

The scope runs NI-free, but its possible NI's software had a stabilizing influence. At least two distinct bugs remain:

Bug #1, the "No Error" message: I traced this down to a problem in usb_urb_transfer(), a routine in libusb-0.1.12/linux.c . The error was due to a timeout that was caught and recognized as such by the code, but the error flags were never set. I've posted a candidate patch on the "Bugs" forum of SourceForge.net's libusb project. Unfortunately, I still get a timeout here. I think this is a bug in the scope, but I can't guarantee it.

Bug #2, usually manifests as a "could not reset: Is a directory" error: This looks like something low-level inside linux. As far as I can tell, what happens is that one of the boot processes or background daemons grabs the scope and doesn't let go of it. As a result, nothing else can access the scope. This problem seems to be more frequent without the NI-VISA package, although A) I had it occasionally with NI-VISA installed, and B) I don't always have it even with NI-VISA missing.

Both bugs somehow involve the ioctl() function declared in /usr/include/sys/ioctl.h, but that function's highly polymorphic and fairly close to the hardware, so I suspect its both robust and hard to debug. (I haven't yet found the source code for it.)

For usb sniffers, you might also look at the module usbcore, which has a boolean flag "usbfs_snoop." Set it to true, and it logs all usbfs traffic. I haven't tried it yet, partly because I'm not sure how to use it and partly because I'm a bit nervous about altering the files in /etc/init.d
Sarah Messer
gamer, physicist, programmer
0 Kudos
Message 15 of 32
(5,175 Views)


I can confirm that I didn't need any of NI-VISA's components to access the scope using pyusb. I used both "lsmod | grep -i ni" and "ps -A | grep -i ni" to scan for NI stuff. I went on to uninstall NI-VISA and reboot.
Can you post your Python test code for this?

N.B.: The UNINSTALL script that comes with the Linux version of NI-VISA doesn't get it completely off the system; after reboot, several NI components were loaded, but UNINSTALL did not detect them when I ran it a second time. I used modprobe -r and kill to get rid of them, then deleted /usr/local/natinst to get rid of the files. After that, I had to go into /etc/init.d and its subdirectories to manually delete the dangling soft links pointing to the (deleted) /usr/local/natinst files.
I'm not suprised, their install scripts didn't really fill me with confidence either.

Bug #2, usually manifests as a "could not reset: Is a directory" error: This looks like something low-level inside linux. As far as I can tell, what happens is that one of the boot processes or background daemons grabs the scope and doesn't let go of it. As a result, nothing else can access the scope. This problem seems to be more frequent without the NI-VISA package, although A) I had it occasionally with NI-VISA installed, and B) I don't always have it even with NI-VISA missing.
Make sure your scope is set to "Rear USB Port Computer" and not "Auto" in menu "Utility" > "Options". Otherwise, I think, the USBHID driver grabs it.

For usb sniffers, you might also look at the module usbcore, which has a boolean flag "usbfs_snoop." Set it to true, and it logs all usbfs traffic. I haven't tried it yet, partly because I'm not sure how to use it and partly because I'm a bit nervous about altering the files in /etc/init.d

I had a look at it, not bad, easier to read output than usbmon. You can enable it (as root) like so:

# echo 1 >  /sys/bus/usb/drivers/usbfs/module/parameters/usbfs_snoop

Then look at /var/log/messages to see things like:
Jan 15 10:50:40 root kernel: [17946690.292000] usb 1-5: usbdev_ioctl: SUBMITURB
Jan 15 10:50:40 root kernel: [17946690.292000] usb 1-5: bulk urb
Jan 15 10:50:40 root kernel: [17946690.292000] usb 1-5: submit urb
Jan 15 10:50:40 root kernel: [17946690.292000] usb 1-5: direction=OUT
Jan 15 10:50:40 root kernel: [17946690.292000] usb 1-5: userurb=bff74fb4
Jan 15 10:50:40 root kernel: [17946690.292000] usb 1-5: transfer_buffer_length=20
Jan 15 10:50:40 root kernel: [17946690.292000] usb 1-5: actual_length=0
Jan 15 10:50:40 root kernel: [17946690.292000] usb 1-5: data: 01 04 fb 00 07 00 00 00 01 00 00 00 2a 69 64 6e 3f 0d 0a 00

0 Kudos
Message 16 of 32
(5,160 Views)
SUCCESS! I used SnoopyPro 0.22 (a.k.a. Usb Sniffer for Windows from SourceForge.net) on a Windows PC to record communication with the scope while running Tektronix's OpenChoice Talker/Listener program. I recorded and printed the various exchanges, most of which were configuration commands. At the end of the log were the BULK IN & OUT exchanges. Some notes, then my python source code:

1) "*IDN?" (and presumably other requests) are to be sent with the DEV_DEP_MSG_OUT msgID; looking back at the USBTMC spec, the REQUEST_DEV_DEP_MSG_IN msgID should be the last transfer before checking for receipt of info from the scope. REQUEST_DEV_DEP_MSG_IN consists of no data other than the 12-byte header; it's purely a flag to say "Ok scope, your turn to talk; here's how many bytes you have to play with"

2) The size of the buffer is specified separately by REQUEST_DEV_DEP_MSG_IN and by usb.DeviceHandle.bulkRead(); both sizes must match.

3) I've made it go with *IDN?, but haven't yet put together the routines to automate reading data, so I haven't fully tested the interface. Nevertheless, here's my working python code (w/o NI-VISA):

---

RUN='\x01\x01\xfe\x00\x0d\x00\x00\x00\x01\x00\x00\x00acq:state run\x00\x00\x00'
STOP='\x01\x01\xfe\x00\x0e\x00\x00\x00\x01\x00\x00\x00acq:state stop\x00\x00'
ID='\x01\x01\xfe\x00\x05\x00\x00\x00\x01\x00\x00\x00*idn?\x00\x00\x00'
REQ_IN='\x02\x02\xfd\x00\x00\x01\x00\x00\x00\x00\x00\x00'
import usb
dev=usb.busses()[4].devices[0]
hand=dev.open()
print hand
conf=dev.configurations[0]
intf=conf.interfaces[0][0]
hand.reset()
hand.claimInterface(intf)
hand.bulkWrite(6,ID)
hand.bulkWrite(6,REQ_IN)
stuff=hand.bulkRead(133,256)

---

next time you're going to be in Washington, DC (USA), send me an email; we'll get lunch or something: ikustosu yahoo com

Happy Coding!
Sarah Messer
gamer, physicist, programmer
0 Kudos
Message 17 of 32
(5,140 Views)
Thanks for the code. It's essentially the same as what I had. Unfortunately it doesn't work for me on my machine.

I keep getting the "no error" message on the very first bulk transfer. My original code does the same - unless I run the PyVISA first.

If I run the PyVISA first, request the *IDN? (which works), unload and remove all the NI software, then use your code - it will work. Even if I unplug/replug the scope, I can use our code. But if I power cycle the scope, I can no longer use our code and I have to use the PyVISA method again.

I still think that the NI code does something to the scope that our code isn't doing. I know that I don't require the NI stuff loaded to access the scope. Maybe, it's my PC? This is all really weird.

Hmmm ... what other changes did you make to pyusb and libusb? Which versions did you use? How did you get around the "no error" problem?

0 Kudos
Message 18 of 32
(5,138 Views)
I'm pretty sure I'm using the original files for pyusb 0.3.5
For libusb > linux.c 0.1.12, I only had a small change; I've attached diff's output.  I haven't had any "No error"s  since I applied it - although the real problem for me was that I was sending incorrect requests.

ok, running through the standard tech-support sorts of questions, just to make sure they've been covered:

Have you done a detailed comparison of the I/O your USB sniffer sees and what you expect?
Are you running the current firmware update on your scope (v. 22.01, visible under Utility > System Status)?

Here are the srcversion fields for several of my modules (obtained with modinfo):
usbcore    62B24CE973CC2BAEBF19191
ehci_hcd   32009005883B73E7D6246DB
uhci_hcd   67447CD3083BE197D26E687

All three modules are necessary for me to communicate with the scope.  usbcore is also listed as "in-use" by some process in addition to these modules - I haven't yet figured out which process needs it.  (Mouse, kbd, and monitor don't use usb.)

I've attached a file showing the data that I'm sending and receiving for a single "*IDN?" request.  The data is sent as a sequence of characters, not a single string.
I would attach a portion of my logfile, but that doesn't show actual transmitted data, just which functions get called (lots of REAPURBDELAY and IOCTL).
Do you have multiple TDS 2014B scopes?  Do they all give the same behavior?

Hope this helps.
Sarah Messer
gamer, physicist, programmer
Download All
0 Kudos
Message 19 of 32
(5,128 Views)
whoops. the above testoutput.txt didn't have what I thought. Try this one.
Sarah Messer
gamer, physicist, programmer
0 Kudos
Message 20 of 32
(5,127 Views)