Опыт импортозамещения контроллеров B&R с сохранением проекта. Подробности реализации в конце, под спойлером.

Привет, Хабр. В прошлый раз я рассказывал, как из отдела разработки остался один с компетенциями по софту на двести с лишним моек, и обещал отдельно рассказать, как переводил контроллеры B&R на мини-ПК. Вот, рассказываю.

Сразу оговорка. Код тут не мой, вообще. Драйвер, RT-ядро, патчи стека, шлюзы, скрипты развёртывания — всё писал ИИ. Я знаю, как устроена вся система, поэтому понимал, что стоит попробовать, и спрашивал: а можно ли вот так? Давал ему читать документацию — по проекту, по железу, по протоколам. И в диалоге постепенно стало понятно, что вообще возможно и как. Так всё и сделалось. Подробности реализации — в конце под спойлером, кому надо.

Предыстория

Проект автоматизации у нас на Automation Studio, это среда B&R, и крутился он на контроллере B&R. В 2022-м контроллеры продавать перестали. Сначала ничего страшного: объекты работают, на складе что-то лежит. А потом головы начали умирать. Одна, вторая. Бэушный контроллер через серый импорт — от полумиллиона, и никто не скажет, сколько он протянет.

Меня об этом, если честно, никто не просил. Вендор ушёл, граница закрыта, проблема заказчика — иди покупай что есть. Но как-то не по себе было, что за это платит владелец мойки, у которого объект стоит и денег не приносит. Мини-ПК стоит тысяч двадцать-тридцать. Ну и попробовал.

В сам проект лезть не хотелось совсем. Там годами люди что-то делали, отлаживали, и половину того, почему сделано именно так, я не знаю. Влезешь, что-то поправишь, а через месяц на мойке вылезет то, о чём ты и не подозревал. Поэтому очевидно было, что менять надо по минимуму. А что тут можно поменять, не трогая логику? Только среду, в которой оно работает. То есть во всех случаях — сменить голову, а всё остальное оставить как есть. Перепривязать переменные к другим адресам это ещё терпимо, это конфигурация. Переписывать алгоритм и визуализацию — нет.

Симулятор вместо контроллера

У B&R есть два способа гонять проект на обычном компьютере. ARwin — это настоящее реальное время под Windows, захватывает ядра, гарантирует задержки. Но ему нужна фирменная карта и лицензионный ключ, а их тоже не купить. И есть ARsim — симулятор для отладки, идёт в комплекте с Automation Studio. Реального времени он не обещает, только старается: ядра под себя тянет, но чтобы задержки поменьше были, а не чтобы их гарантировать.

Ставить симулятор в бой — идея, скажем так, не очевидная. Но я посмотрел на мойку: а ей что вообще надо? Насос включить, насос выключить, лампу зажечь, на экране показать. Плюс-минус полсекунды тут никого не волнует. Значит, симулятора хватит. И ARsim работает через Ethernet: REST умеет, Modbus TCP умеет, OPC UA умеет, по нему у нас всё и общается. То есть ставим на любой ПК и цепляем к настоящему железу.

Честно, не был уверен, что взлетит. Попробовали на одной мойке: стойки B&R поменяли на модули другого производителя с контроллером шины на Modbus TCP, поставили мини-ПК с ARsim, вручную составили Modbus-таблицу и перепривязали к ней переменные в проекте. Код не тронули. Заработало. С тех пор так сделано около сотни объектов.

Одна таблица вместо кучи устройств

Дальше упёрся в то, чего не ждал. Устройств на мойке много: каплеры, пылесосы, свет, счётчики. И ARsim с ними не справился — он 32-битный, под каждое Modbus-устройство резервирует память, и на седьмом устройстве упёрся в потолок и начал перезапускаться. Решение простое: шлюз, который сам опрашивает все устройства и складывает их в одну Modbus-таблицу. Для ARsim это одно устройство. Проект опять только перепривязали. Этот шлюз с 2023-го стоит на всех мойках с мини-ПК.

А потом стойки, которые не заменить

Всё это работало, пока не начали умирать головы у старых моек. Там стойки родные, B&R, с каплером POWERLINK. Стойки живые, им ещё лет десять служить, а менять — это перемонтаж сотен точек на каждом объекте. Первая мысль была очевидная: поменять каплер POWERLINK на каплер Modbus TCP и дальше как раньше. Не вышло. По POWERLINK на ПЛК шли фронты с расходомеров, и сам ПЛК их считал. Каплер Modbus так не умеет — его опрашивают раз в сотни миллисекунд, а фронты чаще. Значит, стойку с POWERLINK оставляем, а POWERLINK как-то поднимаем на ПК.

Открытая библиотека есть, openPOWERLINK. Ей нужна система реального времени. Ладно, RT-ядро ИИ собрал и накатил сам, для него это оказалось не проблемой. Проблема в железе: POWERLINK работает не с любой сетевой картой, и в библиотеке драйверы только под старые модели. Достать можно, но долго и ненадёжно. Решили попробовать современную, Intel I226, она во всех мини-ПК стоит, и сделать под неё драйвер по образу и подобию старого. Честно скажу: к тому, что он получился и заработал, я отношения не имею. ИИ сделал, я проверил, работает. Ну и замечательно.

Дальше по накатанной. Ещё один шлюз, который опрашивает стойку по POWERLINK на отдельном ядре, сам считает фронты и импульсы, как раньше ПЛК, и отдаёт всё в ещё одно Modbus-устройство. Его втянули в ту же сводную таблицу, а проект перепривязали на одну линейку Modbus-устройств — переменные привязываются в дереве проекта, не в коде, так что код опять не тронут.

В итоге для проекта весь зоопарк стоек и устройств выглядит как одна Modbus-станция:

Проект Automation Studio на симуляторе рантайма видит одну станцию Modbus TCP, за которой шлюзы скрывают все стойки и устройства

А так это выглядит на уровне железа, две разные конфигурации объектов с разными контроллерами. Родные стойки B&R остаются на своей шине POWERLINK, внешние устройства идут по Modbus TCP через коммутатор, и оба шлюза сводят всё это к одной таблице для проекта:

Конфигурацию для Automation Studio руками тоже никто не рисовал. ИИ написал генератор, который берёт привязки сигналов из старого проекта и делает всё сам: одну Modbus-станцию, три с лишним сотни привязок переменных, таблицы для обоих шлюзов. И два проверочных скрипта, которые сверяют новый проект со старым по физическим каналам модулей. На той стойке, которую переводили, вышло 202 канала и 329 переменных, потерь ноль.

Что я проверял руками

Всё остальное — руками, на стенде и на объекте. Стойка B&R за каплером, мини-ПК, провода. Тыкал входы, смотрел, загораются ли лампочки на нужных модулях. Вешал выход на вход и проверял, что сигнал проходит через шлюз туда и обратно и доходит до проекта. Смотрел, что каждый датчик считается, что все аналоговые значения приходят правильные, что импульсы с расходомеров не теряются. Выдёргивал кабель, отключал питание стойки, убивал шлюз и ARsim, смотрел, как всё это само поднимается. Что задержек нет, что система не падает, что ночью не деградирует.

Потом мойка. Первый выезд не заработал: половина выходов на длинной стойке была мёртвая, энергомонитор показывал нули. Оказалось, что штатная утилита B&R молча выкинула из конфигурации один модуль-заглушку, и вся раскладка после него съехала. Со второго выезда стойка заработала целиком, дозаторы дали импульсы, и дальше мойка работала уже на клиентах. Как искали и что нашли — под спойлером.

Что получилось

Умерший контроллер за полмиллиона заменяется мини-ПК за тридцать тысяч. Стойки не трогаем, код проекта не переписываем, перепривязываем только адреса переменных. На всё ушло три недели: три-четыре дня кода, остальное стенд и объект. Делается один раз, дальше ставится на объект скриптом.

Про ИИ скажу без преувеличений. Драйвер, RT-ядро, патчи стека, шлюзы, скрипты — всё это сделал он, я ничего из этого не писал и не притворяюсь. Что было моё: я знаю, как вся система работает, и поэтому понимал, что стоит попробовать и о чём спросить. Спрашивал у ИИ, можно ли, давал документацию, смотрел, что выходит, и говорил, куда дальше. И схема: симулятор вместо контроллера, шлюзы вместо переписывания, жёсткое время только там, где оно правда нужно. И проверка руками, потому что реальное время в коде не увидишь. Без опыта в железе я бы не смог ни задать ему правильный вопрос, ни понять, работает оно или только кажется. А без него я бы за это не взялся вообще: специалиста на стык ядра Linux, драйверов, промышленных протоколов и среды B&R не найти, а ждать некогда.

Если у вас та же беда — контроллеры B&R умирают, а стойки живые — теперь вы знаете, что это решаемо.

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

Скрытый текст

Ниже отчёт о том, что было сделано и как: драйвер, стек, система, что нашлось на стенде и на объекте. Это писал не я, это разбор от ИИ, который делал работу. Для тех, кому будет интересно повторить.

Железо и система

Мини-ПК с двумя и более сетевыми портами Intel: на стендах I210, на машине, которая поехала на объект, шесть портов I226-V. Модель не принципиальна. Важно другое: несколько ядер процессора с раздельным кэшем, чтобы хотя бы одно ядро можно было целиком отдать под реальное время. Операционная система Ubuntu, ядро собрано под задачу: ванильное 6.8 с патчем PREEMPT_RT, HZ=1000, с параметрами под изоляцию ядер и прерывания.

ARsim это Windows-программа. На Linux она работает через Wine, без виртуальной машины, и с ней есть особенность, о которой стоит знать заранее. ARsim ведёт себя как настоящий рантайм и сам сажает свои потоки на старшее ядро процессора. А старшее ядро это ровно то, которое изолировано под шлюз. Стоило ARsim туда сесть, занятость ядра подскакивала до половины и двухмиллисекундный такт плыл. Точечные заплатки на каждый способ запуска не помогали: закроешь один путь, найдётся другой. Помогло только развести всё через cgroup. Шлюз живёт в своей группе, и только этой группе доступно изолированное ядро, а система, сеанс пользователя и контейнеры получают остальные ядра. Проверялось это не чтением конфигов, а попытками посадить работу на ядро цикла всеми известными способами. Все отбиты, занятость ядра упала с 52 до 6,5 процента. Туда же, на изолированное ядро, уводятся прерывания той сетевой карты, на которой висят стойки. Эту карту ядерный драйвер openPOWERLINK забирает себе целиком, штатному сетевому стеку Linux она не видна. Вторая карта это обычная локальная сеть мойки, по ней ARsim и разговаривает со шлюзами по Modbus TCP.

Отдельного ПЛК на этом ПК нет. Логику исполняет ARsim, а со стойками говорит шлюз через управляющий узел открытого стека openPOWERLINK поверх драйвера сетевой карты.

Скрипты, которые всё это держат

Собрать систему один раз на стенде и заставить её жить на объекте без присмотра — разные задачи. Второе решается скриптами.

Развёртывание полностью скриптовое и без интернета: один установщик поднимает любой ПК из комплекта, в котором лежит всё, пакеты ядра, исходники стека с патчами, драйверы под оба семейства карт и службы. Все проверки, которые могут остановить установку, идут до любых изменений. Если включён Secure Boot, установщик останавливается, потому что ядро и драйвер не подписаны. Ядро под изоляцию выбирается по топологии кэша из /sys, а не зашитым числом. Порт под POWERLINK выбирается по PCI-слоту и запоминается вместе с MAC-адресом, и это не мелочь: на машине с шестью одинаковыми портами отдать шине порт локальной сети значит потерять доступ к ПК вместе с самим ПК. Отдельная служба передаёт карту драйверу в правильном порядке, порядок тут важен, ниже сказано почему.

За живучесть отвечают три вещи. Шлюз при потере линка не падает, а перезапускает стек внутри себя и честно отдаёт ПЛК «стойки нет». Сам процесс шлюза держит systemd. И отдельный сторож следит за ARsim: поднимает симулятор, если тот умер, возвращает рабочий загрузчик после переустановки ARsim из Automation Studio, а с недавних пор ещё и проверяет рукопожатием, что его OPC UA-сервер отвечает, а не просто держит порт открытым. Всё это на Bash и Python, ничего особенного, но именно это позволяет поставить мини-ПК на мойку и уехать.

Почему openPOWERLINK не заводится из коробки

Стек упирается в три вещи.

Стек заброшен. Последняя версия, 2.7.2, вышла в 2019 году, под современное ядро Linux 6.x она не собирается, а сообщество на вопросы почти не отвечает.

Под современные сетевые карты в нём нет драйвера. Чтобы выдерживать цикл, стек не пользуется обычным сетевым стеком Linux, а работает с Ethernet-контроллером напрямую, своим драйвером в пространстве ядра. Готовые драйверы есть только под старые чипы Intel и Realtek. I225 и I226, которые сейчас стоят в большинстве мини-ПК, — другое семейство: в Linux его обслуживает драйвер igc, устроен он иначе, и в стеке под него ничего нет.

И ядро ушло вперёд. За годы без поддержки из ядра исчезли или поменялись вызовы, на которых стек написан. В сумме понадобилось десять патчей, килобайт на двадцать: под API ядра 6.x, под убранный struct timespec, под sched_setscheduler, который больше не экспортируется, под виртуальный интерфейс стека, который писал MAC-адрес прямо в поле структуры и получал за это предупреждение ядра при каждой остановке. Ещё два патча закрывали дефекты реального времени в самом стеке, о них ниже, и ещё два касались жизни модуля: выгрузку при живом потоке и утечку потоков ядра, если стек не смог стартовать.

Драйвер под I226

За основу взяли драйвер из самого стека, тот, что когда-то был написан под карту I210, и портировали его на семейство I225/I226. Регистры MAC, DMA, прерываний и часов 1588 у них совпадают, так что таймеры, кольца дескрипторов и три вектора MSI-X перенесены почти дословно: в новом драйвере 3343 строки, и от исходного отличаются несколько сотен. Но в трёх местах карты железно разные, и каждое место стоило отдельного разбора.

Первое, планировщик. У I210 отправка кадра точно по времени держалась на шейпере Qav с шагом 32 наносекунды. У I225/I226 вместо него полноценный планировщик 802.1Qbv в наносекундах: у каждой из четырёх очередей есть «ворота» с временем открытия и закрытия, есть базовое время и длина цикла. И очередь, у которой ворота не запрограммированы, не передаёт вообще ничего, молча, без единой ошибки в логе. Нулевая длина цикла и нулевое базовое время означают «планировщик выключен». Рядом ловушка с размером буферов передачи: значение по умолчанию, с которого стартовал порт, оставляло очередям ноль байт, и карта опять не отправила бы ни кадра. Всё это нашлось ещё до первого запуска на железе, когда драйвер построчно сверяли с эталонным драйвером ядра igc, и в коде теперь стоят прямые предупреждения.

Второе, тайминги. Энергосбережение Ethernet (EEE) отключается до сброса PHY: вход и выход из спящего режима на 100BASE-TX стоят десятки микросекунд, а это прямо внутри двухмиллисекундного цикла. Компенсация задержки PHY берётся из реально согласованной скорости линка, а не из предположения: карта умеет 2,5 Гбит/с, сегмент POWERLINK идёт на 100 Мбит/с, и если скорость не проверять, неверно согласованный линк остаётся невидимым. Есть ещё тонкость с горизонтом планировщика. Он заканчивается текущим циклом Qbv длиной в секунду, и кадр, нацеленный за его границу, уходит сразу, если не пометить его как первый кадр следующего цикла. При цикле в две миллисекунды это ровно один кадр в секунду, и без пометки он уходил бы на полмиллисекунды раньше положенного. Это тоже поймали сверкой с igc, до железа.

Третье, устойчивость к молчащему железу. В драйвере были места, где неотвечающий PHY или зависший аппаратный семафор могли повесить ядро намертво, в том числе при выгрузке модуля. Все такие ожидания ограничены по числу попыток, и каждое пишет предупреждение в лог. А при выгрузке тракт передачи возвращается в состояние после сброса, чтобы карта попадала к штатному igc в том виде, в каком он её ждёт. С I210 на этом попались: после этого драйвера карта оставалась в форсированном режиме, и штатный драйвер потом не поднимал линк.

Два дефекта реального времени в самом стеке

Эти два не про I226, они про сам стек, и нашлись они только на железе, на стенде с картой I210 и настоящей стойкой. Раз в несколько минут цикл вставал ровно на полсекунды, 502–517 миллисекунд, и узел уходил в неактивное состояние. Полсекунды оказались умолчанием стека: после пяти опозданий подряд мастер уходит в PreOperational1 и ждёт там 500 миллисекунд. А сами опоздания рождали два дефекта.

Первый сидел в обработчике таймера драйвера I210. При старте он включал среди причин прерывания ещё и переполнение системных часов карты, а оно случается раз в секунду. Обработчик, увидев этот бит, выходил досрочно, не проверив такт цикла. Такт, совпавший с переполнением, терялся, таймер не перевзводился, и опоздания шли пачкой по пять, ровно порог, после которого сеть вылетает из рабочего режима. Второй дефект это запас на подготовку кадров цикла: в стеке он 150 микросекунд, то есть 7,5 процента от двухмиллисекундного цикла, и на обычном ПК под RT-ядром этого впритык. Поднят до 500. На провод это не влияет, кадры всё равно выпускает карта по аппаратному времени. После обеих правок 44 минуты без единого опоздания, ноль отвалов узла и ноль потерянных импульсов на 224 273 фронтах, снятых перемычкой с выхода стойки на её же вход. До правок было около семнадцати отвалов в час. Обе правки перенесены и в драйвер I226.

Что искали на стенде

Первая проверка была ещё до железа: та самая построчная сверка с igc, тринадцать ошибок. Коммит того дня заканчивается словами: «Builds clean against 6.8.0-rt. Not yet run on hardware — the card goes in tomorrow». На следующий день карту поставили в мини-ПК, и первый же прогон с настоящей стойкой за каплером дал 297 766 циклов без единого пропуска и без единой потери по счётчикам самого каплера.

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

Прибор не должен подтверждать сам себя. Программный симулятор стойки сначала писал во все каналы одно и то же число, и сдвиг на байт в 55 из 64 аналоговых связей был просто невидим. Стоило завести в каждый канал своё уникальное значение, как сдвиг всплыл сразу.

Арбитр должен быть чужой. Каплер B&R сам считает потерянные кадры, эти счётчики читаются по SDO, и уговорить их никак нельзя. Если за несколько сотен тысяч циклов прирост ноль, значит, ноль. Второй чужой прибор это отдельный ПК на том же сегменте, который слушает кадры SoC с метками времени ядра. Так отделялись провалы мастера от заминок самого наблюдателя: счётчик циклов у шлюза обязан расти ровно на тридцать тысяч в минуту, и если наблюдатель видит паузу в полсекунды, а счётчик полон, значит, заминка у наблюдателя. Что именно наблюдатель намерил — ниже, в прогонах.

Проверять надо попыткой сломать, а не чтением конфигурации. Показательный случай: если стойку включить после шлюза, драйвер заново запрашивает прерывания, они ложатся на общие ядра с приоритетом по умолчанию, и за пять минут набирается 271 потерянный цикл. Нашли ровно этим тестом, вылечили привязкой прерываний после каждого старта стека, отсюда и порядок запуска в скриптах развёртывания. Приоритеты вообще оказались решающими: потоки прерываний карты 95 и 90, цикловой поток 80, поток событий стека 79. По умолчанию PREEMPT_RT даёт потокам прерываний 50, это ниже потока, который ждёт их события, и одна эта инверсия роняла сеть. Что оказалось ни при чём, тоже проверено приборами: прошивка ни при чём (hwlat, SMI ноль), планировщик ни при чём (cyclictest, максимум 61–72 мкс). А вот nohz_full, который обычно советуют для реального времени, здесь только вредит: стек делает системный вызов каждые две миллисекунды и платит за каждый вход в ядро.

И самое долгое расследование было вообще не про этот код. На втором стенде узел выпадал строго по расписанию: через 10,5 секунды, потом через 12,5, и так по кругу. Когда период ровный, это само по себе подсказка, где-то тикает чей-то десятисекундный таймер. ftrace показал, что таймер карты приходит ровно каждые 2,000 мс, а вот обработчик молчит полмиллисекунды на простом чтении регистра. Маленькая программа, читающая регистр карты из пользовательского пространства, показала зависания по 350–770 микросекунд сериями, причём в те же микросекунды зависала и соседняя Realtek. То есть замирала вся шина PCIe. В каждом таком окне было событие ACPI, и по таблицам DSDT оно вело к встроенной графике. Драйвер i915 усыплял GPU через десять секунд простоя, и каждый такой переход замораживал PCIe за южным мостом на пять миллисекунд. Лечится одним udev-правилом, которое держит GPU в D0. Про это стоит помнить всем, кто делает реальное время на бытовом мини-ПК: виновата может быть вообще не та подсистема, на которую смотришь.

Самое долгое по времени было не написание, а прогоны. Ночные, по восемь часов, на двух разных машинах: 7 ч 47 мин и 13,9 миллиона циклов на мини-ПК с I226, который потом поехал на объект, и 8 ч 05 мин и 14,56 миллиона на втором стенде с I210 после лечения графики. Смотрели три вещи: пропуски кадров по счётчикам каплера, выход интервала между кадрами за пределы цикла и стабильность самого ядра ОС под нагрузкой, ни зависаний, ни утечек, ни деградации таймингов к утру. По итогам ноль пропусков и ноль отвалов узла.

Интервал между кадрами по наблюдателю на проводе держится в 2,00 мс, максимум 2,335 мс, дольше 2,5 мс ни одного; но метку времени ставит ядро обычного ПК, и часть этой дрожи принадлежит самому наблюдателю. Дрожь парная: один интервал длиннее, следующий ровно настолько же короче. Это не заслуга каплера, а свойство мастера. Таймер цикла взводится на часах самой карты как «прошлая цель плюс две миллисекунды», и SoC уходит с карты по аппаратному времени запуска на тех же часах. Сетка на проводе принадлежит карте, программе достаточно приготовить кадры за 500 мкс до срока, тот самый запас, поднятый со 150. Опоздание внутри запаса до провода не доходит, сверх запаса кадр уходит поздно, мастер считает это ошибкой цикла, и пять подряд роняют сеть в PreOperational1. У каплера граница своя: SoC должен прийти в пределах цикла плюс допуск потери SoC, каждое нарушение прибавляет к счётчику восемь, каждый чистый цикл вычитает единицу, порог в конфигурации B&R равен 80. Узел выпадает примерно после десяти опозданий подряд. Этот счётчик шлюз и читает у каплера по SDO, и за все прогоны он остался нулём.

Живая мойка: что стенд поймать не мог

На живой мойке проверялись уже не лампочки, а сигналы, которые должны отрабатывать по логике проекта: расходомер считает, дозатор дозирует, тарификация сходится. С первого выезда не заработало, и причина стоит отдельного рассказа, потому что это ровно та граница, дальше которой симулятором ничего не докажешь.

На стойке в одиннадцатом слоте стоит X20ZF0000, модуль-заглушка, без единого сигнала. Но у заглушки есть адрес на внутренней шине стойки X2X. В Automation Studio для неё нет файла описания, и встроенный openCONFIGURATOR молча выкидывает её из конфигурации сети: получается 23 объекта конфигурации модулей при 24 станциях. А каплер адресует конфигурацию каждого модуля по индексу «0x2100 плюс адрес X2X», и по тем же индексам ссылается раскладка данных в кадрах. В итоге конфигурация двенадцатого модуля легла на адрес заглушки, а всё, что дальше, на чужие модули. Обмен идёт, входы до заглушки совпадают с панелью, а все выходы после неё мёртвые, и энергомонитор в конце стойки отдаёт нули. Со штатным ПЛК эта же стойка работала годами, значит, в его конфигурации каплера заглушка была на месте. Потерялась она именно на пути через openCONFIGURATOR и файл CDC.

Вторая ловушка стоила целого дня. Три исправленных файла конфигурации подряд не дали вообще никакого эффекта. Оказалось, каплер хранит конфигурацию у себя во флеше, а менеджер конфигурации openPOWERLINK перезаливает её только тогда, когда дата и время конфигурации, которые узел сообщает о себе, не совпадают с тем, что ждёт мастер. Дата в правках не менялась, и строка «CFM node 1: result 6» на каждом старте означала не «загружено», а «загружать нечего». Догадки съели день. Помог пробник: прямо на объекте в шлюз было добавлено чтение произвольных объектов узла по SDO с выводом в журнал, и он показал две вещи сразу. На адресе заглушки записана конфигурация соседнего модуля выходов, а дата конфигурации в каплере равна ожидаемой, то есть ни одна правка до него не дошла. Механизм в тот же день был доказан на малой стойке стенда: конфигурация с одной только новой датой прошла путь «записана, сброс узла, рабочий режим», и пробник прочитал из узла новую дату.

Исправление это скрипт, который сверяет число станций по карте с числом объектов в конфигурации, вставляет пропущенную станцию, сдвигает последующие конфигурации и 27 ссылок раскладки и поднимает дату. Проверка «станций по карте столько же, сколько объектов в файле» и «дата новая» занимает минуту и теперь стоит в чек-листе перед любым выездом. Со второго выезда стойка заработала целиком: напряжения фаз 230/229/228 вольт на панели, выходы после заглушки принимают команды, дозаторы дали импульсы, и дальше мойка работала уже на клиентах. Почему стенд это пропустил, тоже понятно: главная стойка на всех стендах была программным симулятором узла, настоящей была только малая стойка, а на ней заглушек нет. Симулятор принимает любую конфигурацию. Настоящий каплер нет.

Уже на работающей мойке всплыли ещё два эффекта, которых на контроллере B&R не бывает, и их полезно знать всем, кто запускает ARsim под Wine. Первый: под нагрузкой на трёх ядрах хозяйства (удалённый рабочий стол, обслуживание USB, опрос HDMI-выхода драйвером графики) OPC UA-сервер внутри ARsim однажды завис. Процесс жив, логика работает, шина чистая, а порт 4840 принимает соединения и молчит, и панели постов теряют связь с ПЛК. Лечится перезапуском ARsim, поэтому сторож теперь проверяет рукопожатие OPC UA, а не только то, что процесс есть. Второй: в проекте есть код, который каждый цикл сначала гасит элементы витрины визуализации, а в конце заполняет их заново. На ПЛК это работает без последствий, визуализация не может вклиниться в цикл задачи. А в ARsim задача это обычный поток Linux, ОС может вытеснить его ровно в этом окне, и элемент на мнемосхеме на секунду пропадает. Гонки внутри цикла, которых на ПЛК не бывает, здесь возможны, и такой код лучше переписать так, чтобы витрина публиковалась одним копированием.

Чего пока нет

Отлажены стойки, где на POWERLINK только ввод-вывод. На старых объектах на той же шине висят ещё и частотные преобразователи, их предстоит поднимать отдельно. Драйвер и конфигурация шины на работающем объекте меняются только через перезагрузку: остановка шлюза на ходу один раз повесила машину намертво, а на стенде это не повторилось. Самые длинные прогоны пока — восемь часов на стенде и неделя на живой мойке без единого сбоя. Многомесячной статистики ещё нет.

