Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Расчет таймаутов, Рассчет таймаутов com-порта 
:(
    Опции темы
Fantom87
Дата 28.6.2012, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 16.6.2007

Репутация: нет
Всего: нет



Доброго времени суток.
Проблема такого характера...
На com-порт приходит 19 байт с интервалами межу каждым байтом примерно 1 миллисекунда. Примерно через 1 миллисекунду после последнего байта начинают идти следующие 19 байт. Как правильно рассчитать таймауты, чтбы разделить эти посылки. На данный момент программа принимает каждый байт поотдельности.
PM MAIL   Вверх
xvr
Дата 28.6.2012, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Fantom87 @  28.6.2012,  12:08 Найти цитируемый пост)
Как правильно рассчитать таймауты, чтбы разделить эти посылки. 

Никак. Это вряд ли возможно даже на уровне железа (в UART'е компа есть FIFO)

И вообще вы разделом ошиблись, тут COM порт не обсуждают, местный COM - это Component Object Model smile 

PM MAIL   Вверх
Fantom87
Дата 28.6.2012, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 16.6.2007

Репутация: нет
Всего: нет



Прошу прощение, за то что ошибся с разделом. Спешил, не разобрался что к чему =)
Тогда какой максимальный временой интервал допустим между байтами, чтобы они принимались одним пакетом?
И поясните пожалуйста доступным языком, для чего нужны таймауты, как они работают и как их рассчитывать?
PM MAIL   Вверх
xvr
Дата 28.6.2012, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Fantom87 @  28.6.2012,  15:52 Найти цитируемый пост)
Тогда какой максимальный временой интервал допустим между байтами, чтобы они принимались одним пакетом?

Максимальный может быть любой. Вопрос в минимальном. Под Windows гарантированно нельзя настроить никакой таймаут, т.к. она не real-time ОС

Цитата(Fantom87 @  28.6.2012,  15:52 Найти цитируемый пост)
И поясните пожалуйста доступным языком, для чего нужны таймауты,  

Нужны они что бы гарантировать, что ваш вызов чтения из COM порта вернется через некоторое время. Использовать их для нарезки входящих байтов на пакеты крайне не рекомендуется.
Цитата

как они работают и как их рассчитывать?


http://msdn.microsoft.com/en-us/library/wi...v=vs.85%29.aspx

PM MAIL   Вверх
Fantom87
Дата 29.6.2012, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 16.6.2007

Репутация: нет
Всего: нет



С таймаутами понятно. А вот по поводу приема... Видимо я не правильно вопрос задаю=) Попробую еще раз.
При поступлении данных в ком-порт компьютера:
Код

//главная функция потока, реализует приём байтов из COM-порта
DWORD WINAPI ReadThread(LPVOID)
{
 COMSTAT comstat;        //структура текущего состояния порта, в данной программе используется для определения количества принятых в порт байтов
 DWORD btr, temp, mask, signal;    //переменная temp используется в качестве заглушки

 overlapped.hEvent = CreateEvent(NULL, true, true, NULL);    //создать сигнальный объект-событие для асинхронных операций
 SetCommMask(COMport, EV_RXCHAR);                            //установить маску на срабатывание по событию приёма байта в порт
 while(1)                                //пока поток не будет прерван, выполняем цикл
  {
   WaitCommEvent(COMport, &mask, &overlapped);                //ожидать события приёма байта (это и есть перекрываемая операция)
   signal = WaitForSingleObject(overlapped.hEvent, INFINITE);    //приостановить поток до прихода байта
   if(signal == WAIT_OBJECT_0)                        //если событие прихода байта произошло
    {
     if(GetOverlappedResult(COMport, &overlapped, &temp, true)) //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
      if((mask & EV_RXCHAR)!=0)                    //если произошло именно событие прихода байта
       {
        ClearCommError(COMport, &temp, &comstat);        //нужно заполнить структуру COMSTAT
        btr = comstat.cbInQue;                           //и получить из неё количество принятых байтов
        if(btr)                                  //если действительно есть байты для чтения
        {
         ReadFile(COMport, bufrd, btr, &temp, &overlapped);     //прочитать байты из порта в буфер программы
         counter+=btr;                                          //увеличиваем счётчик байтов
         ReadPrinting();                                   //вызываем функцию для вывода данных на экран и в файл
        }
       }
    }
  }
}

Код не мой, вот и разбираюсь сижу...
Код

void ReadPrinting()
{
...//Здесь идет обработка данных, принятных в bufrd, работая с ним как с массивом
memset(bufrd, 0, BUFSIZE);            //очистить буфер (чтобы данные не накладывались друг на друга)
}

Внимание вопрос...
Если байты приходят в com-порт подряд, без задержки, то заполняют массив. А когда между байтами есть задержка, то каждый байт записывается в bufrd[0], а остальные члены массива остаются нулевыми. То есть, как я понимаю, для приема каждого байта поток запускается по новой. Вот где та временнАя граница межуд байтами, до которой они принимаются в одном потоке. Или я принципиально что-то не так делаю?
PM MAIL   Вверх
xvr
Дата 29.6.2012, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Код неправильный. Не надо ждать никаких WaitCommEvent, надо сразу звать ReadFile и ждать когда он выставит overlapped.hEvent
Потом через GetOverlappedResult проверяете успешно или нет произошло чтение и сколько именно прочиталось.
Либо вообще отказаться от Overlapped режима (в вашем примере он нафиг не нужен) и просто звать ReadFile - когда вернется, тогда уже все будет прочтено (а сколько именно, вернется через 4х параметр)

Цитата(Fantom87 @  29.6.2012,  08:52 Найти цитируемый пост)
То есть, как я понимаю, для приема каждого байта поток запускается по новой.

Нет, поток один, а в нем крутится цикл

Цитата(Fantom87 @  29.6.2012,  08:52 Найти цитируемый пост)
Вот где та временнАя граница межуд байтами, до которой они принимаются в одном потоке.

По истечению таймаута. 

Но надейться на то, что байты будут приходить какими то определенными группами нельзя. У вас будет периодически вызываться ReadPrinting на каждый принятый пакет, при этом размер пакета будет лежать в counter, а данные в bufrd (counter надо очищать сразу после выхода из ReadPrinting, и вообще работа с ним - явная бага в исходнике)

Предсказать, какими именно кусками к вам в ReadPrinting будут сваливаться данные нельзя.
Т.е. если девайс передает к примеру 10 байтов, то вас могут позвать 1 раз с 10 байтами, а могут позвать 2 раза с 5 байтами, или 2 раза с 2мя и 8ю байтами, или 10 раз с одним байтом, или вообще как угодно - но не более 10 раз и общая сумма байтов будет 10  smile 

PM MAIL   Вверх
Fantom87
Дата 29.6.2012, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 16.6.2007

Репутация: нет
Всего: нет



В общем вывод такой... Принимаем по одному байту, а конец пакета определяем по какому-нибудь стоповому байту.
Всем спасибо smile 
PM MAIL   Вверх
Dem_max
Дата 12.7.2012, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: нет
Всего: 39



Вообще стоит почитать 
http://www.realcoding.net/article/view/2416


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.1608 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.