Reukov 0 31 января, 2011 Опубликовано 31 января, 2011 (изменено) · Жалоба Здравствуйте все! Начал тут отлаживать обмен своей железяки путем написания консоли. обмен на скорости 600 бод пакетами до 20 байт. пауза между пакетами (запрос - ответ) не более 100 мс. Принимаю так: - в цикле пытаюсь считать по одному байту (в заголовке есть длинна пакета) - как только набрался пакет - разбираю его в (switch по заголовку) и генерю ответ. Проблема в следующем: подряд принимаются первые 7-8 байт (вместе с заголовком). потом следуют пустые запросы - нет данных на прием (около 100 мс). потом сваливается вторая половина пакета подряд. данные в шине идут без этого разрыва (смотрел осцилографом). соответстенно не успеваю ответить в положенные 100 мс. Пробовал принимать так: - в цикле принимаю по одному байту заголовок и длинну, потом пытаюсь считать данные одним блоком ReadFile, задав ожидаемое число байт в параметрах. Соответственно задаю параметры структуры COMMTIMEOUTS. При любых значених поля ReadIntervalTimeout меньше 100 (кроме 0 соответственно) ReadFile вылетает по таймауту и возвращает, что считала те же 6 байт из нужных, например 14. при значениях 0 и более 100 она таки дожидается весь пакет. Теперь вопрос: откуда такая конская задержка вылазит и как от нее избавиться?) Изменено 31 января, 2011 пользователем Reuk Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
V_G 8 31 января, 2011 Опубликовано 31 января, 2011 (изменено) · Жалоба А это вы на чем программируете? Я под винду пишу на Visual C++, там никаких таймаутов не задаю и не использую. Со стороны моих же девайсов на микроконтроллерах таймауты на прием байта делаю всегда. Если девайс обслуживается моей же прогой на стороне компьютера, таймаут на длину 2-3 байт, если предполагается работа через чужие терминальные программы, таймаут делаю около минуты. PS. Да, и для многозадачных ОС 100 мс - очень маленькое время (для задачи с невысоким приоритетом), я бы не стал так мельчить Изменено 31 января, 2011 пользователем V_G Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reukov 0 31 января, 2011 Опубликовано 31 января, 2011 (изменено) · Жалоба А это вы на чем программируете? Я под винду пишу на Visual C++, там никаких таймаутов не задаю и не использую. Со стороны моих же девайсов на микроконтроллерах таймауты на прием байта делаю всегда. Если девайс обслуживается моей же прогой на стороне компьютера, таймаут на длину 2-3 байт, если предполагается работа через чужие терминальные программы, таймаут делаю около минуты. на ней же))) Visual C++ тоже делаю таймаут на прием байта.... тут просто фига в другом получилась. я эмулирую как раз свою железяку. подключаюсь к чужой, которая ждет начало моего ответа не более 100 мс после своего запроса. я ответить не успеваю из-за описаной выше проблемы - у меня эти 100 мс проходят в ожидании приема всего сообщения, которое 100% было передано без задержек 28276 0.00000254 SUCCESS Length 1: 55 28278 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28278 0.00000244 SUCCESS Length 1: 7E 28279 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28279 0.00000214 SUCCESS Length 1: 04 28280 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28280 0.00000401 SUCCESS Length 1: CD 28281 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28281 0.00000537 SUCCESS Length 1: AB 28282 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28282 0.00000214 SUCCESS Length 1: 02 28283 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28283 0.00288607 TIMEOUT Length 0: 28284 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28284 0.00290760 TIMEOUT Length 0: 28285 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28285 0.00287964 TIMEOUT Length 0: 28286 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28286 0.00278307 TIMEOUT Length 0: 28287 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28287 0.00289570 TIMEOUT Length 0: 28288 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28288 0.00245688 TIMEOUT Length 0: 28289 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28289 0.00289105 TIMEOUT Length 0: 28290 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28290 0.00290621 TIMEOUT Length 0: 28291 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28291 0.00244370 TIMEOUT Length 0: 28292 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28292 0.00290261 TIMEOUT Length 0: 28293 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28293 0.00289803 TIMEOUT Length 0: 28294 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28294 0.00289742 TIMEOUT Length 0: 28295 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28295 0.00288969 TIMEOUT Length 0: 28296 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28296 0.00293397 TIMEOUT Length 0: 28297 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28297 0.00289170 TIMEOUT Length 0: 28298 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28298 0.00289987 TIMEOUT Length 0: 28299 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28299 0.00289501 TIMEOUT Length 0: 28300 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28300 0.00290946 TIMEOUT Length 0: 28301 0.00000000 DebugPV.exe IRP_MJ_READ Serial0 Length 1 28301 0.00088400 SUCCESS Length 1: 53 28302 0.00000000 DebugPV.exe IRP_MJ_WRITE Serial0 Length 8: FF FF 55 03 02 03 13 FF Лог со временами Красным отмечены принимаеиые байты. 6 байт подряд и седьмой внизу где-то через 60 мс. (между пустыми запросами порядка 3 мс.) в шине данные шли подряд. (1 байт примерно за 17 мс.) PS. Да, и для многозадачных ОС 100 мс - очень маленькое время (для задачи с невысоким приоритетом), я бы не стал так мельчить А как можно поднять приоритет?) что-то я не шарю... терминалка, умеющая показывать начало и конец приема, нормально кстати принимает эти же самые пакеты - без задержек Изменено 31 января, 2011 пользователем Reuk Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
V_G 8 31 января, 2011 Опубликовано 31 января, 2011 (изменено) · Жалоба Эмулировать на Винде железяку с жестким таймаутом 100 мс - последнее дело, все-таки Винда - не ОС реального времени. Попробуйте не использовать таймауты. Я для приложений с интенсивным обменом по компорту просто резервирую побольше приемный буфер, а по WaitCommEvent по приему байта уже считываю и разбираю весь буфер. И приемную часть программы организую отдельным процессом (thread) с высоким приоритетом. А уже полученные и обработанные данные пересылаю в основной процесс через PostMessage. Регулировать приоритет - через SetThreadPriority Изменено 31 января, 2011 пользователем V_G Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reukov 0 31 января, 2011 Опубликовано 31 января, 2011 · Жалоба Я для приложений с интенсивным обменом по компорту просто резервирую побольше приемный буфер, а по WaitCommEvent по приему байта. по событию EV_RXCHAR? попробую щас так и сделать) спасибо. я вот тоже тут в раздумьях - винда же вроде потоки переключает как раз с интервалом в десятки мс.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 31 января, 2011 Опубликовано 31 января, 2011 · Жалоба Похоже на последствия работы аппаратного FIFO в порту. Плюс не-реалтаймовость Win. Последнее можно частично вылечить подняв приоритет до Realtime вашему приложению и той нити в нем, которая читает данные из порта. С FIFO все гораздо сложнее, боюсь что простыми методами это не лечится :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
marti 0 2 февраля, 2011 Опубликовано 2 февраля, 2011 · Жалоба А как можно поднять приоритет?) что-то я не шарю... Организуйте отдельный поток реального времени для работы с com. Программа будет летать. Примерчик создания потока должен быть в папке си. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться