Создание Slave устройства в сети Modbus
Создание Slave устройства в сети Modbus
На базе одноплатного ПК imx6ul создаем Slave устройство в сети Modbus.
Канал RS-485, витая пара, 115200.
Используем порт /dev/ttymxc0
флаги открытия порта
flags = O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL;
ctx->s = open(ctx_rtu->device, flags);
параметры порта
stty < /dev/ttymxc0
speed 115200 baud; line = 0;
intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>;
eol = <undef>; eol2 = <undef>; swtch = <undef>; start = <undef>;
stop = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>;
lnext = <undef>; flush = <undef>; min = 0; time = 0;
-brkint -icrnl -imaxbel
-opost -onlcr
-isig -icanon -iexten -echo -echoe -echok -echoctl -echoke
stty -a < /dev/ttymxc0
speed 115200 baud;stty: standard input
line = 0;
intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>;
eol = <undef>; eol2 = <undef>; swtch = <undef>; start = <undef>;
stop = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>;
lnext = <undef>; flush = <undef>; min = 0; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon
-ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0
ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop
-echoprt -echoctl -echoke
Дополнительно пакеты не ставим, используем библиотеку LibModbus, далее вызовы Posix
Структура tios для этого порта
tios @0x740fc8e4 struct termios
c_cc @0x740fc8f5 cc_t[32]
[0] 0 cc_t
[1] 0 cc_t
[2] 0 cc_t
[3] 0 cc_t
[4] 0 cc_t
[5] 0 cc_t
[6] 0 cc_t
[7] 0 cc_t
[8] 0 cc_t
[9] 0 cc_t
[10] 0 cc_t
[11] 0 cc_t
[12] 0 cc_t
[13] 0 cc_t
[14] 0 cc_t
[15] 0 cc_t
[16] 0 cc_t
[17] 0 cc_t
[18] 0 cc_t
[19] 0 cc_t
[20] 0 cc_t
[21] 0 cc_t
[22] 0 cc_t
[23] 0 cc_t
[24] 0 cc_t
[25] 0 cc_t
[26] 0 cc_t
[27] 0 cc_t
[28] 0 cc_t
[29] 0 cc_t
[30] 0 cc_t
[31] 0 cc_t
c_cflag (hex) 18b2 tcflag_t
c_iflag 0 tcflag_t
c_ispeed (hex) 1002 speed_t
c_lflag 0 tcflag_t
c_line 0 cc_t
c_oflag 0 tcflag_t
c_ospeed (hex) 1002 speed_t
Вызов самой функции настройки порта
if (tcsetattr(ctx->s, TCSANOW, &tios) < 0) {
close(ctx->s);
ctx->s = -1;
return -1;
}
Далее настройки
rs485conf @0x740fc900 struct serial_rs485
delay_rts_after_send 0 __u32
delay_rts_before_send 0 __u32
flags 5 __u32
padding @0x740fc90c __u32[5]
[0] 0 __u32
[1] 0 __u32
[2] 0 __u32
[3] 0 __u32
[4] 0 __u32
ioctl(ctx->s, TIOCSRS485, &rs485conf);
Затем еще
rs485conf @0x740fc900 struct serial_rs485
delay_rts_after_send 0 __u32
delay_rts_before_send 0 __u32
flags 5 __u32
padding @0x740fc90c __u32[5]
[0] 0 __u32
[1] 0 __u32
[2] 0 __u32
[3] 0 __u32
[4] 0 __u32
ioctl(ctx->s, TIOCSRS485, &rs485conf);
Все остальные настройки на прикладном уровне.
Алгоритм работы:
зависаем на порте в функции Posix
select(ctx->s+1, rset, NULL, NULL, tv);
на бесконечный таймаут, когда в канале появяться данные, считываем несколькоми портциями (могу рассказать подробнее, но сейчас это не важно, там проблем вроде нет)
анализируем данные, отправляем ответ.
И все работает отлично какое то время, например 6000 посылок/ответов.
Далее два варианта ошибок.
1. Затем посылаем очередной запрос от Master, но ПО с функции select не уходит, то есть прикладная программа данных не видит. Но при этом в канал в ответ уходит 4кБ информации,
частино соответствующей прошлям запросам, это по нашему мнению на сейчас полностью выдается выходной буфер.
Далее обмен восстанавливается. До новых 4кБ. Проявляется при запросах, когда длина ответной посылки более 35 байт.
2. При запросах более коротких ответов нормальный обмен может проходить и более 100 000 раз, но потом порт обрывается наглухо, требуется пререзагрузка Slave устройства.
Канал RS-485, витая пара, 115200.
Используем порт /dev/ttymxc0
флаги открытия порта
flags = O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL;
ctx->s = open(ctx_rtu->device, flags);
параметры порта
stty < /dev/ttymxc0
speed 115200 baud; line = 0;
intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>;
eol = <undef>; eol2 = <undef>; swtch = <undef>; start = <undef>;
stop = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>;
lnext = <undef>; flush = <undef>; min = 0; time = 0;
-brkint -icrnl -imaxbel
-opost -onlcr
-isig -icanon -iexten -echo -echoe -echok -echoctl -echoke
stty -a < /dev/ttymxc0
speed 115200 baud;stty: standard input
line = 0;
intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>;
eol = <undef>; eol2 = <undef>; swtch = <undef>; start = <undef>;
stop = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>;
lnext = <undef>; flush = <undef>; min = 0; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon
-ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0
ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop
-echoprt -echoctl -echoke
Дополнительно пакеты не ставим, используем библиотеку LibModbus, далее вызовы Posix
Структура tios для этого порта
tios @0x740fc8e4 struct termios
c_cc @0x740fc8f5 cc_t[32]
[0] 0 cc_t
[1] 0 cc_t
[2] 0 cc_t
[3] 0 cc_t
[4] 0 cc_t
[5] 0 cc_t
[6] 0 cc_t
[7] 0 cc_t
[8] 0 cc_t
[9] 0 cc_t
[10] 0 cc_t
[11] 0 cc_t
[12] 0 cc_t
[13] 0 cc_t
[14] 0 cc_t
[15] 0 cc_t
[16] 0 cc_t
[17] 0 cc_t
[18] 0 cc_t
[19] 0 cc_t
[20] 0 cc_t
[21] 0 cc_t
[22] 0 cc_t
[23] 0 cc_t
[24] 0 cc_t
[25] 0 cc_t
[26] 0 cc_t
[27] 0 cc_t
[28] 0 cc_t
[29] 0 cc_t
[30] 0 cc_t
[31] 0 cc_t
c_cflag (hex) 18b2 tcflag_t
c_iflag 0 tcflag_t
c_ispeed (hex) 1002 speed_t
c_lflag 0 tcflag_t
c_line 0 cc_t
c_oflag 0 tcflag_t
c_ospeed (hex) 1002 speed_t
Вызов самой функции настройки порта
if (tcsetattr(ctx->s, TCSANOW, &tios) < 0) {
close(ctx->s);
ctx->s = -1;
return -1;
}
Далее настройки
rs485conf @0x740fc900 struct serial_rs485
delay_rts_after_send 0 __u32
delay_rts_before_send 0 __u32
flags 5 __u32
padding @0x740fc90c __u32[5]
[0] 0 __u32
[1] 0 __u32
[2] 0 __u32
[3] 0 __u32
[4] 0 __u32
ioctl(ctx->s, TIOCSRS485, &rs485conf);
Затем еще
rs485conf @0x740fc900 struct serial_rs485
delay_rts_after_send 0 __u32
delay_rts_before_send 0 __u32
flags 5 __u32
padding @0x740fc90c __u32[5]
[0] 0 __u32
[1] 0 __u32
[2] 0 __u32
[3] 0 __u32
[4] 0 __u32
ioctl(ctx->s, TIOCSRS485, &rs485conf);
Все остальные настройки на прикладном уровне.
Алгоритм работы:
зависаем на порте в функции Posix
select(ctx->s+1, rset, NULL, NULL, tv);
на бесконечный таймаут, когда в канале появяться данные, считываем несколькоми портциями (могу рассказать подробнее, но сейчас это не важно, там проблем вроде нет)
анализируем данные, отправляем ответ.
И все работает отлично какое то время, например 6000 посылок/ответов.
Далее два варианта ошибок.
1. Затем посылаем очередной запрос от Master, но ПО с функции select не уходит, то есть прикладная программа данных не видит. Но при этом в канал в ответ уходит 4кБ информации,
частино соответствующей прошлям запросам, это по нашему мнению на сейчас полностью выдается выходной буфер.
Далее обмен восстанавливается. До новых 4кБ. Проявляется при запросах, когда длина ответной посылки более 35 байт.
2. При запросах более коротких ответов нормальный обмен может проходить и более 100 000 раз, но потом порт обрывается наглухо, требуется пререзагрузка Slave устройства.
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Создание Slave устройства в сети Modbus
Уточняем ...Larisa писал(а):На базе одноплатного ПК imx6ul создаем Slave устройство в сети Modbus.
Канал RS-485, витая пара, 115200.
1. У вас отдельный внешний преобразователь RS-232->RS-485 или чип UART платы может переключаться в режим RS-485?
Это серийный одноплатный ПК, или сделанный по образу и подобию?
Архитектура ARM?
2. Нельзя ли поменять (снизить) скорость (временно). Потому что по стандарту (первоначальному, раннему) скорости UART до 57600 были для асинхронной (более надёжной) связи, а 115200 - для синхронной, когда данные могли "проваливаться".
Будут ли те же эффекты наблюдаться при пониженной скорости?
3. У вас действительно ПК это Slave устройство, а оконечное устройство - Master?
Я, вообще-то видел только в точности до наоборот: ПК - Master, а гирлянда оконечных устройств - Slave.
4. Вы через этот же UART можете наблюдать отладочные сообщения периода отладки? Так как описано в соседней теме: загрузчик U-boot и сериальная отладка.
Там всё нормально?
И вот там режим сериальной линии должен быть канонический.
5. Не видел никогда /dev/ttymxc*, но, может это зависит от вашей архитектуры...Larisa писал(а): Используем порт /dev/ttymxc0
Или у вас собственный драйвер UART.
У вас там ничего нет подобного в выводе команды lsmod ?
6. Мне кажется (только IMHO) что у вас -icanon не должно быть установлено, вам нужен неканонический режим сериального порта для байтовой передачи (возможно с вариациями min=1 ? и time ... не помню деталей).Larisa писал(а): параметры порта
stty < /dev/ttymxc0
speed 115200 baud; line = 0;
intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>;
eol = <undef>; eol2 = <undef>; swtch = <undef>; start = <undef>;
stop = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>;
lnext = <undef>; flush = <undef>; min = 0; time = 0;
-brkint -icrnl -imaxbel
-opost -onlcr
-isig -icanon -iexten -echo -echoe -echok -echoctl -echoke
7. LibModbus - это уже есть дополнительный пакет для работы с Modbus, вот как у меня это выглядит в Debian 10:Larisa писал(а): Дополнительно пакеты не ставим, используем библиотеку LibModbus, далее вызовы Posix
Код: Выделить всё
olej@ACER:~$ aptitude search modbus
i libmodbus-dev - development files for the Modbus protocol library
i A libmodbus5 - library for the Modbus protocol
p python-pymodbus - full Modbus protocol implementation for Python 2
i python-pymodbus-doc - full Modbus protocol implementation, documentation
v python2.7-pymodbus -
i python3-pymodbus - full Modbus protocol implementation for Python 3
P.S. Но вопрос я уточнял потому, что Modbus зависит от тайм-аутов ожидания, и вопрос был в том, обеспечиваете ли вы тайм-ауты вручную (это плохо), или за вас это делает библиотека.
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Создание Slave устройства в сети Modbus
Я недавно возился слегка с Modbus (правда из Python 3).Larisa писал(а):На базе одноплатного ПК imx6ul создаем Slave устройство в сети Modbus.
Может вам покажутся полезными вот такие инструменты (хотя это и не имеет прямого отношения к вашим проблемам):
1. Симуляторы для отладки (консольные) - подвесив с ответной стороны можно провести автономную и очень детальную отладку обмена:
- симулятор Master: Modpoll Modbus Master Simulator
- симулятор Slave: Diagslave Modbus Slave Simulator
2. Спецификация MODBUS over serial line specification and implementation guide V1.02, достаточно свежая и там полезные детали:
MODBUS over Serial Line
Specification and Implementation Guide
V1.02
Dec 20, 2006
стр. 46
Re: Создание Slave устройства в сети Modbus
1. Это по этому порту это устройство Slave в сети верхнего уровня.
2. Средст эмуляции Master устройства у нас достаточно, фирма давно работает с этими протоколами, спецификации нами хорошо изучены.
3. С меньшей скоростью (9600) мы пробовали, ситуация та же.
4. Драйвер используется стандартный, он именно ttymxc0.
5. Преобразователь на UART - 485 встроен в само устройство. Устройсво нашей разработки, но практически копирует imx6ul.
На остальные вопрос отвечу позже.
Спасибо за быстрый ответ.
2. Средст эмуляции Master устройства у нас достаточно, фирма давно работает с этими протоколами, спецификации нами хорошо изучены.
3. С меньшей скоростью (9600) мы пробовали, ситуация та же.
4. Драйвер используется стандартный, он именно ttymxc0.
5. Преобразователь на UART - 485 встроен в само устройство. Устройсво нашей разработки, но практически копирует imx6ul.
На остальные вопрос отвечу позже.
Спасибо за быстрый ответ.
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Создание Slave устройства в сети Modbus
Т.е. этот одноплатник (и возможно ещё такие же) как Slave подключен к какому-то управляющему компьютеру верхнего уровня, который Master?Larisa писал(а):1. Это по этому порту это устройство Slave в сети верхнего уровня.
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Создание Slave устройства в сети Modbus
Из man-ов:Larisa писал(а): Структура tios для этого порта
Код: Выделить всё
olej@ACER:~$ man cfmakeraw
...
Raw mode
cfmakeraw() sets the terminal to something like the "raw" mode of the old Version 7 terminal driver: input is available character by character, echoing is disabled, and all
special processing of terminal input and output characters is disabled. The terminal attributes are set as follows:
termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
| INLCR | IGNCR | ICRNL | IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
termios_p->c_cflag &= ~(CSIZE | PARENB);
termios_p->c_cflag |= CS8;
Или, может, просто попробовать использовать для подготовки порта cfmakeraw().
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Создание Slave устройства в сети Modbus
Это что-то вот такое? iMX6ULL. Переход к процессорным модулям (возможно с технологическими отличиями исполнения):Larisa писал(а):На базе одноплатного ПК imx6ul создаем Slave устройство в сети Modbus.
Re: Создание Slave устройства в сети Modbus
Добрый день. По одноплатнику - да, чтото похожее. Не точно такое, но похожее. По Slave - наши устройства Заказчик может объединять в сети, где это устройство выступает в качестве Slave. Но это по одному из портов. По другим 4 портам это же наше устройство выступает в качестве Master и связывается уже со своей периферией также по Modbus или по другим похожим протоколам. То есть на уровне системы порты могут выступать как Master или Slave, и это зависит уже от прикладных задач.
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Создание Slave устройства в сети Modbus
То, что вы называете "порты" - это физически разные интерфейсы RS-485? Я правильно понял? У вас их 5?Larisa писал(а):Но это по одному из портов. По другим 4 портам это же наше устройство выступает в качестве Master и связывается уже со своей периферией также по Modbus или по другим похожим протоколам. То есть на уровне системы порты могут выступать как Master или Slave, и это зависит уже от прикладных задач.
Т.е. /dev/ttymxc0, /dev/ttymxc1, /dev/ttymxc2 ... и т.д.
Re: Создание Slave устройства в сети Modbus
Да, Вы поняли правильно. По остальным интерфейсам наше устройство выступает как Master. И там все в порядке. Проверены не все (ПО в процессе разработки), но на одном из этих интерфейсов проходили длительные испытания с весьма интенсивным обменом (один из интерфейсов - обмен 1,5 кБ раз в 150 мс, скорость 230400, используется модификация протокола Modbus), за сутки ни одной ошибки.
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей