Сетевой протокол modbus rtu

Modbus: простыми словами о популярном протоколе для M2M-взаимодействия

Modbus — это сетевой протокол прикладного уровня, широко используемый в промышленном производстве для обмена данными между устройствами (Machine-to-Machine, M2M).

С момента разработки в 1979 году он не теряет своей популярности. Согласно статистике HMS Industrial Networks в 2021 году Modbus занимает 10% мирового рынка промышленных сетей (по 5% приходится на Modbus RTU и Modbus TCP).

В статье расскажем об основных особенностях протокола Modbus, его преимуществах и недостатках, а также наиболее частых сценариях использования.

Базовые принципы работы Modbus

Modbus использует архитектуру Master-Slave, которая относительно недавно была переименована разработчиком в Client-Server. Согласно этому подходу в сети выделяется клиентское (ведущее) устройство, которое периодически отправляет запросы на серверные (ведомые) устройства с целью чтения или записи их параметров.

Все запросы может инициировать только клиентское устройство: передача сообщений от серверных устройств без предварительного опроса со стороны клиента в протоколе не предусмотрена.

Пакет данных Modbus включает в себя постоянную часть PDU (Protocol Data Unit), общую для всех реализаций протокола и состоящую из кода функции и данных. Кроме этого, возможен ряд специфических полей, которые будут различаться в зависимости от физического уровня сети — чаще всего это адрес серверного устройства и контрольная сумма для выявления ошибок. С учетом дополнительных полей полный пакет Modbus носит название ADU (Application Data Unit). Рассмотрим более подробно каждое поле пакета ADU в обобщенном виде. Особенности, присущие различным вариантам протокола, будут описаны в следующем разделе.

  • Адрес серверного устройства (Additional address). Определяет, по какому адресу следует отправить клиентский запрос. Может принимать значения в диапазоне от 1 до 247. Адрес 0 используется для широковещательной передачи данных от клиента всем серверным устройствам (ответ сервера при этом не предусмотрен), а адреса 248–255 считаются зарезервированными.

    В некоторых реализациях протокола поле игнорируется — например, в Modbus TCP, где чаще всего применяется стандартная IP-адресация.

  • Код функции (Function code). Определяет, какое действие необходимо выполнить серверному устройству. Значения кодов функций лежат в диапазоне от 1 до 255, причем коды от 128 до 255 зарезервированы для сообщений об ошибках. Код 0 не используется.

    Для кодов из диапазонов 65-72 и 100-110 пользователи могут реализовать собственные функции (User-Defined Function Codes). Некоторые коды, например 9, 10, 13 и другие, зарезервированы определенными поставщиками для своего оборудования и закрыты для общего использования (Reserved Function Codes). Не входящие в эти два подмножества коды относятся к публичным (Public Function Codes) — это задокументированные функции, находящиеся в открытом доступе.

  • Данные (Data). Данные, необходимые для выполнения выбранной функции на серверном устройстве. Чаще всего это адреса регистров для чтения или записи, их количество и так далее. Длина и формат поля зависят от кода функции. Некоторые функции не требуют передачи данных.
  • Контрольная сумма (Error check). Содержит рассчитанное при помощи специального алгоритма число для проверки целостности пакета. В качестве алгоритма для расчетов используется CRC-16 или LRC-8. В некоторых реализациях протокола поле отсутствует — например, в Modbus TCP, где контроль целостности пакета обеспечивается средствами протокола TCP/IP.

Рассмотрим передачу пакетов в Modbus. Протокол обеспечивает клиент-серверное взаимодействие в режиме Request/Response. Клиент инициирует запрос в серверное устройство, передавая в PDU код функции и данные. В зависимости от физического уровня сети в пакете могут быть дополнительные поля, рассмотренные выше.

Если обработка запроса проходит без ошибок, то сервер возвращает пакет, содержащий исходный код функции и запрошенные данные.

При возникновении ошибки серверное устройство возвращает в качестве данных код исключения, а вместо исходного кода функции — его значение, увеличенное на 128 (0x80 в шестнадцатеричной системе HEX).

Также предусмотрены тайм-ауты на стороне клиента во избежание длительного ожидания ответа от вышедших из строя устройств.

Разновидности Modbus: ASCII, TCP и RTU

Modbus — это протокол прикладного (седьмого) уровня модели OSI (Open Systems Interconnection model). Он не зависит от нижележащих уровней и может использоваться совместно с другими протоколами, например Ethernet TCP/IP или UDP/IP, а в качестве физической среды для передачи сигналов применять последовательные интерфейсы RS-232, RS-422, RS-485, оптоволокно, радиоканалы и другое.

Опишем отличия наиболее известных реализаций протокола Modbus: RTU, ASCII и TCP.

Modbus RTU (Remote Terminal Unit). Это разновидность протокола, которая в качестве физического уровня сети чаще всего использует последовательный интерфейс RS-485, реже — RS-232 и RS-422. По сути, все эти интерфейсы определяют связь с помощью витых пар, но различаются характеристиками вида максимальной длины кабеля, количества узлов и так далее.

Формат пакета Modbus RTU в целом совпадает с обобщенной формой, описанной ранее: дополнительные поля не используются. Контроль целостности пакетов ведется с помощью алгоритма CRC-16.

Важная особенность Modbus RTU в том, что для разделения пакетов должны использоваться временные паузы продолжительностью не менее чем произведение 3,5*t, где t — время передачи одного байта в текущей сети. А передача байтов данных в пределах одного пакета производится последовательно с промежутком времени между соседними байтами не более 1,5*t, иначе передача будет считаться ложной. Эти правила не дают использовать Modbus RTU в медленных, например модемных, сетях.

Modbus ASCII. Это разновидность протокола, также работающая поверх интерфейсов RS-232/RS-485, но для кодирования сообщений использующая ASCII-символы.

По сравнению с Modbus RTU в формате пакета добавляются еще два поля — специальные символы для отметки начала и конца сообщения: двоеточие и символы возврата каретки / перевода строки. Временные паузы между пакетами не нужны. Для проверки целостности применяется алгоритм LRC-8.

В целом этот вариант протокола сейчас используется крайне редко — из-за сложностей кодирования и большого размера сообщений. Однако он может стать хорошей альтернативой Modbus RTU на линиях с сетевыми задержками и оборудовании с менее точными таймерами.

Modbus TCP. Это реализация ModBus в сетях Ethernet. Работает поверх TCP/IP стека.

В отличие от Modbus RTU и ASCII, в Modbus TCP соединение устанавливается с конкретным устройством средствами TCP/IP. Поэтому адрес в пакете Modbus чаще всего игнорируется, а широковещательная рассылка сообщений не используется. Однако адрес может потребоваться, если соединение устанавливается со шлюзом, который, в свою очередь, выводит на сеть RS485 — чтобы далее общаться с устройствами уже на языке Modbus.

Контроль целостности пакетов также обеспечивается средствами протокола TCP/IP, поэтому нет необходимости в его Modbus-реализации.

Наряду с адресом в заголовке пакета Modbus TCP присутствует ряд дополнительных полей:

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

Мы рассмотрели только открытые и самые распространенные реализации протокола Modbus. Но их гораздо больше, например MODBUS Plus — проприетарный протокол от Schneider Electric, поддерживающий режим Multi-Master.

Регистры и функции Modbus

Так как Modbus предназначен для работы с промышленной автоматикой, обмен данными с Modbus-устройствами происходит через регистры. Они делятся на входы и выходы. Входы можно только читать, а выходы — читать и писать. Бывают 1-битные регистры Modbus для описания дискретных входов/выходов (Discrete Inputs и Coils) и 16-битные регистры для аналоговых входов/выходов (Input Registers и Holding Registers).

Доступ к регистрам осуществляется с помощью 16-битного адреса. Первому элементу в каждой группе регистров соответствует адрес 0. То есть адрес любого регистра может принимать значения из диапазона 0-65535 (0x0000-0xFFFF в HEX-формате). При этом спецификация протокола не определяет, что физически из себя представляют адресные пространства и по каким внутренним адресам устройства должны быть доступны регистры. В общем случае значения регистров с одинаковым адресом, но разными типами отличаются друг от друга.

В документации ряда производителей на некоторые, особенно старые устройства адреса регистров могут быть указаны в других форматах — где адресация начинается не с нуля и первая цифра адреса определяет тип регистра. Например, Input Register с адресом 0 может быть описан как 30001, а Holding Register — как 40001. В таких случаях в пакетах данных следует передавать адреса в стандартном формате Modbus независимо от способа представления их в документации. Для получения верного адреса достаточно вычесть смещение, соответствующее типу регистра. В некоторые программные пакеты заложена автоматическая корректировка адресов.

Тип регистров Назначение Размер Доступ Стандартный адрес Примеры нестандартных адресов
Coils Регистры флагов, обозначающие текущее состояние выхода устройства. Например, при включенном реле значение 1. 1 бит Чтение и запись (выход) 0-65535 (0x0000-0xFFFF в HEX-формате) 00001-09999 или 000001-065536
Discrete Inputs Дискретные входы, описывающие состояние входа устройства. Например, при поданном напряжении значение 1. 1 бит Чтение (вход) 0-65535 (0x0000-0xFFFF в HEX-формате) 10001-19999 или 100001-165536
Input Registers Регистры ввода, предназначенные для чтения настроек (например, текущего значения температуры). 16 битов Чтение (вход) 0-65535 (0x0000-0xFFFF в HEX-формате) 30001-39999 или 300001-365536
Holding Registers Регистры, предназначенные для хранения настроек с возможностью их чтения и записи. 16 битов Чтение и запись (выход) 0-65535 (0x0000-0xFFFF в HEX-формате) 40001-49999 или 400001-465536

Для работы с каждым типом регистров определены функции чтения и записи. Наиболее часто используемые функции описаны ниже.

Код HEX-код для PDU Название функции Тип данных Назначение
1 0x01 Read Coils Coils Чтение значений нескольких регистров флагов
2 0x02 Read Discrete Inputs Discrete Inputs Чтение значений нескольких дискретных входов
3 0x03 Read Holding Registers Holding Registers Чтение значений нескольких регистров хранения
4 0x04 Read Input Registers Input Registers Чтение значений нескольких регистров ввода
5 0x05 Write Single Coil Coils Запись одного регистра флагов
6 0x06 Write Single Register Holding Registers Запись одного регистра хранения
15 0x0F Write Multiple Coils Coils Запись нескольких регистров флагов
16 0x10 Write Multiple Register Holding Registers Запись нескольких регистров хранения

Для каждой функции в спецификации протокола Modbus определена структура PDU: какие данные и в каком порядке должны использоваться в запросах и ответах. Рассмотрим формирование пакетов Modbus RTU на примере функции Read Coils с кодом 1. Эта функция, кроме передачи собственного кода, требует наличия в запросе адреса первого Coil-регистра и количества регистров, которые необходимо прочитать. В случае успешного выполнения запроса в ответе будут возвращены код функции, число байт, необходимое для вывода запрошенных Coil-регистров, и статус всех этих регистров.

Предположим, нам нужно обратиться к серверному устройству с адресом 1 и прочитать 19 его Coil-регистров с номерами 20–38. Адресация регистров ведется с 0, поэтому адрес первого нужного нам регистра будет 0x13 (это 19 в HEX-системе). Требуемое для чтения количество регистров также будет равно 0x13 (для чтения запрошено 19). В качестве адреса и кода функции указываем 01. Контрольная сумма формируется по алгоритму CRC-16 на основе других полей пакета.

В случае отсутствия ошибок в ответе вернутся без изменений адрес серверного устройства и код функции. Для расчета числа байтов, которые потребуются для возврата состояния регистров, нужно разделить запрошенное количество регистров на 8 и к результату прибавить 1, если остаток от деления не равен 0. В нашем случае результат деления 19 на 8 равен 2, но остаток положительный — поэтому для вывода регистров потребуется 2+1=3 байта. Это значение будет указано в ответе после кода функции. И далее будут следовать 3 байта, описывающие состояние выбранных регистров. Например, первый байт будет описывать состояние 8 Coil-регистров с номерами 27-20. Если в поле, к примеру, содержится HEX-значение CD — статус соответствующих 8 регистров такой: 1100 1101.

Если в процессе обработки запроса на серверном устройстве возникнет ошибка (например, обнаружен несуществующий адрес регистра), то в ответе будет содержаться измененный код функции, равный исходному коду плюс смещение 0x80 — в нашем примере 0x81, и код исключения — в нашем примере 03, что значит неверный формат запроса. С полным перечнем возможных исключений можно ознакомиться в документации.

Источник

Читайте также:  Сетевой адрес и протокол передачи данных
Оцените статью
Adblock
detector