Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Задержка ClearCommError ???


Автор: takedo 19.9.2005, 13:53
Вот заковыка та какая:
после того, как определяется, что в буфер поступил символ (порт инициализирован так например SetCommMask(m_hComm,EV_RXCHAR);), запрашиваем, сколько же у нас во входной очереди символов имеется через ClearCommError. Так вот не сразу меняется значение параметра cs.cbInQue!! Поэтому приходится делать дурацкую while!!!.
А как иначе??? Может есть где там каккой-то скрытый Event??? smile
Вот пример кода:
Код

ResetEvent(m_ovp_wait.hEvent);
if(!WaitCommEvent(m_hComm,&dwCommEvent,&m_ovp_wait))
{
   if(GetLastError()!=ERROR_IO_PENDING)
    {
    return PORTERROR;
    }
}
                
ret_wait = WaitForSingleObject(m_ovp_wait.hEvent,DELAY_TO);
switch(ret_wait)
{
case WAIT_OBJECT_0:
while(!cs.cbInQue)
{
if(!ClearCommError(m_hComm,&error,&cs))//далеко не с первого захода!!!
{
    return PORTERROR;
}
}
break;
case WAIT_TIMEOUT:
break;
default:
return PORTERROR;
}


Автор: takedo 21.9.2005, 12:54
Блин, так ни у кого никаких мыслей что-ли по поводу того как после выполнения асинхронного вызова WaitCommEvent гарантированно получить актуальное значение cs.cbInQue ???

Автор: JoyEx 28.12.2005, 11:50
А почему ты не проверяешь dwCommEvent на EV_RXCHAR?

Автор: takedo 28.12.2005, 12:12
JoyEx
Цитата
А почему ты не проверяешь dwCommEvent на EV_RXCHAR?

А что это поменяет?
Если я поставлю условие if(dwCommEvent & EV_RXCHAR){ClearCommError();...}, то я все равно на очередь не повлияю, в том то и дело, что (dwCommEvent & EV_RXCHAR) == true, а очередь равна нулю.

Автор: JoyEx 28.12.2005, 12:31
takedo

Не надо "влиять на очередь", ею занимается \Device\Serial0-1. Ты просто проверь не нуль ли в dwCommEvent.

smile ну и репутация у тебя smile "таганка, я твой навеки арестант"

Автор: takedo 28.12.2005, 13:14
JoyEx
Все равно не понятно, ну проверю - нуль, дальше по логике опять WaitCommEvent(), но событие уже взвелось и если новых символов не прилетит, то я вылечу по таймауту, то есть с ошибкой(по крайне мере у меня так было), а на самом деле пришел правильный кадр.
Тут ведь вот в чем дело, может я чего недопонимаю, но когда приходит символ в потр, выставляется в "свободен" m_ovp_wait.hEvent, а очередь в этот момент равна 0 (не всегда, а когда поместил в буфер часть кадра, ту длина которой была в cbInQue)! Как это связано с проверкой dwCommEvent на EV_RXCHAR? НУ НЕПОНЯТНО! smile

Автор: JoyEx 28.12.2005, 15:54
1)
Цитата(takedo @ 28.12.2005, 13:14)
Все равно не понятно, ну проверю - нуль, дальше по логике опять WaitCommEvent(), но событие уже взвелось и если новых символов не прилетит, то я вылечу по таймауту, то есть с ошибкой(по крайне мере у меня так было), а на самом деле пришел правильный кадр.


нет. m_ovp_wait у тебя для того, чтобы ждать завершения работы WaitCommEvent(), ты же сам проверяешь на PENDING.

2) Смотри выше п.1, про m_ovp_wait

===================
MSDN:
Цитата
EV_RXCHAR  - A character was received and placed in the input buffer.

хоть один байт значит получен


Цитата(takedo @ 19.9.2005, 13:53)
case WAIT_OBJECT_0:
while(!cs.cbInQue)
{
if(!ClearCommError(m_hComm,&error,&cs))//


сначало надо ClearCommError, а потом смотреть что в cs.
К твоему switch-case придраться не могу smile

Автор: takedo 28.12.2005, 16:15
на самом деле код был другой, это на скорую руку сделанная выдержка. Сейчас я делаю по другому, но попробую все-таки ещё раз. перед while естественно был вызов ClearCommError. В том и была проблема, что если сразу после прилетания символа в буфер(по эвенту отслеживаемому) ClearCommError возвращала 0 во входной очереди. И что самое главное, так это то, что в нескольких форумах я находил то же самое, поэтому не думаю, что заковыка здесь именно в приведенном неправильном коде. Но попробую, попробую.

JoyEx А есть кусок текста из реально-работающей программы для работы с ком портом, где бы было реализовано чтение вот именно так: пришел символ, смотрим очередь, читаем из очереди количество байт, которое в данный момент там есть?
Добавлено @ 16:19
JoyEx если бы было именно так, то я бы сидел там вечно while(!cs.cbInQue); => не в этом проблема!

Автор: takedo 28.12.2005, 16:34
чего то запутал smile даже если и сначала while(!InQuene) ну тогда заходим и смотрим сколько в очереди, именно поэтому и появился этот while (вспомнил как на самом деле было smile )!, потому что если без цикла просто вызывая ClearCommError получал я 0! Вот какая была проблема. И ничего смешного, между прочим, просто не все с этим сталкиваются
Добавлено @ 16:36
JoyEx
я же и писал в ПЕРВОМ посте:
Цитата
Так вот не сразу меняется значение параметра cs.cbInQue!! Поэтому приходится делать дурацкую while!!!.

Добавлено @ 16:40
JoyEx
Цитата
сначало надо ClearCommError, а потом смотреть что в cs.
К твоему switch-case придраться не могу
Сначала while, а потом ClearCommError. Таким образом гарантированно заходим в while и считываем размер очереди.

Автор: takedo 28.12.2005, 16:50
JoyEx
Цитата
MSDN:

Цитата 
EV_RXCHAR  - A character was received and placed in the input buffer. 


хоть один байт значит получен
Да это точно, но если сразу смотреть размер очереди, не всегда он там отображается! Именно поэтому я и спрашивал и тему создал, чтобы узнать почему событие поймали, а очередь не изменилась. А особенно ярко эта проблема проявляется, если читать более 500 байт, потому что тогда точно при таком алгоритме придется делать несколько вызовов ReadFile. А вот когда у нас в очередь добавляются символы и одновременно убираются через ReadFile - получаем неактуальные значения InQue. Если использовать синхронное чтение и читать до упора, пока ReadFile не возвратит что-нибудь (хотя бы байт)то проблемы нет.

Автор: JoyEx 28.12.2005, 17:43
takedo

В прошлой теме я дал рабочий код.
Всё что ты пишешь интересно, конечно, но изложение не подсунешь компилятору.

Автор: takedo 29.12.2005, 08:09
JoyEx
надо сказать, что по теме заданного вопроса ты ничего не прояснил, но и на том спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)