【问题标题】:FTDI via libusb error EPIPEFTDI 通过 libusb 错误 EPIPE
【发布时间】:2013-08-06 17:27:42
【问题描述】:

我正在尝试使用基于 FTDIUSB 设备,但出现 -32 (EPIPE) 错误:

08-06 16:32:16.328: WARN/System.err(15547): ftdi_usb_open_dev()
08-06 16:32:16.328: WARN/System.err(15547): usb_detach_kernel_driver_np()libusb: 0.029116 debug [libusb_detach_kernel_driver] interface 0
08-06 16:32:16.328: WARN/System.err(15547): ftdi claim interface ...
08-06 16:32:16.328: WARN/System.err(15547): libusb-compat debug: usb_claim_interface: interface 0
08-06 16:32:16.328: WARN/System.err(15547): libusb: 0.030246 debug [libusb_claim_interface] interface 0
08-06 16:32:16.328: WARN/System.err(15547): claiming interface using fd = 4
08-06 16:32:16.328: WARN/System.err(15547): ftdi_usb_reset ...
08-06 16:32:16.328: WARN/System.err(15547): libusb-compat debug: usb_control_msg: RQT=40 RQ=0 V=0 I=0 len=0 timeout=300
08-06 16:32:16.328: WARN/System.err(15547): libusb: 0.031222 debug [libusb_get_next_timeout] next timeout in 0.300000s
08-06 16:32:16.328: WARN/System.err(15547): libusb: 0.031527 debug [libusb_handle_events_timeout_completed] doing our own event handling
08-06 16:32:16.328: WARN/System.err(15547): libusb: 0.032046 debug [handle_events] poll() 2 fds with timeout in 300ms
08-06 16:32:16.328: WARN/System.err(15547): libusb: 0.033023 debug [handle_events] poll() returned 1
08-06 16:32:16.338: WARN/System.err(15547): libusb: 0.033389 debug [reap_for_handle] urb type=2 status=-32 transferred=0
08-06 16:32:16.338: WARN/System.err(15547): libusb: 0.033755 debug [handle_control_completion] handling completion status -32
08-06 16:32:16.338: WARN/System.err(15547): libusb: 0.034091 debug [handle_control_completion] unsupported control request
08-06 16:32:16.338: WARN/System.err(15547): libusb: 0.034366 debug [usbi_handle_transfer_completion] transfer 0x2915e0 has callback 0x5ccb4
08-06 16:32:16.338: WARN/System.err(15547): libusb: 0.034732 debug [ctrl_transfer_cb] actual_length=0

USB 请求似乎与 FTDI Chip Commands 所要求的完全一致。

FTDI 上下文初始化没有错误,usb_dev 不为空,似乎没问题。电缆没问题,因为我可以用它来将Arduino 草图上传到Duemilanove (FTDI) 板上。

所以我完全被卡住了。我该怎么办?

我的代码

struct ftdi_context *ftdi_ctx;
struct usb_device *dev;
usb_dev_handle *udev;

// ...
ftdi_ctx = ftdi_new();
    if (ftdi_ctx == NULL) {
      fprintf(stderr, "error init ftdi context\n");
      return 1;
    }
    ftdi_ctx->usb_write_timeout = 0;
    ftdi_ctx->usb_read_timeout = 0;
// ...
udev = usb_open(dev);
int ret = ftdi_usb_open_dev(ftdi_ctx, dev, udev);
              if (ret < 0) {
                fprintf(stderr, "error opening ftdi device\n");
                return ret;
              }

ftdi_usb_open_dev() 稍作修改以准备好usb_device 并且不要在里面做 usb_open:

libftdi-0.1 代码(ftdi.c):

int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct usb_device *dev, struct usb_dev_handle *usb_dev)
{
    int detach_errno = 0;
    int config_val = 1;

    fprintf(stderr, "ftdi_usb_open_dev()\n");

    if (ftdi == NULL) {
        fprintf(stderr, "ftdi context invalid\n");
        ftdi_error_return(-8, "ftdi context invalid");
    }

    // 4ntoine (no need to open device if usb_dev is already passed)
    if (usb_dev == NULL) {
        if (!(ftdi->usb_dev = usb_open(dev)))
            ftdi_error_return(-4, "usb_open() failed");
    } else {
        ftdi->usb_dev = usb_dev;
    }

    #ifdef LIBUSB_HAS_GET_DRIVER_NP
        // Try to detach ftdi_sio kernel module.
        // Returns ENODATA if driver is not loaded.
        //
        // The return code is kept in a separate variable and only parsed
        // if usb_set_configuration() or usb_claim_interface() fails as the
        // detach operation might be denied and everything still works fine.
        // Likely scenario is a static ftdi_sio kernel module.
        fprintf(stderr, "detaching kernel driver... \n");
        if (ftdi->module_detach_mode == AUTO_DETACH_SIO_MODULE)
        {
            fprintf(stderr, "usb_detach_kernel_driver_np() ...\n");
            if (usb_detach_kernel_driver_np(ftdi->usb_dev, ftdi->interface) != 0 && errno != ENODATA) {
                fprintf(stderr, "failed to detach\n");
                detach_errno = errno;
            }
        }
    #endif

    fprintf(stderr, "ftdi claim interface ...\n");
    if (usb_claim_interface(ftdi->usb_dev, ftdi->interface) != 0)
    {
        fprintf(stderr, "failed to claim interface\n");
        ftdi_usb_close_internal (ftdi);
        if (detach_errno == EPERM)
        {
            ftdi_error_return(-8, "inappropriate permissions on device!");
        }
        else
        {
            ftdi_error_return(-5, "unable to claim usb device. Make sure the default FTDI driver is not in use");
        }
    }
    fprintf(stderr, "ftdi claimed interface\n");

    fprintf(stderr, "ftdi_usb_reset ...\n");
    if (ftdi_usb_reset (ftdi) != 0)
    {
        ftdi_usb_close_internal (ftdi);
        ftdi_error_return(-6, "ftdi_usb_reset failed");
    }

我已经用另一个 FTDI 板 (Arduino Nano v3) 对其进行了测试,但仍然出现同样的错误,所以问题很可能不在板上...

我已经在另一个支持 USB 主机的 Android 设备和另一个 Android 操作系统版本 (4.0.x) 上对其进行了测试,但仍然出现同样的错误...

【问题讨论】:

    标签: usb libusb ftdi


    【解决方案1】:

    您的主机系统是 Windows 还是 Linux?

    设备似乎未能响应 ftdi_usb_reset() 发出的控制消息。而 ftdi_usb_reset() 实际上是由 ftdi_usb_open_dev() 调用的。

    如果检查 libftdi 源代码: http://www.intra2net.com/en/developer/libftdi/documentation/ftdi_8c_source.html#l00522

    我们发现如果 ftdi_usb_reset() 失败,它将返回 -6。整个错误日志没有在这里发布,所以我想知道它是否是最后真正发生的事情。也许还有更多有趣的东西可以去那里看看。

    也许在这里显示您的代码可以帮助您更好地理解。 :)

    如果可能的话,当你尝试用 ftdichip.com 提供的 D2XX 驱动程序做同样的事情时,结果会一样吗?

    【讨论】:

    • 系统实际上是Android(linux)。我已经用代码更新了这个问题。 PS。我正在使用 libusb-0.x 和 libftdi-0.x
    【解决方案2】:

    如果我的理解有误,请纠正我:您正在开发可在调用 libftdi 和 libusb 的 Android(底层 Linux 系统)上运行的本机代码,对吗?我假设目的是通过 libusb 使用 Android 设备而不需要 root?

    在 Google 上稍作搜索告诉我,libusb 没有“官方”Android 端口。有些平台可以与 libusb 一起使用,而有些则不能。人们有不同类型的反馈。

    如果回到基础,比如说,只使用 libusb 中的函数,而不使用您修改的 libftdi 代码,您是否可以通过基本的 libusb 函数执行设备打开、关闭和向您的 FTDI 设备发送控制消息?

    或者,如果可能,尝试使用未修改的 libftdi。它会完成它应该做的工作吗?

    顺便说一句,为什么是 libftdi0.1?我知道它现在应该是 1.0 版。旧版本可能有问题...

    我只是尝试提供一些值得尝试的东西。它可能是 libusb 问题、libftdi 问题,或者只是您操作设备的顺序问题。因此,如果不确定哪里出了问题,那么将它们分解并确定正确的部分就是我会尝试的。

    【讨论】:

    • 我正在修改 avrdude 以使其在 android 上运行。为此,我修改了 libusb,它非常适合无需 root 的 cdc 设备。我能够打开、读取、写入和关闭设备,这就是为什么我相信获取 usb_dev 是可以的,因为完全相同的代码用于传递给 libftdi。
    • 重点是 libftdi 的唯一变化是我传递了准备好的 usb_dev 指针,而不是在ftdi_usb_open_dev 中打开它。我认为它会开箱即用,但我错了,所以现在我试图了解出了什么问题。我正在使用 libusb-0.x 和 libftdi-0.x,因为 avrdude 使用 libusb-0.x,我想保留 avrdude 代码原样。可能我应该尝试重写它以使用 libusb-1 和 libftdi-1 ..
    • 我在 libftdi 代码中发现了有趣的注释://尝试分离 ftdi_sio 内核模块。 // // 返回代码保存在一个单独的变量中,并且仅在 usb_set_configuration() 或 usb_claim_interface() 失败时才被解析,因为 // 分离操作可能被拒绝,但一切仍然正常。 // 可能的场景是静态 ftdi_sio 内核模块。然后我尝试设置配置 1,但它失败了。这让我觉得内核驱动实际上并没有分离,但结果还可以。
    猜你喜欢
    • 1970-01-01
    • 2014-12-26
    • 2016-04-25
    • 2017-08-10
    • 2014-06-24
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多