реклама на сайте
подробности

 
 
6 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Windows7: прием байтов через COM-порт без потерь, Кто-то имеет личный опыт? чем побороть потерю отдельных байтов?
Ruslan1
сообщение May 22 2017, 06:27
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025



Здравствуйте!
Есть Windows7 Pro, 32-bit, компьютер- китайский одноплатник на Intel 1037U, 4GB RAM.
СОМ-порты- 4 штуки прямо на материнке.
И есть внешний передатчик, посылающий в COM-порт пакеты.
Скорость- 115200, стандартный формат 8N1.
Длина пакета- не более 255 байт, межпакетный интервал- не менее 4 байт, часто гораздо больше (десятки миллисекунд). Каждый пакет имеет контрольную сумму (crc16), по которой и принимается решение о валидности пакета. Общая загрузка канала где-то 5-8 килобайт в секунду, то есть до 80%. Загрузка CPU около 10-15%.

И есть самописная программа на С++Билдере (6), данный вариант делался по прерываниям, с несколькими потоками (базой был вот этот документ).
Есть поток, принимающий все байты по прерываниям и валящий в большой кольцевой буфер. И другой поток периодически выгребает байты из буфера и делит на пакеты для обработки, проверяет валидность.

Только прием, никаких переключений на передачу.
В результате приемник иногда пропускает байты. То есть все принятые байты всегда совпадают с переданными, но некоторые байты пропущены. Всегда пропущено не более одного байта за раз, в любом месте пакета. Часто бывает что пропущено по одному байту в двух следующих друг за другом пакетах.

Обычно фактов потери байта где-то 10-20 в сутки. Корреляция с действиями Виндоуса пока не найдена, очень уж все случайно.
Потери именно в компьютере- подключенный прямо к этому же разъему логический анализатор исправно ловит все байты, никакого криминала или отклонений во времянке не обнаружено (по уровню тоже все без проблем)


Вопросов два:
1. Кто-то в подобных условиях добивался абсолютно безошибочного приема потока через COM-порт в Виндоус (7) на 115200?
2. куда копать? Сильно надеюсь что моя программа виновата. На другом железе пробовал- эффект тот же, то есть это не электроника глючит.
С приоритетами игрался, никакого эффекта.

Заранее спасибо за любые советы (по существу).
Go to the top of the page
 
+Quote Post
AlexRayne
сообщение May 22 2017, 08:15
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Цитата(Ruslan1 @ May 22 2017, 10:27) *
Есть поток, принимающий все байты по прерываниям и валящий в большой кольцевой буфер. И другой поток периодически выгребает байты из буфера и делит на пакеты для обработки, проверяет валидность.

Вот это место непонятно - для каждого порта свой буфер, или общий на все порты? выпадание байта определяете по сбою crc?

Что Вы называете "приемом по прерыванию"?
У выни свои прекрасные дрова для КОМ, и даже целый специальный апи в ядро встроен под устройства Comm - модемы проще. все известные мне либы в борланде являются прокладкой к этому стандартному АПИ. напрямую с прерыванием никто не работает.
проблем с потерями не было, хотя обмен бывал интенсивный - мегабод.
можно посоветовать покрутить :
1)объем буфферов кома (я делал 8кб)
2)приоритет нитки приемника сделать выше нормального
3)если у вас между пакетами есть пауза более 1мс, настроить ее в свойствах таймингов кома. в запросах асинхронного чтения возможно оно поможет АПИ возвращать целиком пакет а не куски случайно презанные.
4)какая может быть гарантия что порт вашего ПК видит ваш поток без потерь, даже если ваш снифер прекрасен? Вы в качестве снифера тот же самый ПК используете?
5) можно поставить прокси с журналированием на ком (я пользовал com0project, но их вроде множество разных), и уже к нему подключать вашу программу. в этом случае вы сможете сравнить поток принятый прокси с потоком принятым вашей софтиной.
6) вы журналировали поток считанный из порта, сравнить его с финальными нарезанными пакетами? точно эти байты не считываются из порта?

Сообщение отредактировал AlexRayne - May 22 2017, 08:22
Go to the top of the page
 
+Quote Post
neiver
сообщение May 22 2017, 08:25
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Начинать надо с того, что COM порт вообще и его реализация в Windows в частности, не гарантирует безошибочной передачи данных.
То есть рассчитывать на это нельзя, и контроль и/или обеспечение целостности данных надо реализовывать в протоколе обмена. Поврежненный пакед должен отбрасываться и если нужно передаваться повторно.
По возможным причинам. У стандартного аппаратного СОМ порта есть внутренний буфер, как правило размером 15 байт. Это не тот буфер, который задается в SetupComm. Если драйвер порта по каким-то причинам не успеет прочитать этот буфер, то принятые байты теряются, о чем извещают соответствующие флаги возвращаемые ClearCommError.
Приоритет пользовательского процесса не влиет на приоритет драйвера СОМ порта при обработке прерываний.
Go to the top of the page
 
+Quote Post
AlexRayne
сообщение May 22 2017, 08:37
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Цитата(neiver @ May 22 2017, 12:25) *
Начинать надо с того, что COM порт вообще и его реализация в Windows в частности, не гарантирует безошибочной передачи данных.
То есть рассчитывать на это нельзя, и контроль и/или обеспечение целостности данных надо реализовывать в протоколе обмена. Поврежненный пакед должен отбрасываться и если нужно передаваться повторно.

Парень сборется с другой проблемой - у него не пропадание сигнала на линии (этим он займется видимо позже, когда жареный петух клюнет), а пропадание байтов прямо на порте. можно это списать на особенности железа, но вероятность невелика
Go to the top of the page
 
+Quote Post
Ruslan1
сообщение May 22 2017, 12:23
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025



AlexRayne, большое спасибо за конструктивный ответ с кучей хороших идей!
Что именно Вы имеете в виде когда говорите про "прекрасные дрова для КОМ, и даже целый специальный апи в ядро встроен под устройства Comm"? Что именно советуете почитать-посмотреть, может даже применительно к простоте прикручивания в Билдер?
Я раньше работал по поллингу, и задачи другие были. А сейчас решил по прерываниям сделать, нашел понятное мне описание в интернете(ссылка в моем письме)- по нему и сделал.

Если уже есть компонент а или просто апишная функция "брать все байты из порта и кидать в большой пользовательский кольцевой буфер" - было бы замечательно. В пятом Билдере ставил пакет TurboPower Async Professional, но использовал по поллингу. Сейчас на новый (хихи) 6-й билдер перешел и думал без сторонних компонентов обойтись.

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

Очень хочется для начала локализовать проблему, и Ваши советы мне отлично подходят- не подумал про независимый сниффер-программу прямо на этой машине. Очень надеюсь что проблема в моем коде- тогда есть большая вероятность ее решения sm.gif
Go to the top of the page
 
+Quote Post
Lagman
сообщение May 22 2017, 12:59
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(AlexRayne @ May 22 2017, 11:15) *
Что Вы называете "приемом по прерыванию"?
У выни свои прекрасные дрова для КОМ, и даже целый специальный апи в ядро встроен под устройства Comm - модемы проще. все известные мне либы в борланде являются прокладкой к этому стандартному АПИ. напрямую с прерыванием никто не работает.

Нда, последнее сообщение автора прояснило что прерывание это не то прерывание о котором все подумали, а прерывание есть прерывание потока, по крайней мере так описано по ссылке sm.gif
Go to the top of the page
 
+Quote Post
sonycman
сообщение May 22 2017, 13:48
Сообщение #7


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(neiver @ May 22 2017, 12:25) *
Начинать надо с того, что COM порт вообще и его реализация в Windows в частности, не гарантирует безошибочной передачи данных.
То есть рассчитывать на это нельзя, и контроль и/или обеспечение целостности данных надо реализовывать в протоколе обмена. Поврежненный пакед должен отбрасываться и если нужно передаваться повторно.
По возможным причинам. У стандартного аппаратного СОМ порта есть внутренний буфер, как правило размером 15 байт. Это не тот буфер, который задается в SetupComm. Если драйвер порта по каким-то причинам не успеет прочитать этот буфер, то принятые байты теряются, о чем извещают соответствующие флаги возвращаемые ClearCommError.
Приоритет пользовательского процесса не влиет на приоритет драйвера СОМ порта при обработке прерываний.

Тоже думаю, что проблема просто в переполнении ФИФО аппаратного приёмника.
Потому, что винда тупо не успевает выгребать данные.

Но тогда надо проверить, флаг переполнения должен быть установлен.

Может, стоит попробовать адаптер COM->USB, там аппаратная буферизация может быть лучше, и ошибок не будет?
Go to the top of the page
 
+Quote Post
rx3apf
сообщение May 22 2017, 15:55
Сообщение #8


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



1. Дурацкий вопрос - а порты вообще с FIFO ? И оно включено ?

2. Как вариант, запустить какую-нибудь терминалку, залоггировать, а потом посмотреть - потери есть ?
Go to the top of the page
 
+Quote Post
Raven
сообщение May 22 2017, 16:10
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 491
Регистрация: 16-01-05
Из: Санкт-Петербург
Пользователь №: 1 987



Если Wind'а иногда не успевает выгребать данные из аппаратного буфера, может стоит подумать в сторону аппаратного управления потоком (RTS/CTS)?
Go to the top of the page
 
+Quote Post
DS
сообщение May 22 2017, 19:49
Сообщение #10


Гуру
******

Группа: СуперМодераторы
Сообщений: 3 096
Регистрация: 16-01-06
Из: Москва
Пользователь №: 13 250



В 7 похоже, есть баг в COM драйвере. Многие программы, нормально работавшие с XP, глючат с ком-портами на 7. Единственное, что надежно под ней работает -USB-COM адаптер, причем с FTDI чипом.


--------------------
Не бойтесь тюрьмы, не бойтесь сумы, не бойтесь мора и глада, а бойтесь единственно только того, кто скажет - "Я знаю как надо". А. Галич.
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 23 2017, 05:09
Сообщение #11


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Я пересылал в комп пакеты данных на скорости 115200, сбоев не замечал. Формат был 8N2. Вот его и посоветую попробовать.
Go to the top of the page
 
+Quote Post
V_G
сообщение May 23 2017, 05:39
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(ViKo @ May 23 2017, 15:09) *
Я пересылал в комп пакеты данных на скорости 115200, сбоев не замечал. Формат был 8N2. Вот его и посоветую попробовать.

Да я тоже много чего пересылал, и на 480 кБод, и без сбоев. Насколько я понял, особенность проблем ТС в том, что данные идут постоянно, что в моей практике не встречается.
Хотя я Билдер не пользую, пишу в MSVC++ с отдельным потоком на прием и WaitCommEvent в том потоке с ивентом по каждому пришедшему байту...
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 23 2017, 07:09
Сообщение #13


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Возможно, фантазирую, детально не вникал, полагаю, если стопов 2 или 1,5 то синхронизироваться по следующему старту можно точнее. Будет больше запаса на неравенство тактовых частот. А также увеличивается время для работы процессора.
Go to the top of the page
 
+Quote Post
AlexRayne
сообщение May 23 2017, 09:20
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Цитата(Ruslan1 @ May 22 2017, 16:23) *
AlexRayne, большое спасибо за конструктивный ответ с кучей хороших идей!
Что именно Вы имеете в виде когда говорите про "прекрасные дрова для КОМ, и даже целый специальный апи в ядро встроен под устройства Comm"? Что именно советуете почитать-посмотреть, может даже применительно к простоте прикручивания в Билдер?

Вот это именно и имел ввиду - что вы путаете всех использованием слова "драйвер". В венде уже написаны дрова под множество материнок и уж тем более под известные стандартные контроллеры УАРТ. Вот они как раз напрямую с железом и прерыванием работают. писать их не требуется - они готовы и встроены в Ось. Овь прелагает довольно простое стандартное АПИ для работы с Сомм портами. Если вы поставили борланд - покурите их хелпы Win32 SDK или чтото вроде этого. Это огромный хелп по всем ресурсам венды. и в частности там описан и Comm интерфейс. Если вы полезете в изходники АсинкПро - то наглядно увидите как вендовые вызовы используются. АсинкПро - это обертка вендовых вызовов.
Когда я говорю "прекрасные" - значит они есть работают, отлажены, и проверены. (и удобны)

Цитата(Ruslan1 @ May 22 2017, 16:23) *
AlexRayne, большое спасибо за конструктивный ответ с кучей хороших идей!

Если уже есть компонент а или просто апишная функция "брать все байты из порта и кидать в большой пользовательский кольцевой буфер" - было бы замечательно. В пятом Билдере ставил пакет TurboPower Async Professional, но использовал по поллингу. Сейчас на новый (хихи) 6-й билдер перешел и думал без сторонних компонентов обойтись.

Большой буфер уже предоставляет Сомм интерфейс, размер его можно настраивать, по моей памяти он по умолчанию 4кБ делается. собственно из него и читается данные порта обычными файловыми чтениями.
По моему опыту - оказалось проще работать без оболочек, напрямую. это не требует стороннего кода и возни со сторонними пакетами.
требует освоения навыка работы с асинхронными вызовами венды чтения\записи файла - там их называют почемуто overlaped

Цитата(Ruslan1 @ May 22 2017, 16:23) *
AlexRayne, большое спасибо за конструктивный ответ с кучей хороших идей!
И это не железо, я пробовал на другом компьютере- эффект тоже имеет место быть.
И это действительно потеря в машине- прямо на порт включал независимый лог анализатор, и после сравнивал содержимое буферов его и моей программы.

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

Вам уже посоветовали использовать 1,5-2 стопбита. это хорошее предложение, если оно конечно возможно для ваших абонентов.

С адаптерами КОМ-УСБ советую не играться если есть нормальный порт на матери или PCI плате ввода вывода. Я встретил кривой адаптер от МОХи, народ жаловался на ФТДИ - у обоих проблемы с буфером приемника на больших трафиках.
Go to the top of the page
 
+Quote Post
V_G
сообщение May 23 2017, 09:30
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Кстати, о больших трафиках. Так ли они необходимы?
Очень много встречал профессиональных программистов, которые для своего личного удобства используют большие скорости и постоянно кидают в порт повторяющиеся данные (типа проверки связи и информации "я живой"). Причем в ситуациях, когда достаточно скорости 9600 и работы по принципу "запрос-ответ". А потом еще переносят эти принципы на радиоканал и забивают все вокруг.
Может, все-таки сначала подумать о минимизации трафика?
Go to the top of the page
 
+Quote Post

6 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 12th July 2025 - 19:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01487 секунд с 7
ELECTRONIX ©2004-2016