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

 
 
9 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> сниффер ком порта
Alex_2015
сообщение Sep 6 2016, 13:56
Сообщение #1





Группа: Участник
Сообщений: 14
Регистрация: 8-08-15
Пользователь №: 87 893



Всем доброго дня. Есть сеть устройств, работающих по протоколу модбас через RS485. Необходимо написать перехватчик сообщений для ком порта, способный ловить паузы между сообщениями.
Вот как поймать паузы, пока не соображу. Драйвер возвращает пачки по несколько байт, но поймать получается только длинные паузы (между запросами), а вот разделить запрос-ответ пока не могу.
Есть программы снифферы, которые как-то реализуют такую возможность. Надо написать свою, в которой данные преобразовать в удобоваримый вид, удобный для отладки работы сети устройств.
В винде это наверное тяжело будет сделать, но может есть способ, о котором я пока не знаю.
Go to the top of the page
 
+Quote Post
bolden
сообщение Sep 6 2016, 14:07
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 100
Регистрация: 26-12-10
Из: Санкт-Петербург
Пользователь №: 61 884



Добрый день,
если вы ловите запрос+ответ и если не принципиально ловить паузы между ними, то разделить запрос и ответ, как мне кажется, можно "расшифровкой" протокола, если конечно данные приняты без ошибок.
При этом методе если запрос принят с ошибкой, то не сможем определить его длину, как следствие не "расшифруем" и ответ.
Go to the top of the page
 
+Quote Post
dm37
сообщение Sep 6 2016, 14:24
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 14-08-16
Пользователь №: 92 949



Можно принимать байты по одному с таймаутом, т.е. таймаут только на приём одного байта. Пока синхронизация приёма пакетов не нарушилась работаем только с crc, если нарушилась, то устанавливаем таймаут равный времени приёма одного байта + небольшой запас (не помню интервал тишины в modbus, вроде три байта). Если передача идёт по стандарту modbus, то таймаут на два-три байта тишины должен помочь
Go to the top of the page
 
+Quote Post
Alex_2015
сообщение Sep 6 2016, 14:39
Сообщение #4





Группа: Участник
Сообщений: 14
Регистрация: 8-08-15
Пользователь №: 87 893



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

Эксперименты с таймаутом особо не помогают. При скорости 115200 время передачи байта составляет 95мкс, а таймауты устанавливаются в миллисекундах.
Основную проблему я вижу в том, что драйвер подбирает у системы данные с некоторым периодом. Программа у драйвера запрашивает данные тоже с каким-то периодом. За это время фактически драйвер может взять у системы несколько байт. Причём может схватить хвост запроса и начало ответа.
Отсюда и лезут проблемы.
Go to the top of the page
 
+Quote Post
dm37
сообщение Sep 6 2016, 15:06
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 14-08-16
Пользователь №: 92 949



т.е. вы подключаетесь к какой либо паре устройств работающих по modbus (запросы отправляете не вы) и задача стоит разобрать протокол (синхронизироваться)?
если да, то можно со сдвигом принятых данных считать crc и где crc верна, там и есть начало пакета. Определить "запрос" или "ответ" можно уже по протоколу.
Go to the top of the page
 
+Quote Post
DASM
сообщение Sep 6 2016, 15:56
Сообщение #6


Гуру
******

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



честно говоря я бы такую задачу решал иначе. А именно - сниффер пишется на МК, и отдает пакеты в комп приплюсовывая к ним time stamp
Go to the top of the page
 
+Quote Post
_3m
сообщение Sep 6 2016, 18:08
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 745
Регистрация: 28-12-06
Пользователь №: 23 960



Цитата(Alex_2015 @ Sep 6 2016, 17:39) *
Основную проблему я вижу в том, что драйвер подбирает у системы данные с некоторым периодом. Программа у драйвера запрашивает данные тоже с каким-то периодом. За это время фактически драйвер может взять у системы несколько байт. Причём может схватить хвост запроса и начало ответа.
Отсюда и лезут проблемы.

Вы все правильно понимаете.
Вывод из этого простой : стандартные ОС со стандартными компортами (обычно 16550-compatible) ловить таймауты modbus-rtu неспособны. Ставьте конвертор на МК.
Go to the top of the page
 
+Quote Post
Lagman
сообщение Sep 6 2016, 20:35
Сообщение #8


Знающий
****

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



Очень давно, чем то подобным занимался (отлавливал пакет modbus который завешивал устройство), сейчас для измерения времянок воспользовался бы каким нибудь цифровым логическим анализатором (например недорогим китайским), а тогда использовал программу COM Port Toolkit (раньше была бесплатной для русcкоговорящих), в ней даже штамп времени есть (вроде как миллисекунды, но с какой точность не знаю). Т.к. по стандарту modbus рекомендуют на скоростях более 19200 делать T3.5 = 1,750мс то возможно программа поймает начало ответа и отправку нового запроса.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Sep 7 2016, 06:47
Сообщение #9


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

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Если пишете сами, попробуйте использовать таймауты драйвера
см. тут
Писать надо на достаточно низком, в хорошем смысле, уровне. С, CPP PAS, с событиями-потоками.
Win32API, ReadFileEx() etc.
Для модбаса надо отлавливать паузы 3.5 байта.

Go to the top of the page
 
+Quote Post
megajohn
сообщение Sep 7 2016, 08:36
Сообщение #10


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

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



Цитата(Alex_2015 @ Sep 6 2016, 17:56) *
Всем доброго дня. Есть сеть устройств, работающих по протоколу модбас через RS485.
...
Надо написать свою, в которой данные преобразовать в удобоваримый вид, удобный для отладки работы сети устройств.

как вариант, соберите данные любым готовым сниффером и скормите этой программе
mb_dump_parser

если результат устроит и вам нужно в реалтайме, то тогда вердикт "ЭТО ВОЗМОЖНО и без таймаутов, пишите софт"


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
Alex_2015
сообщение Sep 7 2016, 12:42
Сообщение #11





Группа: Участник
Сообщений: 14
Регистрация: 8-08-15
Пользователь №: 87 893



На тему конвертора мысли были. Но только на самый крайний случай.
Сейчас пока используется модифицированный модбас, в котором есть признаки, позволяющие однозначно определять начало и конец посылок.
Есть потребность перейти к стандартному модбасу и будет нужна прога, которая позволит в реальном времени отслеживать обмен между устройствами в целях отладки.
Сегодня перечитывал старую информацию, которую использовал при освоении программирования ком порта и нашёл то, что пропустил. Есть в структуре DCB символ XOFCHAR, который позволяет определить конец посылки. Осталось непонятным, его записывает драйвер в массив приёма или этот символ должен быть записан передатчиком в конец сообщения.
Интернет по этому поводу подробностей пока не дал. Буду пробовать экспериментально.
Была ещё мысль отслеживать событие DCD data carrier detect, но боюсь оно ожидаемого результата не даст.
Была мысль алгоритмически ловить конец посылки через подсчёт CRC, но вариант не самый красивый. Хотя должен привести к результату.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 7 2016, 18:22
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(DASM @ Sep 6 2016, 21:56) *
честно говоря я бы такую задачу решал иначе. А именно - сниффер пишется на МК, и отдает пакеты в комп приплюсовывая к ним time stamp

Я бы тоже решал по-другому. А именно: с открытия MSDN и прочтения всего, что касается работы с COM-портом. Чего автор как видно не сделал.
Иначе он знал бы о функции SetCommTimeouts() WinAPI и многих других полезных. А не строил пустые предположения.
Далее: установил-бы ReadIntervalTimeout and ReadTotalTimeoutMultiplier to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than zero and less than MAXDWORD
как советует MSDN, повысил приоритет принимающего потока, а также прочитал в MSDN про семейство функций QueryPerformanceFrequency()/QueryPerformanceCounter() и понял бы, что даже 95мкс - не есть проблема.
Другое дело что всё это лучше делать на железном RS-232 компа, а не USB-COM переходнике, времянки которого сомнительны.

Даже и с железным COM-портом и приоритетом потока ==REALTIME возможно будут проблемы из-за работы других драйверов винды (винта, видео и т.п.). Так что возможно лучше вынести такую работу на уровень драйверов.

Цитата(Alex_2015 @ Sep 7 2016, 18:42) *
Есть в структуре DCB символ XOFCHAR, который позволяет определить конец посылки.

Это вообще из другой оперы. Это для software flowcontrol.

Цитата(Alex_2015 @ Sep 7 2016, 18:42) *
Была мысль алгоритмически ловить конец посылки через подсчёт CRC, но вариант не самый красивый. Хотя должен привести к результату.

Лучше откройте наконец-то MSDN, а не занимайтесь ерундой.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 7 2016, 21:06
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (jcxz @ Sep 7 2016, 21:22) *
QueryPerformanceFrequency()/QueryPerformanceCounter() и понял бы, что даже 95мкс - не есть проблема.

К чему опрос счетчиков хоть с тактовой процессора, если их НЕЛЬЗЯ со сколь-нибудь детерминированной точностью привязать к событиям UART.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Alex_2015
сообщение Sep 8 2016, 01:23
Сообщение #14





Группа: Участник
Сообщений: 14
Регистрация: 8-08-15
Пользователь №: 87 893



Читал я MSDN в своё время, когда осваивал программирование ком порта. Но это ни чего не даёт. Когда драйвер захочет вернуть данные пользовательской программе, тогда и вернёт. И совсем не в режиме реального времени.
А с таймоутами я экспериментировал, результат далёк от желаемого.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 8 2016, 03:53
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(zltigo @ Sep 8 2016, 03:06) *
К чему опрос счетчиков хоть с тактовой процессора, если их НЕЛЬЗЯ со сколь-нибудь детерминированной точностью привязать к событиям UART.

ТСу нужно не опрашивать счётчики, а вести лог обмена по каналу UART. Причём с таймштампами точностью до десятков мкс. Ну или хотя-бы видеть, что между двумя соседними байтами X1 и X2 была хоть какая-то пауза, обнаруженная драйвером канала или её не было. Аппаратура UART 16550 позволяет определять наличие паузы, значит и драйвер это должен видеть. А функция SetCommTimeouts(), как следует из её описания, должна позволить получить эту инфу юзеру.

Цитата(Alex_2015 @ Sep 8 2016, 07:23) *
Читал я MSDN в своё время, когда осваивал программирование ком порта. Но это ни чего не даёт. Когда драйвер захочет вернуть данные пользовательской программе, тогда и вернёт. И совсем не в режиме реального времени.

Т.е. - Вы утверждаете что MSDN врёт, говоря, что:
Код
If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than zero and less than MAXDWORD, one of the following occurs when the ReadFile function is called:
If there are any bytes in the input buffer, ReadFile returns immediately with the bytes in the buffer.
If there are no bytes in the input buffer, ReadFile waits until a byte arrives and then returns immediately.

Читаем первую строку с "if" и вторую, видим там слово "immediately", думаем.
Я почти уверен, что если приоритет вызывающего потока будет ==THREAD_PRIORITY_TIME_CRITICAL, а приоритет процесса ==REALTIME_PRIORITY_CLASS, то как только аппаратура UART зафиксирует, что в FIFO есть символы и с момента приёма последнего из них прошло более 3.5 символьных интервала, так сразу и вернёт управление вызывающему потоку.
Возможно даже хватит меньших приоритетов у процесса/потока, главное - превысить приоритеты всех других работающих в системе потоков.
И всё конечно зависит ещё от драйвера. Стандартный виндовый драйвер для UART 16550 на сис. шине должен соответствовать требованиям MSDN. Про сторонние драйвера UART, тем более для USB-UART речи нет - они могут только примерно соответствовать MSDN. Но думаю, если устройство, реализующее CDC-класс USB, при отправке данных, выделяет разные кадры ModBus в отдельные пакеты по USB, то и драйвер CDC-класса под виндой также сможет выполнить требования SetCommTimeouts().
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th April 2024 - 21:32
Рейтинг@Mail.ru


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