On 02/04/2010 01:57 AM, Uwe Bonnes wrote:
"Jie" == Jie Zhang<jie.zhang@xxxxxxxxxx> writes:
Jie> ftdi_read_data = ftdi_read_data_submit + ftdi_transfer_data_done.
Jie> So actually the same code is executed whether do_async is true or
Jie> not. Generally async mode is used to submit data transfer requests
Jie> without need to wait for their completion until you really need the
Jie> data read back.
Jie> I did those work about half a year ago and then switched to other
Jie> tasks. So I need to refresh my memory before answer your
Jie> question. I will also try to review and test your patches for
Jie> libftdi-1 in this week I hope.
Probably we have different needs, a non-blocking read versus a streaming
read. A streaming read would imply that we can have outstanding
ftdi_read_data_submit() calls. But in the present implementation, as soon as
the remaining buffer can not fill up the size of the request, another
libusb_fill_bulk_transfer() is started with the same readbuffer as argument,
and now both pending libusb_fill_bulk_transfer()s write to the same buffer.
Is the urjtag problem of non-blocking transactions also solved with a
streaming approach as in fastftdi?.
I didn't know the answer for this question. But I can explain how the
async mode helps UrJTAG.
Currently the usbconn_ftdi_flush code looks like below:
ftdi_write_data ()
if (there is anything to read)
ftdi_read_data ()
ftdi_write_data () sends FT2232 commands to perform JTAG operations,
which will generate data. The data is cached in a buffer in FT2232 chip
and waits for host to send a read command to fetch it. The problem is
the buffer in FT2232 is small (4 * 64 bytes). When it's full, you have
to read it back. So in this sync mode, you can only send a small number
of commands to read back a small number bytes.
With async mode, I change the usbconn_ftdi_flush to be
if (there is any thing to read)
ftdi_read_data_submit ()
ftdi_write_data ()
if (there is any thing to read)
ftdi_transfer_data_done ()
Yes, with async mode we can submit a read transfer request before
writing data! In this way the host can read back data as soon as they
are generated by the written FT2232 commands and empty the buffer in
FT2232 chip which used to cache the data. So writing FT2232 commands and
reading back data occurs concurrently. The buffer will not be filled up
quickly. That means, we can accumulate much more FT2232 commands until
there are 63 * 64 bytes to read back. This will increase the USB bus
usage largely.
A draft patch for UrJTAG to use async mode is attached. It's based on
the latest UrJTAG svn trunk.
libftdi-1.0 can achieve the same performance on memory read for our
gdbproxy as libftd2xx. My observation is that libftd2xx uses multiple
threads to achieve this performance. It looks like one of those threads
is always trying to read data in a loop, which has the same concurrent
effect as async mode but pays much higher cost. It always occupies a
high percentage of CPU even in idle. Async mode libftdi can be looked as
an advantage compared with proprietary libftd2xx.
But then there is the other problem with compiling libusb-1 code for
windows. Or is the libusb-1 for windows effort already in some usefull
state? There was a lot mailing list activity recently...
Yes. I have already tried to build our gdbproxy + UrJTAG + libftdi-1.0 +
libusb-winusb. It worked and passed several initial tests.
Jie
--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
urjtag-async-usb-read.diff
Description: Text Data
|