CODESYS V3.5 для enterprise-разработчика. Часть 1
Как быстро освоить среду разработки
Современные тенденции в разработке логических контроллеров
Первые программируемые логические контроллеры (ПЛК), появившиеся в конце 60-х годов прошлого века, представляли собой замену шкафов релейной автоматики. Их задачей являлось формирование нужного состояния дискретных выходов в зависимости от состояния дискретных входов. Современные контроллеры представляют собой подвид промышленных компьютеров, выполняющих не только простейшую дискретную логику, но и гораздо более сложные операции – обмен данными с другими устройствами, архивирование значений технологических параметров в специфических форматах, запись значений в базы данных и т. д.
Другой тенденцией является всё более тесная интеграция систем автоматизации технологических процессов с системой управления предприятием (MES, ERP). Это приводит к тому, что всё чаще к программированию контроллеров привлекают не инженеров АСУ ТП, а «классических» программистов, привыкших использовать современные enterprise-языки: C++, C#, Java и т. д. Подходы, используемые при программировании контроллеров, могут при первом знакомстве показаться им непривычными. В данной статье мы расскажем, как enterprise-разработчику быстро освоить среду разработки CODESYS V3.5, сделав акцент на известных ему понятиях. Эта среда используется для программирования множества контроллеров – в том числе, для программирования линеек контроллеров ПЛК2хх и СПК1хх, выпускаемых компанией ОВЕН.
Среда разработки и система исполнения
CODESYSV3.5 является интегрированной средой разработки (IDE), включающей в себя редакторы языков программирования, редактор для создания графического интерфейса (GUI), компилятор, отладчик и другие компоненты.
Созданный пользователем проект перед загрузкой контроллер преобразует в набор файлов, загружаемых в директорию PlcLogic, расположенную в памяти ПЛК. Главным среди них является файл с расширением .app, содержащий машинный код для конкретного процессора (для этого в CODESYS входят генераторы кода для разных платформ – Intel, ARM, PowerPC и др.). Контроллеры ОВЕН используют архитектуру ARM и операционную систему OpenWrt, основанную на Linux.
Чтобы использовать CODESYSIDE для программирования контроллера, этот контроллер должен включать в себя систему исполнения (runtime). Система исполнения входит в состав прошивки контроллера и «зашивается» в него на этапе изготовления.
Среда разработки является бесплатной для конечного пользователя; некоторые дополнительные компоненты (например, инструмент для интеграции с системой контроля версий Git) требуют лицензирования и приобретаются отдельно.
Лицензия на систему исполнения оплачивается производителем контроллера.
Таргет-файл
Чтобы создать проект в CODESYS, нужно обязательно указать контроллер, для которого он будет создан. Это связано с тем, что CODESYS должен «знать» характеристики контроллера (в частности, требуемый для него генератор кода). Эта информация содержится в таргет-файлах. Они обычно распространяются в виде пакетов (файлов формата .package). Таргет-файлы контроллеров ОВЕН также можно загрузить с сайта ОВЕН в разделе CODESYS V3/Сервисное ПО. В современных версиях CODESYS установка пакетов выполняется через утилиту CODESYS Installer, которая входит в состав среды разработки.
Механизм выполнения приложения
Контроллеры ориентированы на циклическое выполнение заложенных в них операций. Приложение контроллера выполняется в автоматически создаваемом средой бесконечном цикле, называемом задачей. В проекте может быть несколько задач с разными периодами вызова и приоритетами. Их настройки выполняются в компоненте Конфигурация задач.
Это может быть непривычно для enterprise-разработчиков, привыкших организовывать подобный цикл в своем коде или использовать планировщики задач для вызова своего ПО. Поэтому учтите, что весь написанный вами код будет вызываться циклически.
Большинство контроллеров с CODESYS V3.5 (в том числе контроллеры ОВЕН) используют вытесняющую многозадачность.
Стандарт МЭК 61131-3 и язык ST
Большинство контроллеров программируются на специальных языках, описанных в стандарте МЭК 61131-3. Стандарт определяет 5 языков:
- LD, FBD, SFC – графические языки программирования;
- IL – низкоуровневый текстовый язык, синтаксически похожий на язык ассемблера. При этом IL не является «настоящим» языком ассемблера (то есть его команды не соответствуют командам процессора). В последней редакции стандарта этот язык признан устаревшим;
- ST – единственный высокоуровневый текстовый язык, описанный в стандарте.
Наличие 5 языков программирования вызвано историческими причинами – первые несколько десятилетий развития контроллеров каждый производитель создавал собственный язык, и перед разработчиками стандарта стояла задача как-то ограничить их количество, учитывая при этом интересы крупных компаний, уже вложивших множество средств в разработку своего ПО.
Для enterprise-разработчика естественным выбором будет язык ST (Structured Text). Это высокоуровневый текстовый язык, представляющий собой промышленный диалект языка Pascal. У него лаконичный и строгий синтаксис и типовой набор управляющих операторов – IF, CASE, циклы FOR и WHILE.
Сравните код для вычисления факториала, написанный на языках Java и ST:
Не вдаваясь в мелкие синтаксические нюансы, рассмотрим те моменты, которые отличаются концептуально.
Во-первых, напомним, что весь код программы контроллера выполняется циклически. Это необходимо, чтобы вычислять факториал только тогда, когда это действительно нужно, добавив команду булевского типа с именем DoCalculate. Так как код задачи выполняется циклически, то можно отказаться от цикла FOR, представив его в виде операции инкремент. Таким образом, этот код будет выполняться асинхронно, в течение нескольких циклов задачи. Если бы использовали цикл FOR, то код выполнялся бы синхронно (подробнее про синхронное и асинхронное выполнение мы поговорим ниже).
Во-вторых, вывод в лог, традиционно используемый в других языках для отладки, при программировании контроллеров используется редко (лог контроллера используется системой исполнения контроллера для вывода сообщений об исключениях и ошибках в его работе). Вместо этого значения переменных удобно наблюдать в IDE в режиме отладки – они отображаются во всех фрагментах кода, где эти переменные используются. В примере на ST выше мы просто сформировали текстовое сообщение (как в исходном примере на Java) и записали его в текстовую переменную str_fact. Перегрузка оператора «+» для объединения строк в языке ST не поддерживается; вместо этого используется функция стандартной библиотеки CONCAT, которая позволяет объединить две строки (у этой функции фиксированное число аргументов, так что объединить более двух строк не получится). Не поддерживается и неявная конверсия типов, поэтому мы приводим INT к STRING с помощью оператора TO_STRING.
Объявление переменных происходит на отдельной панели текстового редактора; объявлять переменные в области кода нельзя.
ST (как и другие языки стандарта МЭК 61131-3) – это компилируемый язык со статической типизацией и статическим выделением памяти (строго говоря, CODESYS предоставляет средства для динамического выделения памяти, но они используются крайне ограниченно и, в основном, при разработке библиотек, а не пользовательских приложений).
Это связано с тем, что основные требования к приложению контроллера – быстродействие и надежность. За них приходится расплачиваться существенно меньшим уровнем гибкости по сравнению с тем, что предоставляют современные enterprise-языки.
В основном приложения для контроллеров разрабатываются в парадигме структурного программирования. CODESYS – это одна из немногих сред разработки, которая помимо этого предоставляет средства для использования объектно-ориентированного подхода (ООП). Реализация ООП похожа на язык Java и использует те же ключевые слова: INTERFACE, EXTENDS, IMPLEMENTS, SUPER, THIS и т. д. Но широкого распространения ООП в задачах программирования контроллеров не получил. Примеров и документации на эту тему крайне мало. В основном ООП используется самими разработчиками CODESYS (например, он активно применяется в библиотеках GUI и протоколах обмена).
Программирование на ST по своему принципу близко к разработке на ANSI C для embedded-устройств – здесь тоже часто приходится работать с битами, заниматься сериализацией/десериализацией байтовых массивов и т. д.
В CODESYS присутствует стандартный набор типов данных (числа, строки, специальные типы для работы с датой и временем, массивы, структуры, перечисления) и операторов. Для работы с памятью «напрямую» поддерживаются указатели.