#c #winapi #usb #hid
Вопрос:
Я пытаюсь отправить сообщение на внешнее устройство и получить от него сообщение через USB.
Он отлично работает с HidD_GetInputReport() и HidD_SetOutputReport(). Проблема в том, что когда я отправляю команду, у меня возникает некоторая временная задержка, потому что устройству, с которым я разговариваю, требуется некоторое время, чтобы ответить и заполнить буфер ответов. Мы хотим избавиться от этой задержки.
Я рассмотрел возможность использования API-интерфейсов ReadFile() и WriteFile ().
Я делаю файл записи, подобный этому:
DWORD bytesRead; OVERLAPPED osWrite = { 0 }; osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); bool success = WriteFile(Device, packetBuffer, packetLength, amp;bytesRead, amp;osWrite); if ( false == success ) { WaitForSingleObject(osWrite.hEvent, INFINITE); if (!GetOverlappedResult(Device, amp;osWrite, amp;bytesRead, TRUE)) { printf("write failed n"); GetErrorMessage(); } else { printf("write passed n"); } success = TRUE; } CloseHandle(osWrite.hEvent);
Файл записи работает нормально. Устройство, с которым я разговариваю, получает мое сообщение, а затем отвечает.
Затем я выполняю ReadFile (), чтобы получить эту информацию. Вот фрагмент кода для этого:
DWORD bytesRead; OVERLAPPED osReader = { 0 }; osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); bool success = ReadFile(Device, packetBuffer, packetLength, amp;bytesRead, amp;osReader); if ( success == false) { if (!GetOverlappedResult(m_hDevice, amp;osReader, amp;bytesRead, TRUE)) { GetErrorMessage(); } }
Мы также получаем ответ. Таким образом, он работает нормально и отлично, но иногда (для некоторых конкретных команд), если устройству требуется некоторое время для ответа, кажется, что хост-сторона продолжает ждать сигнала и никогда не двигается дальше. Я проверил, что устройство в конечном итоге отвечает (скажем, через 10 секунд), но, похоже, хост никогда не получает сигнал. Я использую анонимное событие, чтобы убедиться, что оно не будет съедено каким-либо другим процессом.
Итак, мы просто застряли на if (!GetOverlappedResult(m_hDevice, amp;osReader, amp;bytesRead, TRUE))
Может ли кто-нибудь внести какой-либо вклад в то, чего мне не хватает, или если есть что-то, что кажется неправильным?
ФУ, вот как я создаю устройство
Device = CreateFile( Path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
Комментарии:
1. в любом случае ваш код неверен. вы не проверяете результат или вызов ввода
GetOverlappedResult
-вывода имеет смысл только в том случаеERROR_IO_PENDING
, если он возвращен вводом-выводом. Также, почему вы открываете файл сFILE_FLAG_OVERLAPPED
помощью, но на самом деле используете синхронный ввод-вывод ?2. @RbMm Я знаю, что перекрывающийся и синхронный ввод-вывод на самом деле плохо сочетаются друг с другом, поскольку это противоречит цели перекрывающегося ввода-вывода. На данный момент это просто требование, и оно не должно вызывать никаких проблем при нормальной работе. Я проверил ответ на чтение файла, хотя он не включен здесь, и это ОШИБКА_IO_PENDING. Кроме того, видите ли вы какую-либо проблему, из-за которой об этом не будет сообщено?
3. Я проверил ответ на чтение файла, хотя он здесь не указан — почему вы не публикуете фактический код в этом случае ? конкретный код в сообщении неверен. если чтение или запись возвращают false — вам нужно при начале вызова
GetLastError()
. за то, что вы все еще называетеWaitForSingleObject
после чтения (бессмысленно) и не делаете этого после записи. снова — или используйте реальный асинхронный ввод — вывод-не ждите на месте после ввода-вывода или снимитеFILE_FLAG_OVERLAPPED
флаг.4. я думаю, что это не второстепенные детали. почему
GetOverlappedResult
ожидание бесконечно ? в конкретном коде — еслиReadFile
произойдет сбой, но не сERROR_IO_PENDING
помощью — osReader. Событие не будет установлено, как результат иGetOverlappedResult
бесконечное ожидание5.
hEvent
не установлено, если запрос не завершен или если он не был синхронным (ввод-вывод возвращает значение false, но последняя ошибка не находится в состоянии ожидания). основываясь на вашем коде и информации — невозможно дать другой ответ. они действительно отвечают на наш первоначальный запрос — этот момент абсолютно неясен