Как вы вообще обходитесь без POWERLINK?

Прокомментировать Просмотры: 3

Практический опыт импортозамещения контроллеров B&R с полным сохранением исходного проекта. Все технические нюансы реализации традиционно спрятаны под спойлером в конце статьи.

Приветствую, SE7EN! В предыдущей публикации я рассказывал о том, как остался единственным разработчиком с экспертизой по программному обеспечению для более чем двухсот автомоек, и обещал поделиться деталями перевода контроллеров B&R на мини-ПК. Выполняю обещание.

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

Предыстория вопроса

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

Строго говоря, прямой необходимости заниматься этой проблемой у меня не было: вендор ушёл с рынка, границы закрыты, и формально это головная боль заказчика, которому приходится искать доступные запчасти. Но мне было по-человечески неприятно осознавать, что за подобные форс-мажоры расплачивается владелец автомойки, чей бизнес простаивает и теряет выручку. В то время как обычный мини-ПК стоит в пределах 20–30 тысяч рублей. В общем, я решил попробовать найти альтернативу.

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

Эмуляция вместо аппаратного ПЛК

У экосистемы 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-станцию:

Как вы вообще обходитесь без POWERLINK?

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

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

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

Всю рутинную отладку на стенде и в полевых условиях я выполнял самостоятельно. Комплект выглядел так: стойка B&R с интерфейсным модулем, мини-ПК и коммутационные провода. Я вручную замыкал входы, контролируя срабатывание светодиодной индикации на соответствующих модулях. Соединял выходы со входами, проверяя прохождение сигнала через шлюз в обе стороны до уровня управляющего проекта. Убеждался в корректности опроса каждого датчика, точности аналоговых измерений и в том, что импульсы расходомеров не теряются. Имитировал аварийные сценарии: обрывал кабель, обестачивал стойку, принудительно «убивал» шлюзы и процесс ARsim, наблюдая за процедурами автовосстановления. Проверял отсутствие лагов, общую стабильность системы и её устойчивость при длительной работе.

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

Итоговые результаты

Вышедший из строя контроллер стоимостью полмиллиона рублей успешно заменяется компактным мини-ПК за тридцать тысяч. Аппаратные стойки не демонтируются, прикладной код не переписывается — корректируются исключительно адреса переменных. Весь процесс модернизации занял три недели, из которых 3–4 дня ушло на кодинг, а остальное время — на стендовые и полевые испытания. Процедура стандартизирована и развертывается на объекте с помощью скрипта.

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

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

Технические подробности реализации

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

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

Аппаратная база и системное окружение

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

Среда ARsim представляет собой приложение под Windows. В Linux она запускается через слой совместимости Wine без использования виртуальных машин, однако здесь кроется важный нюанс, о котором необходимо знать заранее. ARsim функционирует как полноценная среда исполнения и автоматически распределяет свои потоки на старшие ядра процессора. Ирония в том, что старшим обычно является как раз то ядро, которое мы изолировали под нужды шлюза. Как только ARsim занимал это ядро, утилизация процессора взлетала до 50%, и двухмиллисекундный цикл начинал плыть. Точечные заплатки для разных способов запуска не помогали: перекрываешь один вектор — всплывает другой. Проблему удалось решить исключительно с помощью механизма cgroups. Шлюз изолирован в собственном контрольной группе (cgroup), и только ей разрешен доступ к выделенному ядру, в то время как системные процессы, сеанс пользователя и контейнеры распределяются по оставшимся ресурсам. Работоспособность подхода проверялась не чтением конфигурационных файлов, а попытками принудительно запустить стороннюю нагрузку на целевом ядре. Все попытки были заблокированы, утилизация ядра снизилась с 52% до 6.5%. На это же изолированное ядро перенаправляются прерывания той сетевой карты, к которой подключены аппаратные стойки. Данный сетевой интерфейс целиком забирается ядерным драйвером openPOWERLINK и полностью скрывается от стандартного сетевого стека Linux. Второй сетевой интерфейс обслуживает локальную сеть автомойки, через которую ARsim обменивается данными со шлюзами по протоколу Modbus TCP.

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

Скрипты автоматизации и отказоустойчивость

Одно дело — собрать систему на лабораторном стенде, и совсем другое — заставить её автономно функционировать на удаленном объекте без постоянного присмотра инженера. Вторая задача решается средствами автоматизации.

