![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
xvr |
|
||||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Если нужно читать в Overlapped, то WaitCommEvent все равно не нужен. Нужно сразу запускать ReadFile, и если она вернулась с ошибкой IO_STILL_PENDING (кажется так), запускать WaitForSingleObject на event'е из OVERLAPPED, а затем GetOverlappedResult. (А можно сразу GetOverlappedResult и поставить ему TRUE в последнем параметре)
![]()
|
||||||||
|
|||||||||
TheDestroyer |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
в режиме Overlapped получился такой поток чтения:
ReadFile стоит чуть больше секунды и возвращает ERROR_IO_PENDING всегда. Приняты данные или нет можно судить по bytes_read. Так поток и "крутится". В Overlapped режиме, в отличие от обычного, ReadFile не создает описанных ранее подвисаний. Таймауты такие:
В первом посте я описывал, что принимается 14+1 байт при отправке 15-ти байт. В потоке чтения в цикле принималось сначала 14 байт (как сообщалось в comstat.cbInQue), на втором цикле принимался еще один байт (также сообщалось в comstat.cbInQue). Делаю замер скорости на двух компьютерах. Настройки COM порта такие:
На 2х компьютерах запускаю написанную программу, на 2-ом устанавливаю флаг slave_mode (т.е. сразу после чтения он отправляет принятое назад). Передаю циклически буфер из 20 байт, содержимое каждый раз меняю для контроля правильной передачи и приема.Время контролирую с помощью компонента Timer из стандартного набора Borland. Интервал таймера выставлен 55мс, т.к. меньшие интервалы, похоже, таймер не чувствует. Делаю 15 циклов передачи, соответственно вижу, что на компьютере, с которого отправлял: отправлено 300 байт (15 раз по 20 байт) и принято 300 байт. Все без ошибок. Затраченное время 3740мс = 3,74с. Подсчитываю скорость: 300 байт * 2 / 3,74 c ~ 160,43 байт/с = 1283 бит/с. Никак не 9600 бит/с Учтем, что пересылка идет, наверное, по 8 информационных бит, к которым добавляется 1 старт и 1 стоп бит. Итого на 300 байт информационных издержек: 300*2 =600 бит = 75 байт. Т.к. в тесте пересылка идет туда и обратно: 75*2 = 150 байт. Итого передано всего (300+75)*2 байт / 3,74 с ~ 200,54 байт/с = 1604,3 бит/с. Опять далеко не 9600 бит/с Не учитываю время затраченное компьютерами на запись информации в буфера, т.к. считаю его незначительным по сравнению со временем, затраченным на передачу данных. В чем ошибка расчета скорости? Может не по 8 информационных бит передается? |
||||||
|
|||||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Что то не так. Передается по 10 бит (минимум). Попробуй отправить большой пакет данных (все 300 байт за раз), и замерять время не таймером, а функцией замера времени (GetTickCount() например)
|
|||
|
||||
TheDestroyer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Сделал таким образом:
Запускается поток MainThread, который запоминает значение точного счетчика, запускает запись в порт, дожидается окончания чтения ответа и сравнивает текущее значение счетчика с запомненным ранее. В итоге, вроде как, точность - 10ки микросекунд. Пересылаю буфер размером 300 байт. Результат: время пересылки к slave и обратно = 628623 мкс (в среднем) Скорость: 300 байт * 2 / 0,63 с = 952,5 байт/с = 7619 бит/с Транспортных издержек (1 старт и 1 стоп бит): 300 * 2 = 600 бит = 75 байт Итого: (300 +75)байт * 2 / 0,63 с = 1190,5 байт/с = 9523,8 бит/с Это уже похоже на правду. Почему же при пересылке маленькими пачками скорость так падает? |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Переключение thread'ов отнимает много времени. Возможно еще где то есть лишние системные вызовы |
|||
|
||||
TheDestroyer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Выяснил, что если в ReadFile ставить приемный буфер больше, чем реально пересылается байт, то возникает задержка.
Так при передаче 300 байт и с 300 байтным буфером приема пересылка туда и обратно происходила за 0,052сек. При передаче 17 байт с 300 байтным буфером приема такая пересылка занимает более 0,2сек. Если же выставить 17 байтный буфер приема, то пересылка занимает 0,0037сек, что соответствует скорости 93176 Бит/с (при настройке порта на 115200 Бит/с). Видимо на эту задержку в зафисимости от размера приемного буфера влияют таймауты. |
|||
|
||||
xvr |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Естественно
![]() Если в процессе приема данных закончился буфер, то ReadFile немедленно прекращает чтение, остаток данных останется лежать в буфере системы (и timeout'ы на это не влияют). Если же в процессе приема закончился входной поток, то система будет как минимум ждать ReadIntervalTimeout ms после приема последнего байта (ну нету другого способа узнать, что поток прекратился), и только потом ReadFile прекратит чтение. |
||||
|
|||||
TheDestroyer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Имеется ввиду буфер системы, который устанавливается SetupComm(COMport,2000,2000) ? Правильно ли я понимаю, что на пути принятой информации всего два буфера: аппаратный FIFO буфер, который можно отключить или задать размер 1-14 байт на прием и 1-16 на запись и программный, устанавливаемый SetupComm? Что будет если отключить FIFO буфер? Данные сразу будут писаться в программный буфер? Тогда для чего вообще нужен FIFO буфер, он как-то ускоряет обмен? |
|||
|
||||
xvr |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Да
Это было актуально на старых машинах, на современных машинах это может проявится только на мегабодных скоростях и 100% загрузке процессора ![]() |
||||||
|
|||||||
TheDestroyer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Спасибо большое за ответы. Поставил бы плюс, если б у меня было достаточно постов.
Похоже, данная тема форума единственное место, где можно найти ответы на почти все возникающие вопросы при написании обмена по COM порту во всем инете. Все примеры, что раскиданы по инету (по большому счету их около 3х видов) не помогли мне, как помогли здесь. |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
xvr +1 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |