Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: сниффер ком порта
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Программирование
Страницы: 1, 2, 3
Alex_2015
Всем доброго дня. Есть сеть устройств, работающих по протоколу модбас через RS485. Необходимо написать перехватчик сообщений для ком порта, способный ловить паузы между сообщениями.
Вот как поймать паузы, пока не соображу. Драйвер возвращает пачки по несколько байт, но поймать получается только длинные паузы (между запросами), а вот разделить запрос-ответ пока не могу.
Есть программы снифферы, которые как-то реализуют такую возможность. Надо написать свою, в которой данные преобразовать в удобоваримый вид, удобный для отладки работы сети устройств.
В винде это наверное тяжело будет сделать, но может есть способ, о котором я пока не знаю.
bolden
Добрый день,
если вы ловите запрос+ответ и если не принципиально ловить паузы между ними, то разделить запрос и ответ, как мне кажется, можно "расшифровкой" протокола, если конечно данные приняты без ошибок.
При этом методе если запрос принят с ошибкой, то не сможем определить его длину, как следствие не "расшифруем" и ответ.
dm37
Можно принимать байты по одному с таймаутом, т.е. таймаут только на приём одного байта. Пока синхронизация приёма пакетов не нарушилась работаем только с crc, если нарушилась, то устанавливаем таймаут равный времени приёма одного байта + небольшой запас (не помню интервал тишины в modbus, вроде три байта). Если передача идёт по стандарту modbus, то таймаут на два-три байта тишины должен помочь
Alex_2015
Такой вариант я рассматривал, но здесь ключевая фраза, если принята без ошибок. Самый надёжный способ - именно ловить паузы.

Эксперименты с таймаутом особо не помогают. При скорости 115200 время передачи байта составляет 95мкс, а таймауты устанавливаются в миллисекундах.
Основную проблему я вижу в том, что драйвер подбирает у системы данные с некоторым периодом. Программа у драйвера запрашивает данные тоже с каким-то периодом. За это время фактически драйвер может взять у системы несколько байт. Причём может схватить хвост запроса и начало ответа.
Отсюда и лезут проблемы.
dm37
т.е. вы подключаетесь к какой либо паре устройств работающих по modbus (запросы отправляете не вы) и задача стоит разобрать протокол (синхронизироваться)?
если да, то можно со сдвигом принятых данных считать crc и где crc верна, там и есть начало пакета. Определить "запрос" или "ответ" можно уже по протоколу.
DASM
честно говоря я бы такую задачу решал иначе. А именно - сниффер пишется на МК, и отдает пакеты в комп приплюсовывая к ним time stamp
_3m
Цитата(Alex_2015 @ Sep 6 2016, 17:39) *
Основную проблему я вижу в том, что драйвер подбирает у системы данные с некоторым периодом. Программа у драйвера запрашивает данные тоже с каким-то периодом. За это время фактически драйвер может взять у системы несколько байт. Причём может схватить хвост запроса и начало ответа.
Отсюда и лезут проблемы.

Вы все правильно понимаете.
Вывод из этого простой : стандартные ОС со стандартными компортами (обычно 16550-compatible) ловить таймауты modbus-rtu неспособны. Ставьте конвертор на МК.
Lagman
Очень давно, чем то подобным занимался (отлавливал пакет modbus который завешивал устройство), сейчас для измерения времянок воспользовался бы каким нибудь цифровым логическим анализатором (например недорогим китайским), а тогда использовал программу COM Port Toolkit (раньше была бесплатной для русcкоговорящих), в ней даже штамп времени есть (вроде как миллисекунды, но с какой точность не знаю). Т.к. по стандарту modbus рекомендуют на скоростях более 19200 делать T3.5 = 1,750мс то возможно программа поймает начало ответа и отправку нового запроса.
k155la3
Если пишете сами, попробуйте использовать таймауты драйвера
см. тут
Писать надо на достаточно низком, в хорошем смысле, уровне. С, CPP PAS, с событиями-потоками.
Win32API, ReadFileEx() etc.
Для модбаса надо отлавливать паузы 3.5 байта.

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

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

если результат устроит и вам нужно в реалтайме, то тогда вердикт "ЭТО ВОЗМОЖНО и без таймаутов, пишите софт"
Alex_2015
На тему конвертора мысли были. Но только на самый крайний случай.
Сейчас пока используется модифицированный модбас, в котором есть признаки, позволяющие однозначно определять начало и конец посылок.
Есть потребность перейти к стандартному модбасу и будет нужна прога, которая позволит в реальном времени отслеживать обмен между устройствами в целях отладки.
Сегодня перечитывал старую информацию, которую использовал при освоении программирования ком порта и нашёл то, что пропустил. Есть в структуре DCB символ XOFCHAR, который позволяет определить конец посылки. Осталось непонятным, его записывает драйвер в массив приёма или этот символ должен быть записан передатчиком в конец сообщения.
Интернет по этому поводу подробностей пока не дал. Буду пробовать экспериментально.
Была ещё мысль отслеживать событие DCD data carrier detect, но боюсь оно ожидаемого результата не даст.
Была мысль алгоритмически ловить конец посылки через подсчёт CRC, но вариант не самый красивый. Хотя должен привести к результату.
jcxz
Цитата(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, а не занимайтесь ерундой.
zltigo
QUOTE (jcxz @ Sep 7 2016, 21:22) *
QueryPerformanceFrequency()/QueryPerformanceCounter() и понял бы, что даже 95мкс - не есть проблема.

К чему опрос счетчиков хоть с тактовой процессора, если их НЕЛЬЗЯ со сколь-нибудь детерминированной точностью привязать к событиям UART.
Alex_2015
Читал я MSDN в своё время, когда осваивал программирование ком порта. Но это ни чего не даёт. Когда драйвер захочет вернуть данные пользовательской программе, тогда и вернёт. И совсем не в режиме реального времени.
А с таймоутами я экспериментировал, результат далёк от желаемого.
jcxz
Цитата(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().
k155la3
Если не требуется переносимость-универсальгность, а также работа на физ. RS232 из серии 16550.
Можно попробовать "накрутить" FT2232, например, используя ихнюю (FTDI) библиотеку, позвляющую
работать напрямую, и с расширенным сервисом-API к функциям.
Но надо как следует прокурить даташиты и док на API
ps - оно еще и неплохо увязывается с RS485.
Alex_2015
Я не утверждаю, что MSDN врёт. Просто констатирую факты.
Возможно ошибка есть более глубоко в моём коде и я её пока не вижу. Поэтому пытаюсь освежить информацию по работе с портом, возможно пока та самая ошибка не проявлялась за несколько лет работы проги.
zltigo
QUOTE (jcxz @ Sep 8 2016, 06:53) *
ТСу нужно не опрашивать счётчики, а вести лог обмена по каналу UART. Причём с таймштампами точностью до десятков мкс.

Повторю еще раз - нет никакого смысла в "таймштампами точностью до десятков мкс", если само событие фиксируемое уже "драйвером" совершенно произвольгую задержку и сами события начинают склеиваться в одно уже на уровне FIFO UART.
QUOTE
Аппаратура UART 16550 позволяет определять наличие паузы...

Нет. Только выдает прерывании при заполнении FIFO и при межбайтовой паузе более 4x символов. При этом прием последующих символов продолжается в то же FIFO.
QUOTE
видим там слово "immediately", думаем.

Когда придумаете, где это "immediately" отнормированно в микросекундах и куда денутся байты пришедшие после 3,5 символьного интервала, причем UART будет еще тянуть собственый 4x символьный таймаут до того, как сгенерит прерывание, обязательно сообщите sm.gif.



QUOTE (k155la3 @ Sep 8 2016, 09:00) *
ps - оно еще и неплохо увязывается с RS485.

Ослинные уши пакетного а НЕ БАЙТОВОГО интерфейса USB будут торчать по любому.
DASM
Цитата(jcxz @ Sep 7 2016, 21:22) *
Я бы тоже решал по-другому. А именно: с открытия 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 возможно будут проблемы из-за работы других драйверов винды (винта, видео и т.п.). Так что возможно лучше вынести такую работу на уровень драйверов.


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


Лучше откройте наконец-то MSDN, а не занимайтесь ерундой.

MSDN в именно в этой части читал лет 15 назад. Неифга оно так не работает (еще на тех -то компах, когда COM порт не был чудом). zltigo прав абсолютно. Точно вспоминать что именно не работает уже не смогу, помню что нужен был именно Modbus RTU и помню что эта возня с таймаутами в винде достала так, что ушел на SLIP протокол, благо не был ограничен
jcxz
Цитата(zltigo @ Sep 8 2016, 12:28) *
Повторю еще раз - нет никакого смысла в "таймштампами точностью до десятков мкс", если само событие фиксируемое уже "драйвером" совершенно произвольгую задержку и сами события начинают склеиваться в одно уже на уровне FIFO UART.

Именно на уровне FIFO эти события никак не склеиваются. От UART есть прерывание заполнения всего FIFO и есть прерывание таймаута. Этих двух прерываний абсолютно достаточно для определения - была дырка между байтами или нет. И для ModBus эти таймштампы не нужны, но нужен факт наличия дырки.
Такой алгоритм работы UART есть во многих контроллерах, например LPC17xx. И он позволяет легко разделять кадры по дыркам между ними. И этот алгоритм - наследство от железного 16550.
Виндовый драйвер после чтения FIFO конечно может склеить, но как-бы описание SetCommTimeouts() говорит об обратном.

Цитата(zltigo @ Sep 8 2016, 12:28) *
Нет. Только выдает прерывании при заполнении FIFO и при межбайтовой паузе более 4x символов. При этом прием последующих символов продолжается в то же FIFO.

А это не одно и то же? Прерывание по таймауту пришло - считали содержимое FIFO, запомнили что после этого содержимого была пауза. Всё.
Или Вы думаете, что вход в ISR может настолько запоздать, что придёт новый символ после 3.5-символьной паузы?

Цитата(zltigo @ Sep 8 2016, 12:28) *
Когда придумаете, где это "immediately" отнормированно в микросекундах и куда денутся байты пришедшие после 3,5 символьного интервала, причем UART будет еще тянуть собственый 4x символьный таймаут до того, как сгенерит прерывание, обязательно сообщите sm.gif.

Какие 3.5 + 4 интервала?? Принят очередной байт - запускается счётчик таймаута - он отсчитывает 3.5 символьных интервала - генерится прерывание - ISR считывает содержимое UART, пишет в программный FIFO и пишет туда же признак наличия дырки.
А ещё можно в свойствах COM-порта выключить FIFO. Вот тогда будет: пришёл байт, сразу прерывание, ISR кладёт символ в программное FIFO и задача, вызвавшая ReadFile() и ждущая появления данных, тут же переходит из состояния wait в состояние run и получает управление от шедулера и выгребает данные из этого программного FIFO. Вот тогда след. символ точно успеет прийти до входа в ISR. И у драйвера есть все возможности выполнить обязательство "immediately".

Цитата(DASM @ Sep 8 2016, 14:14) *
MSDN в именно в этой части читал лет 15 назад. Неифга оно так не работает (еще на тех -то компах, когда COM порт не был чудом).

Возможно конечно, что есть ошибки в дровах винды. Но принципиальной невозможности организовать со стороны драйвера обнаружение этих дырок я не вижу. И проверять надо под современной виндой.
zltigo
QUOTE (jcxz @ Sep 8 2016, 12:10) *
Именно на уровне FIFO эти события никак не склеиваются. От UART есть прерывание заполнения всего FIFO и есть прерывание таймаута. Этих двух прерываний абсолютно достаточно для определения - была дырка между байтами или нет.

Разумеется нет.
1) таймаут отрабатывает на 4 символа паузу и приход следующего MODBUS фрейма приведет с склеиванию фреймов.
2) Если драйвера и система не успеет отработать прерывание до прихода следующего фрейма, то они опять склеятся или FIFO или уже в буферах драйвера.
3) Прерывания по таймауту и по заполнению FIFO не отличаются, так что приход прерывания, как такового не означает конца фрейма.
QUOTE
И для ModBus эти таймштампы не нужны,

О чем я Вам уже и писал.
QUOTE
но нужен факт наличия дырки.

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

Какой "такой"? В том же помянутом всуе LPC17XX есть еще навороты, типа CTI и самое главное, есть в отличие от WIN, жесткое реальное время и кучка аппаратных таймеров для организации поддержки таймаутов, как собственно UART, так и протоколов типа того же MODBUS-RTU (да гореть его недоучкам авторам в аду). Так что для микроконтролера, даже с минималистичным 55, проблем в реализации кривейшего MODBUS нет.
QUOTE
Виндовый драйвер после чтения FIFO конечно может склеить, но как-бы описание SetCommTimeouts() говорит об обратном.

