Программирование ARM Библиотека FreeMODBUS Fri, July 03 2020  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Библиотека FreeMODBUS Печать
Добавил(а) microsin   

FreeMODBUS это бесплатная реализация популярного протокола MODBUS, специально разработанная для встраиваемых систем. MODBUS это популярный сетевой протокол, широко используемый в производственной индустрии.

Стек коммуникаций MODBUS требует наличия двух слоев протокола:

Modbus Application Protocol (протокол приложения Modbus) - определяет модель данных и функции.
Network - определяет среду обмена данными.

В текущей версии FreeMODBUS (на момент написания статьи это версия FreeMODBUS 1.6) предоставляется реализация Modbus Application Protocol v1.1a, и поддерживаются режимы передачи RTU/ASCII, определенные в спецификации Modbus over serial 1.0. Поскольку версия 0.7 FreeMODBUS также поддерживает MODBUS TCP, определенный в руководстве [2]. Стек FreeMODBUS лицензируется под защитой лицензии BSD (что не относится к демо-приложениям, которые могут лицезироваться отдельно), разрешающей использование в коммерческих целях. В настоящий момент поддерживаются следующие функции MODBUS:

Код Функция
0x01 Read Coils
0x02 Read Discrete Inputs
0x03 Read Holding Registers
0x04 Read Input Register
0x05 Write Single Coil
0x06 Write Single Register
0x0F Write Multiple Coils
0x10 Write Multiple Registers
0x11 Report Slave ID
0x17 Read/Write Multiple Registers

Библиотека FreeMODBUS основана на самых свежих стандартах, и должна быть с ними полностью совместима. Прием и передача фреймов Modbus RTU/ASCII реализованы на машинах состояний, управляемых callback-функциями из слоя абстракции от аппаратуры (hardware abstraction layer, HAL). Это делает простым портирование стека на другие платформы. Если фрейм завершен, то он передается в слой приложения (Modbus Application Layer), где анализируется его содержимое. В слое приложения доступны хуки, позволяющие добавлять новые функции Modbus.

Протокол MODBUS определяет структуру обмена сообщений между главным и подчиненным устройствами (модель master-slave). Устройство master выдает slave-устройству инструкции, которые позволяют считывать или записывать данные slave-устройства. Slave-устройства отвечает на инструкции, которые ему дает master.

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

Modbus master передает данные, содержащие адрес опрашиваемого slave (1 байт), код функции, определяющий запрос (1 байт), данные для обмена (n байт), проверочный код CRC16 (2 байта).

В рабочем режиме Modbus slave никакого функционального блока для коммуникации по протоколу Modbus не требуется. Отправка и прием телеграмм Modbus выполняются автоматически.

[Режим последовательной передачи]

Режим передачи определяет содержимое бит в байтах сообщения, которые передаются по сети, и как информация сообщения упаковывается в поток сообщений, и как декодируется. Существует два стандартных режима последовательной передачи:

ASCII mode
RTU mode

Кодирование фреймов для обоих этих режимов показано на рисунке ниже.

Modbus data framing ASCII and RTU modes

Режим ASCII. В этом режиме каждый байт сообщений кодируется двумя символами ASCII (American Standard Code for Information Interchange). Режим ASCII позволяет применять интервалы времени до секунд, что упрощает декодирование как отдельных символов, так и границ сообщений.

Сообщение ASCII начинается с символа двоеточия, и заканчивается на последовательность возврата каретки и перевода строки (CRLF, коды ASCII 0DH и 0AH). В режиме ASCII байт данных или символ несет в себе только 7 полезных бит данных.

В режиме ASCII все устройства сети ждут поступления символа двоеточия, которое обозначает начало сообщения. И это сообщение декодируется только тем устройством, которому оно было адресовано.

Режим RTU. В режиме RTU (Remote Terminal Unit) каждый 8-битный байт сообщения содержит два 4-битных HEX-символа (т. е. байт передается в двоичном виде), и сообщение передается как непрерывный поток байт.

Промежуток времени между сообщениями позволяет отделить сообщения друг от друга. В режиме RTU сообщения начинаются в интервале тишины, который должен быть по длительности как минимум 3.5 символа на заданной скорости передачи данных сети. Во время передачи сообщения интервалы между отдельными байтами не должны превышать длительности 1.5 символа. Если интервал превысил 1.5 символа, то следующий байт будет адресован как новое сообщение.

Утилиты проверки Modbus используются для диагностики обмена данными и проверки данных по определенному адресу. Эти утилиты используются для тестирования slave-устройств Modbus.

[Radzio! Modbus Master Simulator]

Это бесплатная Windows-утилита, может использоваться как альтернатива для Modscan, Modbus Poll, Simplymodbus. Утилита может обмениваться данными с несколькими slave-устройствами. Интерфейс программы очень удобен и надежен. Поддерживаемый протокол – Modbus RTU / Modbus TCP 1.6.

Modbus Radzio Master Simulator

Ссылка для загрузки - Radzio! Modbus Master Simulator site:en.radzio.dxp.pl.

[Modbus Tester компании Schneider electric]

Modbus Tester бесплатен. Это простая Windows-утилита, позволяющая читать из регистра и записывать в регистр slave-устройства Modbus. Поддерживаемые протоколы - Modbus TCP/IP, Modbus RTU, Modbus ASCII, Jbus.

Modbus Tester Schneider Electric

Чтобы соединиться со slave-устройством через TCP/IP, нужно выбрать порт подключения и ввести IP-адрес устройства. Для последовательного подключения к slave-устройству ASCII/MODBUS RTU нужно выбрать COM-порт и ввести параметры передачи данных - скорость (baud rate), использовать или нет контроль четности (parity). Затем нужно ввести адрес устройства, тип данных, адрес нужного регистра. После этого можно читать или записывать значения регистра.

Ссылка для загрузки - What is Modbus Tester and how do I use it? site:se.com.

[QModMaster]

Бесплатная утилита для систем Windows и Linux, поддерживает протоколы Modbus RTU и Modbus TCP. Позволяет легко обмениваться данными со slave-устройствами и мониторить трафик Modbus.

Modbus QModMaster

Ссылка для загрузки - QModMaster Download site:sourceforge.net.

[Modpoll Modbus® Polling Tool]

Это бесплатная утилита командной строки - симулятор мастера Modbus, работающая на Windows, Linux, Solaris, QNX 6, Raspberry Pi, BeagleBoard и других основанных на ядре ARM устройствах Linux.

Пример вывода утилиты modpoll:

C:\Program Files (x86)\MPT>modpoll.exe -c 4 -r 2000 -m tcp 192.168.0.100
modpoll 3.6 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2018 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.
 
Protocol configuration: MODBUS/TCP
Slave configuration...: address = 1, start reference = 2000, count = 4
Communication.........: 192.168.0.100, port 502, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table
 
-- Polling slave... (Ctrl-C to stop)
[2000]: 0
[2001]: 0
[2002]: 0
[2003]: 0
-- Polling slave... (Ctrl-C to stop)
[2000]: 0
[2001]: 0
[2002]: 0
[2003]: 0
-- Polling slave... (Ctrl-C to stop)
[2000]: 0
[2001]: 0
[2002]: 0
[2003]: 0
-- Polling slave... (Ctrl-C to stop)
[2000]: 0
[2001]: 0
[2002]: 0
[2003]: 0
-- Polling slave... (Ctrl-C to stop)
^C
C:\Program Files (x86)\MPT>

Справка по командной строке (вывод в ответ на команду modpoll.exe -h):

Usage: modpoll [OPTIONS] SERIALPORT|HOST [WRITEVALUES...]
Аргументы:
SERIALPORT    Последовательный порт, когда используется протокол Modbus ASCII или Modbus RTU.
              COM1, COM2 ...                на Windows
              /dev/ttyS0, /dev/ttyS1 ...    на Linux
HOST          Имя хоста или IP-адрес, когда используется протокол MDBUS/TCP.
WRITEVALUES   Список значений для записи. Если ничего не указано (по умолчанию) то modpoll
              прочитает данные.
Основные опции:
-m ascii      Протокол Modbus ASCII.
-m rtu        Протокол RTU (по умолчанию, если SERIALPORT содержит \ или COM).
-m tcp        Протокол MODBUS/TCP (иначе по умолчанию).
-m udp        MODBUS UDP.
-m enc        Modbus RTU, инкапсулированный через TCP.
-a #          Slave address (1-255 для serial, 0-255 для TCP, 1 по умолчанию).
-r #          Начальный адрес значений (1-65536, по умолчанию 100).
-c #          Количество значений для чтения (1-125, 1 по умолчанию).
-t 0          Тип данных дискретный выход (coil).
-t 1          Тип данных дискретный вход.
-t 3          Тип данных 16-битный входной регистр.
-t 3:hex      Тип данных 16-битный входной регистр с HEX-отображением.
-t 3:int      Тип данных 32-битный integer в таблице входных регистров.
-t 3:mod      Тип данных 32-битный module 10000 в таблице входных регистров.
-t 3:float    Тип данных 32-битный float в таблице входных регистров.
-t 4          Тип данных 16-битный регистр выхода (holding), по умолчанию.
-t 4:hex      Тип данных 16-битный регистр выхода (holding), с HEX-отображением.
-t 4:int      Тип данных 32-битный integer в таблице выходных регистров (holding).
-t 4:mod      Тип данных 32-битный module 10000 в таблице выходных регистров (holding).
-t 4:float    Тип данных 32-битный float в таблице выходных регистров (holding).
-i            Slave работает с 32-битными integer с порядком байт big-endian.
-f            Slave работает с 32-битными float с порядком байт big-endian.
-e            Использовать 32-битный режим регистра Daniel/Enron (подразумевает -i и -f).
-0            Начальный адрес отсчитывается от 0 (адресация PDU) вместо 1.
-1            Опросить только один раз, иначе опрашивать с интервалом poll rate.
-l #          Интервал опроса (poll rate) в мс, (по умолчанию 1000).
-o #          Таймаут в секундах (0.01 .. 10.0, по умолчанию 1.0 секунда).
Опции для MODBUS/TCP, UDP и RTU через TCP:
-p #          номер порта IP (по умолчанию 502).
Опции для Modbus ASCII и Modbus RTU:
-b #          Скорость, baudrate (например 9600, 19200, ...). По умолчанию 19200.
-d #          Количество бит в фрейме (7 или 8 для протокола ASCII, 8 для RTU).
-s #          Количество stop-бит (1 или 2, по умолчанию 1).
-p none       Без контроля четности.
-p even       Контроль по четности (по умолчанию).
-p odd        Контроль по нечетности.
-4 #          Режим RS-485, RTS включен при передаче и еще # мс после этого.

Ссылка для загрузки - Modpoll Modbus Master Simulator site:modbusdriver.com.

Все описанные утилиты можно скачать по ссылке [6].

[Реализация устройства Modbus TCP]

Здесь рассматривается реализация устройства Modbus TCP на основе FreeRTOS и библиотек LwIP и FreeMODBUS. Подразумевается, что вы уже создали рабочий проект, где можете создавать и запускать задачи FreeRTOS, и стек LwIP сконфигурирован и работает. Осталось добавить функционал устройства ModbusTCP.

Процесс по шагам:

1. Скачайте библиотеку FreeMODBUS [4]. На момент написания статьи это была версия FreeMODBUS 1.6. Распакуйте архив библиотеки в отдельный каталог, находящийся в папке проекта.

2. Создайте задачу FreeRTOS, которая до входа в бесконечный цикл for(;;) запускает функцию eMBTCPInit, и внутри бесконечного цикла делает вызовы eMBPoll (конкретный пример см. во врезке далее).

3. Перекомпилируйте проект. Компилятор ругнется на отсутствие определений для новых функций Modbus, которые Вы только что добавили (eMBTCPInit, eMBPoll). Разрешите в проекте все необходимые зависимости путем добавления нужных модулей FreeMODBUS и настройки в проекте путей поиска необходимых заголовочных файлов.

4. На каком-то этапе добавления модулей в проект компилятор запросит реализацию функций для портирования FreeMODBUS на рабочую среду, где библиотека работает (функции порта FreeMODBUS). Это функции генерации и обработки событий, установки и закрытия соединения TCP, приема и передачи пакетов, отладки и т. п., реализация функций привязана к особенностям целевой системы - к модели микроконтроллера, библиотеке TCP и особенностям RTOS. Функции порта FreeMODBUS перечислены в таблице ниже:

Функция Описание
Модуль portevent.c (необходимые функции).
xMBPortEventInit Инициализация подсистемы генерации и обработки событий.
vMBPortEventClose Деинициализация подсистемы генерации и обработки событий.
xMBPortEventPost Генерация события библиотеки FreeModbus. Появление события разблокирует поток обработки события FreeModbus, и будут выполнены соответствующие действия.
xMBPortEventGet Выборка информации о событии.
Модуль portother.c. Это отладочные функции, и они нужны только в том случае, если разрешена отладка кода библиотеки FreeMODBUS.
prvvMBTCPLogFrame Генерирует краткое описание содержимого фрейма Modbus TCP, и выводит его с помощью функции vMBPortLog.
vMBPortLog Функция физического вывода отладочной информации. В зависимости от реализации может выводить текст отладочных сообщений либо на экран LCD, либо в порт UART (пример реализации вывода в порт USART6 микроконтроллера STM32F4xx см. во врезке ниже).
Модуль porttcp.c (необходимые функции).
xMBTCPPortInit Подготавливает систему обмена пакетами TCP.
prvvMBPortReleaseClient Останавливает сессию соединения с сервером Modbus TCP.
vMBTCPPortClose Закрытие всех сетевых сокетов TCP.
vMBTCPPortDisable Закрывает все существующие сессии Modbus TCP.
prvxMBTCPPortAccept Принимает сетевое соединение.
prvvMBTCPPortError Обработка фатальной ошибки.
prvxMBTCPPortReceive Прием пакета.
xMBTCPPortGetRequest Получение запроса Modbus TCP.
xMBTCPPortSendResponse Отправка ответа на запрос Modbus TCP.

Примечание: в качестве сервера Modbus выступает подчиненное опрашиваемое устройство, а в качестве клиента - главное устройство сети, обычно персональный компьютер. Однако в терминологии протокола TCP/IP оба этих устройства в процессе обмена выступают в двух ролях - и как сервер TCP (прослушивающий по умолчанию порт 502), и как клиент TCP.

Проще всего взять функции порта FreeMODBUS готовые, из рабочих примеров. Примеры находятся в каталоге demo, а модули portevent.c, portother.c и porttcp.c в подкаталоге port примера. При необходимости эти модули можно модифицировать, чтобы они учитывали специфику Вашего проекта. Модули для микроконтроллера STM32F4xx см. во врезке ниже.

5. Функциональные возможности устройства Modbus (какие запросы обрабатываются, и каким образом) определяются таблицей xFuncHandlers. Это простая таблица, где каждая строка состоит их двух полей - команда (запрос) Modbus и указатель на функцию его обработки (строка это экземпляр структуры xMBFunctionHandler). Пример таблицы xFuncHandlers:

static const xMBFunctionHandler xFuncHandlers[10] =
{
   {0x01, eMBFuncReadCoils                       },
   {0x02, eMBFuncReadDiscreteInputs              },
   {0x03, eMBFuncReadHoldingRegister             },
   {0x04, eMBFuncReadInputRegister               },
   {0x05, eMBFuncWriteCoil                       },
   {0x0F, eMBFuncWriteMultipleCoils              },
   {0x10, eMBFuncWriteMultipleHoldingRegister    },
   {0x11, eMBFuncReportSlaveID                   },
   {0x17, eMBFuncReadWriteMultipleHoldingRegister},
   {0, NULL}
};

В этой таблице реализован следующий функционал устройства Modbus: чтение обмоток (запрос 0x01), чтение цифровых входов (запрос 0x02), чтение регистра хранения (запрос 0x03), чтение входного регистра (запрос 0x04), запись обмоток (запрос 0x05), запись нескольких обмоток (запрос 0x0F), запись нескольких регистров хранения (запрос 0x10), запрос идентификатора устройства Modbus (запрос 0x11), обновление нескольких регистров хранения (запрос 0x17).

Для своего устройства Modbus Вам необходимо подготовить аналогичную таблицу и реализовать код обработчиков запросов.

6. Если что-то пошло не так, и необходимо отлаживать поведение стека FreeMODBUS, то в заголовочном файле port.h определите в 1 макрос MB_TCP_DEBUG, и подготовьте необходимую реализацию функции vMBPortLog (пример см. во врезке ниже).

