Содержание


Справка по ModbusSrv

Сервер &ModbusSrv - универсальный сервер шины для обслуживания запросов по протоколу MODBUS.

Перейти к Содержанию


Назначение

Сервер ModbusSrv:

Таким образом, один сервер "закрывает" сразу большой спектр задач.

Одним из главных применений сервера &ModbusSrv является связь с внешними системами SCADA и HMI. При всех своих недостатках, протокол MODBUS является промышленным стандартом, поддерживается большим числом программ и позволяет организовывать "гибридные" системы, работающие на базе нескольких пакетов.

Имеется работающий пример demo_mdbs.

Перейти к Содержанию


Конфигурирование

Стандартное описание сервера ModbusSrv (кроме обычного подключения кривых) имеет примерно такой вид:

[DeviceList]
&ModbusSrv = device software program
[&ModbusSrv]
Comment       = MODBUS SERVER (SLAVE).
InquiryPeriod = 0
DevicePolling = 1, tpTimeCritical
ProgramSource = ~~\resource\daqsite\modbusserver\modbussrv.pas
DebugFlags    = 3
OpenConsole   = 2
StdInFifo     = 512
StdOutFifo    = 512
StartupScript = [&ModbusSrv.StartupScript]
FinallyScript = [&ModbusSrv.FinallyScript]
[]

  либо подключение стандартного библиотечного модуля

[ConfigFileList]
ConfigFile = ~~\resource\daqsite\default\modbussrv.cfg
[]

  при этом

- в секцию [&ModbusSrv] надо поместить описание подключений (кривых),
  данные которые которых будут передаваться и приниматься сервером

- в секцию [&ModbusSrv.StartupScript] надо поместить описание портов,
  узлов (устройств MODBUS), а также таблицы адресов регистров MODBUS

Таблица параметров и адресов MODBUS задается в секции StartupScript через консольные команды, описанные ниже. Поэтому эта секция обязательно должна быть описана. Хотя, строго говоря, все описание может генерироваться и динамически, через посылку сообщений. При этом размер буфера StdInFifo должен быть достаточным для размещения таблиц из секции StartupScript.

  1. @Port port prot decl - таблица логических портов.
    Логический порт - это просто элемент в таблице для последующего подключения к нему устройств (узлов). Каждый логический порт имеет номер port, протокол prot и определение decl. В данной версии номера логических портов port занимают диапазон от 1 до 16. Протокол prot может принимать значения IP, RTU, ASCII. Определение decl может содержать писание порта TCP или COM, как описано в справке по функции pipe_init (при этом TCP подключение должно быть серверным). Например:
@port 1 IP tcp port 502 server 16
  - логический порт №1 работает по протоколу IP, использует TCP порт №502 (это стандартный порт MODBUS)
  - сервер поддерживает подключение до 16 клиентов.

@port 2 RTU com port 4 baudrate 9600 parity even databits 8 stopbits 1
  - логический порт №2 работает по протоколу RTU, использует COM порт №4, скорость 9600 бит/сек,
  - контроль четности EVEN, 8 бит данных, 1 стоповый бит.
  1. Командой @PortErrorCounters port Rx Tx Ex можно задать теги счетчиков ошибок данного порта.
    Командой @PortErrorRates port Rx Tx Ex можно задать теги скорости счета ошибок данного порта.
    Здесь
    port - номер порта.
    Rx - имя тега для счетчика ошибок приемника, когда приходят запросы с неверным адресом устройства, неверной контрольной суммой и т.д.
    Tx - имя тега для счетчика ошибок передатчика, когда не удается отправить ответ на запрос.
    Ex - имя тега для счетчика ошибок - исключений MODBUS, когда в запросе указан неверный адрес статусного или регистрового входа-выхода.
    Аналогично задаются теги для подсчета трафика:
    Командой @PortPollCounters port Rx Tx можно задать теги счетчиков запросов данного порта.
    Командой @PortPollRates port Rx Tx можно задать теги скорости поступления запросов данного порта.
    Командой @PortByteCounters port Rx Tx можно задать теги счетчиков потока байтов данного порта.
    Командой @PortByteRates port Rx Tx можно задать теги скорости счета потока байтов данного порта.
    Теги счетчиков могут иметь тип Integer или Real (лучше Real). При необходимости общего счетчика допустимо многократно ссылаться на один и тот же тег, в этом случае счета из разных источников будут складываться.
    В случае, если теги ошибок не указаны, будут инкрементироваться стандартные счетчики ошибок, общие для всех портов. Эти стандартные ошибки влияют на статус DAQ-системы (улыбающийся человечек пожелтеет и покраснеет). В случае, когда теги ошибок указаны, они будут инкрементироваться при ошибках на данном порте, но при этом стандартные счетчики задействованы не будут (поэтому статус DAQ системы при ошибках не изменится). Это позволяет делать индивидуальную обработку ошибок, по выбору прикладного программиста.

  2. @Node node port addr - Таблица логических узлов, т.е. устройств.
    Логический узел - это подключенное к одному из портов устройство с определенным сетевым адресом. Каждый узел имеет логический номер node (в данной версии от 1 до 64). Он подключен к порту номер port (который должен быть описан в таблице портов) и имеет сетевой адрес addr (по спецификации - от 1 до 247). Адреса используются для различения устройств, подключенных к одному порту.
    Для каждого узла node можно дополнительно указать базовые адреса base командами:
  3. Таблицы адресов статусных и регистровых входов и выходов - для каждого из объявленных узлов.
    Эти таблицы задаются командами:

Перейти к Содержанию


Список команд и примеры

Краткое описание команд MODBUS в секции StartupScript:

@Reset
@View
@View node
@Port port prot decl
@Node node port neta
@PortErrorRates port Rx Tx Ex
@PortErrorCounters port Rx Tx Ex
@PortPollRates port Rx Tx
@PortPollCounters port Rx Tx
@PortByteRates port Rx Tx
@PortByteCounters port Rx Tx
@CoilStatusBase node base
@InputStatusBase node base
@InputRegisterBase node base
@HoldingRegisterBase node base
@CoilStatus node addr bit src ref dst out
@InputStatus node addr bit src ref
@InputRegister node addr typ src ref
@HoldingRegister node addr typ src ref dst out
  где
    port - логический порт, 1..16
    prot - протокол IP,RTU,ASCII
    decl - описание порта: (tcp port 502 server 16),(com port 1 baudrate 9600 parity even databits 8 stopbits 1)
    node - логический узел, 1..228
    neta - сетевой адрес, 1..247
    base - базовый адрес в таблице данного узла
    addr - адрес элемента данных, начиная с base
    typ  - тип элемента данных: int16,int32,float,double
    bit  - бит статуса: bit0,bit1,bit3,..,bit31
    src  - тип источника данных: AnalogInput,DigitalInput,Tag
    ref  - индекс источника данных: номер AI,DI или имя тега
    dst  - тип приемника данных: AnalogOutput,DigitalOutput,Tag
    out  - индекс приемника данных: номер AO,DO или имя тега
    Rx   - имя тега (integer,real) для накопления ошибок приемника
    Tx   - имя тега (integer,real) для накопления ошибок передатчика
    Ex   - имя тега (integer,real) для накопления ошибок - исключений
  типы данных:
    int16       - 1 регистр,  2 байта
    int32       - 2 регистра, 4 байта
    float       - 2 регистра, 4 байта
    double      - 4 регистра, 8 байт
    bit0..bit31 - для статусных 1-битных данных
    
Например:
  
[&ModbusSrv.StartupScript]
;--- Задание таблицы портов (порт,протокол,описание)
;--- Задание счетчиков приема/передачи/ошибок
;--- Логический порт 1
@Port 1 ip  tcp port 502 server 16
@PortByteCounters 1 BYTECOUNT.RX BYTECOUNT.TX
@PortPollCounters 1 POLLCOUNT.RX POLLCOUNT.TX
@PortErrorCounters 1 BUGSCOUNT.RX BUGSCOUNT.TX BUGSCOUNT.EX
@PortByteRates 1 BYTERATE.RX BYTERATE.TX
@PortPollRates 1 POLLRATE.RX POLLRATE.TX
@PortErrorRates 1 BUGSRATE.RX BUGSRATE.TX BUGSRATE.EX
;--- Логический порт 2
@Port 2 rtu com port 4 baudrate 9600 parity even databits 8 stopbits 1
@PortByteCounters 2 BYTECOUNT.RX BYTECOUNT.TX
@PortPollCounters 2 POLLCOUNT.RX POLLCOUNT.TX
@PortErrorCounters 2 BUGSCOUNT.RX BUGSCOUNT.TX BUGSCOUNT.EX
@PortByteRates 2 BYTERATE.RX BYTERATE.TX
@PortPollRates 2 POLLRATE.RX POLLRATE.TX
@PortErrorRates 2 BUGSRATE.RX BUGSRATE.TX BUGSRATE.EX
;--- Очистка счетчиков ошибок
@ZeroPortCounters
;--- Задание таблицы узлов (узел,порт,сетевой адрес)
@Node 1 1 1
@Node 2 1 2
;---Задание базовых адресов узла 1 (указаны стандартные значения)
@CoilStatusBase 1 1
@InputStatusBase 1 10001
@InputRegisterBase 1 30001
@HoldingRegisterBase 1 40001
;---Регистры Holding узла 1, только чтение
@HoldingRegister 1 40001 int16  DigitalInput  0
@HoldingRegister 1 40002 int32  DigitalInput  1
@HoldingRegister 1 40004 float  AnalogInput   0
@HoldingRegister 1 40006 double AnalogInput   1
@HoldingRegister 1 40010 int16  tag demo_test_1
;---Регистры Holding узла 2, чтение и запись
@HoldingRegister 2 40001 int16  DigitalInput 0 DigitalOutput 0
@HoldingRegister 2 40002 int32  tag TEST.L1 tag TEST.L1
@HoldingRegister 2 40004 float  tag TEST.F2 tag TEST.F2
@HoldingRegister 2 40006 double tag TEST.D2 tag TEST.D2
;---Регистры Input узла 1, только чтение
@InputRegister 1 30001 int16 DigitalInput 0
@InputRegister 1 30002 int32 DigitalInput 1
@InputRegister 1 30004 float AnalogInput 0
@InputRegister 1 30006 double tag demo_test_2
;---Статусы Coil узла 1, только чтение
@CoilStatus 1 1 bit0  DigitalInput 0
@CoilStatus 1 2 bit1  DigitalInput 0
;---Статусы Coil узла 2, чтение и запись
@CoilStatus 2 3 bit0  tag TEST.W1 tag TEST.W1
@CoilStatus 2 4 bit1  tag TEST.W1 tag TEST.W1
@CoilStatus 2 5 bit2  tag TEST.W1 tag TEST.W1
;---Статусы Input узла 1, только чтение
@InputStatus 1 10001 bit0  DigitalInput 0
@InputStatus 1 10002 bit1  DigitalInput 0
[]

