1

私のアプリケーションは、USB ベースの FTDI チップと D2XX ドライバーを使用しています。OIO (Overlapped IO) を使用して、USB への読み取りと書き込みを行います。私の要件には 30 秒のタイムアウトが含まれており、これを減らすことはできません。コードは非常に堅牢で安定しているように見えます。

新しい要件は、USB ケーブルの不注意による切断と再接続 (看護師がケーブルを蹴り飛ばした) を克服することです。

Windows からデバイス削除メッセージを受信し、それが FTDI デバイスであると判断すると、以前の OIO 呼び出しタイムアウト (要件からの 30 秒のタイムアウト) まで、OIO からの再接続で新しいデータを受信できないことがわかりました。

切断を発見したら、キューに入れられたすべての 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 が 1 ミリ秒未満で終了するようです。

このコードのテストとして、USB ケーブルを接続して呼び出したところ、1ms で返ってきました。

したがって、問題はケーブルを抜いたときのようです。

質問: 何が欠けていますか? 他にかけられる電話はありますか?これはバグですか?

私が試した他のこと: を呼び出す前にハンドルを閉じFT_W32_GetOverlappedResultます。これにより、リターンが速くなります。しかし、私のアプリは新しいハンドルからデータを受信できなくなりました。変。理由を知っている人はいますか?

このコードを呼び出していません。アプリは新しいハンドルから新しいデータを受信できますが、これらのタイムアウト後にのみです。なぜ?

サイクルポート。これにより、これらの OIO がより迅速に戻ることはありません。これらのタイムアウトまで、OIO 受信データの使用は変更されません。

4

1 に答える 1