Ниже показаны только куски кода, демонстрирующие основной функционал. Полный готовый проект IAR 8.30 с исходным кодом для STM32F407 можно скачать по ссылке [5].

[main.c]

Поток FreeRTOS, обрабатывающий протокол ModbusTCP:

static void modbusTask(void *argument)
{
   bool bModBusInitOK;
   eMBErrorCode xStatus;
 
   /* Код инициализации для LWIP */
   MX_LWIP_Init();
   
   // Инициализация стека Modbus:
   if(eMBTCPInit(MB_TCP_PORT_USE_DEFAULT) != MB_ENOERR)
   {
      umsg("FreeMODBUS: can't initialize modbus stack!\n");
      bModBusInitOK = false;
   }
   else if (eMBEnable() != MB_ENOERR)
   {
      umsg("FreeMODBUS: can't enable modbus stack!\n");
   }
   else
   {
      bModBusInitOK = true;
   }
   
   /* Бесконечный цикл */
   for(;;)
   {
      if (bModBusInitOK)
      {
         xStatus = eMBPoll();
         if (MB_ENOERR != xStatus)
         {
            umsg("Ошибка FreeMODBUS: %i\n", xStatus);
         }
         CheckLink();
      }
   }
}

Примечание: функция umsg позволяет выводить произвольные отладочные сообщения в последовательную консоль USART6.

[port.h]

#define MB_TCP_DEBUG     1
 
// Этот вариант работает (блокировка на мьютексе средствами RTOS):
//#define  OS_ENTER_CRITICAL()     sys_arch_protect()
//#define  OS_EXIT_CRITICAL()      sys_arch_unprotect(NULL)
 
// Этот вариант тоже работает (жесткая блокировка с прямым запретом
// прерываний и поддержкой вложенности):
#define  OS_ENTER_CRITICAL()     vPortEnterCritical()
#define  OS_EXIT_CRITICAL()      vPortExitCritical()
 
// Можно даже совсем закомментировать макросы OS_ENTER_CRITICAL и OS_EXIT_CRITICAL.
 
#define ENTER_CRITICAL_SECTION(  )   OS_ENTER_CRITICAL()
#define EXIT_CRITICAL_SECTION(  )    OS_EXIT_CRITICAL()

[portevent.c]

#include "settings.h"
 
#if (MODBUS_EVENT_PORT == MODBUS_EVENT_WITH_QUEUE)
   #include "portevent-with-queue.c"
#elif (MODBUS_EVENT_PORT == MODBUS_EVENT_WITH_MBOX)
   #include "portevent-with-mbox.c"
#else
   #error "None Modbus portevent selected!"
#endif

Макросом MODBUS_EVENT_PORT можно выбрать один из вариантов организации обработки событий - на основе очереди или на основе mailbox FreeRTOS. На мой взгляд, они работают почти одинаково, на основе mailbox отклик на события немного быстрее.

[portother.c]

#define MB_FRAME_LOG_BUFSIZE 512
 
#ifdef MB_TCP_DEBUG
void prvvMBTCPLogFrame( UCHAR * pucMsg, UCHAR * pucFrame, USHORT usFrameLen )
{
   int             i;
   int             res = 0;
   int             iBufPos = 0;
   size_t          iBufLeft = MB_FRAME_LOG_BUFSIZE;
   static CHAR     arcBuffer[MB_FRAME_LOG_BUFSIZE];
 
   assert( pucFrame != NULL );
 
   for( i = 0; i < usFrameLen; i++ )
   {
      /* Выводит на печать некоторую дополнительную информацию о фрейме. */
      switch ( i )
      {
      case 0:
         /* TID = Transaction Identifier (идентификатор трансляции). */
         res = snprintf( &arcBuffer[iBufPos], iBufLeft, "| TID = " );
         break;
      case 2:
         /* PID = Protocol Identifier (идентификатор протокола). */
         res = snprintf( &arcBuffer[iBufPos], iBufLeft, " | PID = " );
         break;
      case 4:
         /* Длина */
         res = snprintf( &arcBuffer[iBufPos], iBufLeft, " | LEN = " );
         break;
      case 6:
         /* UID = Unit Identifier (идентификатор юнита). */
         res = snprintf( &arcBuffer[iBufPos], iBufLeft, " | UID = " );
         break;
      case 7:
         /* MB Function Code (код функции MODBUS). */
         res = snprintf( &arcBuffer[iBufPos], iBufLeft, "|| FUNC = " );
         break;
      case 8:
         /* MB PDU rest (остаток: данные PDU). */
         res = snprintf( &arcBuffer[iBufPos], iBufLeft, " | DATA = " );
         break;
      default:
         res = 0;
         break;
      }
      if( res == -1 )
      {
          break;
      }
      else
      {
          iBufPos += res;
          iBufLeft -= res;
      }
 
      /* Вывод на печать данных. */
      res = snprintf( &arcBuffer[iBufPos], iBufLeft, "%02X", pucFrame[i] );
      if( res == -1 )
      {
          break;
      }
      else
      {
          iBufPos += res;
          iBufLeft -= res;
      }
   }
 
   if( res != -1 )
   {
       /* Добавление конца строки фрейма. */
       res = snprintf( &arcBuffer[iBufPos], iBufLeft, " |\r\n" );
       if( res != -1 )
       {
           vMBPortLog( MB_LOG_DEBUG, (const CHAR*)pucMsg, "%s", arcBuffer );
       }
   }
}
 
