1. The current release of libusb doesn't support async requests.
win32-libusb has extended the API and does support async requests. There
is a development version of libusb proper which does have an
asynchronous API, but the whole API has changed (for a start all the
function names are prefixed by libusb_ rather than just usb_).
=20
2. You will get better performance even without interleaving, but there
will still be 'dead' periods when no transfered are queued. It's better
if you can always have something queued.
=20
3. That sounds very dodgy! Sequencing could be a problem. It's possible
it could work, you'll have to try it or read the source to find out.
=20
4. Ah. That's not good. The OS usually constrains what sort of transfer
is allowed based on the endpoint. It's very hard to distuinguish a bulk
from an interrupt transfer on the bus since their transaction
characteristics are the same. However, interrupt transfers are only
meant to be attempted once per frame, and if NAKed, won't be retried
until the next period for which they've been scheduled. Bulk transfers
will retry as soon as they are next scheduled (which is often
immediately). Also, even if successful an interrupt transfer won't
continue until the next period (n frames, where n is specified in the
endpoint descriptor), whereas a successful bulk endpoint will retry
immediately until the host controller has filled the buffer provided, at
which point it will immediately move on to the next transfer scheduled.
Basically you're going to get very bad performance if your device is
trying to use interrupt transfers for data input, they're meant for
notification.
=20
5. lspci will list what pci devices are present on linux, the device
manager in windows. It'll say OHCI (or Open Host Controller), UHCI
(Universal Host Controller), EHCI (Enhanced Host Controller) or
something else in the very unlikely case that it's none of these.
=20
Dan.
________________________________
From: Kam Tsa [mailto:kamtsa@...
Sent: 24 January 2006 17:33
To: Dan Ellis; libusb-devel@...
Subject: Re: [Libusb-devel] Cannot read bulk faster than once very 2ms
Thanks Dan, and everybody else that answered.
=20
Your explanation clarifies it and is consistent with my experiments
(e.g. why a 0.5ms delay in the reading loop still got one reading every
2 ms).
=20
I have few follow up questions, I wonder if you (or anybody else) can
answer them.
=20
1. How do I issue async read requests? I did not see any async reading
functions in my usb.h? Is there is an example or doc somewhere how to
use async reads?
=20
2. I don't need to interleave the async read request from the same EP,
right? That is, I just need to make sure that I have one or more pending
before the start of each USB frame and the driver will pick the next one
and service it.=20
=20
3. Can I use two threads with blocking reading requests of the same EP
instead of async requests.
=20
4. I just realized that the EP I am reading is defined (as displayed by
lsusb) as Interrupt and not bulk even though I am reading it with
usb_bulk_read(). What is the difference between usb_bulk_read() and
usb_interrupt_read() and does it matters if I read interrupt EP with
usb_bulk_read()? (the max data size of this EP is 64 bytes).=20
=20
5. How do I determine what type of USB controller (UHCI, etc) my host
uses ?
=20
Thanks,
=20
Kamtsa
=20
On 1/24/06, Dan Ellis <Dan.Ellis@...> wrote:=20
USB1 host controllers work in different ways. Is yours OHCI,
UHCI or other? In any case it's likely that the controller won't notice
the addition of your new transfer until the beginning of a frame (when
it checks to see what work needs to be done). Although the trasaction
may get completed very soon after that, notification only occurs at the
end of the frame. Host controllers only generate interrupts at the end
of a frame - OHCI passes a pointer to the head of a list of completed
transfers, and UHCI just says 'stuff happened' and the host controller
driver has to inspect the transfers to see what's completed.=20
=20
The upshot is that it's going to take longer than 1ms to get
your transfer done. Paradoxically, you may find that if there is more
happening on the bus you transfer will get processed faster ( e.g. in
the case of OHCI, if there are constantly items on the bulk list to
process, then you won't have to wait for the start of a frame to get the
list enabled). You may also find that your device performs faster if
operated through a high speed hub, since then the EHCI controller will
be in operation which probably has faster scheduling.=20
=20
However, the real solution to your problem would be to use
asynchronous transfers and have more than one queued to receive. Even
though the first one may take 2ms to return, the next one should return
either at the same time, or shortly afterwards. You may need to queue a
number of transfers if you're going to receive a number of short
transfers. Scanners I've played with before usually send the main data
stream in one long transfer, and double buffering is usually sufficient
to maintain maximum bus bandwidth.=20
=20
Dan.
________________________________
From: libusb-devel-admin@... [mailto:
libusb-devel-admin@...] On Behalf Of Kam Tsa
Sent: 24 January 2006 06:41=20
To: libusb-devel@...
Subject: [Libusb-devel] Cannot read bulk faster than once very
2ms=20
=09
=20
Hello,
=09
I am writing a user space driver for USDigital USB1 encoder and
far libusb works just great (thanks to all the contributers).
=09
One thing that puzzles me is that I cannot perform a bulk read
in a rate greater than 2 ms per read.=20
=09
If I perform the read in a tight loop, each bulk read takes
exactly 2 ms (while CPU usages is virtually zero). Then, I insert in the
reading loop a delay of 0.5ms, the entire loop still take 2 ms (0.5ms
for the delay and 1.5 ms for the bulk read).
=09
It seems that the reading is tied to some invisible 1ms clock
and the call to a bulk read need to be long enough such that it covers
two 1 ms ticks.
=09
Anybody knows what may be the cuase?=20
=09
The USDigital USB1 is specified to be able to provide a reading
every 1ms so is it possible that the restriction is somewhere on the
host?
=09
BTW, my system is relativly old (I don't have the kernel or
libusb version here with me at home).=20
=09
Thanks,
=09
Kamtsa=20
|