Поворю, что для начала склеит уже аппаратное FIFO UART ну и "описание" ни о чем не говорит, кроме того, что не будет ДОБАВЛЯТЬ никаких ДОПОЛНИТЕЛЬНЫХ таймаутов к тем, которые так или иначе получатся в системе, которая НИКАК НЕ поддерживает реальное время.
QUOTE
А это не одно и то же? Прерывание по таймауту пришло - считали содержимое FIFO, запомнили что после этого содержимого была пауза. Всё.

Перечитайте неписанное выше.
QUOTE
Или Вы думаете, что вход в ISR может настолько запоздать, что придёт новый символ после 3.5-символьной паузы?

Третий раз - сам таймаут FIFO уже 4 символа. Дальше обслуживание прерывания еще может запоздать и еще как, тем более, что тут НЕ микроконтроллерр и Вы висите НЕ на прерывании. На прерывании висит драйвер, который его обслужит, и запустит планировщик системы, который уж потом в меру своих очередей и приоритетов сообщит ожидающему приложению. Результат всего этого плачевен - никакой повторяемости результатов по времени нет. Совсем нет. Смиритесь.
Так что надежно работающий снифер выделяющий MODBUS-RTU фреймы из 485 под Win нереален. Для низких скоростой и медленнннннооо отвечающих перeферийных устройств, да, частные реализации оаботающие на конкретной машине, возможны.



QUOTE (jcxz @ Sep 8 2016, 12:10) *
И проверять надо под современной виндой.

Будет только хуже sad.gif. Все обещания, которые Вы захотели увидеть в описании драйверов на самом деле тянутся от тех самых Win 3.1/85, котрые еще были как то похожи на "микроконтроллер". В "современных" байтовые интерфесы вообще похоронены де-факто.
jcxz
Цитата(zltigo @ Sep 8 2016, 16:42) *
Разумеется нет.
1) таймаут отрабатывает на 4 символа паузу и приход следующего MODBUS фрейма приведет с склеиванию фреймов.
2) Если драйвера и система не успеет отработать прерывание до прихода следующего фрейма, то они опять склеятся или FIFO или уже в буферах драйвера.

Кто-ж спорит что в этом случае склеятся. Только:
1) ТС нужна не рабочая система сбора данных, а система для мониторинга в целях отладки. Значит к этой системе можно предъявить спец. требования (отсутствие посторонних задач, достаточная мощность и др., которые обеспечат достаточную реалтаймовость системы и скорость реакции на прерывания железа).
2) рассмотрим как работает ПО в сети обмена ModBus и начинаем думать какие будут минимальные дырки:
а) предположим мы наблюдаем обмен двух устройств - устройство А передаёт кадр, устройство Б - принимает, обрабатывает и отвечает (режим запрос-ответ), а наше устройство (комп) мониторит этот обмен со стороны:
А передаёт кадр-запрос, заканчивает его передачу (передан последний бит), в приёмнике Б начинается отсчёт таймаута, проходит 4 символьных интервала - устройство Б начинает обработку кадра-запроса, а потом отвечает на него своим кадром-ответом, т.е. - переключает свой драйвер в режим передачи, начинается выдвигание битов первого передаваемого слова ответа.
Когда в FIFO устройства-монитора появится этот первый байт ответа? Правильно, через: 4 символа таймаута + время обработки в Б + 1 символ ответа. Даже если предположить, что устройство Б обрабатывает запросы мгновенно, всё равно имеем в устройстве-мониторе паузу в 5 символов! Т.е. - устройство-монитор сгенерит прерывание таймаута как минимум за один символ до прихода 1го символа ответа.
А теперь ещё немного подумаем и поймём, что после того как устройство Б переключило свой драйвер RS-485 в режим передачи, то после этого и до начала выдвигания бит первого слова ответа, оно должно обеспечить некую паузу для того, чтобы и устройство А принимающее его ответ заведомо успело переключить свой драйвер RS-485 в режим приёма. А ведь и устройство Б может иметь драйвер RS-485 с гальванической развязкой, которому нужно время на переключение RX->TX и у устройства А тоже может быть такой драйвер, требующий доп. задержки. И ПО ModBus-драйвера, написанное прямыми руками, должно учитывать, что у устройств с которыми оно будет работать, могут быть медленные опторазвязки RS-485, а значит давать возможность или конфигурировать минимальное время переключения себя RX->TX или просто хотя-бы выдерживать это время с большим запасом.
Это всё приводит нас к мысли, что паузы запрос-ответ будут заведомо больше чем 5 символьных интервалов.
б) конечно возможен вариант системы работающей в режиме не запрос-ответ, а запрос-запрос-запрос-...-ответ (т.е. - цикл запроса состоит из нескольких ModBus-кадров). Или просто в режиме широковещательной передачи кадров. Но, имхо, это редкий вариант. Да и в этом случае такая система должна обспечить чтобы дырки между кадрами были заведомо больше 4 символов, хотя-бы для того чтобы гарантировать чёткое их обнаружение на приёмной стороне. А не работать на грани фола с дыркой между двумя TX-кадрами ==4 символам.

Цитата(zltigo @ Sep 8 2016, 16:42) *
3) Прерывания по таймауту и по заполнению FIFO не отличаются, так что приход прерывания, как такового не означает конца фрейма.

Да ладно?
Открываем даташит на LPC17xx содержащий UART с, как в нём утверждается: Register locations conform to 16C550 industry standard. Читаем описание регистра IIR и видим две разные причины прерывания: RDA и CTI. И даже если размер принимаемого кадра равен FIFO trigger level, то всё равно можно обнаружить границу кадра: после получения RDA считать (FIFO trigger level - 1) символов и через некоторое время получить ещё и CTI, сигнализирующее о границе кадра.
Даташит на прародитель 16C550 найти конечно сейчас трудно, но вот эта ссылка например http://www.lookrs232.com/rs232/iir.htm говорит, что и в нём дело обстояло так же.

Цитата(zltigo @ Sep 8 2016, 16:42) *
Какой "такой"? В том же помянутом всуе LPC17XX есть еще навороты, типа CTI и самое главное, есть в отличие от WIN, жесткое реальное время и кучка аппаратных таймеров для организации поддержки таймаутов,

Для "поддержки таймаутов" в LPC17xx таймера не нужны, вполне достаточно RDA и CTI. Это на приём. Только на передачу нужен таймер, чтобы отследить момент опустошения сдвигового регистра передатчика и переключения драйвера RS-485 с TX на RX.

Цитата(zltigo @ Sep 8 2016, 16:42) *
Третий раз - сам таймаут FIFO уже 4 символа. Дальше обслуживание прерывания еще может запоздать и еще как, тем более, что тут НЕ микроконтроллерр и Вы висите НЕ на прерывании. На прерывании висит драйвер, который его обслужит, и запустит планировщик системы, который уж потом в меру своих очередей и приоритетов сообщит ожидающему приложению. Результат всего этого плачевен - никакой повторяемости результатов по времени нет. Совсем нет. Смиритесь.

Это всего лишь слова и предположения. Тут может рассудить только эксперимент(-ы).
Я не вижу никаких причин в современной системе, не загруженной тяжёлой работой, имеющей как правило несколько процессорных ядер с ГГц-выми тактовыми частотами, которые почти всё время просто тупо простаивают, не отреагировать на событие почти мгновенно, обработав например прерывание одним ядром и тут же переключить другое ядро на выполнение высокоприоритетного thread-а драйвера сис. уровня UART, а третьим ядром выполнить пользовательский высокоприоритетный код с ReadFile.

Цитата(zltigo @ Sep 8 2016, 16:42) *
к которому они никакого отношения не имеют, о чем уже тоже писал. Тау что помянуты они всуе.

Таймштампы нужны пользовательскому процессу, вызывающему ReadFile(), особенно с выключенным FIFO, чтобы обнаружить дырки:
Код
LARGE_INTEGER t1, t2;
while () ReadFile(); //опустошаем RX-поток UART
for (QueryPerformanceCounter(&t2);; t2 = t1) {
  ReadFile();
  QueryPerformanceCounter(&t1);
  t2.QuadPart = t1.QuadPart - t2.QuadPart;
  //вот здесь t2 будет или примерно равно 1-му символьному интервалу, если чтение идёт внутри кадра; или больше 4-х символьных кадров, если последняя ReadFile() считала 1-й символ ModBus-кадра
  //т.е. - поставив пороговое сравнение скажем на сравнение t2 < 3-х символьных интервалов или t2 >= 3 символьным интервалам можно с запасом обнаружить дырку
  //временем выполнения этого кода на мощном незагруженном процессоре и высокоприоритетном thread-е можно пренебречь
}
Alex_2015
Я всё-таки внесу некоторые дополнения.
Использую преобразователь USB-RS485. Провёл несколько экспериментов и выяснил, что данные из порта читаются пачками по 4-16 байт. Причём начало запроса всегда читается с начала, начало ответа читается вместе с хвостом запроса.
Эксперименты с таймаутами мало что меняют. Здесь, я думаю, большую роль играет характер устройства (виртуальный порт).
Так случилось, что преобразователь построен на основе FTDI микросхемы. У неё есть возможность работы через D2XX драйвер, который, если верить описанию, в большей степени позволяет мониторить события железки. Если кто работал с ним, насколько это так.
Сейчас вынужден временно переключиться на другую задачу, поэтому по этой буду только инфу изучать в свободное время.
zltigo
QUOTE (jcxz @ Sep 8 2016, 21:02) *
Т.е. - устройство-монитор сгенерит прерывание таймаута как минимум за один символ до прихода 1го символа ответа.

Сколько много слов было написано выше, но результат неизменный - прерывание должно быть обработано драйвером, который должен дернуть операционную систему, которая должна запустить ожидающую сигнала задачу, котороая должна вычитать принятую информацию, за время прихода ОДНОГО символа. О скорсти передачи здесь, кажется не говорилось, но при, например, 115200 это очень мало sad.gif для монстральных операционок типа WIN/LIN.
QUOTE
А теперь ещё немного подумаем и поймём....

Неправильно написано, правильно "еще придумаем" sm.gif.
Проблема в том, что на любую Вашу фантазию, можно нафантазировать противоположную sad.gif
QUOTE
, что после того как устройство Б переключило свой драйвер RS-485 в режим передачи, то после этого и до начала выдвигания бит первого слова ответа, оно должно обеспечить некую паузу для того, чтобы и устройство А принимающее его ответ заведомо успело переключить свой драйвер RS-485 в режим приёма.

Для этого у устройства передатчика есть вагон времени:
1) тот самый 3.5 таймаут (да, да я знаю, что так делать не надо, но знаю, что делают)
2) 0.5 символьный таймаут до срабатывания прерывания.
QUOTE
А ведь и устройство Б может иметь драйвер RS-485 с гальванической развязкой, которому нужно время на переключение RX->TX и у устройства

Может, но быстродействие развязки должно быть таким, что бы обеспечивать передачу одиносного БИТА без существенных искажений, так что мимо.
QUOTE
А тоже может быть такой драйвер, требующий доп. задержки. И ПО ModBus-драйвера, написанное прямыми руками, должно учитывать, что у устройств с которыми оно будет работать, могут быть медленные опторазвязки RS-485, а значит давать возможность или конфигурировать минимальное время переключения себя RX->TX или просто хотя-бы выдерживать это время с большим запасом.

Ох уж это "должно" прежде всего оно должно обеспечить собственную работоспостобность, а не возможность подключения неприспособленного для этого железа, типа PC c Windows.
QUOTE
Это всё приводит нас к мысли, что паузы запрос-ответ будут заведомо больше чем 5 символьных интервалов.

Не нас, а Вас sm.gif. И не будут заведомо, а могут быть sad.gif. Об желаемых "огромных" 5 символьных интервалах тоже можно поговорить. FIFO в UART появилость в PC не сразу и по одной простой причине - операционые системы тупо не успевали обрабатывать потоки байтов уже на скростях 9600 sad.gif.
QUOTE
Открываем даташит на LPC17xx содержащий UART с, как в нём утверждается: Register locations conform to 16C550 industry standard. Читаем описание регистра IIR и видим две разные причины прерывания: RDA и CTI. И даже если размер принимаемого кадра равен FIFO trigger level, то всё равно можно обнаружить границу кадра: после получения RDA считать (FIFO trigger level - 1) символов и через некоторое время получить ещё и CTI, сигнализирующее о границе кадра.
Даташит на прародитель 16C550 найти конечно сейчас трудно, но вот эта ссылка например http://www.lookrs232.com/rs232/iir.htm говорит, что и в нём дело обстояло так же.

