Я заметил странную задержку при общении с устройством FTDI через Virtual Comm Port в C / C ++ (Visual Studio).
Я посылаю команду (11 символов) на устройство, которое возвращает строку(18 символов) и занимает около 5 мс (отправить + получить).Связь осуществляется со скоростью 57600 бод.
После некоторого тестирования я обнаружил, что выполнение этого кода на моем компьютере дает хорошее время (5 мс), в то время как выполнение на других компьютерах занимает от 15 до 20 мс.Любопытно, что этот эффект не появляется при использовании System.IO.Ports через C # для связи с FTDI (я всегда получаю время выполнения 5 мс, независимо от того, какой ПК это выполняет).Время в этом конкретном приложении является критическим, поэтому удаление этих дополнительных мс очень важно.
Задержка буфера порта была вручную установлена на 1 мс (диспетчер устройств).
Я полагаю, это должнобыть связан с тем, как я открываю порт, но я протестировал много решений, и ничего не работает.
Вот код, который я использую для открытия порта:
hCom = CreateFile(DevPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if ( hCom==INVALID_HANDLE_VALUE) {
CloseHandle(hCom);
hCom = NULL;
return false;
} else {
if (!SetupComm(hCom,2048,2048)) {
CloseHandle(hCom);
hCom = NULL;
return false;
}
try {
dcb.DCBlength = sizeof(DCB);
GetCommState(hCom, &dcb);
//No Flow control
dcb.BaudRate = CBR_57600;
dcb.ByteSize = 8; // Setting ByteSize = 8
dcb.StopBits = ONESTOPBIT;// Setting StopBits = 1
dcb.Parity = NOPARITY; // Setting Parity = None
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fTXContinueOnXoff = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
if(!SetCommState(hCom, &dcb)) {
CloseHandle(hCom);
hCom = NULL;
return false;
}
} catch (std::string strCatchErr) {
CloseHandle(hCom);
hCom = NULL;
return false;
}
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 40;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
if(!SetCommTimeouts(hCom, &CommTimeouts)) {
CloseHandle(hCom);
hCom = NULL;
return false;
}
//purge port buffers
PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT);
return true;
Процессчтение и запись в порт выполняется с помощью простых инструкций ReadFile и WriteFile:
DWORD BytesRead = 0;
DWORD TotalBytesRead = 0;
DWORD BytesToRead = 20;
DWORD bytesWritten = 0;
BOOL bSuccess;
char rxbuffer[1024];
char * InBuffer;
int fRun = 1;
//Send data
PurgeComm(hCom, PURGE_RXCLEAR | PURGE_RXABORT);
WriteFile(hCom, "TESTCMD001\n", (DWORD)11, &bytesWritten, NULL);
//receive data
InBuffer = &rxbuffer[0];
while(fRun) {
BytesRead = 0;
bSuccess = ReadFile(hCom, InBuffer, BytesToRead, &BytesRead, NULL);
if ( bSuccess==TRUE ) {
if (BytesRead>0) {
TotalBytesRead += BytesRead;
rxbuffer[TotalBytesRead] = '\0';
InBuffer = &rxbuffer[TotalBytesRead];
if ( strchr(rxbuffer, '\n')!=NULL ) fRun = 0;
} //IF_BytesRead>0
} //IF_ReadFile
}
ПРИМЕЧАНИЕ!-> это упрощенная версия кода, поэтому возможны ошибки.
Кто-нибудь испытывал подобное раньше?Любая помощь будет высоко оценена.