[PATCH] Re: unreliable USBTMC driver with Tektronix TDS1012B

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2009/9/4 Gergely Imreh <imrehg@xxxxxxxxx>:
> 2009/9/4 Greg KH <greg@xxxxxxxxx>:
>> On Thu, Sep 03, 2009 at 07:08:17PM +0800, Gergely Imreh wrote:
>>> 2009/9/3 Gergely Imreh <imrehg@xxxxxxxxx>:
>>> > 2009/9/3 Greg KH <greg@xxxxxxxxx>:
>>> >> On Thu, Sep 03, 2009 at 09:09:54AM +0800, Gergely Imreh wrote:
>>> >>> Dear Christoph,
>>> >>>
>>> >>> 2009/9/2 Zimmermann Christoph <christoph.zimmermann@xxxxxx>:
>>> >>> > hi gergely
>>> >>> >
>>> >>> > please read the mailing list archives before you ask a question.
>>> >>> > yes you are absolutely right, the behaviour you see is what we also reported here on the mailinglist. i'm a usbtmc driver user, not a kernel hacker, so i follow the mailing list and wait for patches to test.
>>> >>>
>>> >>> Yes, I read the archives before posting and I've seen two messages in
>>> >>> the last few months with similar issues.
>>> >>> 1) "Is anyone maintaining (or even using) usbtmc?" thread in the
>>> >>> beginning of August which ended with no conclusion, just a guess that
>>> >>> maybe the firmware is wrong. I know that it is not the case here.
>>> >>> 2) "usbtmc driver" thread - I think by you in June, where with a
>>> >>> usbmon log, but then left the further questions unanswered (at least
>>> >>> they are not on the list).
>>> >>
>>> >> Hm, I do have a number of usbtmc patches queued up for the next kernel
>>> >> release that might resolve some of these issues.  Could you run the
>>> >> latest linux-next release to see if that resolves them?
>>> >>
>>> >
>>> > Tried it with:
>>> > echo "*IDN?" > /dev/usbtmc0
>>> > cat /dev/usbtmc0
>>> >
>>> > On the visible side, all the same (timeout error, occasional no
>>> > answer). Using usbmon, there's a little difference, the trace now
>>> > loooks like this
>>> >
>>> > f660f480 4084277869 S Bo:3:003:6 -115 20 = 0126d900 06000000 01000000
>>> > 2a49444e 3f0a0000
>>> > f660f480 4084279150 C Bo:3:003:6 0 20 >
>>> > f660f480 4087365550 S Bo:3:003:6 -115 12 = 0227d800 f1070000 000a0000
>>> > f660f480 4087366642 C Bo:3:003:6 0 12 >
>>> > f660f480 4087366672 S Bi:3:003:5 -115 2048 <
>>> > f660f480 4087373634 C Bi:3:003:5 0 60 = 0227d800 30000000 01000000
>>> > 54454b54 524f4e49 582c5444 53203130 3132422c
>>> > f660f480 4087373691 S Bo:3:003:6 -115 12 = 0228d700 f1070000 000a0000
>>> > f660f480 4087374630 C Bo:3:003:6 0 12 >
>>> > f660f480 4087374661 S Bi:3:003:5 -115 2048 <
>>> > f660f480 4087384632 C Bi:3:003:5 -2 0
>>> >
>>> > Here the difference compared to the one in the thread start is that
>>> > previously the conversation ended with something like:
>>> > f672ae00 2503575589 S Ci:3:113:0 s a2 03 002b 0085 0002 2 <
>>> > f672ae00 2503583450 C Ci:3:113:0 -2 0
>>> > which is now not present. Not sure if this signifies anything.
>>> >
>>> > I've been trying to get the agilent usbtmc driver to work so there 's
>>> > someting to compare with, but it fails at the moment...
>>> >
>>> > Cheers,
>>> >   Greg
>>> >
>>>
>>> Got the Agilent driver working, the same command:
>>> echo "*IDN?" > /dev/usbtmc0
>>> cat /dev/usbtmc0
>>>
>>> Output of usbmon:
>>> f6b4fe80 1957891403 S Bo:3:003:6 -115 20 = 0106f900 06000000 01000000
>>> 2a49444e 3f0a0000
>>> f6b4fe80 1957892450 C Bo:3:003:6 0 20 >
>>> f6809380 1959423246 S Bo:3:003:6 -115 12 = 0207f800 e20f0000 000a0000
>>> f6809380 1959425195 C Bo:3:003:6 0 12 >
>>> f6809380 1959425301 S Bi:3:003:5 -115 4096 <
>>> f6809380 1959432199 C Bi:3:003:5 0 60 = 0207f800 30000000 01000000
>>> 54454b54 524f4e49 582c5444 53203130 3132422c
>>>
>>> Seems to have larger buffer, and not sending an extra read to the device?
>>
>> Yes, looks that way, the usbtmc driver is using 2048 as a buffer size.
>> If you change the #define at the start of the driver to 4096, does it
>> work better for you?
>>
>> thanks,
>>
>> greg k-h
>>
>
> I checked around that area and and actually, the buffer size does not
> need to be touched. On the other hand from the original list of
> issues, 2) 3) and 4) seems to be solved by setting a longer USB
> timeout:
>
> E.g. I change it from 10ms to 200ms:
> /* Default USB timeout (in milliseconds) */
> #define USBTMC_TIMEOUT          200
>
> If I had shorter than this, there were sometimes problems with
> consecutive commands. E.g. 140ms timeout handled a single read request
> well, but if I had a data encoding set before the read, the driver
> times out. At 200ms all seems to work okay so far. I tested it with
> the following python script.
>
> (It sets the encoding to binary and the reads a single dataset. The
> return of the "CURVE?" command is something like:
> "#45000...." where "2" is the number of following digits to code the
> number of returned bytes: here 4 digits. The next 4 digits then is
> 5000 that is the number of bytes to read. The actual bytes follow,
> plus a line-feed in the end.)
>
> #!/usr/bin/env python
> scopedev =3D "/dev/usbtmc0"
> handle =3D open(scopedev, "r+")
> # Set binary data
> handle.write("DATA:ENCDG RPBINARY\n")
> handle.write("CURve?\n")
> # 2bytes: Answer should be like #2
> # where 2 means the number of digits to read next
> digits =3D int(handle.read(2)[1])
> # "digits" bytes: how many bytes of data to read
> nbytes =3D int(handle.read(digits))
> # read the actual data (2500 or 5000 for this model in binary)
> data =3D handle.read(nbytes)
> print "Read data length: %s" % (len(data))
> data =3D handle.read(1)
> handle.close()
> handle =3D -1
>
> This read 5000 bytes without problem, reliably, with the original
> buffer size (2048) after increasing the USB timeout, and no sleep()
> calls are needed. Couldn't find the exact timeout setting in the
> Agilent driver for comparison, measured it on the order of seconds (2
> or 3...).
>
> Is there a universal way to determine the appropriate timeout for the
> device? Or should it just be set some "big" (within reasonable limits)
> value that is likely to go well with all devices?
>
>
> Regarding problem 1)
> At the Agilent driver's page [1] they have a little discussion about
> about "read" and "fread". The difference comes down to that "read" is
> happy to have less then the number of characters it asked for, while
> "fread" retries until it gets what it wants. In the python code I use
> "read" (and I guess most other code would use that too) and indeed I
> don't see any problem once the USB timeout is increased.
> "cat /dev/usbtmc0" on the other hand uses "fread", which caused the
> timeout to appear (since the device indeed didn't have any data to
> give for the second time it was trying). The Aglient driver tricks the
> fread, that's why no timeout appears.
>
> With the above in mind, I think 1) is much less of an issue now, as in
> a program (using readline and proper length read calls) the timeout
> will not appear under normal circumstances.
> Would be nice to fix up the "fread" output as well, but maybe it's
> better to adjust the expectations?
>
>   Cheers,
>       Greg
>
>
> [1]http://www.home.agilent.com/upload/cmc_upload/All/usbtmc.html
>


