Блог

IL и ST в одном POU: после миграции проекта не компилируется

2026-07-31 11:26

Открыли legacy-проект в CODESYS 3.5.16 после апгрейда с 3.5.14: половина POU подсвечена красным. В одном FB_MotorControl три секции - __IMPLEMENTATION__ на IL, вложенный метод на ST, старый __ACTION__ на IL с директивами, которых в новом компиляторе уже нет. Сообщение компилятора: «IL not supported in this context» или «unexpected token LD». Заказчик хочет «просто перекомпилировать», integrator предлагает переписать 40 POU на ST за две недели. Пока спорят, пуск стоит.

Instruction List (IL) в IEC 61131-3 официально помечен как legacy; CODESYS постепенно ужесточает смешение IL и ST в одном POU и между версиями. Статья разбирает ошибки после миграции, стратегию поэтапного перевода на ST, типовые сообщения компилятора. Не учебник ST с нуля - фокус на границе IL/ST и upgrade проекта.

Короткий ответ

Если после миграции CODESYS проект с IL и ST в одном POU не компилируется, причина в устаревшем IL, запрете смешения языков в одном блоке или в action/transition на IL при ST-теле. Стратегия: инвентаризация POU по языкам; изоляция IL в отдельные POU без ST внутри; поэтапная замена IL на ST с сохранением имён переменных и интерфейса; для SFC - перенос actions на ST; проверка compiler messages по таблице ниже. Не «включить совместимость» - в 3.5.16 полной обратной совместимости IL со ST в одном теле нет. После каждого POU - build, online test, regression по критичным interlock.

Почему IL и ST в одном POU - проблема

IEC 61131-3 допускает разные языки в разных POU, но одна program/function block/function имеет один язык реализации. Исключения исторически ломались при миграции: inline IL в ST через {lang IL}, actions на другом языке, старые импорты из CoDeSys 2.3.

CODESYS 3.5.x:

POU body - один основной язык (ST, LD, FBD, IL - где ещё доступен). Методы FB - свой язык, но вызов из IL-body в ST-method и наоборот создаёт границы, которые новый компилятор не принимает. Actions при ST program - должны быть ST (или согласованы).

После upgrade компилятор 3.5.16.40 строже 3.5.10 - проект «без изменений кода» падает на build.

Типовые сообщения компилятора

«IL code generation is deprecated» - предупреждение, скоро error. «Cannot mix IL and ST in the same POU» - явный запрет. «Unknown instruction CAL» - синтаксис IL изменился или POU вызывается не так. «Action A1 language mismatch» - action на IL, program на ST. «POU cannot be compiled» без детали - смотреть первый IL-файл в списке ошибок.

Экспорт списка ошибок в текст, сортировка по POU - план работ.

Инвентаризация перед переписыванием

  1. Отчёт Project → Cross-reference или скрипт: список POU с Language = IL.
  2. Отметить критичность: safety, interlock, часто не трогаемые.
  3. Зависимости: кто вызывает IL FB, есть ли external library на IL.
  4. Оценка: строк IL vs сложность (таймеры, PID в IL - больнее всего).

Параллельно git branch или копия проекта - версионирование проектов ПЛК перед массовой миграцией.

Стратегия поэтапной миграции IL → ST

Шаг 1. Новый FB на ST с тем же VAR_INPUT/VAR_OUTPUT, старый IL FB переименовать в _Legacy, вызов заменить на новый FB в одном месте, тест.

Шаг 2. Построчный перенос IL в ST: LD → присваивание, AND/OR → логические выражения, TON → вызов стандартного TON. Таблица соответствий IL-ST держать в комментарии POU первую неделю.

Шаг 3. Actions SFC: каждый action - отдельный мини-POU на ST или inline ST action.

Шаг 4. Удалить _Legacy после regression на стенде.

Не переводить весь проект одним commit без стенда - один пропущенный NOT в IL = latch на объекте.

Материал про IL в CODESYS и Structured Text для инженеров - опора при переписывании.

Смешение в одном файле: что делать с {lang IL}

Старые проекты содержат ST с вставками {lang IL} ... {end} . Новый компилятор может отказать. Решение: вынести вставку в отдельный IL POU (если IL ещё компилируется изолированно) или переписать вставку на ST сразу.

Если изолированный IL POU тоже не собирается - полный ST rewrite этого блока.

MasterSCADA vs CODESYS на одном железе

На ПЛК СТАБУР CODESYS и MasterSCADA 4D - взаимозаменяемые среды заказа. Legacy IL - проблема импорта в CODESYS. MasterSCADA проект на том же контроллере IL не использует для логики ПЛК - но если мигрировали «железо + среда» с IL-проекта CODESYS, сценарий тот же.

SFC и IL actions

Sequential Function Chart с actions на IL - частый источник «половина проекта IL». Каждый action переводят на ST, transitions оставляют на LD/ST/SFC как было. Проверка online: шаг залипает из-за action, написанного с ошибкой при переносе.

Библиотеки и vendor FB

Старая библиотека .lib с IL внутри - после upgrade «library not found» или «incompatible». Обновить библиотеку от вендора или заменить FB на ST-аналог из стандартной библиотеки CODESYS.

Ошибка «бiblioteka ne naydena» на чужом ПК из week2 - пересекается: миграция + пути + IL library.

Тестирование после каждого POU

Build all - zero errors. Download на стенд. Online: force входы, проверить выходы против таблицы истины legacy. First scan, cold start - retain не ломается. Документ: POU мигрирован, дата, кто проверил.

Для motor interlock - два сценария: нормальный пуск и аварийный stop.

Когда не мигрировать IL, а заморозить среду

Если объект на старом контроллере без поддержки и «работает 10 лет» - иногда осознанный отказ от upgrade CODESYS дешевле полного ST rewrite. Риск: новое железо не поддержит старый runtime. Для новых контроллеров СТАБУР с 3.5.16 - ST-only политика на новых POU, legacy IL только временно.

Технический долг legacy ПЛК - когда рефакторить обязательно.

Языки IEC 61131-3 в одном проекте

Языки программирования ПЛК: ST, FBD, LD - нормальная практика: разные POU на разных языках. Проблема - не «ST и LD в одном проекте», а «IL и ST в одном POU».

Новые блоки пишут на ST или LD; IL не добавляют.

Справочник ST при переносе

Structured Text IEC 61131-3: синтаксис и ошибки - типовые ловушки: := vs =, MOD для INT, таймеры IN/PT/Q.

IL JMPC, JMPNC - в ST через IF/RETURN с осторожностью, не GOTO без меток.

Автоматизация и ручной контроль

Полностью автоматический конвертер IL→ST для production-кода не существует в надёжном виде. Можно использовать построчные таблицы соответствий и проверку таблиц истинности на стенде. Copilot и LLM для генерации ST по IL - только черновик, каждый блок ревьюит инженер с доступом к online.

Для больших FB разбейте на методы ST с говорящими именами: EvaluateOverload, HandleResetPulse - проще regression, чем монолит из 400 строк IL.

Коммуникация с заказчиком во время миграции

Заказчик слышит «перекомпилировать» и ждёт один день. Объясните: N POU на IL, M дней стенд, zero downtime только при поэтапной замене на резервном контроллере. Параллельный стенд с копией I/O - золотой стандарт; миграция «на живом» без стенда - риск latch на пуске.

Фиксируйте в КП: миграция IL не входит в «апгрейд версии CODESYS» по умолчанию. Отдельная строка с объёмом POU.

LD и FBD в том же проекте: не путать с IL

После миграции IL команда иногда переписывает всё на ST, хотя LD и FBD в соседних POU компилируются без проблем. Не трогайте LD latch interlock, если они не в списке ошибок - scope только IL POU из отчёта компилятора.

Если LD после аварии «залипает» - смежная тема latch/reset; миграция IL не заменяет проверку приоритета сетей в LD.

Первый старт CODESYS после миграции

После массовой замены IL проверьте первый старт CODESYS 3.5: target device, библиотеки, download vs online change. Cold download после смены типов переменных в новом ST может сбросить retain - предупредите эксплуатацию до выгрузки.

Online change для мелких правок ST после миграции - OK; смена интерфейса FB (новые VAR_INPUT) - только download с планом простоя.

Сообщение компилятора, причина, шаг миграции

Сообщение компилятора Причина Шаг миграции
Cannot mix IL and ST IL body + ST method в одном FB Вынести method или переписать body на ST
IL not supported Версия CODESYS отключила IL Полный ST rewrite POU
Action language mismatch SFC action IL, program ST Переписать action на ST
Unknown instruction LD IL внутри ST без lang block Отдельный POU или ST
{lang IL} deprecated Inline IL вставка ST эквивалент
Library IL incompatible Старая .lib Обновить/заменить библиотеку
CAL parameter count Вызов FB изменился в новой lib Сверить сигнатуру ST
POU compiled, link error Дубликат символа после split Rename legacy
Transition IL error Guard на IL ST expression в transition
Build OK, runtime wrong Логика переноса Таблица истины vs online

Вопросы с пуска

Можно ли включить режим совместимости IL?
В 3.5.16 - ограниченно. Рассчитывайте на ST, не на флаг.

Сколько времени на 1000 строк IL?
Зависит от сложности: 3-10 дней инженер с опытом ST при стенде.

MasterSCADA проект затронут?
Логика IL в CODESYS; MasterSCADA на том же ПЛК - отдельный проект.

LD проще перевести чем IL?
Часто LD визуально мигрирует; IL построчно ближе к ST по структуре.

Нужен ли git на время миграции?
Да. Один POU - один commit, откат без боли.

Что делать, если IL только в vendor library без исходников?
Запросить обновлённую библиотеку у вендора или заменить FB на ST-аналог с тем же интерфейсом.

Компилируется, но поведение другое - кто виноват?
Ошибка переноса логики. Таблица истинности на стенде обязательна, не только build OK.

Ссылки по теме