2009-09-11 3 views
1

У меня есть устройство, которое генерирует сообщения через последовательный порт. Когда я перезагружаю устройство, порт завершения ввода-вывода перестает считывать байты.GetQueuedCompletionStatus перестает читать последовательный порт

Код вызывает GetQueuedCompletionStatus():

BOOL bRet = GetQueuedCompletionStatus(
     m_hCompletionPort, 
     &dwBytesTransferred, 
     &dwCompletionKey, 
     &pOverlapped, 
     INFINITE); 

PortMon выглядит следующим образом:

... 
IRP_MJ_WRITE Serial1 SUCCESS  LENGTH: 7 REBOOT. 
IRP_MJ_READ  Serial1 CANCELLED LENGTH: 1  

Logging показывает следующий результат:

bRet=true, dwBytesTransferred=7, pOverlapped=0x0202B028, GetLastError()=997 
(sleep forever) 

Есть ли способ, чтобы обнаружить это отказ и восстановление связи?

Я могу отслеживать тепловой удар и закрывать/открывать последовательный порт, но не кажется правильным, что API окон позволяет бесшумно отключать последовательную связь.

ответ

1

Если вы делаете WaitForSingleObject на ручке для последовательного порта, который вы открыли, чтобы начать считывать данные, появляется ли ручка, когда устройство перезагружается? Может быть, это способ сказать, когда вам нужно снова открыть порт?

+0

Спасибо. Я пытался справиться с этим, не отвлекаясь на использование порта завершения ввода-вывода, но похоже, что у меня нет выбора. – 2009-09-14 00:13:45

+0

У вас есть выбор: см. Мой ответ! – janm

1

IO Завершение Порты могут, безусловно, справиться с этим случаем без проблем. Вам не нужно закрывать и снова открывать устройство.

Наиболее вероятной проблемой в этом случае является то, что у вас есть ошибка в строке (вызванная сбросом устройства), которую вы не очистили с помощью ClearCommError().

Вам необходимо использовать SetCommState() и SetCommTimeouts() для вашего устройства спереди. В DCB вы переходите к SetCommState(), вам нужно установить fAbortOnError. Если вы выполните деактивацию ошибки, вам нужно вызвать ClearCommError(), прежде чем вы будете запрашивать другое чтение.

1

RE: janm (я не могу показаться, чтобы добавить комментарий к вашему ответу пардон)

я попробовать установить различные флаги, в том числе fAbortOnError в DCB, но GetQueuedCompletionStatus() будет по-прежнему ждать бесконечно. Я также периодически проверял время вызова и проверял последовательный порт на наличие ошибок. Последовательный порт всегда выглядел отлично, но разъединение все равно навсегда сломало порт завершения ввода-вывода. Перезагрузка устройства, вероятно, создает переходное состояние ошибки ... Я говорю, вероятно, потому что я никогда не мог его обнаружить!

У другого разработчика также была проблема с этой проблемой, и они тоже потерпели неудачу. Поэтому мы просто переписали код, чтобы использовать перекрывающиеся последовательные порты, и теперь он отлично работает.

Возможно, что-то есть, где-то мы пропустили ... в конце концов мы потратили больше времени на то, чтобы решить загадку, чем потребовалось, чтобы переписать код.

+0

Интересно. Я разработал ряд систем, которые выполняют именно это, используя IOCompletionPorts; мои проекты, как правило, используют большое количество однобайтовых чтений. Они используются для систем управления, где во время тестирования последовательный порт подвергался всевозможным злоупотреблениям. Другая возможность заключается в том, что в драйвере последовательного устройства есть ошибка. Это более вероятно, если вы используете стороннюю последовательную плату, а не родной драйвер Windows со стандартным последовательным портом. – janm

Смежные вопросы