【问题标题】:Reading USB with ioctl fails for "value too large for defined data type"使用 ioctl 读取 USB 失败,因为“值对于定义的数据类型而言太大”
【发布时间】:2014-12-09 03:22:58
【问题描述】:

我正在尝试使用 ioctl 和 USBDEVFS_BULK(在 Android 上为原生)读取 USB。我正在使用的 USB 电缆包含一个 FTDI 芯片,并从一个 Arduino UNO 发送数据,它写入串行。

Android 上的写入似乎总是成功,但读取要么总是失败,要么成功完成几个条目,然后不断失败,并出现“值对于定义的数据类型而言太大”(75)。我正在使用这个设置进行简单的 ping 测试:在 Android 上写入一个字节,一个序列号; Arduino 读取字节并以相同的序列号回复。

我不完全确定这个错误在说什么。我理解它的方式是设备发送的数据多于我传递给 ioctl 的缓冲区可以容纳的数据。我确保我的 Arduino 只发回 1 个字节,我希望 FTDI 还能看到 2 个字节,总共 3 个字节。即使增加缓冲区大小似乎也不能解决问题。

char mReadData[3];
struct usbdevfs_bulktransfer bulkTransferRead = {
    mReadEndpoint,  // Endpoint
    3,              // Length in bytes
    0,              // Timeout (ms)
    mReadData,     // Data
};

ret = ioctl(mFd, USBDEVFS_BULK, &bulkTransferRead);

这是我在本地使用的代码。如果我尝试使用 Android/Java 代码进行读写(使用 bulkTransfer()),我会看到与读取相同的间歇性问题。在 Android 上的 Java 中,我确保在任何写入/读取之前执行以下操作:

1) 复位引脚 2) 设置波特率 3) 8N1

谁能帮我描述一下我对 FTDI/USB 的误解,或者解释一下这个关于“值对于定义的数据类型来说太大”的错误吗?

【问题讨论】:

    标签: android serial-port usb ioctl ftdi


    【解决方案1】:

    我找到了解决方案。似乎这个错误,EOVERFLOW,可以通过指定一个等于端点最大数据包大小的缓冲区大小来修复。这解决了我的问题。

    【讨论】:

      【解决方案2】:

      我最近也遇到了这个错误,感谢@Jary 为我指明了正确的方向。对于最终在这里寻找最大数据包大小的其他任何人,请将您的设备插入 Linux 机器并找到所需的设备和端点:

      lsusb -v | grep 'Bus\|bEndpointAddress\|wMaxPacketSize\|idVendor\|idProduct'

      示例输出:

      Bus 001 Device 027: ID 0451:d109 Texas Instruments, Inc. 
        idVendor           0x0451 Texas Instruments, Inc.
        idProduct          0xd109 
              bEndpointAddress     0x81  EP 1 IN
              wMaxPacketSize     0x0200  1x 512 bytes
              bEndpointAddress     0x02  EP 2 OUT
              wMaxPacketSize     0x0200  1x 512 bytes
              bEndpointAddress     0x82  EP 2 IN
              wMaxPacketSize     0x001c  1x 28 bytes
              bEndpointAddress     0x83  EP 3 IN
              wMaxPacketSize     0x0200  1x 512 bytes
              bEndpointAddress     0x03  EP 3 OUT
              wMaxPacketSize     0x0200  1x 512 bytes
      

      缓冲区所需的最大数据包大小在端点地址下给出。

      如需更多信息,请参阅this page,其中包含其他有趣的花絮:

      仅全速和高速设备支持批量传输。 对于 全速端点,最大批量数据包大小为 8、16、32 或 64 字节长。对于高速端点,最大数据包大小 最长可达 512 字节。 如果数据有效负载低于 最大数据包大小,不需要用零填充。一大块 当它已经转移了确切的 请求的数据量,传输的数据包小于最大值 端点大小,或传输长度为零的数据包。 (强调我的)

      缓冲区需要等于这些大小之一。使它们任意大或只是一些其他值(例如 1024 字节)似乎不起作用。在我的情况下,缓冲区最初是 64 字节,适用于旧设备,但是当连接到最大数据包大小为 512 字节的新设备时,它因 OP 错误而失败。增加到 512 字节对我有用,旧设备似乎仍然可以正常工作。

      【讨论】:

        猜你喜欢
        • 2012-12-03
        • 1970-01-01
        • 1970-01-01
        • 2013-08-21
        • 1970-01-01
        • 1970-01-01
        • 2020-08-28
        • 1970-01-01
        • 2013-11-24
        相关资源
        最近更新 更多