Основные аспекты среды разработки CODESYS Программные объекты
В приложении CODESYS программа состоит из различных программных объектов (POU), которые можно классифицировать в три типа:
- Программы: Это высокоуровневые программные объекты, связанные с циклически вызываемыми задачами контроллера. Они аналогичны точкам входа в пользовательский код, таким как функция main() в других языках программирования. Программы представляют крупные фрагменты технологического процесса, например, “управление вентиляцией” или “обработка тревог”.
- Функции: Это аналог функций в других языках программирования.
- Функциональные блоки: Это аналог классов в современных языках программирования. Для использования функциональных блоков необходимо объявить их экземпляры (инстансы), каждому из которых выделяется своя область памяти. Отличительной особенностью функциональных блоков от функций является сохранение переменных блоков своих значений между вызовами. Они применяются для создания счетчиков, таймеров и других объектов, требующих сохранения данных.
Библиотеки
Среда CODESYS предоставляет обширный набор библиотек с дополнительными функциональными блоками и функциями, такими как генераторы импульсов, регуляторы, блоки чтения/записи файлов и т.д.
Отдельно следует упомянуть библиотеку, которая будет полезна тем, кто привык программировать на языке C и использовать функции из string.h, такие как memset, memcpy, memcmp и др. В CODESYS аналог этой библиотеки называется CAA Memory.
Пользователь может также создавать собственные библиотеки.
Библиотеки, разработанные компанией ОВЕН, доступны на сайте ОВЕН в разделе CODESYS V3/Библиотеки и компоненты. Большинство из этих библиотек поддерживаются только контроллерами ОВЕН.
Синхронное и асинхронное выполнение
Как упоминалось ранее, приложение контроллера выполняется в циклически вызываемой задаче, одной или нескольких. Основные требования к приложению контроллера – высокая скорость и надежность. Каждая итерация этого цикла должна занимать как можно меньше времени и быть детерминированной (то есть время выполнения не должно меняться от итерации к итерации).
Ранее в программировании ПЛК широко использовался подход, при котором почти весь код приложения выполнялся синхронно. Однако есть исключения, такие как таймеры стандартной библиотеки, которые выполняются асинхронно, не блокируя работу кода, расположенного после их вызова.
PROGRAM PLC_PRG
VAR
xDi: BOOL; // Сигнал от дискретного входа ПЛК
xAlarm: BOOL; // Сигнал тревоги
fbDelay: TON; // Экземпляр таймера задержки включения
i: INT;
END_VAR
fbDelay
(
IN := xDi,
PT := T#5S,
Q => xAlarm
);
i := i + 1;
Приведенный пример демонстрирует задержку формирования сигнала тревоги (переменной xAlarm) при замыкании дискретного входа ПЛК (переменной xDi) с помощью таймера задержки (экземпляра fbDelay блока TON).
Технически, таймер вызывается в каждом цикле задачи, но его код начнет выполняться только после того, как вход IN примет значение TRUE. Через 5 секунд выход Q таймера примет значение TRUE, но в течение этого времени инкремент переменной i продолжит выполняться, не прерываясь.
Важно отметить, что многие системные библиотеки предлагают как синхронные, так и асинхронные варианты реализации. Для проиллюстрирования этого, рассмотрим производственную линию по маркировке бутылок. Бутылки движутся по конвейеру, и контроллер должен обеспечивать наклейку этикеток без пропусков. На каждой этикетке должен быть напечатан уникальный код, который необходимо сохранить в файл. Операция записи в файл может занимать разное время, зависящее от модели flash-памяти, размера файла и других факторов. Если запись выполняется синхронно, блокируя другие операции, время одной итерации цикла может значительно увеличиться, что приведет к пропуску следующей бутылки. В таком случае, более разумным решением будет выполнение записи в асинхронном режиме, чтобы она занимала несколько итераций цикла задачи, но время выполнения каждой из них было незначительным.
Синхронные библиотеки основаны на использовании функций, которые выполняются последовательно:
SysFile.SysFileWrite(hFile := hFile, ADR(sWriteData), SIZEOF(sWriteData),
ADR(dwResult) );
// этот код будет выполнен только после окончания записи в файл...
// ...потому что функция SysFileWrite выполняется синхронно
i := i + 1;
Асинхронные библиотеки построены на использовании функциональных блоков:
fbFileWrite
(
xExecute := xWriteToFileCmd,
hFile := hFile,
pBuffer := ADR(sWriteData),
szSize := SIZEOF(sWriteData)
);
IF fbFileWrite.xDone THEN
// здесь разместите код, который будет однократно выполнен после завершения записи
ELSIF fbFileWrite.xError
// здесь разместите код обработки ошибок
END_IF
// этот код будет выполняться каждый цикл задачи
// в том числе, и во время записи в файл
// потому что экземпляр fbFileWrite выполняется асинхронно
i := i + 1;
Примеры выше не включают объявление переменных, открытие файла и другие дополнительные действия – они предназначены для демонстрации разницы в использовании синхронных и асинхронных операций.
Примеры также показывают использование пространств имен (namespaces), что является характерным для enterprise-языков. В CODESYS пространства имен присутствуют у библиотек, функциональных блоков, структур, перечислений и некоторых других объектов.
Отладка
CODESYS предоставляет удобные средства для отладки проекта, включая:
- Отображение текущих значений переменных во время онлайн-подключения к контроллеру.
- Возможность задавать и “фиксировать” значения переменных.
- Точки останова, позволяющие прекратить выполнение приложения в заданном фрагменте кода и оценить значения переменных в этот момент.
- Пошаговое исполнение приложения.
- Поиск значений в оперативной памяти по заданному паттерну и другие функции.
Интерфейс IDE
CODESYS предоставляет разработчикам удобные инструменты, включая:
- Подсветку синтаксиса с возможностью настройки цветов.
- Автодополнение и автоформатирование кода.
- Темную тему для редактора ST.
- Возможность переименования переменных с обновлением всех фрагментов, в которых они используются.
- Перекрестные ссылки для вызываемых объектов (cross-references) и др.
Автоматизированные сборка и тестирование
Хотя программирование ПЛК не полностью соответствует методологии DevOps, CODESYS поддерживает ряд платных плагинов, которые частично решают задачи автоматизации:
- CODESYS Test Manager – инструмент для автоматического тестирования.
- CODESYS Git – плагин для интеграции с системой управления версиями Git.
- CODESYS Static Analysis – статический анализатор для проверки соответствия кода заданным правилам.
- CODESYS Profiler – профилировщик для оценки времени выполнения конкретных фрагментов кода и оптимизации.
Кроме того, разработчики могут создавать скрипты на языке Python для автоматизации операций в CODESYS.
Доступ к ОС контроллера
В большинстве случаев пользователи ограничены средствами IDE и не могут напрямую взаимодействовать с операционной системой контроллера. Однако контроллеры ОВЕН предоставляют два инструмента для решения специфических задач:
- Вызов утилит операционной системы контроллера с помощью библиотеки CmpSysExec. В состав прошивки входят утилиты, такие как curl, jq, клиенты для СУБД и другие, доступные для использования.
- Написание скриптов на языке Python. С помощью библиотеки CmpSysExec можно вызывать скрипты Python, которые выполняют дополнительные задачи, но не заменяют приложение CODESYS.
Документация и гайдлайны
CODESYS предоставляет онлайн-справку и документацию, а также поддерживает гайдлайны от консорциума PLCopen. Однако гайдлайнов для программирования контроллеров пока что не так много, как для enterprise-языков программирования.
А теперь передаем слово вам
Если вы enterprise-разработчик, столкнувшийся с программированием ПЛК, мы будем рады услышать о вашем опыте и трудностях при переходе от “обычного” программирования к программированию контроллеров. Вы можете связаться с нами по адресу internet@owen.ru.