Процесс развёртывания полностью скриптовый и не требует подключения к интернету: универсальный инсталлятор поднимает любую целевую машину из подготовленного бандла, содержащего пакеты ядра, исходные коды стека с патчами, драйверы для обоих семейств сетевых контроллеров и управляющие службы. Все предварительные проверки, способные прервать установку, выполняются до внесения каких-либо изменений. Так, если в BIOS активирован Secure Boot, инсталлятор аварийно завершает работу, поскольку кастомное ядро и неподписанный драйвер не пройдут проверку безопасности. Целевое ядро для изоляции определяется динамически на основе топологии кэша из директории /sys, а не прописывается жестким числом. Сетевой порт для POWERLINK идентифицируется по слоту PCI и жестко привязывается по MAC-адресу — это критически важно: на машине с шестью идентичными портами ошибочно отдать сетевую карту шине автоматики означает мгновенно потерять удаленный доступ к самому мини-ПК. Специализированный демон инициализации передает сетевой интерфейс драйверу в строго определенной последовательности (о важности порядка будет сказано ниже).

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

Почему открытый стек openPOWERLINK не запускается из коробки

При попытке запустить оригинальный стек разработчик неизбежно упирается в три фундаментальные проблемы.

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

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

Третья — эволюция ядра Linux. За годы отсутствия поддержки в ядре изменились или были упразднены системные вызовы, на которых строился стек. Потребовалось подготовить пакет из десяти патчей общим объемом около 20 Кб: адаптация под API ядра 6.x, удаленная структура struct timespec, переписанный вызов sched_setscheduler (который больше не экспортируется для модулей), а также устранение проблемы с виртуальным сетевым интерфейсом стека, который записывал MAC-адрес напрямую в поле структуры, вызывая предупреждения ядра при каждой выгрузке. Еще два патча устраняли дефекты реального времени внутри самого стека (о них подробнее ниже), а оставшиеся два касались стабильности жизненного цикла модуля — корректной выгрузки при активных потоках и предотвращения утечки потоков ядра в ситуации, когда инициализация стека завершалась с ошибкой.

Разработка драйвера для контроллера Intel I226

За основу был взят оригинальный драйвер из состава стека, написанный некогда под чип I210, и портирован на семейство контроллеров I225/I226. Регистры подсистемы MAC, прямого доступа к памяти (DMA), прерываний и аппаратных часов IEEE 1588 у них схожи, поэтому таймеры, кольцевые буферы дескрипторов и векторы прерываний MSI-X перенесены практически дословно: новый драйвер насчитывает 3343 строки, из которых заимствованы несколько сотен. Тем не менее, в трех аспектах «железо» кардинально различается, и каждый узел потребовал глубокой переработки.

Момент первый — планировщик пакетов. У чипа I210 отправка фреймов точно по расписанию обеспечивалась аппаратным шейпером Qav с дискретностью 32 наносекунды. На смену ему в I225/I226 пришел полноценный стандартный планировщик 802.1Qbv, оперирующий наносекундами: каждая из четырех очередей имеет программируемые «окна» (gates) открытия и закрытия, привязанные к базовому времени и длине цикла. Если для очереди окна явно не заданы, контроллер молча блокирует передачу любых кадров, не генерируя при этом никаких ошибок в системном журнале. Нулевые значения длины цикла и базового времени трактуются аппаратным обеспечением как «планировщик отключен». Дополнительная ловушка скрывалась в размере передающих буферов: конфигурация по умолчанию выделяла очередям нулевой объем памяти, из-за чего интерфейс также отказывался отправлять пакеты. Все эти нюансы были выявлены еще до первого полевого тестирования путем построчного сравнения драйвера с эталонным кодом ядерного модуля igc, и теперь в коде явно прописаны защитные механизмы.

Момент второй — тайминги и энергосбережение. Функция энергосбережения Ethernet (EEE) в обязательном порядке деактивируется до аппаратного сброса физического уровня (PHY): циклы входа и выхода спящего режима на стандарте 100BASE-TX отнимают десятки микросекунд, что критично для нашего жесткого двухмиллисекундного цикла. Компенсация задержек PHY вычисляется на основе реально согласованной скорости линка, а не принимается по умолчанию: контроллер поддерживает скорость до 2.5 Гбит/с, тогда как сегмент POWERLINK функционирует на 100 Мбит/с, и если не верифицировать скорость соединения, рассинхронизация останется незамеченной. Существует также тонкость с горизонтом планировщика. Он ограничивается текущим циклом Qbv длиной в одну секунду, и пакет, попадающий за его границу, уходит немедленно, если предварительно не пометить его как стартовый фрейм следующего периода. При двухмиллисекундном цикле это ровно один кадр в секунду, который без специальной маркировки уходил бы на полмиллисекунды раньше положенного. Данная особенность также была обнаружена и купирована аналитически до монтажа на «железо».

