Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Таймауты чтения с Com порта

1.8K
22 июля 2005 года
SeregaLBN
62 / / 03.10.2003
Что-то не могу добиться нужного результата.
Есть железка, подключаемая в COM. Работает на скорости 19200.
Ещё известно что таймаут ожидания очередного байта - 1..2 сек.
После отправки запроса на железку, оператор должен с ним поработать. И после этого девайс отвечает.
На всё это (ввод данных оператором и ответ железки) я даю 30 сек.
Я немогу добится следующего - когда девайс вообще неподключён к порту, мне, получается, надо что бы через 30 сек ф-ция ReadFile отработалась с таймаутом.
Делаю так:
Код:
BOOL CComPort::SetCommReadTimeOuts(DWORD dwReadIntervalTimeout, DWORD dwReadTotalTimeoutMultiplier, DWORD dwReadTotalTimeoutConstant) {
   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 dwReadIntervalTimeout        = 2000;  // таймаут ожидания очередного байта
   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 сек.
Как мне добиться нужного результата?
Подскажите, плз!
243
23 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Как-то оно смутно получилось у вас:
Цитата:
Originally posted by SeregaLBN

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


Непонял - с кем? С девайсом, или программой?

Цитата:
Originally posted by SeregaLBN

Я немогу добится следующего - когда девайс вообще неподключён к порту, мне, получается, надо что бы через 30 сек ф-ция ReadFile отработалась с таймаутом.
.........................
Вот с таким вызовом ReadFile возвращает WAIT_TIMEOUT через 2 сек.


Ну?.. Это же естественно, т.к. у вас ничего не подключено к порту, следовательно программа выжидает 2 секунды, которые вы ей задали при конфигурировании порта и после этого выполняется дальше.

А вообще, судя по примеру - вы просто не знаете как правильно работать с СОМ-портом. Найдите в инете статью Титова Олега и прочитайте. После этого вам все станет ясно.

Объяснять сейчас, что и чему - у меня к сожалению нет времени. Коротко: неправильно почти все.

Не расстраивайтесь прочитайте то, что посоветовал и все сделаете сами.
ЗЫ: работу с портом организуйте в параллельном потоке, иначе не избежеть "тормозов" с пользовательским интерфейсом программы.

1.8K
25 июля 2005 года
SeregaLBN
62 / / 03.10.2003
Цитата:
Originally posted by pacific_7

Непонял - с кем? С девайсом, или программой?


Клиент должен поработать с устройством - нажать кнопки.

Цитата:

Ну?.. Это же естественно, т.к. у вас ничего не подключено к порту, следовательно программа выжидает 2 секунды, которые вы ей задали при конфигурировании порта и после этого выполняется дальше.

А вообще, судя по примеру - вы просто не знаете как правильно работать с СОМ-портом. Найдите в инете статью Титова Олега и прочитайте. После этого вам все станет ясно.


Статью, я конечно, прочитал сразу, и SDK смотрел... Но, наверное, непонял :(
Я ведь задаю 2 сек. в переменной ReadIntervalTimeout - макс. время между двумя последовательными символами. Так почему у меня вылетает с таймаутом именно через 2 секунды? Хотя нет никаких символов - из порта ничего не приходит. Я ж ведь общий таймаут задал больше?

Даже когда железяка подключена - всё тоже самое.
Она начнёт отвечать, когда оператор закончит ввод данных - это где-то, в среденем, секунд через 5-15 сек.

Цитата:

Объяснять сейчас, что и чему - у меня к сожалению нет времени. Коротко: неправильно почти все.


8(

Цитата:

Не расстраивайтесь прочитайте то, что посоветовал и все сделаете сами.
ЗЫ: работу с портом организуйте в параллельном потоке, иначе не избежеть "тормозов" с пользовательским интерфейсом программы.


С паралелизмом как раз проблем нет.
Хоть это радует ;)

243
25 июля 2005 года
pacific_7
1.9K / / 06.09.2004
Цитата:
Я ведь задаю 2 сек. в переменной ReadIntervalTimeout - макс. время между двумя последовательными символами. Так почему у меня вылетает с таймаутом именно через 2 секунды? Хотя нет никаких символов - из порта ничего не приходит. Я ж ведь общий таймаут задал больше?


Кое-как понял, что вам нужно (вспомнил при этом себя :)). Видимо, что бы вылетало только через 30 секунд. Теперь к сути. Невнимательно вы статью читали:

Цитата:

ReadIntervalTimeout
Максимальное время, в миллисекундах, допустимое между двумя последовательными символами считываемыми с коммуникационной линии. Во время операции чтения временной период начинает отсчитываться с момента приема первого символа. [color=red]Если интервал между двумя последовательными символами превысит заданое значение, операция чтения завершается[/color]...


Теперь понятно? Для того, что бы ваша функция не вылетала вам нужно установить значение этого параметра в 0.

Цитата:

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


Т.е. он должен быть равен времени которое по вашим рассчетам нужно для считывания одного байта, а не всех, как это сделано у вас.
Можно не использовать установив в 0.

Цитата:

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


Вроде должно быть понятно. Ее желательно использовать в любом случае. Иначе - при неответе устройства, ваш поток зависнет намертво, пока не дождется какого-либо ответа из порта, либо завершения всей программы. Можно использовать только ее - из ваших расчетов она должна быть равна 294 мс.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог