使用ioctl读取USB失败,因为#34;值太大而无法定义数据类型"

时间:2014-12-09 03:22:58

标签: android serial-port usb ioctl ftdi

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

Android上的写入似乎总是成功但是读取总是失败,或者成功输入一些条目然后经常失败并且#34;值太大而无法定义数据类型" (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的误解,或解释这个错误的关于"对于定义的数据类型而言太大的问题"请?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

我最近也有这个错误,感谢@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字节对我来说,旧设备似乎仍然可以正常工作。