Момент третий — отказоустойчивость при работе с неисправным или неотвечающим аппаратным обеспечением. В исходном драйвере обнаруживались участки кода, где зависший PHY или блокировка аппаратного семафора могли намертво повесить ядро операционной системы, в том числе на этапе выгрузки модуля. Все подобные циклы ожидания теперь жестко ограничены по числу итераций, а любые таймауты сопровождаются предупреждениями в логах. Кроме того, при выгрузке драйвера тракт передачи приводится в исходное состояние после аппаратного сброса, дабы передать контроллер штатному драйверу igc в ожидаемом им виде. На ранних тестах с I210 мы на этом обожглись: после остановки нашего драйвера чип оставался в форсированном режиме, и стандартный сетевой стек уже не мог поднять линк.

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

Данные баги не связаны с контроллером I226 — они присущи архитектуре самого стека openPOWERLINK и проявились исключительно на лабораторном стенде с использованием чипа I210 и реальной аппаратной стойки. Каждые несколько минут цикл управления замирал ровно на полсекунды (502–517 мс), после чего узел сваливался в аварийное состояние. Анализ показал, что эти 500 миллисекунд зашиты в логику стека как таймаут: после пяти подряд пропущенных тактов мастер-устройство переходит в режим PreOperational1 и ожидает там полсекунды. Сами же пропуски тактов провоцировались двумя дефектами.

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

Лабораторные испытания на стенде

Первая верификация кода проводилась без физического «железа» — посредством той самой построчной сверки с драйвером igc, в ходе которой было выявлено и исправлено 13 потенциальных ошибок. Коммит того дня завершался примечательной фразой: «Сборка под ядро 6.8.0-rt проходит без ошибок. На реальном «железе» еще не запускалось — завтра ставим плату». На следующий день контроллер был установлен в мини-ПК, и первый же прогон с подключенной физической стойкой зафиксировал 297 766 отработанных циклов подряд без единого пропуска и без малейших потерь по счетчикам самого каплера.

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

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

Инструмент контроля должен быть независимым. Фирменный каплер B&R самостоятельно ведет учет потерянных фреймов, причем эти счетчики считываются исключительно по протоколу SDO, и обнулить их программно невозможно. Если за сотни тысяч циклов прирост счетчика равен нулю, значит, система работает безупречно. Вторым независимым инструментом выступал отдельный ПК в том же сетевом сегменте, прослушивающий кадры SoC (Start of Cycle) с аппаратными временнЫми метками ядра. Это позволяло дифференцировать сбои мастера от микропауз самого наблюдателя: счетчик циклов на шлюзе обязан инкрементироваться ровно на 30 000 единиц в минуту, и если монитор фиксирует паузу в полсекунды при неизменном счетчике, значит, заминка произошла на стороне наблюдателя.

Надежность проверяется стресс-тестами на отказ, а не умозрительным анализом конфигураций. Показательный пример: если подать питание на стойку после запуска шлюза, драйвер производит реинициализацию прерываний, распределяя их по общим процессорным ядрам с дефолтными приоритетами, в результате чего за пять минут фиксируется 271 пропущенный цикл. Ошибка была локализована именно этим тестом и устранена путем жесткой привязки прерываний после каждого рестарта стека — отсюда и строгая последовательность инициализации в установочных скриптах. Приоритеты потоков вообще имеют решающее значение: потокам прерываний сетевой карты выставлены приоритеты 95 и 90, цикловому потоку — 80, обработчику событий стека — 79. По умолчанию PREEMPT_RT назначает прерываниям приоритет 50, что ниже приоритета ожидающего их потока, и одна эта инверсия гарантированно роняет сеть. А вот параметр ядра nohz_full, традиционно рекомендуемый для задач реального времени, в нашем сценарии приносил лишь вред: стек выполняет системный вызов каждые 2 миллисекунды и несет избыточные накладные расходы на каждый переход в пространство ядра.

Самое затяжное расследование оказалось вообще не связано с разрабатываемым кодом. На втором стенде тестируемый узел выпадал из сети строго по расписанию: спустя 10.5 секунд после запуска, затем ровно через 12.5 секунд, и так циклически. Периодичность сбоя — главный ключ к разгадке: где-то сбоит чей-то фоновый десятисекундный таймер. Трейсер ftrace показал, что аппаратный таймер сетевой карты генерирует события с идеальным интервалом в 2.000 мс, но при этом обработчик зависает на 500 микросекунд банально при чтении регистра. Написанная на коленке утилита, циклически опрашивающая регистры карты из пользовательского пространства, выявила серии заморозок длительностью от 350 до 770 микросекунд, причем ровно в те же микросекунды замирал и соседний контроллер Realtek. Иными словами, периодически «вставала» вся шина PCIe. Анализ показал, что каждое такое окно коррелирует с событиями ACPI, ссылающимися в таблицах DSDT на встроенную графическую подсистему процессора. Драйвер i915 переводил интегрированный GPU в режим энергосбережения после 10 секунд простоя, и каждый такой переход замораживал шину PCI Express южного моста на пять миллисекунд. Проблема решилась добавлением одного udev-правила, принудительно удерживающего графический чип в активном состоянии D0. Этот опыт полезен всем, кто пытается реализовать жесткое реальное время на потребительских мини-ПК: корневая причина сбоев может крыться в совершенно неожиданной подсистеме.

Наиболее трудоемким этапом оказались даже не разработка и отладка, а длительные стресс-тесты. Ночные прогоны продолжительностью по 8 часов выполнялись на двух различных машинах: 7 часов 47 минут (13.9 млн циклов) на мини-ПК с чипом I226, отправившемся в итоге на объект, и 8 часов 5 минут (14.56 млн циклов) на втором стенде с картой I210 после устранения проблем с графикой. Контролировались три параметра: пропуски кадров по аппаратным счетчикам каплера, стабильность интервалов между кадрами и общая устойчивость ОС под нагрузкой (отсутствие утечек памяти, зависаний и деградации таймингов к утру). Итог: нулевой уровень пропусков и абсолютная стабильность связи.

Фактический интервал между кадрами по данным внешнего мониторинга стабильно удерживается на отметке 2.00 мс, пиковое значение составило 2.335 мс, ни единого заброса за 2.5 мс зафиксировано не было. При этом временнЫе метки проставлялись ядром стандартного ПК, поэтому часть зарегистрированного джиттера обусловлена погрешностью самого измерителя. Джиттер носит симметричный характер: один интервал чуть длиннее, следующий — ровно на столько же короче. Это не заслуга каплера, а особенность функционирования мастера: таймер цикла взводится по часам самого контроллера по принципу «прошлое целевое время плюс 2 миллисекунды», и пакет уходит с карты по аппаратному моменту старта. Организация сетевого трафика полностью лежит на плечах аппаратного обеспечения сетевой карты, программе достаточно подготовить фреймы за 500 мкс до дедлайна (тот самый увеличенный запас). Запоздания внутри этого буфера до физической линии не доходят; если же задержка превышает запас, кадр уходит с опозданием, мастер фиксирует ошибку цикла, и серия из пяти таких сбоев переводит сеть в состояние PreOperational1. У каплера свои критерии: пакет SoC должен прийти в пределах периода плюс допустимый лимит потерь; каждое нарушение увеличивает внутренний счетчик на 8, каждый успешный цикл уменьшает его на 1, а аварийный порог в конфигурации B&R равен 80. Узел теряет связь примерно после 10 пропусков подряд. Именно этот интегральный счетчик шлюз считывает у каплера по протоколу 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. Первый: под комплексной нагрузкой на трех процессорных ядрах (удаленный рабочий стол RDP, обслуживание периферии USB, опрос HDMI-выхода графическим драйвером) OPC UA-сервер внутри ARsim однажды завис. Сам процесс функционирует, прикладная логика крутится, шина чистая, но TCP-порт 4840 принимает соединение и молча зависает, из-за чего терминалы на постах теряют связь с ПЛК. Проблема лечится перезапуском симулятора, поэтому сторожевой таймер был доработан и теперь проверяет не просто наличие процесса ОС, а выполняет активный хендшейк с OPC UA-сервером. Второй эффект: в структуре проекта присутствует код, который на каждом такте сначала сбрасывает элементы графической визуализации, а затем заполняет их заново. На аппаратном ПЛК это отрабатывает абсолютно бесшовно, так как визуализация физически не может вклиниться в выполнение задачи. В случае с ARsim задача выполняется как стандартный поток Linux, и операционная система может вытеснить его как раз в этом окне, из-за чего элемент на мнемосхеме на доли секунды пропадает. Подобные гонки данных внутри цикла на аппаратных контроллерах невозможны, но здесь они проявляются, поэтому проблемные участки кода потребовалось переписать так, чтобы визуализация обновлялась атомарно, единым блоком памяти.

Планы на будущее

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

 

Источник

Поделиться:

Похожие статьи

Поиск по играм, новостям и статьям…

Введите не менее двух символов

Введите не менее двух символов