On 02/08/2010 11:02 PM, Jie Zhang wrote:
Hi,
I have ported libftdi to libusb-1.0. The work is hosted in the following
repository:
git://developer.intra2net.com/libftdi-1.0
My work brought asynchronous transfer to libftdi. I explained how this
would help UrJTAG in this email:
http://developer.intra2net.com/mailarchive/html/libftdi/2010/msg00065.html
Now I propose a patch for UrJTAG to use this new libftdi to improve the
performance. When using the new libftdi, gdbproxy reads memory at about
110.2KB/s. Compared with previous 10.3KB/s, I would say it's a big
improvement.
This UrJTAG patch, which is attached in this email, does not change the
default settings. But it changes --with-libusb to to accept "1.0" and
"0.1". This patch also checks if libftdi is the new one. It will check
if the combination of libusb version and libftdi version is good. For
example, libusb-1.0 cannot be used with the old libftdi. libusb-0.1
cannot be used with the new libftdi. It changes usbconn_ftdi_flush to
utilize the asynchronous mode of the new libftdi. So we can enlarge the
receive buffer to (63 * 64). See the email on the above URL for further
explanation.
Since this patch does not change the default settings of UrJTAG, it's
not intrusive. I'm going to commit it in 24 ~ 48 hours if no one objects.
Here is an update of the patch. The new patch will error out when the
specified libusb does not exist. Otherwise, it's same as previous one.
Jie
* src/tap/usbconn/libftdx.h (URJ_USBCONN_FTDI_MAXRECV): Define
to be (63 * 64) if HAVE_LIBFTDI_ASYNC_MODE defined.
* src/tap/usbconn/libftdi.c (usbconn_ftdi_flush): Use async
mode libftdi if HAVE_LIBFTDI_ASYNC_MODE defined.
* configure.ac: Check libusb-1.0 and libftdi async mode.
Index: src/tap/usbconn/libftdx.h
===================================================================
--- src/tap/usbconn/libftdx.h (revision 1768)
+++ src/tap/usbconn/libftdx.h (working copy)
@@ -30,7 +30,11 @@
Larger values might speed up comm, but there's an upper limit
when too many bytes are sent and the underlying libftdi or libftd2xx
don't fetch the returned data in time -> deadlock */
+#ifdef HAVE_LIBFTDI_ASYNC_MODE
+#define URJ_USBCONN_FTDI_MAXRECV (63 * 64)
+#else
#define URJ_USBCONN_FTDI_MAXRECV ( 4 * 64)
+#endif
#define URJ_USBCONN_FTD2XX_MAXRECV (63 * 64)
#define URJ_USBCONN_FTDX_MAXRECV (URJ_USBCONN_FTD2XX_MAXRECV < URJ_USBCONN_FTDI_MAXRECV ? URJ_USBCONN_FTD2XX_MAXRECV : URJ_USBCONN_FTDI_MAXRECV)
Index: src/tap/usbconn/libftdi.c
===================================================================
--- src/tap/usbconn/libftdi.c (revision 1768)
+++ src/tap/usbconn/libftdi.c (working copy)
@@ -68,6 +68,9 @@ usbconn_ftdi_flush (ftdi_param_t *p)
{
int xferred;
int recvd = 0;
+#ifdef HAVE_LIBFTDI_ASYNC_MODE
+ struct ftdi_transfer_control *tc;
+#endif
if (!p->fc)
return -1;
@@ -75,6 +78,7 @@ usbconn_ftdi_flush (ftdi_param_t *p)
if (p->send_buffered == 0)
return 0;
+#ifndef HAVE_LIBFTDI_ASYNC_MODE
if ((xferred = ftdi_write_data (p->fc, p->send_buf, p->send_buffered)) < 0)
urj_error_set (URJ_ERROR_FTD, _("ftdi_write_data() failed: %s"),
ftdi_get_error_string (p->fc));
@@ -87,6 +91,7 @@ usbconn_ftdi_flush (ftdi_param_t *p)
}
p->send_buffered = 0;
+#endif
/* now read all scheduled receive bytes */
if (p->to_recv)
@@ -106,6 +111,30 @@ usbconn_ftdi_flush (ftdi_param_t *p)
return -1;
}
+#ifdef HAVE_LIBFTDI_ASYNC_MODE
+ if ((tc = ftdi_read_data_submit (p->fc,
+ &(p->recv_buf[p->recv_write_idx]),
+ p->to_recv)) == NULL)
+ urj_error_set (URJ_ERROR_FTD,
+ _("Error from ftdi_read_data_submit(): %s"),
+ ftdi_get_error_string (p->fc));
+ }
+
+ if ((xferred = ftdi_write_data (p->fc, p->send_buf, p->send_buffered)) < 0)
+ perror (ftdi_get_error_string (p->fc));
+
+ if (xferred < p->send_buffered)
+ {
+ urj_error_set (URJ_ERROR_FTD, _("Written fewer bytes than requested."));
+ return -1;
+ }
+
+ p->send_buffered = 0;
+
+ if (p->to_recv)
+ {
+ recvd = ftdi_transfer_data_done (tc);
+#else
while (recvd == 0)
if ((recvd = ftdi_read_data (p->fc,
&(p->recv_buf[p->recv_write_idx]),
@@ -113,6 +142,7 @@ usbconn_ftdi_flush (ftdi_param_t *p)
urj_error_set (URJ_ERROR_FTD,
_("Error from ftdi_read_data(): %s"),
ftdi_get_error_string (p->fc));
+#endif
if (recvd < p->to_recv)
urj_log (URJ_LOG_LEVEL_NORMAL,
Index: configure.ac
===================================================================
--- configure.ac (revision 1768)
+++ configure.ac (working copy)
@@ -150,7 +150,7 @@ AC_ARG_WITH([libusb],
[with_libusb=check])
HAVELIBUSB=no
-AS_IF([test "x$with_libusb" != xno], [
+AS_IF([test "x$with_libusb" != xno -a "x$with_libusb" != x1.0], [
save_LIBS=$LIBS
save_CPPFLAGS=$CPPFLAGS
PKG_CHECK_MODULES(LIBUSB, libusb, [:;], [dnl
@@ -161,7 +161,7 @@ AS_IF([test "x$with_libusb" != xno], [
LIBUSB_CFLAGS="-I$with_libusb/include"
;;
*)
- LIBUSB_LIBS="-Lwith_libusb -lusb"
+ LIBUSB_LIBS="-L$with_libusb -lusb"
LIBUSB_CFLAGS="-I$with_libusb"
;;
esac
@@ -179,7 +179,11 @@ AS_IF([test "x$with_libusb" != xno], [
AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb])
HAVELIBUSB=yes
],[
- AC_MSG_WARN([*** libusb not detected. No support for USB JTAG cables via libusb.])
+ AS_IF([test "x$with_libusb" = x0.1], [
+ AC_MSG_ERROR([*** libusb-0.1 not detected.])
+ ],[
+ AC_MSG_WARN([*** libusb not detected. No support for USB JTAG cables via libusb.])
+ ])
LIBS=$save_LIBS
CPPFLAGS=$save_CPPFLAGS
])
@@ -187,6 +191,35 @@ AS_IF([test "x$with_libusb" != xno], [
AM_CONDITIONAL(HAVE_LIBUSB, [test "x$HAVELIBUSB" = "xyes"])
+dnl check for libusb-1.0
+
+HAVELIBUSB1=no
+AS_IF([test "x$with_libusb" != xno -a "x$with_libusb" != x0.1 -a "x$HAVELIBUSB" != "xyes"], [
+ save_LIBS=$LIBS
+ save_CPPFLAGS=$CPPFLAGS
+ PKG_CHECK_MODULES(LIBUSB1, libusb-1.0, have_libusb1=yes, have_libusb1=no)
+ AS_IF([test "$have_libusb1" = "yes"],[
+ LIBUSB_CFLAGS="$CFLAGS $LIBUSB1_CFLAGS"
+ LIBUSB_LIBS="$USB_LIBS $LIBUSB1_LIBS"
+ ],)
+ LIBS="$LIBS $LIBUSB1_LIBS"
+ CPPFLAGS="$CPPFLAGS $LIBUSB1_CFLAGS"
+ AC_CHECK_FUNC([libusb_get_device_list], [
+ AC_DEFINE(HAVE_LIBUSB1, 1, [Define if you have libusb-1.0])
+ HAVELIBUSB1=yes
+ ],[
+ AS_IF([test "x$with_libusb" = x1.0], [
+ AC_MSG_ERROR([*** libusb-1.0 not detected.])
+ ],[
+ AC_MSG_WARN([*** libusb-1.0 not detected. No support for async mode for FTDI cables.])
+ ])
+ LIBS=$save_LIBS
+ CPPFLAGS=$save_CPPFLAGS
+ ])
+],)
+AM_CONDITIONAL(HAVE_LIBUSB1, [test "x$HAVELIBUSB1" = "xyes"])
+
+
dnl Use FTDI library?
AC_ARG_WITH([libftdi],
@@ -220,8 +253,20 @@ AS_IF([test "x$with_libftdi" != xno], [
LIBS=$save_LIBS
CPPFLAGS=$save_CPPFLAGS
])
+ AC_CHECK_FUNC([ftdi_read_data_submit], [
+ AS_IF([test "x$HAVELIBUSB" = "xyes"], [
+ AC_MSG_ERROR([this libftdi cannot be used with libusb-0.1, libusb-1.0 is needed])
+ ],)
+ AC_DEFINE(HAVE_LIBFTDI_ASYNC_MODE, 1, [Define if libftdi support async mode])
+ HAVELIBFTDI_ASYNCMODE=yes
+ ], [
+ AS_IF([test "x$HAVELIBUSB1" = "xyes"], [
+ AC_MSG_ERROR([this libftdi cannot be used with libusb-1.0, libusb-0.1 is needed])
+ ],)
+ ])
],)
AM_CONDITIONAL(HAVE_LIBFTDI, [test "x$HAVELIBFTDI" = "xyes"])
+AM_CONDITIONAL(HAVE_LIBFTDI_ASYNC_MODE, [test "x$HAVELIBFTDI_ASYNCMODE" = "xyes"])
dnl Use FTDI ftd2xx library?
@@ -682,6 +727,20 @@ AC_OUTPUT
dnl
dnl Configuration summary
dnl
+AS_IF([test "x$HAVELIBUSB" = "xyes"], [
+ FLAG_HAVELIBUSB=0.1
+], [
+ AS_IF([test "x$HAVELIBUSB1" = "xyes"], [
+ FLAG_HAVELIBUSB=1.0
+ ],[
+ FLAG_HAVELIBUSB=no
+ ])
+])
+AS_IF([test "x$HAVELIBFTDI_ASYNCMODE" = "xyes"], [
+ FLAG_HAVELIBFTDI_ASYNCMODE="(have async mode)"
+],[
+ FLAG_HAVELIBFTDI_ASYNCMODE="(no async mode)"
+])
AC_DEFUN([MAKE_YESNO_VAR],[dnl
AS_IF([test ${$1:-$2} != $2], [dnl
FLAG_$1=yes
@@ -690,7 +749,6 @@ AC_DEFUN([MAKE_YESNO_VAR],[dnl
])
])
MAKE_YESNO_VAR([HAVELIBFTDI], [no])
-MAKE_YESNO_VAR([HAVELIBUSB], [no])
MAKE_YESNO_VAR([HAVELIBFTD2XX], [no])
MAKE_YESNO_VAR([HAVE_INPOUTXX], [no])
MAKE_YESNO_VAR([svf], [false])
@@ -700,7 +758,7 @@ AC_MSG_NOTICE([
jtag is now configured for
Detected libusb : $FLAG_HAVELIBUSB
- Detected libftdi : $FLAG_HAVELIBFTDI
+ Detected libftdi : $FLAG_HAVELIBFTDI $FLAG_HAVELIBFTDI_ASYNCMODE
Detected libftd2xx : $FLAG_HAVELIBFTD2XX
Detected inpout32 : $FLAG_HAVE_INPOUTXX
Build SVF player : $FLAG_svf
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
UrJTAG-development mailing list
UrJTAG-development@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/urjtag-development