Открывать 17xx не надо. Это НЕ PC. И найти 550 очень легко. Только искать нужно вообще-то не его, а 450. FIFO начиналось 82450 чипе, где дополнительных идентификаторов нет. А драйвера PC обслуживают и вобще 8250. Так что появившиеся инентификаторы прерывания драйверам PC по барабану - не обрабатывабтся и ПРИЛОЖЕНИЮ НЕ ПЕРЕДАЮТСЯ.
QUOTE
Для "поддержки таймаутов" в LPC17xx таймера не нужны, вполне достаточно RDA и CTI. Это на приём. Только на передачу нужен таймер, чтобы отследить момент опустошения сдвигового регистра передатчика и переключения драйвера RS-485 с TX на RX.

Еще раз - причем тут 17xx к PC? Вообше формально 17xx и помянутый Вами таймер не нужен, но это уже другая тема.
QUOTE
Это всего лишь слова и предположения. Тут может рассудить только эксперимент(-ы).

c 1984 года и поныне занимаюсь "экспериментами" с PC и UART на них.
Результаты не радуют отсутствием гарантированой стабильности. Причина одна - НЕ УСПЕВАЕТ гарантированно отработать операционная система и приложение за время прихода одного байта по UART.

Последние "эксперименты" были по весне - дабы не отсылать кучу железа, вместо железа написал эмулятор для PC некоего протокола у которого в стиле MODBUS признаком конца фрейма пауза длительностью более 64 бит на 115200. Казалось-бы sad.gif, должно было проскочить. У немцев на их стендовой писишке не заработало, причем абсолютно стабильно не заработало. Пришлось живое железо таки посылать. Хотя, конечно, можно было и DOS приблуду написать sm.gif.
Ruslan1
Мне кажется, изначально вопрос некорректно поставлен: из " данные преобразовать в удобоваримый вид, удобный для отладки работы сети устройств" вовсе не следует что "Надо написать свою".
Берите китайский логический анализатор за 10 баксов, там уже все написано. Для " отладки работы сети устройств" - самое оно. И писать ничего не нужно (если очень хочется, то конечно можно и свое дописать).
И для отладки сети устройств очень важно работать именно на уровне сигналов, а не байтов.так как байтовый уровень не покажет, что кто-то там не то количество стоповых передает, или что кто-то раньше положенной паузы передавать начал. А логический анализатор это покажет (ну и, конечно, псе корректное в байты переведет, чтобы самому не декодировать).

Хотя странно, что там отлаживать. Сначала на бумажке расписываете чего хочется, потом реализовываете и моделируете на этой же бумажке как код работает, ну и проверяете соответствует ли реальность бумажке с помощью логического анализатора. А байтовый лог в случае конфликтов и некорректной реализации никак не поможет разборкам и не покажет правильность работы.
jcxz
Цитата(zltigo @ Sep 9 2016, 13:23) *
Может, но быстродействие развязки должно быть таким, что бы обеспечивать передачу одиносного БИТА без существенных искажений, так что мимо.

Вы путаете скорость передачи (от входа до выхода) и время переключения TX/RX. Скорость передачи может быть достаточной для передачах в МГц, а вот время переключения будут сотни мксек или даже миллисекунды.
Чем выше скорость переключения - тем дороже элемент. Во многих устройствах стоят дешёвые опторазвязки, вполне обеспечивающие скорость передачи и с запасом, а вот время переключения может быть и несколько мсек.
Соответственно - любой вменяемый передатчик RS-485 должен это учитывать и позволять увеличить время своего переключения RX на TX.

Цитата(zltigo @ Sep 9 2016, 13:23) *
Ох уж это "должно" прежде всего оно должно обеспечить собственную работоспостобность, а не возможность подключения неприспособленного для этого железа, типа PC c Windows.

Всё это только Ваше личное мнение.
Аргументы я привёл, Ваши доводы против них - считаю малоубедительными. Дальнейший спор - бессмысленным. Имеющий уши - да услышит и сам всё опробует и вполне возможно - добъётся желаемого результата.

Цитата(Ruslan1 @ Sep 12 2016, 00:59) *
Берите китайский логический анализатор за 10 баксов, там уже все написано. Для " отладки работы сети устройств" - самое оно. И писать ничего не нужно (если очень хочется, то конечно можно и свое дописать).

Кстати - тоже хотел это с самого начала предложить. В этих лог.анализаторах как правило стоит CY7C68013A. Можно даже отключить внутреннюю EEPROM и написать свою прошивку для CY7C68013A и ПО на PC, разбирающее пакеты от CY7C68013A - тоже несложно своё написать.
zltigo
QUOTE (jcxz @ Sep 13 2016, 08:32) *
Вы путаете скорость передачи (от входа до выхода) и время переключения TX/RX. Скорость передачи может быть достаточной для передачах в МГц, а вот время переключения будут сотни мксек или даже миллисекунды.

Я все понял и ничего не путаю. Давайте пример, а не фантазии называемые "убедительными доводами", такого дивного приемопередатчика на бочку!
juvf
2ТС Тут только аппаратный снифер поможет. Можно сделать MODBUS-RS485 to MODBUS-TCP. А вот тсп-модбас уже акулой смотреть, она знает модбас и может его парсить.

2jcxz Утопия. Ни фига не сможет вин/лин по таймаутам работать. Если только на скорости 100 бод. У нас MODBUS на 921600 работает, ОСи скромно отдыхают в сторонке.

Бред какой-то вы пишите.... Теоретически лошадь, практически упала. Я эти теоретические сказки про возможность реализации чистого модбаса на ПК слышу много лет. Все они разбиваются о попытки практической реализации модбаса на ПК. Попробуйте написать консольную программку, без гуи... которая просто бы принимала и считала кол-во пакетов с правильным црц? и в студию.

ps Ну если говорить про совсем чистый модбас, то по спецификации пакет, у которого внутри между байтами больше 1,5 символьного интервала считается не годным.

pps
Цитата
Я не вижу никаких причин в современной системе, не загруженной тяжёлой работой, имеющей как правило несколько процессорных ядер с ГГц-выми тактовыми частотами, которые почти всё время просто тупо простаивают, не отреагировать на событие почти мгновенно, обработав например прерывание одним ядром и тут же переключить другое ядро на выполнение высокоприоритетного thread-а драйвера сис. уровня UART, а третьим ядром выполнить пользовательский высокоприоритетный код с ReadFile.

ВНЕЗАПНО в Qt 5.6 появился класс для работы с модбасом. Покопался в дебрях документации и нашел, что этот класс не может распознавать фреймы в 3.5 символа. В документации Qt5.7 не могу это ограничение найти. В libmodbus тоже не сказано, что у них не чистый модбас.... Гдето же были оговорки по таймаутам.... не могу найти..... может и вправду эти сказки реализовали и финты с RDA и CTI запилили? Кто пользовал эти либы? Сможет QtModbus или libmodbus распознать(разделить) 2 пакета RTU, идущих подряд и разделённых 3.5 символами тишины, на скорости 921600, на каком нить стареньком одноядерном компе, на котором еле-еле гуи ворочится и процессор занят кучей увесистых задач?
Lagman
Цитата(juvf @ Sep 21 2016, 21:29) *
Сможет QtModbus или libmodbus распознать(разделить) 2 пакета RTU, идущих подряд и разделённых 3.5 символами тишины, на скорости 921600, на каком нить стареньком одноядерном компе, на котором еле-еле гуи ворочится и процессор занят кучей увесистых задач?

В рекомендациях modbus сказано (MODBUS over Serial Line Specification and Implementation Guide V1.02, стр. 13)
Цитата
The implementation of RTU reception driver may imply the management of a lot of interruptions due to the t1.5 and t3.5 timers. With
high communication baud rates, this leads to a heavy CPU load. Consequently these two timers must be strictly respected when the
baud rate is equal or lower than 19200 Bps. For baud rates greater than 19200 Bps, fixed values for the 2 timers should be used: it is
recommended to use a value of 750μs for the inter-character time-out (t1.5) and a value of 1.750ms for inter-frame delay (t3.5).


Но наверно даже с этими значениями без ОСРВ не поймать эти моменты, и если T1.5 почти никто не проверяет, то с T3.5 главное не начинать передачу пакета (запрос или ответ) раньше этого момента и можно "терпеть" с передачей вплоть до истечения времени ожидания ответа.
juvf
Цитата(Lagman @ Sep 22 2016, 15:16) *
it is recommended to use a value of 750μs for the inter-character time-out (t1.5) and a value of 1.750ms for inter-frame delay (t3.5).
ЗАПЕЙСАЛ.
zltigo
QUOTE (Lagman @ Sep 22 2016, 13:16) *
и если T1.5 почти никто не проверяет

Что очень зря, ибо это есть механизм отсева сбоев и быстрого восстановления фреймовой синхронизации.
QUOTE
то с T3.5 главное не начинать передачу пакета (запрос или ответ) раньше этого момента и можно "терпеть" с передачей вплоть до истечения времени ожидания ответа.

Терпеть-то можно, если в конкретном случае общая скорость обмена не волнует, но при требовании быстрого обмена все эти таймауты катострофически снижают пропускную способность. В частном случае, когда конкретные реализаторы протокола "плют", "терпят" и медленно обмениваются пакетами в которых паузы между фреймами определяются не протоколом а неспешым темпом обмена и меееедлееенннооо реагирующими на запросы слейвами, софтовый снифер под WIN как-бы ваделяет фреймы без проблем. Но при полноскоростном обмене шансов под WIN никаких sad.gif.
Lagman
Цитата(zltigo @ Sep 22 2016, 13:40) *
В частном случае, когда конкретные реализаторы протокола "плют", "терпят" и медленно обмениваются пакетами в которых паузы между фреймами определяются не протоколом а неспешым темпом обмена и меееедлееенннооо реагирующими на запросы слейвами, софтовый снифер под WIN как-бы ваделяет фреймы без проблем. Но при полноскоростном обмене шансов под WIN никаких sad.gif.

Пропускная способность, это да, пострадает, но стандарты протокола никто не нарушает.
demiurg_spb
Добрый день коллеги!
Захотелось обсудить вопрос "продувки шины" перед выдачей пакта в линию сразу после включения драйвера RS485 на передачу.

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

У меня есть сомнения, что если этого не делать можно наступить на грабли. Поясню.

1) Мастер хочет передать и не знает был ли шум в линии - следовательно надо "продуть" до, ну а после само-собой разумеется продувать необходимо чтобы слейв словил тишину.

2) Слейв хочет ответить на принятый запрос и тоже не знает про то, был-ли шум на линии с момента приёма пакета до переключения драйвера на передачу. Ведь по окончании паузы сформированной мастером, проходит некоторое время на обработку пакета и в это время линия висит либо в воздухе, либо растянута слабенькими резисторами и помехи могут дать ложный старт-бит. Пока писал это осознал, что если помеха в этот момент случилась, то продувка линии может уже и не спасти ситуацию, т.к. мастер может принять мусор, после которого правильный ответ слейва уже может быть и не валиден. Отсюда напрашивается вывод, что слейв должен мгновенно отвечать мастеру после приёма валидного запроса, либо сразу включать свой передатчик и заниматься подготовкой ответа.
Это несколько затруднительно, т.к. в моей текущей реализации это не реализовано (считать CRC на лету, сранивать первый байт запроса со своим адресом и даже может быть готовить ответ во время паузы, формируемой мастером). Кто-нибудь так уже сделал?

Давайте порассуждаем над этим увлекательным занятием - реализацией идеального MODBUS-RTU MASTER/SLAVE!
megajohn
Цитата(demiurg_spb @ Sep 22 2016, 15:26) *
Давайте порассуждаем над этим увлекательным занятием - реализацией идеального MODBUS-RTU MASTER/SLAVE!


RS422
demiurg_spb
Нет. Интересует именно RS485!
Наверное мне стоило создать отдельную тему. Прошу извинения у ТС, если это ему помешало.
juvf
Цитата
Мастер хочет передать и не знает был ли шум в линии - следовательно надо "продуть" до, ну а после само-собой разумеется продувать необходимо чтобы слейв словил тишину.

Не нужно ни чего продувать. когда нет драйвера на линии там лог "1". Линяя RS485 должна быть подтянута (А к +V, B k GND). посмотрите осциллографом перевод из приема в передачу и через какое время начинает бит старт бит вылазить. Работает на скоростях от 9600 до 921600. По окончании ни чего мастеру дуть не надо... после передачи последнего байта я снимаю передачу и перехожу на прием. линия остается без драйвера. Подтягивающие резисторы обеспечат слейву лог "1" - это и будет тишина.
Если кто боиться, что в лини без драйвера есть шум... или может возникнуть шум.... нет там шумов. Подтяжка делает сво дело. На длинной линии можно словить наводку, электромагнитную помеху.... НО.... в рс485 длинная линия тянеться витой парой.... наведенный импульс в А+ таже будет и в B-, в итоге разность A и B сохраниться как без помехи.

