내 응용 프로그램은 USB 기반 FTDI 칩과 D2XX 드라이버를 사용합니다. OIO (Overlapped IO)를 사용하여 USB를 읽고 씁니다. 내 요구 사항에는 30 초 제한 시간이 포함되어있어 줄일 수 없습니다. 코드는 매우 견고하고 안정적으로 보입니다.FTDI D2XX USB 케이블을 분리하고 다시 연결 한 후 중복되는 IO (OIO) 취소
새로운 요구 사항은 우발적 인 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는 1ms 이내에 종료되는 것 같습니다.
이 코드의 테스트에서 나는 USB 케이블을 연결하여 전화를 걸었고 1ms로 돌아왔다.
그래서 케이블이 분리되었을 때 문제가있는 것 같습니다.
질문 : 나는 무엇이 누락 되었습니까? 내가 할 수있는 또 다른 전화가 있습니까? 이것은 버그입니까?
다른 시도 : FT_W32_GetOverlappedResult
을 호출하기 전에 핸들을 닫습니다. 따라서 빠른 수익을 올릴 수 있습니다. 그러나 내 응용 프로그램은 더 이상 새 핸들에서 데이터를받을 수 없습니다. 기묘한. 왜 그런지 알아?
이 코드를 호출하지 않습니다. 앱이 새로운 핸들에서 새 데이터를받을 수는 있지만 시간이 초과 된 후에 만 가능합니다. 왜?
CyclePort. 이로 인해 OIO가 더 빨리 반환하지 않습니다. 이 제한 시간까지 OIO 수신 데이터의 사용은 변경되지 않습니다.