Win32 API: время чтения файла не истекло

Я пишу код для взаимодействия с оборудованием. Оборудование подключается к ПК через USB-порт с преобразователем USB-to-Serial внутри устройства (в Windows он отображается как устройство с COM-портом).

У меня проблемы с системным вызовом Win32 API ReadFile. Кажется, я не могу заставить его работать, как рекламируется. Я установил структуру COMMTIMEOUTS так:

COMMTIMEOUTS ct;
ct.ReadIntervalTimeout = MAXDWORD;
ct.ReadTotalTimeoutconstant = 0;
ct.ReadTotalTimeoutMultiplier = 0;
ct.WriteTotalTimeoutConstant = 0;
ct.WriteTotalTimeoutMultiplier = 0;

if(SetCommTimeouts(device_id_, &ct) == 0)
{
     return ERROR; // this is never hit.
}

Что, согласно документации Win32 API, гласит:

ReadIntervalTimeout

Максимальное время в миллисекундах, которое может пройти между поступлением двух байтов в линию связи. Во время операции ReadFile период времени начинается с момента получения первого байта. Если интервал между поступлением любых двух байтов превышает это количество, операция ReadFile завершается и возвращаются все буферизованные данные. Нулевое значение указывает, что интервалы времени ожидания не используются.

Значение MAXDWORD в сочетании с нулевыми значениями для обоих членов ReadTotalTimeoutConstant и ReadTotalTimeoutMultiplier указывает, что операция чтения должна немедленно возвращаться с уже полученными байтами, даже если не было получено ни одного байта.

Отправляемая мной команда должна возвращать однобайтовое целое число. В большинстве случаев команда получает устройство и возвращает соответствующее значение. Иногда, однако, кажется, что он не возвращает значение и блоки ReadFile (), пока не будет получено больше байтов (например, при нажатии кнопок на устройстве). Как только кнопка нажата, начальный целочисленный ответ, которого я ожидал, получен вместе с кодом нажатия кнопки. Хотя это не то поведение, которое я ожидаю от самого устройства, меня больше беспокоит блокировка ReadFile (), когда этого не должно быть, согласно документации MSDN. Есть ли здесь средство от блокировки ReadFile ()?


person Grant Limberg    schedule 20.10.2010    source источник
comment
Вы проверяли, успешен ли вызов SetCommTimeouts?   -  person casablanca    schedule 21.10.2010
comment
Действительно, я сделал. Ошибка не вернулась. Я даже попытался впоследствии снова вызвать GetCommTimeouts () на устройстве в новой структуре COMMTIMEOUTS, просто чтобы убедиться, что настройки устройства верны.   -  person Grant Limberg    schedule 21.10.2010
comment
Возможно, UART на USB-порту не имеет буфера - я понял это из второго абзаца процитированной документации - что-то там выглядит подозрительно. Кроме того, в документации ReadFile ничего не говорится о возврате, если данные недоступны. Кроме того, не мешало бы посмотреть, каково значение MAXDWORD - или попробовать поставить вместо него 1 ...   -  person Daniel Mošmondor    schedule 21.10.2010
comment
@Danel: Из документации ReadFile (): при чтении с устройства связи поведение ReadFile определяется текущим тайм-аутом связи, установленным и полученным с помощью функций SetCommTimeouts и GetCommTimeouts. Непредсказуемые результаты могут произойти, если вы не установите значения времени ожидания. Дополнительные сведения о тайм-аутах связи см. В разделе COMMTIMEOUTS.   -  person Grant Limberg    schedule 21.10.2010
comment
Ага, именно так это интерпретирует драйвер последовательного порта Microsoft. Фриккинский придурок, который пишет все те эмуляторы последовательного порта USB, на которые все купили лицензию по действительно разумной цене, еще не понял этого.   -  person Hans Passant    schedule 21.10.2010


Ответы (1)


Ооо! Оказалось, что блокировка ReadFile была всего лишь симптомом, а не проблемой. Аппаратное устройство, о котором идет речь, имеет только процессор с тактовой частотой 4 МГц. Разделение 3-символьной команды, записанной на устройство, и отправка их по отдельности с паузой в 1 мс между символами устраняет проблему.

person Grant Limberg    schedule 20.10.2010