ESPN DeportesGilberto Mora ilumina el debut de Rafael Márquez con MéxicoInquirerRiding Pulangi’s wild rapids in Bukidnonוואלהאיראן: "רק פתרון במשא ומתן יכול להביא לסיום המשבר"ESPNProjecting the CFP top 12 after Week 4: Gators claw into contentionPunchAgbara Nla premieres in AbujaComplete SportsAFCON 2027Q: Super Eagles To Hold Closed-Door Training, Depart For Bissau SundayCollider8 ‘Far Side’ Comics That Prove Gary Larson Is a Genius, RankedGMA NewsChina conducts naval, air exercise around Scarborough ShoalStraits Times SportRevitalised Russell says he can fight for victory week-in, week-outABC News (Australia)Firefighters 'shook up' after planned burn destroys fire tankerThe Jerusalem PostUS, EU reject UN declaration promising international collaboration in face of another pandemicBBC NewsControversial Orange Order march to go ahead for first time in nearly 30 years after late night drama
The Daily Newsstand · Free, Always
Sunday, September 27, 2026

Как вы вообще живёте без POWERLINK…

Translate

Промавтоматика B&R после санкций, без шаманства и плясок с бубнами: как заменить умерший контроллер мини-ПК, оставить родные стойки и не переписывать проект. Драйвер под сетевые карты Intel I226, шлюз реального времени, ядро под задачу и проверка на настоящем железе.

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

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

А вот со старыми мойками так не выйдет. У них стойки родные, B&R, и общаются они с контроллером по POWERLINK. Это протокол жёсткого реального времени с циклом в две миллисекунды, и стоял он там не ради красоты: ПЛК на нём считал фронты расходомеров и формировал импульсы дозаторов. Умирает на таких объектах, как правило, именно контроллер, а стойки живут и готовы служить ещё лет десять. Менять их жалко и дорого, покупать контроллер тоже дорого, подержанный через серый импорт стоит от полумиллиона до трёх с половиной миллионов рублей, и это на каждый отказ. Вот про этот случай статья: как поставить вместо контроллера мини-ПК и не тронуть ни стойки, ни сам проект.

Что оставляем и что меняем

Оставляем всё смонтированное железо. Шкаф, стойки модулей B&R X20, проводку, датчики, исполнительные механизмы, всё остаётся как есть. Меняем только «голову», и здесь главная хитрость. Логику проекта на ПК исполняет ARsim, штатный симулятор рантайма от B&R. В Automation Studio любой проект можно прогнать через ARsim, и мало кто пользуется тем, что он умеет не только симулировать периферию, но и общаться с настоящей по Modbus TCP. Так что проект в нём не переписывается. Логика, визуализация, удалённые рабочие столы, всё это остаётся нетронутым, меняется только конфигурация ввода-вывода.

У ARsim есть свои ограничения. Первое: физический ввод-вывод он умеет только по Modbus TCP, никакого POWERLINK. Второе выяснилось уже в деле: ARsim 32-битный, и под каждую Modbus-станцию он резервирует буферы. В проекте 2019 года Modbus-устройств десять, каплеры пылесосов и освещение, и уже при семи станциях он упёрся в адресное пространство. Занято 2038 мегабайт из 2048, на визуализацию не хватило четырёх, и рантайм ушёл в перезапуск. Есть и третье ограничение, про непрерывную работу, но оно решено на нашей стороне, и в подробности я тут не полезу. Первые два обходятся одним приёмом: между ARsim и реальным железом ставится шлюз, а в проекте остаётся ровно одна Modbus-станция.

Почему бы вообще не подключить POWERLINK к ПК напрямую, без всяких шлюзов? Этот вопрос я закрыл ещё до начала работы, покопавшись в файлах установки самой Automation Studio. У панельных ПК B&R, которые стоят на наших мойках, POWERLINK живёт на отдельной интерфейсной плате, у компактных контроллеров он в ПЛИС, а в каталоге из почти двух тысяч модулей нет ни одной цели «обычный процессор», только x86-ПК. Драйвер POWERLINK под такой ПК в поставке есть, но ровно один, и привязан он к одному чипу, Intel 82574L. А ARwin, промышленная версия рантайма под Windows, требует старый PCI-слот, фирменную карту и лицензионный USB-ключ. Так что стойки оставить можно только со своим мастером шины, других вариантов нет.

Что тянул ПЛК и что теперь тянет ПК

Перед тем как что-то писать, я прошёл по проекту и посмотрел, что в нём реально требует миллисекунд. Оказалось, почти ничего. Логика мойки спокойно живёт при опросе раз в несколько сотен миллисекунд, её мы так и оставили симулятору. А вот два места без реального времени не работают: счёт импульсов расходомеров, потому что от него зависит тарификация и деньги клиента, и стомиллисекундные импульсы дозаторов химии. Именно это раньше делал ПЛК в своём двухмиллисекундном такте, и именно это переехало в шлюз, который крутится на выделенном ядре ПК с тем же циклом.

В шлюз ушло ровно то, что жило в такте контроллера: десять свободнобегущих 32-битных счётчиков импульсов (ПЛК берёт разность, и частота опроса на счёт не влияет), восемь генераторов импульсов дозаторов (ПЛК пишет «столько-то импульсов в минуту», а шлюз сам их формирует), зеркало входов-выходов, пересчёт шкал и диагностика узлов. Если в цифрах, для стоек 2019 года это 184 сигнала: каждые две миллисекунды 152 байта из стоек и 43 байта в стойки. Дальше шлюз отдаёт готовые данные по Modbus TCP, и для ARsim это выглядит как обычная Modbus-станция.