Забудте про всякие продувки..... слейв как только принял пакет и обработал без всяких пауз и продувок может отвечать.
demiurg_spb
Цитата(juvf @ Sep 22 2016, 15:47) *
Мне бы Вашу непоколебимую уверенность!
Попробуйте поработать с силовой преобразовательной техникой...
juvf
ps
Цитата
помехи могут дать ложный старт-бит.
не всё так печально. в 485 этого вообще не будет. но такое может возникнуть в рс232.... и тем не менее.... процессор получает уже UART.... так вот... как работает UART (по крайней мере в С51 ядре, да и в остальных примерно также)... переход из лог 1 в лог 0 - это ещё не старт бит. любая помеха в UART-е не является стартбитом. Чтоб уарт начал принимать байт, нужно нулевой уровень в линии на протяжении длительности 1-го бита. в 51-ом проце после перехода 1-0 запускается таймер... чререз 1/4 длительности импульса проверяется уровень на линии.... потом ещё через 1/4, и потом ещё раз через 1/4.... если все 3 раза на входе был лог 0 - то это считается стартбит. так что какаянить иголка в линии не запустит уарт на прием.
demiurg_spb
Цитата(juvf @ Sep 22 2016, 15:56) *
Про то, что бит поллится не за один раз - я естественно в теме. Но при высоких скоростях количество поллингов за бит как правило снижается вплоть до 4. Кто сказал, что помеха не в состоянии 4 раза за бит случиться? Я на это никак не могу не рассчитывать...
juvf
Цитата(demiurg_spb @ Sep 22 2016, 17:51) *
Мне бы Вашу непоколебимую уверенность!
Попробуйте поработать с силовой преобразовательной техникой...

Работал..... обвязывали 485-ым трансформаторные подстанции, распределительные подстанции, дизельные генераторы... а также на объектах с высоким ВЧ излучением.

ps была проблема однажды.... сильное ВЧ излучение.... и оно лезло везде.... решили проблему полной опторазвязкой RS485 мастера и слейва. Но ни каких продувок не делали.

Цитата
линия висит либо в воздухе, либо растянута слабенькими резисторами
в воздухе нельзя её вешать.... а резисторы... растяните не слабенькими... 5 кОм... или 2.4 кОм.

Цитата(demiurg_spb @ Sep 22 2016, 18:01) *
Кто сказал, что помеха не в состоянии 4 раза за бит случиться? Я на это никак не могу не рассчитывать...
А реально были такие случаи? если предположить, что брошенная линия постоянно "шумит".... то получается все слейвы на линии постоянно получают мусор по уарту... т.е. постоянно срабатывает прерывание поприему, обработчик байт кудато помещает, запускает таймер на 3.5 символа (а некоторые ещё и црц налету считают).... это же сколько работы процессору - постоянно шум анализировать... а если уартов 4? Не должно быть шумов и всякого мусора в 485. если есть - нужно над линией работать.

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

Полная опторазвязка - это оптоволокно?

Я никогда не делаю не изолированные RS485 выходы у приборов.
Спасибо!
Ваше мнение я услышал.
juvf
Цитата(demiurg_spb @ Sep 22 2016, 18:13) *
Полная опторазвязка - это оптоволокно?

нет. не правильно выразился.... это связь через оптопары, и если драйвера на грязной стороне, то они запитыватся от гальванически развязанного питания. развязанного и по земле и по плюсу. просто видел, некоторые делают опторазвязку, но при этом земля общая. по земле лезет шум. либо применяют изолированные драйверы, и вроде питают их раздельным питанием, но опять с общей землёй.
zltigo
QUOTE (demiurg_spb @ Sep 22 2016, 15:26) *
Я обычно формирую требуемую паузу на шине с включенным передатчиком до и после передачи пакта.

Увы, для 485 пауза есть неизбежное зло.
Величина паузы зависит от способа выделения фрейма и при MODBUS самый плохой вариант c точки зрения величины пауз -
1,5 байта в начале и 3,5 байта в конце.
При байтстафинговом фреймере - 1 байт в начале, а в конце не нужно.
QUOTE
У меня есть сомнения, что если этого не делать можно наступить на грабли. Поясню.

Ваши сомения несостоятельны.
QUOTE
Давайте порассуждаем над этим увлекательным занятием - реализацией идеального MODBUS-RTU MASTER/SLAVE!

Из дерьма конфетку не сделаешь, а как максимально соблюсти - написано выше.
demiurg_spb
Понятно, что изолированный - это гальванически не связанный и никаких общих земель.
Кстати, про загрузку процессора - если фильтровать по адресу слейва и коду функции то CRC считать для мусора и "не твоих запросов" фактически и не придётся.
zltigo
QUOTE (juvf @ Sep 22 2016, 15:47) *
Не нужно ни чего продувать. когда нет драйвера на линии там лог "1". Линяя RS485 должна быть подтянута (А к +V, B k GND).

За такую "подтяжку" криворуким дизайнерам надо отрывать гениталии. Она КАТОСТРОФИЧЕСКИ гробит дальность передачи.
Есть более-менее приемлимые решения в виде использования Failsafe приемником со смещенным уровнем. Но на них тоже полагаться нельзя, поскольку запас для помехи по минммуму. Их использование есть хороший способ уменьшить помехи, но не исключить.


QUOTE (juvf @ Sep 22 2016, 15:47) *
Если кто боиться, что в лини без драйвера есть шум... или может возникнуть шум.... нет там шумов. Подтяжка делает сво дело. На длинной линии можно словить наводку, электромагнитную помеху.... НО.... в рс485 длинная линия тянеться витой парой.... наведенный импульс в А+ таже будет и в B-, в итоге разность A и B сохраниться как без помехи.

Помеха в длинной линии есть уже и без всяких наведенных - просто колебательный процесс при включении и выключении передатчика.
Вот такой сюрприз для любителей растяжек НИКОГДА не работавших с длинными реальными линиями. Это раз. А два, это то, что подавление синфазных далеко не 100% и нормируется только в достаточно узком диапазоне синфазных, а синфазные помехи в десятки и сотни вольт, это тоже реальность длинных линий.
Никакие опторазвязки от помех на 100% не спасают, ибо любая развязка имеет паразитную емкость, через которую прекрасно пролезают импульсы с высокой энергией. Гальваническая развязка это прежде всего защита от выхода из стоя, защита от помех с пологими фронтами, но не защита от любых помех вообще.
juvf
Цитата
для любителей растяжек НИКОГДА не работавших с длинными реальными линиями.
А что такое длинная реальная линия? с линией в 1200 метров не работал..... но несколько сотен метров - был опыт. Ни чего в линию не дули, ни до ни после передачи... линия была на растяжках.

Цитата
За такую "подтяжку" криворуким дизайнерам надо отрывать гениталии. Она КАТОСТРОФИЧЕСКИ гробит дальность передачи.
Так в даташитах на драйвера эти растяжки в схемах как ..... Typical Half-Duplex RS-485 Network.

zltigo, а вы как с 485-ым работаете? вообще без растяжек? Иногда разработчики забывали растяжку на линии сделать... так, когда линия свободна - все на линии непрерывно ловят мусор... непрерывно по уарту а процессор идёт мусор и связи толком нет.
zltigo
QUOTE (juvf @ Sep 23 2016, 06:14) *
zltigo, а вы как с 485-ым работаете? вообще без растяжек?

Разумеется без.
Предпочтение отдается, как уже писал, Failsafe приемникам (разумеется тем, которые True), но это для уменьшения помех, а не для того что бы мечтать, что помех не будет.
Растяжки опциональные в железе предусмотрены, но ТОЛЬКО на случай подключений чужого железа которое делали убогие программисты не поддерживающие активное состояние линии перед началом передачи. Увы, сие не редкость sad.gif и Вы тому живое свидетельство. Для систем в котором используется гарантрованно свое оборудование на своем протоколе - нет и этой опции за полной ненадобностью.
QUOTE
Иногда разработчики забывали растяжку на линии сделать... так, когда линия свободна - все на линии непрерывно ловят мусор... непрерывно по уарту а процессор идёт мусор и связи толком нет.

Все это совершенно нормально БЕСПРОБЛЕМНО фильтруется. Для фильтрации, например, в случае MODBUS и заложены те самые 1,5 и 3,5 интервалы АКТИВНОГО состояния, но без передачи, и само собой обработка ошибок собственно UART.
juvf
Цитата(zltigo @ Sep 23 2016, 14:08) *
Все это совершенно нормально БЕСПРОБЛЕМНО фильтруется. Для фильтрации, например, в случае MODBUS и заложены те самые 1,5 и 3,5 интервалы АКТИВНОГО состояния, но без передачи, и само собой обработка ошибок собственно UART.
не ради холевара.... а ради прокачки скила.... как допустим, ПК БЕСПРОБЛЕМНО делает интервал активного состояния без передачи данных? как в покупных преобразователях усб-485 или 232-485 ПК делает активные паузы? это раз

2)но понятно.... что перед отправкой пакета сделать паузу, то вероятность ошибок будет меньше.... линяя будет "нешумная" и слейв получит пакет нормально. Но если линяя брошена... растяжек нет... то в УАРТ постоянно сыплет мусор. Понятно, что слейв считает црц и вероятность что получился из мусора годный пакет бесконечно мала.... Слейв в мусоре годного пакета не найдет. Но мусор то есть... и слейву нужно этот мусор обрабатывать... т.е. слейв непрерывно копается в мусоре и тратит свои ресурсы. Кто-то скажет - что эти ресурсы ничтожно малы.... но на каком нить АтТини не так уж и малы. с растяжками мусора нет.... может и могут быть помехи.... но они очень редки

Цитата
в случае MODBUS и заложены те самые 1,5 и 3,5 интервалы АКТИВНОГО состояния
эээээ.... в MODBUS вроде нет ни каких интервалов активного состояния. там есть интервалы тишины.


ps я всегда в своих устройствах делаю счетчик пакетов с битыми црц, и счетчик пакетов адресованных "мне". всегда интересно.... на сколько качественная связь.... сколько пакетов потеряно? каковы помехи? Приятно увидеть через год, что счетчик битых либо не изменился, либо инкрементировался на 1.
demiurg_spb
Цитата(zltigo @ Sep 22 2016, 16:50) *
Увы, для 485 пауза есть неизбежное зло.
Величина паузы зависит от способа выделения фрейма и при MODBUS самый плохой вариант c точки зрения величины пауз -
1,5 байта в начале и 3,5 байта в конце.
Про 1,5 байта в начале не понял.
Там ведь и в начале и в конце 3,5 байта, а от 1,5 до 3,5 - это признак битого пакета.


Цитата(juvf @ Sep 23 2016, 13:34) *
ээээ.... в MODBUS вроде нет ни каких интервалов активного состояния. там есть интервалы тишины.
Да именно тишины, а как вы её должны добиться в стандарте ИМХО не сказано. Единственно возможный способ гарантированно этого добиться - включить шину в активное состояние.
А что касается настоящих usb преобразователей в MODBUS-RTU то такие, я думаю есть в природе и в них наверняка стоит контроллер.

Кстати про FAILSAFE - большая их часть нифига не FAILSAFE (т.е. без смещённого порога).
Поскольку последнее время разрабатываем девайсы на отечественной элементной базе могу сказать, что у Миландра правильные RS485 драйверы.
juvf
Цитата(demiurg_spb @ Sep 23 2016, 15:45) *
Единственно возможный способ гарантированно этого добиться - включить шину в активное состояние.
не единственный. Я уже писал выше про растяжки.

Цитата
Кстати, про загрузку процессора - если фильтровать по адресу слейва и коду функции то CRC считать для мусора и "не твоих запросов" фактически и не придётся.
Я сначала принимаю весь пакет, потом проверяю црц, только потом принимаю решение что пакет без ошибок и обрабатываю его. Проверять адрес без принятия всего пакета не совсем правильно.... но хотя кому как удобнее.... но тем не менее... допустим считаем црц после каждого приема байта....

1)пришел байт мусора
2)посчитал црц для 1 байта (табличным способом)
3)goto 1
сработал таймер 3,5, если црц == 0, то пакет годный, смотрим адрес.

в таком алгоритме придётся для мусора считать црц.... если не считать црц, а фильтровать по адресу...
1)пришел байт мусора
2)проверили адрес
3)goto 1

где профит? 2-ой шаг - или фильтрация, или подсчет црц всеравно тратить время, все равно вход в прерывание, выход из прерывания....
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.