Таймауты чтения с Com порта
Есть железка, подключаемая в COM. Работает на скорости 19200.
Ещё известно что таймаут ожидания очередного байта - 1..2 сек.
После отправки запроса на железку, оператор должен с ним поработать. И после этого девайс отвечает.
На всё это (ввод данных оператором и ответ железки) я даю 30 сек.
Я немогу добится следующего - когда девайс вообще неподключён к порту, мне, получается, надо что бы через 30 сек ф-ция ReadFile отработалась с таймаутом.
Делаю так:
COMMTIMEOUTS CommTimeOuts;
BOOL bRes = ::GetCommTimeouts(m_hCom, &CommTimeOuts);
if (!bRes) {
//...
}
CommTimeOuts.ReadIntervalTimeout = dwReadIntervalTimeout; // Maximum time between read chars
CommTimeOuts.ReadTotalTimeoutMultiplier = dwReadTotalTimeoutMultiplier; // Multiplier of characters.
CommTimeOuts.ReadTotalTimeoutConstant = dwReadTotalTimeoutConstant; // Constant in milliseconds.
bRes &= ::SetCommTimeouts(m_hCom, &CommTimeOuts);
if (!bRes) {
//...
}
return bRes;
}
ну и вызываю так:
DWORD dwReadTotalTimeoutMultiplier = 294; // читаю по 512 байт. Используется 8 бит на символ, без чётности и 2 стоповых бита. Т.е. 512*(8+2)/19200 = 0.29333 сек.
DWORD dwReadTotalTimeoutConstant = 30000; // 30 сек на всё
m_Com.SetCommReadTimeOuts(dwReadIntervalTimeout, dwReadTotalTimeoutMultiplier, dwReadTotalTimeoutConstant);
Вот с таким вызовом ReadFile возвращает WAIT_TIMEOUT через 2 сек.
Как мне добиться нужного результата?
Подскажите, плз!
После отправки запроса на железку, оператор должен с ним поработать. И после этого девайс отвечает.
Непонял - с кем? С девайсом, или программой?
Я немогу добится следующего - когда девайс вообще неподключён к порту, мне, получается, надо что бы через 30 сек ф-ция ReadFile отработалась с таймаутом.
.........................
Вот с таким вызовом ReadFile возвращает WAIT_TIMEOUT через 2 сек.
Ну?.. Это же естественно, т.к. у вас ничего не подключено к порту, следовательно программа выжидает 2 секунды, которые вы ей задали при конфигурировании порта и после этого выполняется дальше.
А вообще, судя по примеру - вы просто не знаете как правильно работать с СОМ-портом. Найдите в инете статью Титова Олега и прочитайте. После этого вам все станет ясно.
Объяснять сейчас, что и чему - у меня к сожалению нет времени. Коротко: неправильно почти все.
Не расстраивайтесь прочитайте то, что посоветовал и все сделаете сами.
ЗЫ: работу с портом организуйте в параллельном потоке, иначе не избежеть "тормозов" с пользовательским интерфейсом программы.
Непонял - с кем? С девайсом, или программой?
Клиент должен поработать с устройством - нажать кнопки.
Ну?.. Это же естественно, т.к. у вас ничего не подключено к порту, следовательно программа выжидает 2 секунды, которые вы ей задали при конфигурировании порта и после этого выполняется дальше.
А вообще, судя по примеру - вы просто не знаете как правильно работать с СОМ-портом. Найдите в инете статью Титова Олега и прочитайте. После этого вам все станет ясно.
Статью, я конечно, прочитал сразу, и SDK смотрел... Но, наверное, непонял :(
Я ведь задаю 2 сек. в переменной ReadIntervalTimeout - макс. время между двумя последовательными символами. Так почему у меня вылетает с таймаутом именно через 2 секунды? Хотя нет никаких символов - из порта ничего не приходит. Я ж ведь общий таймаут задал больше?
Даже когда железяка подключена - всё тоже самое.
Она начнёт отвечать, когда оператор закончит ввод данных - это где-то, в среденем, секунд через 5-15 сек.
Объяснять сейчас, что и чему - у меня к сожалению нет времени. Коротко: неправильно почти все.
8(
Не расстраивайтесь прочитайте то, что посоветовал и все сделаете сами.
ЗЫ: работу с портом организуйте в параллельном потоке, иначе не избежеть "тормозов" с пользовательским интерфейсом программы.
С паралелизмом как раз проблем нет.
Хоть это радует ;)
Кое-как понял, что вам нужно (вспомнил при этом себя :)). Видимо, что бы вылетало только через 30 секунд. Теперь к сути. Невнимательно вы статью читали:
ReadIntervalTimeout
Максимальное время, в миллисекундах, допустимое между двумя последовательными символами считываемыми с коммуникационной линии. Во время операции чтения временной период начинает отсчитываться с момента приема первого символа. [color=red]Если интервал между двумя последовательными символами превысит заданое значение, операция чтения завершается[/color]...
Теперь понятно? Для того, что бы ваша функция не вылетала вам нужно установить значение этого параметра в 0.
ReadTotalTimeoutMultiplier
Задает множитель, в миллисекундах, используемый для вычисления общего тайм-аута операции чтения. Для каждой операции чтения данное значение умножается на количество запрошеных для чтения символов.
Т.е. он должен быть равен времени которое по вашим рассчетам нужно для считывания одного байта, а не всех, как это сделано у вас.
Можно не использовать установив в 0.
ReadTotalTimeoutConstant
Задает константу, в миллисекундах, используемую для вычисления общего тайм-аута операции чтения. Для каждой операции чтения данное значение прибавляется к результату умножения ReadTotalTimeoutMultiplier на количество запрошеных для чтения символов.
Вроде должно быть понятно. Ее желательно использовать в любом случае. Иначе - при неответе устройства, ваш поток зависнет намертво, пока не дождется какого-либо ответа из порта, либо завершения всей программы. Можно использовать только ее - из ваших расчетов она должна быть равна 294 мс.