Шлюзов на самом деле два. Первый новый, он переводит POWERLINK в Modbus TCP и заранее готовит данные по логике каналов, те самые счётчики, импульсы и шкалы. Второй у нас штатный, он с 2023 года стоит на всех мойках с мини-ПК и собирает устройства, которые и так были на Modbus TCP, в одну сводную таблицу. Относительно этой единой таблицы и переконфигурируется проект в Automation Studio. В итоге со стороны проекта весь зоопарк стоек и внешних устройств схлопывается в одну-единственную Modbus-станцию, а всё остальное прячется за шлюзами:

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

Саму конфигурацию для Automation Studio руками никто не рисует. Есть генератор: он читает описание стоек и привязки сигналов из исходного проекта 2019 года и пишет всё сразу, одну Modbus-станцию, блоки опроса, три с лишним сотни привязок переменных, таблицу для сводного шлюза и карту адресов для шлюза POWERLINK. Разойтись эти вещи не могут, у них один источник. А перенос проверяют два отдельных скрипта: один сверяет карту с исходным проектом по физическому каналу модуля, а не по имени переменной, второй сравнивает два проекта Automation Studio напрямую, карте вообще не доверяя. Для 2019 года вышло 202 канала POWERLINK и 329 переменных Modbus, расхождений ноль, потерь ноль.

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

Мини-ПК с двумя и более сетевыми портами 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 не заводится из коробки

Открытая реализация протокола существует, называется openPOWERLINK, и на бумаге это ровно то, что нужно. На практике она упирается в три вещи.

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

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

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

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

Драйвер под 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.

Как это делалось и как проверялось

Сразу про роли, чтобы не было недомолвок. Сама идея — заменить контроллер на ПК, оставив стойки, поставить между ARsim и железом шлюзы и вынести в них обработку сигналов, которую раньше делал ПЛК, — моя, и архитектура всей схемы тоже. А вот код мы писали вместе с ИИ, и большая его часть за ИИ: ядро, драйвер, патчи стека, шлюзы, переконфигурация проекта. Я не сидел с редактором и не набирал регистры руками, и притворяться, что было иначе, не собираюсь. Моя работа была другая: ставить задачи, проверять результат и гонять итерации. И стенд с живой мойкой — тоже моя работа, потому что реальное время нельзя проверить, глядя в код.

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

По календарю на всё ушло три недели, не считая первой ночи на объекте. 26 августа принял решение, к 5 сентября стек собран под ядро 6.8 и мастер поднят на I210, 7-го разобраны дефекты реального времени, 8-го первый коммит проекта, 10-го написан драйвер I226, 13-го он впервые заработал с настоящей стойкой и в тот же день собран и проверен в виртуалке комплект развёртывания, 15-го поднят второй стенд, 17-го первый выезд. Сам код, ядро, драйвер, шлюзы и переконфигурация, по чистому времени укладывается в три-четыре дня. Всё остальное это стенд, и там всё было руками. Стойка B&R за каплером, мини-ПК, провода. Тыкал входы, смотрел, загораются ли лампочки на нужных модулях, вешал выходы на входы, чтобы проверить, что сигнал проходит через шлюз туда и обратно и попадает в проект. Выдёргивал патч-корд, отключал питание стойки, убивал шлюз, убивал ARsim и смотрел, как всё это восстанавливается.

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

Прибор не должен подтверждать сам себя. Программный симулятор стойки сначала писал во все каналы одно и то же число, и сдвиг на байт в 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, ОС может вытеснить его ровно в этом окне, и элемент на мнемосхеме на секунду пропадает. Гонки внутри цикла, которых на ПЛК не бывает, здесь возможны, и такой код лучше переписать так, чтобы витрина публиковалась одним копированием.

Экономика

Подержанный контроллер B&R стоит от 0,5 до 3,5 млн ₽, и это за каждый отказ. Мини-ПК на порядок-два дешевле. Разработка заняла три недели одного человека по календарю, из них три-четыре дня чистого кода, и делается один раз: дальше решение тиражируется на объекты скриптами.

Границы применимости

  • Отлажено поколение стоек 2019 года, где ввод-вывод целиком на POWERLINK. На объектах 2015–2018 годов на той же шине висят ещё и восемь частотных инверторов, их предстоит поднимать отдельно.

  • Сквозная задержка «вход стойки → реакция логики → выход стойки» отдельно не измерялась. Всё миллисекундное считает сам шлюз, а логике хватает опроса в сотни миллисекунд, так что на практике это не мешает, но цифры у меня нет.

  • Один дефект ядра при выгрузке драйвера на стенде не воспроизводится, а на объекте повторился: остановка шлюза однажды повесила машину намертво. Правило теперь простое: драйвер и конфигурация шины на работающем объекте меняются только перезагрузкой, на ходу драйвер не выгружаем.

  • Самые длинные чистые прогоны это восемь часов на стенде и сутки на живой мойке, 43 миллиона циклов без единого пропуска. Многомесячной статистики пока нет.

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

Вывод

Итог такой. Умерший контроллер B&R заменяется мини-ПК, стойки и проект остаются. Код проекта не переписывается — логика, визуализация, удалённые рабочие столы как были, — меняется только конфигурация ввода-вывода под сводную таблицу шлюзов. Три недели работы одного человека против миллионов за каждый отказ и против нового проекта автоматизации на каждом объекте. Зависимость от вендора, которого в стране больше нет, снята.

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

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

0%Есть, контроллеры уже умирают, и что делать — непонятно0

0%Есть, пока держимся на запасах и сером импорте0

0%Есть, переводим на другую платформу с переписыванием проекта0

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.