При задании таблиц данных указывается узел, адрес, тип данных (int16, int32, float, double) для регистров или номер бита bit0..bit31 для статусов, тип источника (цифровой или аналоговый вход или тег), индекс источника (номер входа или имя тега). Для перезаписываемых данных (CoilStatus,HoldingRegister) также указывается тип приемника (цифровой или аналоговый выход или тег) и индекс приемника (номер выхода или имя тега). Эти данные связывают адрес таблицы MODBUS с базой данных (кривых и тегов), чтобы сервер знал, где и какого типа данные ему использовать.

Работа сервера происходит в пассивном режиме опроса со стороны клиентов. Это значит, что сервер передает данные только по инициативе подключенных клиентов, по их запросам. Частота опроса также определяется клиентами. Этот факт ограничивает область применения сервера. Потокол MODBUS нельзя применять, если система требует запросов на обслуживание или обновления данных по инициативе сервера (а не клиентов). Это свойство не является особенностью данного сервера - оно присуще самой логике протокола MODBUS.

Ограниченный спецификацией MODBUS размер пакета данных, передаваемого за одну транзакцию (запрос-ответ) в 250 байт ограничивает траффик данных величиной примерно 125 килобайт в секунду (исходя из реалистичной цифры - 500 транзакций в секунду). Это ограничение также не является особенностью данного сервера - оно присуще самой логике протокола MODBUS. Поэтому сервер предназначен для передачи сравнительно небольших пакетов данных в псевдо-реальном времени. Для увеличения траффика запросы можно (и нужно) делать в несколько потоков, так как в одном потоке сложно получить более 100 транзакций в секунду. При этом среднее время транзакции (запрос-ответ) в каждом потоке составляет порядка 4 мс.

Перейти к Содержанию


Особенности реализации

  1. В выражении @CoilStatus node addr bitN tag S tag T данные по адресу addr будут считываться из бита N тега S, а записываться в бит N тега T. Если имена S и T совпадают, то читаться - записываться будет тот же самый тег. Если имена не совпадают, то логическая связка читаемого и записываемого значения должна выполняться программно. Это позволяет делать запись в тег после проверки тех или иных условий.

  2. В выражении @CoilStatus node addr bitN DigitalInput S DigitalOutput T данные по адресу addr будут считываться из бита N цифрового входа S, однако записываться будут в бит 0 цифрового выхода T. Это связано с тем, что в случае кривых из-за буферизации нельзя менять отдельные биты данных. Поэтому под запись каждого статуса надо отводить отдельную кривую, в которой будет занят только один нулевой бит.

  3. В текущей версии сервера используются статические таблицы адресов, занимающие довольно много места (около 10 МБ). Это надо учитывать при работе на малоресурсных компьютерах.

Перейти к Содержанию


Желаем успешного использования &ModbusSrv.


CRW-DAQ Copyright (c) 2001-2024 Alexey Kuryakin daqgroup@mail.ru.