Комментарии (10)


  1. IlyasA74
    27.09.2026 07:11

    Спасибо, прочитал с большим интересом. Когда же будет третья часть, с подробным описанием протокола разработки в паре с ИИ, настройки окружения и т.д? Это же самое интересное.

    И еще вопрос - вам не кажется, что проект запредельно усложнен, в особенности - использование "контроллера B&R"?


    1. leodimark Автор
      27.09.2026 07:11

      Спасибо. Третья часть про работу в паре с ИИ — интерес понял, подумаю. Там есть что рассказать, но пока не обещаю.

      Про сложность — вопрос правильный, и я его сам себе задавал. Только сравнивать надо не «сложно или просто», а «с чем сравниваем». Контроллер B&R я не выбирал. Он уже стоит на сотнях объектов, вместе со стойками, проводкой и проектом, который годами работает. Простой вариант — выбросить стойки, поставить Modbus-модули и переписать проект — на бумаге выглядит проще. Но это перемонтаж двух-трёх сотен точек на каждой мойке, новая проверка всей логики, и главное — простой объекта, который каждый день принимает деньги. На одной мойке это ещё можно, на двух сотнях — нет.

      То, что описано в статье, сложно сделать один раз. Зато потом это ставится скриптом за час, стойки не трогаются, проект не переписывается, мойка не останавливается. Вся сложность живёт в одном мини-ПК, а на объекте ничего не меняется. Для парка это единственный вариант, который сходится по деньгам и срокам. С нуля я бы, конечно, всё это так не строил — но с нуля никто и не строит.


  1. Siemargl
    27.09.2026 07:11

    Мда. B&R конечно, как морская свинка в мире ПА.

    И достаточно экзотика, хотя когда-то входили в мировую 10ку.


    1. leodimark Автор
      27.09.2026 07:11

      Про мировую десятку спорить не буду, в топе они не были, доля в ПЛК около 4%. Но «морская свинка» и «экзотика» — это не про них. B&R делала машинную автоматику для BMW, Volkswagen, Nestle, P&G, 4000 машиностроителей по миру, 600 млн долларов оборота на момент покупки ABB. Это стандарт для тех, кто делает машины, а не заводы.

      А для России важнее другое. B&R массово ставили в оборудование, которое собиралось здесь: мойки самообслуживания, упаковка, пищевое, вендинг. Только в моей отрасли на B&R сотни объектов, и они не исчезли — они стоят и работают, просто контроллеров к ним больше не купить. То, что мировая доля скромная, ничем не помогает владельцу, у которого встала линия. Ему нужен не рейтинг вендора, а работающий способ её поднять. Про него и статья.


      1. Siemargl
        27.09.2026 07:11

        Морская свинка - потому что он одновременно ПЛК и ембеддед. Хочешь - LAD, а хочешь - С.

        Экзотика понятие относительное. Все действительно широко распространенное (более 4%) продается на алиэкспрессе из Китая, и A-B и Сименс и Омрон итп

        И с сетями то же самое - под Профибас или CAN гораздо проще найти замены, чем для поверлинка или интербаса.


  1. Moog_Prodigy
    27.09.2026 07:11

    B&R это все же экзотика. Причем проприетарная, где вход рубль а выход десять рублей. Уход именитых производителей конечно ударил по производству, но с другой стороны вынудил руководство думать наперед и заранее готовить замену, или изначально покупать без вот этой всей залочки. В итоге оказывается, что большинство функций, которые завязаны на эту всю проприетарщину, реализуются элементарно на более простом железе. Причем это касается и отечественных разработчиков (я их называю бракоделами-доильщиами), которые лепят в производимое ими оборудование самодельные ПЛК вообще ни с чем не совместимые. Ноль схем, ноль прошивок, обращайтесь к производителю. Был такой аппарат с несложной логикой работы - но управление двумя частотниками, экранчик, кнопочки красивые. Выкинул оттуда плк и поставил 9 реле. И все. Аппарат работает как и прежде, ну разве что нет больше кнопок и экранчиков. С каждым витком автоматизации мы уходим все дальше от собственно автоматизации...


  1. VT100
    27.09.2026 07:11

    А вот код мы писали вместе с ИИ

    Отчëт на Хабр, видимо, - тоже. Но, продолжайте - интересно и познавательно.


  1. leodimark Автор
    27.09.2026 07:11

    Ну да, и код, и статью. Я про это и написал вообще-то. Или вы ждали, что я буду это скрывать?
    Без ИИ вообще бы никогда ничего не написал для других. У меня нет писательских талантов. Я могу только устно в разговоре что-то излагать, более менее внятно.


  1. NutsUnderline
    27.09.2026 07:11

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

    но вот чего я не понял из всего текста - а что такое "каплер"


    1. leodimark Автор
      27.09.2026 07:11

      В автоматике каплер, это контроллер шины, объединяющий модули ввода/вывода с ПЛК, по одному из промышленных протоколов. При этом внутренняя шина модулей может быть какой угодно (зависит от производителя).