#c #linux #serial-port #debian #rs485
#c #linux #последовательный порт #debian #rs485
Вопрос:
Я работаю над системой Linux, которая использует modbus rtu RS485 для отправки и получения данных. Мое устройство является основным и просто отправляет «запрос последних данных» (8 байт, включая 2 байта CRC) работорговцу (с этого момента только 1 работорговец) каждые 1 секунду. когда работорговец получит запрос, он подготовит данные (71 байт, включая CRC) и отправит обратно мастеру. Я не вижу источника Slaver, потому что это коммерческий продукт. Оба мастера и работорговца используют одинаковую скорость передачи 38400.
Результат:
- При проверке связи между мастером и работорговцем иногда (в среднем 1-2 часа) данные от работорговца теряют несколько первых байтов, а первый полученный байт был изменен другим значением, отправленным от работорговца (иногда теряется только несколько первых байтов)
- Иногда данные от работорговца не поступают (тайм-аут, но не получают никаких данных). Я попытался увеличить время ожидания на 500 мс или 1 сек, но все равно происходит без каких-либо изменений
- Я протестировал Slaver посредством связи с Teraterm, и такой ошибки, как указано выше, нет. Отправленные и полученные данные в порядке. С Master я также тестировал с Teraterm, и ошибки нет.
- Когда я пытаюсь перехватить данные, в то время как мастер и работорговец отправляют и получают данные, когда возникает проблема (не получают никаких данных или теряют несколько первых байтов) как на стороне мастера, так и на стороне моего ПК (попробуйте перехватить байт данных Teraterm на ПК).
Я считаю, что проблема на стороне мастера и, возможно, в настройке последовательного порта, но я не знаю, где были ошибки. Пожалуйста, помогите.
Извините за мой плохой английский!
Комментарии:
1. Вы опубликовали только фрагменты кода, а не минимальный и полный пример. Коды возврата от всех системных вызовов обрабатываются неправильно. Многочисленные идентификаторы не определены, например
assW_buf
, вwhile( 0 < read( fd, amp;buf[0], sizeof(assW_buf)) );
Baudrate установлена фиктивнаяnew_options
структура. Инициализация Termios является неправильной и ненадежной из-за использования обнуленной структуры. См. раздел Правильная настройка режимов терминала и руководство по последовательному программированию для операционных систем POSIX2. Я считаю, что в этом случае обнуленная структура Termios не является проблемой, потому что мне передали вашу ссылку, но улучшения нет. Проблема может быть не в программном обеспечении. Извините за неопределенную переменную в исходном коде, это ошибка ввода, никаких проблем в программе нет, и, пожалуйста, игнорируйте ее.
3. «Проблема может быть не в программном обеспечении. » — Тогда, если проблема в оборудовании, почему проблема не возникает при использовании Teraterm? Общее правило для устранения неполадок: если замена X на Y устраняет симптом, тогда подозревайте X в качестве причины, а не Z. Но если вы считаете, что это HW, как вы прокомментировали ниже, то ваш пост не по теме для этого сайта.
4. @sawdust: Спасибо за ваше замечание. В teraterm время отправки данных обратно из полученных данных от Master больше (из-за того, что я использовал Marco, и для обработки и отправки данных обратно требуется 30-50 мс), чем у устройства-работорговца. Я был добавлен в журнал и вижу, что когда-нибудь работорговец отправляет обратные данные менее чем за 1 мс. И, как мой комментарий ниже, я добавляю время задержки в Slaver и вижу улучшение. Мне нужно знать, почему переключение режима приема и режима передачи в драйвере шины RS485 занимало много времени, как обычно, чтобы избежать или исправить это. Можете ли вы мне помочь?
Ответ №1:
Раньше я много работал с шиной RS485. И одна проблема, которая иногда появлялась, была очень похожа на вашу. Поскольку RS485 является полудуплексной шиной, существует механизм переключения режима приема и режима передачи в драйвере шины RS485. И это было именно причиной моих проблем.
Когда ведущее устройство отправляло некоторые данные, ведомое устройство было готово ответить (и ответило) до того, как драйвер шины (на стороне ведущего устройства) был переключен в режим приема. Такое поведение закончилось потерей данных.
Могу ли я предложить вам проверить с помощью осциллографа правильность отправки данных подчиненным устройством? Если это так, то у вас, вероятно, не так уж много вариантов действий, поскольку возможные решения:
- Ведомому устройству придется подождать некоторое время, прежде чем отправлять ответ ведущему устройству.
- Измените HW, какой-нибудь драйвер RS485, который будет быстрее переключаться в режимах или использовать другую шину.
Комментарии:
1. Спасибо за ответ. И я считаю, что вы правы, потому что я пытался добавить задержку на 5-10 мс перед отправкой данных обратно мастеру на стороне работорговца и увидеть улучшение, но все равно происходит. Есть одна вещь, которую я не понимаю, почему иногда драйвер шины переключается в режим приема слишком поздно? Я считаю, что при обычном переключении в режим приема проблем нет. Возможно, другое прерывание или что-то еще, что может повлиять на переключение режима. Я не могу изменить аппаратное обеспечение, мне нужно повторить попытку отправки и получения в программном обеспечении, чтобы избежать этой проблемы, но мне нужно знать основную причину, прежде чем что-либо делать. Пожалуйста, помогите.
2. Честно говоря, я понятия не имею. Это зависит от того, какой HW вы используете для подключения RS485 к вашему компьютеру. Это также может зависеть от используемого вами SW. Эти вещи обычно создаются как USB для UART (например, FT232), а затем UART для драйвера RS485. У этого драйвера RS485 есть RX amp; TX для подключения UART, A amp; B для подключения RS485 и штырь направления, который обычно управляется FT232.
3. Спасибо за вашу помощь. Я попытаюсь с помощью осциллографа определить, с какой стороны эта проблема.