After a bit more testing and consideration, I attach a patch, that
increases the USBTMC_TIMEOUT value to a more workable level. The
current 10ms value might be an error anyway (correct me if I'm wrong):
The original Agilent driver had:
// Default USB timeout (in jiffies)
#define USBTMC_DEFAULT_TIMEOUT  10*HZ
which should be around 10 seconds. (I say "about" because after the
definition it is used in the form of something like:
USBTMC_DEFAULT_TIMEOUT/HZ*1000, which I'm not sure about, but should
be more than 10ms). The current form is written as:
/* Default USB timeout (in milliseconds) */
#define USBTMC_TIMEOUT         10
Can it be that it was converted wrong from jiffies to ms?

Anyway, even if the 10ms is deliberate, for my Tektronix 'scopes it's
completely unworkable, and I think (based on what I read on the list)
it can cause problems for other people's devices.

So, what value should it be in the current driver? Provided the
timeout is long enough for the device's normal operation, the upper
limit depends on when do we still expect to hit it. At this point I
can only base my experience on the Tektronix scopes, for which one can
always figure out how much one has to read from the device: until "\n"
for ASCII data, or device gives byte-count for binary data. Thus if
one has a well-written program in userspace, never have to worry about
the timeout.
On the other hand, if one uses echo / cat (as many examples do, e.g.
for the old driver) or other fread() type of interfacing, then it will
try to force reading even when the device doesn't have anything and
shouldn't expect anything, and the driver will try until it hits
timeout.

As I tested the longest operation that I could find on my device
(retrieving complete waveform of 2500 points, 16bit resolution, ASCII
encoding), it needed about 3.6s to complete the operation, with a big
wait of about 3s in the beginning. Given this, I propose at least 5s
(to be on the safe side) timeout value and see whether there are any
other devices for which it still causes problems in their normal
operation.

The cat timeout will be rather long (actually, cat will take 2x this
value, as there's a "read" and an "abort_in" that has to time out, at
least as I tested) for even the simplest operations, but this seems to
need major changes in the handling of  fread() and read(). (Is that
really so?) Probably instead of that, read()-based approach should be
suggested in the relevant documentation.

I know some of this was discussed about about a year ago [1] in
connection to other issues. Tried to take into account the things said
there, let me know if I missed something...

Cheers,
    Greg

[1] http://lkml.org/lkml/2008/8/26/375



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux