Отсутствует сигнал о событии?

#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, но последняя ошибка не находится в состоянии ожидания). основываясь на вашем коде и информации — невозможно дать другой ответ. они действительно отвечают на наш первоначальный запрос — этот момент абсолютно неясен