FTDI D2XX在USB电缆断开并重新连接后取消重叠IO(OIO)

问题描述 投票:1回答:1

我的应用程序使用基于USB的FTDI芯片和D2XX驱动程序。它使用OIO(重叠IO)来读写USB。我的要求包括30秒超时,这是我无法减少的。代码看起来非常强大和稳定。

一项新要求是克服无意中断开连接并重新连接USB电缆(护士将电缆踢出)。

一旦从Windows接收到设备删除的消息并确定它是我们的FTDI设备,我发现在OIO重新连接之前我无法接收新数据,直到之前的OIO调用超时(需求的30秒超时)。

一旦我发现断开连接,我就会循环接下来的呼叫,直到收到所有排队的OIO:

bool CancelOIO()
{
    if (!FtdiRemaining)
        return false;

    FT_SetTimeouts(FtdiHandle, 1, 1);
    FT_W32_PurgeComm(FtdiHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

    while (FtdiRemaining)
    {
        DWORD nBytes = 0;
        if (!FT_W32_GetOverlappedResult(FtdiHandle, &FtdiOverLap[FtdiQindex], &nBytes, FALSE))
        {
            if (FT_W32_GetLastError(FtdiHandle) == ERROR_IO_INCOMPLETE)
                return true;

            if (FT_W32_GetLastError(FtdiHandle) != ERROR_OPERATION_ABORTED)
            {
                CString str;
                str.Format("FT_W32_GetOverlappedResult failed with %d\r\n", FT_W32_GetLastError(FtdiHandle));
                SM_WriteLog(str, RGB_LOG_NORMAL);
            }
        }

        FtdiRemaining--;
        FtdiTodo++;
        FtdiQindex++;
        if (FtdiQindex >= FtdiQueueSize)
            FtdiQindex = 0;
    }

    return !!FtdiRemaining;
}

我将超时时间设置为1ms。这似乎不会更改先前安排的OIO的超时。

我打电话给FT_W32_PurgeComm取消一切。这似乎也没有取消OIO。

我试着调用CancelIo,这返回错误,句柄无效。我的理解是响应它是驱动程序代码。这可能是由于断开连接造成的。

无论如何,我在循环中调用上面的代码,直到收到所有预定的OIO。什么都不会发生30秒。然后所有的OIO似乎都在不到1ms的时间内结束。

作为对此代码的测试,我连接了USB电缆并在1ms内返回。

所以问题似乎是在拔掉电缆的时候。

问题:我错过了什么?我可以打另一个电话吗?这是一个错误吗?

我试过的其他事情:在调用FT_W32_GetOverlappedResult之前关闭句柄。这导致快速返回。但我的应用程序无法再从新句柄接收数据。奇怪的。谁知道为什么?

没有调用此代码。该应用程序能够从新句柄接收新数据,但仅在这些超时之后。为什么?

CyclePort。这不会导致这些OIO更快地返回。在这些超时之前,它不会更改OIO接收数据的使用。

visual-c++ usb ftdi overlapped-io
1个回答
0
投票

我经过反复测试后发现两种不同的行为。最快的一个合理地快速返回,取消OIO。另一个使用完整的30秒超时。

尝试减少超时以减少取消OIO的延迟。

© www.soinside.com 2019 - 2024. All rights reserved.