xxxxx@spiritdsp.com wrote:
> While waiting for an exact answer, though, you may be able to run your own
> experiment by just changing your URB request size to 512 bytes.
>
Thanks Walter
I set URB Size = 512 bytes.
Some words about application&driver. I use ReadFile Function in my application with overlapped method to “create” IRPs for my driver. [One ReadFile call with 512 byte buffer]= [one IRP] = [one URB]. I keep queue of 4096 IRP to my driver.
That’s a ridiculously large number. If you can’t keep up using a queue
of 32 IRPs, then no number will ever be large enough, and you need to
change the design.
When I have switched off other thread in my application I have ceased to lose bytes. But each refreshing of Internet Explorer, leads to loss of the data.
Whether there can be big CPU loading result of 16384 ReadFile calls/second?
Well, of course there is. Take a few moments to think about what this
involves. Your request has to pass down through the user-mode ReadFile
API processing, through validation, switch into kernel mode, go through
additional validation, get converted to an IRP, pass into the top of the
USB stack for your device, eventually find its way to your driver, where
you lock the buffers, create an URB, send it down to the host
controller, which then creates a DMA request and adds it to the
scheduling list for the next available microframe. Then, when the
microframe is finished, the reverse happens: the request gets marked
complete, passed back up to your driver, which does more processing on
it, then percolates back through the I/O system, crosses back into
user-mode, and returns back to your thread. You are hoping to do all of
that in less than 60 microseconds.
The ONLY way to sustain high bandwidth USB performance is to use URBs
with large buffers, and that REQUIRES that your device ship complete
512-byte packets. Your best solution, by far, is to have your hardware
pad the packets to 512 bytes. You can include a “length” field in the
data, if you need to.
If a problem in it I can call ReadFile with 8192 buffer and then split this request on 16 x 512 bytes IRP/URB requests in my driver.
The problem is only slightly reduced. You still have an enormous amount
of overhead between you and the host controller.
Another alternative, if you really really cannot pad the packets, is to
switch to an isochronous pipe instead of a bulk pipe. With isochronous
data, each packet stands alone. You don’t have this “short packet”
issue. You can send down a single request of 32 packets of 512 bytes
each, and what you get back contains the results from the next 32
intervals. If the device sent 419 bytes, you get 419 bytes in the
packet. If the device skipped an interval, you get back 0 bytes.
Perhaps this fits your model a bit better.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.