void vMBPortLog( eMBPortLogLevel eLevel,
                 const CHAR * szModule,
                 const CHAR * szFmt,
                 ... )
{
   va_list args;
   static const char *arszLevel2Str[] = {"DEBUG", "INFO", "WARN", "ERROR"};
   static char mbtmpbuf[UPRINTF_BUF_SIZE];
   int16_t outsize;
   
   va_start( args, szFmt );
   outsize = vsprintf(mbtmpbuf, szFmt, args);
   mbtmpbuf[outsize+1] = 0;
   va_end( args );
   umsg("%s: %s: %s", arszLevel2Str[eLevel], szModule, mbtmpbuf);
}
#endif

[umsg.h]

int16_t uprintf (const char *fmt, ...)
{
   int16_t outsize;
   va_list ap;
 
   // Вернет ошибку, если формат является указателем NULL:
   if (!fmt) { return -1; }
   // Вернет ошибку, если строка превышает размер буфера, с учетом
   // необходимых дополнительных 2 символов: CR и нулевой терминатор ASCIIZ:
   if (UPRINTF_BUF_SIZE-2 < strlen(fmt)) { return -1; }
 
   va_start (ap,fmt);
   outsize = vsprintf(strbuf,fmt,ap);
   strbuf[outsize+1] = 0;
   va_end (ap);
 
   usartputs(strbuf);
   xSemaphoreGive(usarttxSemaphore);
   return outsize;
}
 
//***************************************
//* Макрос umsg выводит форматированный текст в UART точно так же,
//* как это делает printf в стандартный вывод. Аргумент fmt содержит
//* набор спецификаторов преобразования, директивы и обычные символы,
//* которые используются для управления выводом.
//*
//* Параметры:
//*   fmt      текст, который может содержать спецификаторы формата
//*   ...      список аргументов
//*
//* Возвращаемое значение: количество переданных символов, за
//* исключением CR. Если произошла ошибка, то будет возвращено
//* отрицательное значение.
//*
//* Команды управления:
//* '\e' escape character. It maps to the ASCII Escape code, 27
//* '\f' form feed/flush screen
//* '\n' new line
//* '\r' carriage return
//* '\t' horizontal tab
//* '\v' vertical tab
//*/
#define umsg(...) \
        { \
            uprintf (__VA_ARGS__); \
        }

[Ссылки]

1. FreeMODBUS A portable MODBUS ASCII/RTU and TCP implementation site:embedded-solutions.at.
2. Modbus Messaging on TCP/IP Implementation Guide v1.0a site:modbus.org.
3. Modbus Test Utility - Free alternative to Modscan / Modbus Poll / Simply Modbus site:automationforum.in.
4. cwalter-at/freemodbus site:github.com.
5191011Modbus-STM32F407-public.zip - исходный код примера устройства Modbus TCP (проект для IAR 8.3, микроконтроллер STM32F407).
6. 191211Modbus-server.zip - утилиты для тестирования устройств Modbus (эмуляторы клиента Modbus).
7. MODBUS: спецификация протокола приложения.

 

Добавить комментарий


Защитный код
Обновить

Top of Page