Tag Archives: CoDeSys

Отладка проекта CoDeSys

ПО CoDeSys располагает несколькими инструментами отладки проекта. Их краткие описания приведены ниже.

В режиме отладки ПЛК работает существенно медленнее. Из-за этого возможны прерывания связи по таймауту. Поэтому при отладке следует перенастроить таймауты в окне настройки, вызываемом командой «Проект | Опции (Project | Options)» главного меню ПО CoDeSys: на вкладке «Рабочий стол (Desktop)», значение параметра «Таймаут связи (Communication timeout)» увеличить до 15000.

Опция «Отладка»

Опция отладки ПО CoDeSys заставляет компилятор формировать дополнительный код, упрощающий поиск ошибок. Опция «Отладочный код (Debugging)» включается установкой флажка переключателя «Отладочный код (Debugging)» в окне «Опции (Options)», вызываемом командой «Проект | Опции (Project | Options)» главного меню, на вкладке «Генератор кода (Build)» (см. рисунок 1).

Рисунок 1 – Окно «Опции (Options)» вкладка «Генератор кода»

 Точки останова

Точки останова – это места, в которых выполнение программы будет приостанавливаться, что позволяет просмотреть значения переменных на определенном этапе работы программы. Точки останова можно задавать во всех редакторах. В текстовом редакторе точка останова устанавливается на номер строки, в FBD и LD – на графический элемент, в SFC – на шаг.

Система исполнения CoDeSys SP32 Bit Full автоматически деактивирует сторожевой таймер задачи, если она выходит на точку останова.

Пошаговое выполнение

Пошаговое выполнение позволяет проверить логическую правильность программы. Под «шагом» подразумевается:

  • IL: Выполнить программу до следующего оператора CAL, LD or JMP.
  • ST: Выполнить следующую инструкцию.
  • FBD, LD: Выполнить следующую цепь.
  • SFC: Продолжить действие до следующего шага.

Выполнение по циклам

Команда «Онлайн | Один цикл (Online | Single Cycle)» выполняет один рабочий цикл и останавливает контроллер после выполнения.

Эмуляция

Режим эмуляции последовательно включается и отключается выбором команды «Онлайн | Режим эмуляции (Online | Emulation)» главного мню. Включенный режим маркируется устновленным флажком в строке главного меню и записью «Эмул.» в строке состояния главного окна. Во время эмуляции созданная программа выполняется не в ПЛК, а в компьютере, на котором запущено ПО CoDeSys. В этом режиме допустимы все функции онлайн, что позволяет проверить логическую правильность программ, не используя контроллер.

В режиме эмуляции функции внешних библиотек не выполняются.

Бортжурнал (Log)

«Бортжурнал (Log)» хронологически записывает действия пользователя, внутренние сообщения системы исполнения, изменения состояния и исключения в режиме онлайн. Это позволяет анализировать условия возникновения ошибки при отладке программы. Просмотр записей «Бортжурнала (Log)» производится в режиме, вызываемом выбором строки «Бортжурнал (Log)» дерева ресурсов проекта на вкладке «Ресурсы» организатора объектов CoDeSys.

Сложные типы данных в CoDeSys 2.3

Массивы

Элементарные типы данных могут образовывать одно-, двух-, и трехмерные массивы. Массивы могут быть объявлены в разделе объявлений POU или в списке глобальных переменных.

Путем вложения массивов можно получить многомерные массивы, но не более 9-мерных («ARRAY[0..2] OF ARRAY[0..3] OF …»).

Синтаксис:

<Имя_массива>:ARRAY [<ll1>..<ul1>,<ll2>..<ul2>] OF <базовый тип>

Здесь ll1, ll2, ll3 указывают нижний предел индексов; ul1, ul2 и ul3 указывают верхние пределы. Индексы должны быть целого типа. Нельзя использовать отрицательные индексы.

Перечисления

Перечисление – это определяемый пользователем тип данных, задающий несколько строковых псевдонимов для числовых констант.

Перечисление доступно в любой части проекта, даже при локальном его объявлении внутри POU. Поэтому рационально создавать все перечисления на вкладке «Типы данных» Организатора Объектов. Объявление должно начинаться с ключевого слова TYPE и заканчиваться строкой END_TYPE.

Синтаксис:

TYPE <Имя_перечисления>:(<Элемент_0> ,< Элемент _1>, …, < Элемент_n>); END_TYPE

Переменная типа <Имя_перечисления> может принимать только перечисленные значения. При инициализации переменная получает первое значение из заданного списка. Если числовые значения элементов перечисления не указаны явно, то им присваиваются последовательно возрастающие числа, начиная с 0. Фактически элемент перечисления – это число типа INT, и работать с ними можно точно так же.

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

Структуры

Структуры создаются командой «Добавить объект (Add Object)» контекстного меню вкладки «Типы данных» Организатора Объектов. Новый объект отображается в дереве объектов, окно задания параметров объекта открывается в рабочей области главного окна ПО CoDeSys (см. рисунок 1).

Объявление должно начинаться с ключевых слов TYPE и STRUCT и заканчиваться строками END_STRUCT и END_TYPE.

Синтаксис:

TYPE <Имя _структуры>:

STRUCT

<Объявление переменной 1>

.

.

<Объявление переменной n>

END_STRUCT

END_TYPE

<Имя _структуры> образует новый тип данных, который может быть использован в любой части проекта наряду с базовыми типами.

Рисунок 1 – Вкладка «Типы данных»

Допускаются вложенные структуры, но запрещено размещение элементов структуры по прямым адресам (в частности, недопустимы AT объявления). Для доступа к элементам структуры используется следующий синтаксис:

<Имя_структуры>.<Имя_компонента>

Например, если структура «Week» содержит компонент «Monday», то обращение к нему будет выглядеть так: Week.Monday.

Указатели

Указатели позволяют работать с адресами переменных или функциональных блоков.

Синтаксис:

<Имя_указателя>: POINTER TO <Тип данных/Функциональный блок>;

Указатели применимы для всех базовых типов данных или функциональных блоков, включая определяемые пользователем.

Корпоративная многозадачность в CoDeSys

Допустим, нам нужно управлять тремя устройствами. Можно бы поставить три отдельных ПЛК, но устройства несложные и вполне можно попробовать обойтись одним контроллером. В таком случае, возникает логичная мысль не сваливать весь программный код в одну кучу, а разделить его на три программы.

Теперь представьте себе, что мы имеем обычный однозадачный ПЛК с классическим рабочим циклом: 1)чтение входов, 2) вызов прикладной программы, 3) запись выходов. Мы можем поступить очень просто:

написать 3 программы и добавить их вызовы один за другим в главную прикладную программу:

PRG_A;

PRG_B;

PRG_C.

Вполне работоспособное решение. Но может оказаться, что общий цикл стал слишком медленным для PRG_A, хотя PRG_C можно бы, напротив, вызывать значительно реже. Тоже не проблема. Запрограммируем в главной программе некие счетчики, так чтобы каждая программа вызывалась не в каждом цикле, а только через определенное число циклов (например, 1 раз на 10 рабочих циклов). Изменяя параметры этих счетчиков, мы можем настраивать интервалы вызова наших программ. По сути дела мы реализовали три параллельно работающих задачи. Естественно, что в один момент времени работает только одна из них, но с позиции наблюдателя они работают параллельно.

Конечно, не очень удобно возиться со счетчиками. Это лишняя работа, лучше бы поручить ее системе исполнения. Собственно это и достигается с помощью конфигуратора задач CoDeSys.

Описанный выше механизм называется корпоративной многозадачностью либо многозадачностью без вытеснения. Корпоративность обозначает тот факт, что для нормальной работы всей системы, задачи должны сотрудничать между собой. Очевидно, что если одна из задач станет выполнять очень длинные вычисления, длиннее чем заданное время рабочего цикла, то она задержит выполнение других задач. Для корректной работы каждая задача не должна содержать длительных вычислений. Их необходимо разбивать на несколько циклов вызова задачи. Например, не использовать поиск в массиве с помощью итераций по циклу FOR, а обрабатывать каждый следующий элемент массива при очередном вызове задачи. В случае ‘зацикливания’ в одной задаче, останавливается все. Каждая задача должна аккуратно отработать свой цикл, прежде чем сможет получить управление другая задача. В этом главный минус корпоративной многозадачности. В каждой задаче нужно не забывать о других задачах и аккуратно избегать длительных вычислений в одном цикле вызова.

С другой стороны, в том, что каждая задача всегда дорабатывает свой цикл и не может быть прервана в произвольный момент, состоит и большой плюс. Мы можем абсолютно спокойно использовать результаты вычислений одной задачи в другой. Почему это так, станет понятно ниже при описании вытесняющей многозадачности. Отсюда следует, что ‘корпоративная’ многозадачность не означает ‘плохая’. Часто она удобнее. В первую очередь тогда, когда задачи должны тесно взаимодействовать между собой. Без всяких ограничений в нескольких задачах можно использовать глобальные переменные любого типа. Все входы ПЛК опрашиваются перед вызовом каждой задачи, после каждой задачи происходит синхронное обновление всех выходов. Каждая задача может работать с произвольными входами/выходами, в том числе может контролировать выходы, изменяемые в другой задаче. Никакой опасности считать с них некие промежуточные, недостоверные значения нет. Практически мы пишем программы для нескольких корпоративных циклических задач точно так, как и в случае с одной задачей. Если в программе допущена серьезная ошибка, приводящая к зацикливанию, то при корпоративной многозадачности контроллер полностью теряет работоспособность. Это равносильно фатальному сбою контроллера и его приходится перезапускать вручную. Преодолеть эту проблему в CoDeSys позволяют программные сторожевые таймеры. Алгоритм их работы предельно прост: если задача не возвращает управление дольше заданного времени, то таймер ‘срабатывает’ и происходит вызов специального обработчика системного события. По умолчанию этот обработчик выполняет перезапуск контроллера. Вы можете заменить его собственной реализацией, например, включить индикацию ошибки или инициализировать зависшую программу. Как писать обработчики системных событий, мы рассмотрим позднее.

Вытесняющая многозадачность

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

Основной плюс состоит в том, что задачи с низким приоритетом не влияют на задачи с высоким приоритетом. Каждая задача может делать сколь угодно длинные вычисления. Она автоматически будет прервана, при необходимости выполнить более приоритетную задачу и затем снова получит управление и продолжит работу с того места, где она была прервана. Таким образом, отпадает нужда думать об обеспечении заданного времени вычислений в рамках одного цикла вызова программы.

При вытесняющей многозадачности система исполнения CoDeSys плотно взаимодействует с операционной системой ПЛК. Каждая прикладная МЭК задача является отдельным потоком ОС. Каждая задача имеет свой собственный рабочий цикл ПЛК. Опрос ‘своих’ входов, вызов ‘своих’ программ, запись ‘своих’ выходов происходит автономно, независимо от остальных задач. При компиляции проекта CoDeSys автоматически распределяет входы/выходы по задачам, в которых они задействованы и передает соответствующую конфигурацию драйверам аппаратуры.

Грубо можно считать, что при вытесняющей многозадачности мы имеем несколько ПЛК в одном корпусе. К сожалению, в CoDeSys V2.3 текст задач нельзя компилировать, перезагружать и отлаживать автономно, не нарушая работу других задач (это возможно в CoDeSys V3).

Проблемы в многозадачных проектах при вытесняющей многозадачности возможны при использовании общих аппаратных ресурсов и глобальных переменных. Представьте себе, что одна задача начала изменять некую глобальную переменную, например, структуру или строку. Пока изменение не полностью закончено, содержимое данной переменной не определено. Теперь представьте, что в этот момент другая задача получает управление и читает или, хуже того, записывает данную переменную. Результат непредсказуем. Ситуация может проявиться один раз после многих дней нормальной работы ПЛК. ‘Поймать’ ее отладчиком не реально. Остается только не допускать. Классическим приемом защитой от такой ситуации является использование семафоров. Одна задача захватывает некий ресурс для себя и взводит семафор, другие задачи ждут ‘зеленый свет’. Семафоры в CoDeSys реализованы в библиотеке SysLibSem.lib. Работа с ними описана в файле SysLibSem_RU.pdf.

Очень важным является правильный выбор приоритетов задач в конфигураторе. Нулевое значение соответствует наивысшему приоритету. Свободная задача в проекте может быть только одна. Она занимает все свободное время процессора. Если присвоить ей высокий приоритет, то никакие менее приоритетные задачи никогда не получат управления. Всегда присваивайте свободной задаче низший приоритет.

Выше мы рассмотрели способы измерения длительности выполнения своих программ. Обратите внимание, что непредвиденные задержки выполнения способны вызывать и некоторые библиотечные функции. Допустим, функция осуществляет запись в файл или запрос данных от устройства по последовательному каналу связи. Очевидно, это требует определенного времени (до нескольких секунд).

Есть два способа реализации функций. При синхронной реализации функция не возвращает управления вплоть до получения результата. Ее использование очень просто – вызываем функцию, получаем результат. Если такие функции сосредоточены в низкоприоритетной задаче, то их задержки не критичны, при вытесняющей многозадачности. Альтернативный вариант – это асинхронная реализация длительных операций. Одна функция начинает операцию и моментально возвращает управление. Некоторая отдельная функция проверяет факт окончания операции. Ее нужно вызывать периодически. Задержек в функциях нет, но программа усложняется. Трудно сказать, что удобнее. Поэтому для работы с файлами в CoDeSys есть две библиотеки: SysLibFile с синхронными функциями и SysLibFileAsync с асинхронными функциями.

Альтернативой циклическим задачам является ‘событийный’ вызов задач. Вариант ‘по событию’ в конфигураторе задач позволяет вызвать данную задачу при изменении указанной логической переменной, например, дискретного входа. Такая задача также имеет приоритет и работает с вытеснением или корпоративно, как и циклические задачи.

В некоторых моделях ПЛК существуют устройства, способные генерировать так называемые ‘внешние события’. Например, аппаратные таймеры, счетчики, компараторы и др. Вызов такой задачи может инициироваться аппаратным прерыванием.

Все отладочные средства CoDeSys доступны и в многозадачных проектах. Тонкость состоит в том, что для пошагового выполнения и контроля стека вызовов, CoDeSys нужно знать какую именно задачу мы отлаживаем. Не забудьте в конфигурации задач выбрать нужную и в контекстном меню дать команду ‘Отлаживать эту задачу’.

Мы детально рассмотрели отличия корпоративной и вытесняющей многозадачности. Вытесняющая многозадачность реализована в ПЛК с CoDeSys, выполненных на базе 32-х разрядных процессоров с многозадачной ОС. Во всех остальных случаях в системе исполнения реализуется корпоративная многозадачность.

Как точно проверить, что в имеющемся у нас ПЛК реализована вытесняющая или корпоративная многозадачность? Давайте для практики напишем тестер качества реализации многозадачности. Если вы сможете самостоятельно придумать, как написать такую программу в CoDeSys, то это означает, что вы являетесь пользователем высшей квалификации и можете смело браться за любые задачи с многозадачностью. В противном случае, следуйте за изложением ниже. Начнем с создания классической простейшей программы для ПЛК, инкрементирующей целую глобальную переменную при каждом вызове. Например, так:

g_udiQuickCounter := g_udiQuickCounter + 1;

Свяжем ее с циклической задачей названной QuickTask. Дадим ей высокий приоритет 5. Пусть она вызывается с интервалом в 2 мс.

Рис 1. Задача QuickTask

Теперь делаем вторую ‘вредную’ программу. Она будет содержать аналогичный счетчик и делать некие сложные математические вычисления в цикле. Никакого смысла кроме траты процессорного времени в этих вычислениях нет:

g_udiMainCounter := g_udiMainCounter + 1;

FOR iActIndex := 0 TO iMaxIndex DO

rArg := (2 * rPI * (iActIndex MOD 360)) / 360.0;

rRes := 40 * SIN(rArg / (2 * rPI)) + 40;

END_FOR

Ее мы поместим в другую циклическую задачу с меньшим приоритетом 10 и интервалом 10мс. Вредность этой программы заключена в том, что она будет тратить на свои бессмысленные вычисления 8мс, оставляя’окно’ 2мс. При корпоративной многозадачности в это окно будет вписываться ровно один вызов первой задачи. Мы увидим, что оба счетчика меняются одинакового, несмотря на заданные разные интервалы задач.

Соотношение счетчиков должно быть один к одному. При качественной вытесняющей многозадачности, более приоритетная задача будет вызываться четко в пять раз чаще. Соотношение счетчиков должно быть пять к одному. Отклонения от этих идеальных величин возможны, если выполнение системных сервисов (например, обслуживание сети) вызовет нарушение точности выдержки интервалов прикладных задач. Подстраивать время вычислений нашей ‘вредной’ программы мы можем, изменяя число итераций цикла iMaxIndex. Конечно, его можно просто подобрать вручную под быстродействие испытуемого ПЛК, дабы вычисления занимали 8мс. Но это не технично. Добавим в программу регулятор, который будет автоматически поддерживать заданную длительность цикла вычислений:

TickBase(SystemTime:=SystemTime);

t1 := SystemTime.ulLow;

(* тут стоит цикл вычислений FOR, см выше*)

TickBase(SystemTime:=SystemTime);

t2 := SystemTime.ulLow;

t3 := t2 — t1;

IF t3 < 7950 THEN

iMaxIndex := iMaxIndex + 100;

END_IF

IF t3 > 8050 AND iMaxIndex > 1000 THEN

iMaxIndex := iMaxIndex — 100;

END_IF

Здесь TickBase – это системный таймер CurTime из библиотеки SysLibTime. При объявлении переменная iMaxIndex получает начальное значение 20000. В данном фрагменте она регулируется так, чтобы интервал задачи составлял 8000мкс +-50.

Осталось вычислить соотношение счетчиков:

g_rRatio := UDINT_TO_REAL(g_udiQuickCounter) / UDINT_TO_REAL(g_udiMainCounter);

Полная реализация этой программы и конфигурация задачи показана на рис. 2.

Рис 2.Реализация задачи MainTask

Результаты запуска тестовой программы таковы:

CoDeSys SP RTE: соотношение 4.99. Ничего удивительного, так и должно быть в качественном контроллере с вытесняющей многозадачностью.

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

Итак, для использованных нами ПЛК множество задач не стало проблемой.

Задачи и контроль времени выполнения в CoDeSys

Слово ‘задача’ в CoDeSys служит исключительно для организации планирования вычислительного процесса. На практике мы имеем дело с задачами только в ‘Конфигураторе задач’. Здесь мы создаем задачи, назначаем им имена и настраиваем их параметры. Для выполнения полезной работы с каждой задачей связывается как минимум одна программа (POU типа PROGRAM). Когда мы создаем новый проект в CoDeSys, то в нем неявно организуется одна задача, содержащая вызов одной программы PLC_PRG.

Данная задача всегда выполняется циклически. В зависимости от типа ПЛК могут быть два способа ее вызова. Обычно она запускается так часто как это только можно. Как только программа отрабатывает один цикл вызова, система исполнения выполняет обслуживание входов/выходов и снова запускает прикладную задачу. Очевидно, период вызова такой задачи не стабилен и может плавать в зависимости от того, по какой ветви работает программа в данный момент. Обслуживание системой исполнения аппаратных устройств, коммуникационных каналов, работа отладчика также могут влиять на периодичность такой задачи. В окне ‘Конфигурация ПЛК’ задача такого типа называется ‘свободная’ (freewheeling). Второй способ состоит в поддержке стабильного интервала выполнения единственной задачи. Даже если программа пуста, то она не будет вызываться чаще, чем задано. В окне ‘Конфигурация ПЛК’ такая задача называется ‘циклическая’.

Например, в ПЛК-150 компании Овен по умолчанию единственная задача вызывается циклически с интервалом 1 мс. Время рабочего цикла можно изменять от 0 до 50 мс (параметр MinCycleLength в конфигурации ПЛК). При задании нулевого времени контроль отключается и задача превращается в ‘свободную’. Такой встроенный механизм настройки ПЛК достаточно удобен для начинающих пользователей.

Для любых типов ПЛК мы можем открыть в CoDeSys диалоговое окно ‘Конфигурация ПЛК’, создать новую задачу и настроить ее параметры так, как нам нужно. Обратите внимание на то, что если мы беремся за самостоятельное определение задач в CoDeSys и создаем в конфигураторе хотя бы одну задачу, то действовавший по умолчанию вызов PLC_PRG отключается. Нам нужно будет вручную добавить вызов этой программы в одну из задач, даже если она всего одна. См. рис. 1.

Рис 1. Настройка циклической задачи с вызовом программы PLC_PRG

 

При задании интервала циклической задачи нужно быть реалистом и не задавать физически недостижимых величин. Так, если используемая вами модель ПЛК имеет системный таймер, который ‘тикает’ раз в 10 мс, то установка интервала не кратного 10 мс не имеет смысла. Если в конфигурации ПЛК Овен вы задали время рабочего цикла 50мс, то чтобы вы не задали в конфигураторе задач, никакая задача не будет вызываться чаще.

При малых значениях интервала задачи весьма вероятно написать программу с настолько большим числом вычислений в одном цикле ее вызова, что она не будет ‘помещаться’ в заданный интервал. При этом интервал вызова программы будет нестабилен, что может быть нежелательно. Но как это проверить при отладке?

В ПЛК компании Овен для этой цели реализован встроенный механизм контроля времени рабочего цикла. В конфигурацию ПЛК необходимо добавить модуль статистики, который включает вход Cycle time. Здесь вы получите число, содержащее измеренное время цикла в сотнях миллисекунд.

Рис 2. Измерение длительности цикла в ПЛК 150 Овен

 

Универсальным способом измерения коротких интервалов является использование точного таймера из системной библиотеки SysLibTime.lib. Библиотека содержит функциональный блок CurTime, который дает время системного таймера в микросекундах. Естественно, практически нельзя рассчитывать, что системный таймер любого ПЛК ‘тикает’ каждую микросекунду. Поэтому прежде чем полагаться на результаты этого способа измерения, уточните частоту его работы. Данная библиотека является не обязательной и может неподдерживаться для определенных типов ПЛК. На рисунке 2 показан результат прогона на ПЛК-150 Овен простой программы, которая измеряет интервал своего вызова в мкс, при установленном рабочем цикле 10мс. Для контроля приведены результаты измерений с использованием модуля статистики. С учетом дискретности таймера 100мкс мы получаем одинаковые результаты для обоих способов измерения.

Диалоговое окно ‘Конфигурация задач’ CoDeSys имеет свой встроенный диагностический инструмент. Для его работы необходимо включить в проект библиотеки SysLibTime и SysTaskInfo. Учтите что, они поддержаны не для всех типов ПЛК. На рисунке 3 показана информация о работе одной циклической задачи (5 мс), включающей программу, выполняющую сто тысяч операций с переменной типа REAL в CoDeSys SP RTE. На диаграмме видна заданная длительность цикла (светлая полоса) и реальное время вычислений. Оно занимает до 3.3 мс. Очевидно, что для данной задачи задавать интервал менее 4мс нет смысла.

Рис 3. Конфигурация ПЛК в режиме онлайн.

 

Далеко не в каждом ПЛК удается напрямую измерить длительность выполнения программы. Часто она меньше или сравнима с дискретностью системного таймера.

Конфигурирование ведомого CANopen-устройства (CANopen Slave)

ПЛК, программируемый с помощью CoDeSys, можно использовать как CANopen Slave-устройство в сети. В дальнейшем будем называть CANopen Slave как CanDevice.

Для этого необходимо определить ПЛК конфигурацию и сохранить ее в EDS-файле. Такой EDS-файл можно в дальнейшем использовать при определении конфигурации CANopen мастера.

Требования для создания CanDevice:

1. Библиотеки

a. 3S_CanDrv.lib

b. 3S_CanOpenManeger.lib

c. 3S_CanOpenDevice.lib

должны быть включены в проект. Они необходимы для того, чтобы ПЛК мог работать как устройство CAN.

2. В конфигурационном файле с расширением *.cfg, который описывает конфигурацию ПЛК, должны быть сделаны соответствующие настройки. Только в этом случае в PLC Configuration появится дополнительный подэлемент “CanDevice”. Этот объект настраивается в дополнительном диалоге с 3 вкладками: Base settings, CAN settings, Default PDO mapping.

Базовые настройки CanDevice

Диалог Base settings

Bus identifier: пока не используется

Name of updatetask: название задачи, из которой будет вызываться CanDevice. В выпадающем списке вы можете выбрать необходимую задачу.

EDS file generation: включите эту опцию, если хотите чтобы текущие настройки были сохранены в EDS-файле, который потом можно использовать для настройки любого CAN-устройства. В поле Name of EDS file введите имя и путь к файлу. Вы можете вручную создать шаблон для EDS и указать к нему путь в поле Template of EDS file. Например, создайте текстовый файл, содержащий элементы EDS- файла, сохраните его как EDS_template.txt и укажите к нему путь в поле Template of EDS file. Теперь, если вы создаете EDS-файл “device_xy.eds” для текущего проекта, то настройки, сделанные в проекте, будут объединены с настройками из шаблона и сохранены в файле “device_xy.eds” (расширение шаблона не должно быть “.eds”). Если настройки текущего проекта уже определены в шаблоне, то они не будут перезаписаны.

Для указания пути к файлам используйте стандартный диалог, который открывается при нажатии кнопки Browse…

CAN-параметры CanDevice

Диалог CAN settings

В этом диалоге вы можете определить Node id и Baud rate. Node id – это идентификатор узла, который используется для адресации к устройству по сети CANopen.

Так же можно настроить Nodeguarding и Emergency Telegram (описание этих механизмов приведено выше). Heartbeat не поддерживается.

Стандартное PDO отображение для CanDevice

Диалог Default PDO mapping

В этом диалоге элементы локального Менеджера параметров могут быть сопоставлены с PDO, которые отправляются и принимаются этим CanDevice. Полученное PDO-отображение будет доступно в любом конфигураторе, в который CanDevice интегрируется. Параметры, описанные в Менеджере параметров, присоединяются к переменным проекта с помощью системы индексов/подиндексов.

List of mappable objects: Здесь вы можете выбрать список параметров, элементы которого будут отображаться в PDO данного CanDevice. В зависимости от целевой платформы, можно создать список параметров типа “Mapping”, который специально предназначен для отображения в PDO CanDevice. В этом случае для настройки отображения PDO будет доступен только этот список параметров. В противном случае будут доступны все списки параметров типа “Variables” и “Instance”.

Элементы выбранного списка появляются в списке Objects. В списке PDO’s настраивается конфигурация PDO. Добавить в список принимаемые и передаваемые PDO можно с помощью кнопок Insert receive PDO и Insert send PDO. Для того чтобы отобразить объект в PDO, выберите объект в левом окне, PDO в правом и нажмите кнопку >>. Параметры PDO настраиваются с помощью диалога, который появляется при нажатии кнопки Properties.

С помощью кнопки Delete выбранное PDO можно удалить из списка.

Пример:

Цель: В первое принимаемое PDO(COB-Id = 512+NodeId) нужно отобразить переменную PLC_PRG.a Для этого в менеджере параметров нужно создать параметр с определенным индексом/подиндексом и связать его с переменной PLC_PRG.a. Менеджер параметров подключается на вкладке “Network functionality” в настройках целевой платформы. Там же определятся диапазоны индексов и подиндексов.

Теперь в диалоге “Default PDO-Mapping” можно отобразить этот параметр в принимаемое PDO.

Конфигурирование CANopen-модулей в CoDesys 2.3 (часть 2)

Раздел экстренных телеграмм (Emergency Telegram):

Модуль передает аварийное сообщение с уникальным идентификатором COB-Id, когда происходит внутренняя ошибка. Это сообщение, различное для разных модулей, хранится по диагностическому адресу. Нажав кнопку ‘Инфо’ (Info), вы можете просмотреть содержание EDS или DCF файлов. Информация разбита на 3 раздела: ‘О файле’ (FILE INFO), ‘Об устройстве’ (DEVICE INFO) и “O PDO” (PDO INFO).

Выбор CAN-модулей модульных ведомых устройств

В левой колонке (Available modules) находятся все доступные модули. Выберите нужные вам модули и с помощью кнопки Add добавьте их в правую колонку (Selected Modules). С помощью кнопки Remove модуль можно будет удалить. Настройки PDO и SDO изменяются автоматически.

Отображение PDO в CAN-модулях

Вкладки ‘Отображать приним. PDO’ (Receive PDO mapping) и ‘Отобр. приниающие PDO’ (Send PDO mapping) в диалоге конфигурирования модуля позволяют изменить образ PDO (PDO mapping), описанный в EDS-файле.

Все доступные объекты располагаются в левой части окна и могут быть отображены в PDO (Process Data Object) с помощью кнопки “>>” и удалены из PDO кнопкой Remove. Объекты типа Standard-DataTypes могут быть использованы для заполнения пустых промежутков в PDO.

Конфигурация CAN-модуля, настройка PDO-отображения

 

Кнопка ‘Вставить PDO’ (Insert PDO) используется для создания дополнительного PDO. В новое PDO вы можете отобразить дополнительные объекты. Распределение памяти входов/выходов для этих объектов производится автоматически, и его можно увидеть в конфигурации контроллера. Кроме того, в конфигурации контроллера появляются символьные имена добавленных объектов.

Настройки PDO можно изменить, нажав кнопку ‘Свойства’ (Properties).

Диалог PDO Properties

 

Каждое PDO имеет собственный идентификатор COB-Id (Communication Object Identifier). Настройки PDO, недоступные для данного модуля, неактивны. ‘Задержка’ (Inhibit Time) – это минимальное время между двумя посылками данного PDO. Нужно выбрать это значение так, чтобы PDO не посылалось слишком часто. Это происходит в том случае, когда значения параметров, отображенных в PDO, передаются чаще, чем меняются их значения, что приводит к необоснованному увеличению загрузки сети.

CMS Priority Group — приоритет PDO при его передаче по сети. Может принимать значения от 0 до 7, причем наивысшему приоритету соответствует значение 0.

‘Тип передачи’ (Transmission Type) Доступны следующие режимы:

  • Ацикличный-синхронный (acyclic-synchronous): PDO передается синхронно, но не периодически
  • Цикличный-синхронный (cyclic-synchronous): PDO передается синхронно, через каждые ‘Число синхр.’ (Number of Sync) синхронизирующих сообщений.
  • Синхр.-только RTR (synchronous-RTR only): PDO обновляется после каждого синхронного сообщения, но передается только после специального запроса (Remote Transmission Request)
  • Асинхр.-только RTR (asynchronous-RTR only): PDO обновляется и передается только после специального запроса (Remote Transmission Request)
  • Асиинхр.-специф. устройства (asynchronous-device profile specific) и Асинхр.-специф. изготовителя (asynchronous-manufacturer specific): PDO передается после специального события.
  • Число синхр. (Number of Sync): число синхронизирующих сообщения между передаваемыми

PDO в режиме синхронной передачи.

Время события (Event-Time): период между двумя сообщениями для соответствующего режима передачи.

Сервисные объекты данных (SDO)

На вкладке сервисных объектов данных (Service Data Object) вы найдете список всех объектов, определенных в EDS и DCF файлах, с индексами от 0x2000 до 0x9FFF. Эти объекты доступны для записи.

Диалог настройки SDO

 

Каждый объект имеет свойства ‘Индекс’ (Index), ‘Имя’ (Name), ‘Значение’ (Value) и ‘По умолчанию’ (Default). Значения этих свойств можно изменять. Выделите нужное вам значение и нажмите <Пробел>. После этого внесите необходимые изменения и для подтверждения нажмите <Enter>, а для отмены — <Esc>. Эти значения передаются в виде SDO (Service Data Object) при инициализации сети.

Конфигурирование CANopen-модулей в CoDesys 2.3 (часть1)

CoDeSys поддерживает настройку оборудования в соответствии со спецификацией CANopen Draft Standart 301. Конфигурирование контроллера производиться практически так же, как описано выше для обычного аппаратно-зависимого конфигурирования ПЛК.

Все файлы электронной спецификации EDS (Electronic Data Sheet) и DCF (Device Configuration File), которые находятся в директории конфигурационных файлов (обычно PLCCONF), интегрируются в CoDeSys. Их содержание можно просмотреть и изменить с помощью ПЛК конфигурации. В EDS описываются параметры CAN-модуля, которые можно настраивать. Если вы добавите модуль, описанный с помощью DCF, можно будет настраивать только МЭК-адреса, а все остальные параметры модуля будут зафиксированы.

Модули CAN настраиваются удаленно с помощью обмена сетевыми сообщениями. Необходимые значения параметров задаются в диалоге ‘CAN параметры’ (CAN Parameters). Затем прием и передача данных модулей происходит через PDO (Process Data Objects), что определяется в диалогах ‘Отобр. принимаемый PDO’ (Receive PDO) и ‘Отобр. перед. PDO’ (Send PDO-Mapping). Значения доступных SDO (Service Data Objects) задаются в диалоге Service Data Objects. Дополнительные параметры CAN модулей, определенные в файлах описания устройств, настраиваются в диалоге ‘Параметры модуля’ (Module parameters). Если программируемый в CoDeSys контрроллер должен быть включен в сеть CANopen как ведомый (“CAN device”), то он настраивается с помощью конфигуратора ПЛК. Его конфигурация записывается в EDS-файл, который может затем может быть использован с любым CANopen мастером.

Ниже описан процесс конфигурирования устройств CANopen.

Базовые параметры CAN-мастера

Настройка таких параметров, как Идент. модуля (Module-Id), Адреса входов/выходов (input/output addresses), Адрес диагностики (Diagnostic address), описана в разделе 0.

Параметры сети CAN можно настраивать сразу после добавления модуля либо после вызова команды “Дополнения” “Свойства” (“Extras” “Properties”).

CAN-параметры CAN-мастера

Выберите скорость передачи данных из списка ‘Скорость’ (Baud rate).

PDO (Process Data Object) может передаваться в синхронном и асинхронном режимах. Синхронизирующее сообщение, имеющее уникальный идентификатор ‘Синхр. COB-ID’ (Sync. COB-ID) (Communication Object Identifier), передается с периодом, указанным в поле ‘Общее время цикла’ (Communication Cycle Period). Для передачи PDO выделяется временной интервал ‘Ширина окна синхронизации’ (Sync. Window Length) сразу после передачи синхронизирующего сообщения. Величина этого интервала указывается в микросекундах. Синхронизирующее сообщение не посылается, если ‘Общее время цикла’ (Communication Cycle Period) и ‘Ширина окна визуализации’ (Sync. Window Length) равны 0. Флажок ‘Активация’ (activate): разрешает передачу синхронизирующего сообщения.

‘Идент. узла’ (Node-Id): уникальный идентификатор CAN-устройства (узла). Принимает значения от 1 до 127. Это значение должно быть уникальным для каждого устройства в сети и задается в десятичном виде. (Не путайте поля Node-Id и Node number.)

Сеть CAN будет автоматически инициализироваться и включаться в работу сразу после загрузки программы, если активна опция ‘Автостарт’ (Automatic startup). Если эта опция не активна, то сеть нужно запускать непосредственно из программы.

Если активна опция ‘Поддержка DSP301, V3.01 и DSP306’ (Support DSP301, V3.01 and DSP306), то будут поддерживаться модульные CAN-Slave устройства, а также еще некоторые возможности, описанные в стандарте DSP301, V3.01 и DSP306, в том числе и сердцебиение. В этом случае CAN устройство будет передавать специальные сообщения, сообщающие о том, что оно работает, с периодом, указанном в поле ‘Сердцебиение’ (Heartbeat Master[ms]). Такой механизм называется сердцебиение (Heartbeat) и является альтернативой механизма Защита узла (Node guarding), но отличается тем, что может работать как на Master, так и на Slave-устройствах. Обычно этот механизм запускается на CAN-мастере.

Параметры модуля CAN-мастера

Диалог настройки параметров модуля CAN мастера такой же, как и для других модулей (см. 0). Дополнительные параметры CAN-мастера, описанные в конфигурационном файле, также доступны пользователю, и их можно редактировать.

Базовые CAN параметры

МЭК-адреса для обращения к PDO из проекта, вводятся в полях ‘Адрес выходов’ (output address) и ‘Адрес входов’ (input address) в зависимости от направления передачи данных, которая осуществляется PDO. В поле ‘Адрес диагностики’ (diagnostic address) нужно ввести МЭК-адрес маркированной памяти (M). По этому адресу будет размещена диагностическая информация о модуле.

CAN-параметры CAN-модуля

Диалог CAN параметров CAN-модуля

Раздел General ID узла (Node-Id): идентификатор CAN-устройства (узла). Принимает значения от 1 до 127. Это значение должно быть уникальным для каждого устройства в сети и задается в десятичном виде. Если активна опция ‘Записать DCF’ (Write DCF), то при компиляции проекта создается файл с расширением DCF, имя которого состоит из имени соответствующего EDS файла и идентификатора узла, для которого создавался этот файл. Если активна опция ‘Создавать все SDO’ (Create All SDO’s), то SDO создаются для всех объектов, а не только для тех, которые изменены. Если активна опция ‘Сброс узла’ (Reset node) (ее наличие зависит от содержимого файла описания устройства), то ведомое устройство сбрасывается перед загрузкой конфигурации. Опция ‘Опц. устройство’ (Optional device) (ее наличие зависит от специфики целевой платформы) приводит к тому, что мастер будет выполнять только одну попытку чтения из данного узла. Отсутствие ответа игнорируется, то есть мастер продолжит нормальное функционирование. Опция ‘Без иниц.’ (No initialization) указывает мастеру немедленно активировать данный узел без посылки конфигурационного SDO. (Данные SDO будут созданы и сохранены в контроллере в любом случае.) Если поддерживается целевой системой, то создание SDO может быть ограничено по трем уровням. Это может потребоваться при недостаточной памяти:

  • CreateCommSDOs: SDO коммуникационных параметров
  • CreateMappingSDOs: конфигурационные SDO
  • CreateBasicSDOs: SDO базовых параметров (Nodeguarding, Sync и др.)

Будут создаваться только SDO разрешенного типа. Вышеописанная опция ‘Создавать все SDO’ (Create All SDO’s) влияет только на активированные здесь типы. Раздел охрана узла (Node guard альтернатива механизму Сердцебиение — Heartbeat). Если активна опция ‘Защита узла’ (NodeGuarding), то модулю посылается сообщение с периодом (Guard Time) (указывается в миллисекундах). В ответ модуль должен послать сообщение с идентификатором “Защитный COB-ID” (Guard COB-ID) (Communication Object Identifier). Если этого не происходит, то он получает статус “timeout”. Если модуль не отвечает на ‘Фактор работоспособности’ (Life Time Factor) сообщений, то он получает статус “not OK”. Статус модуля можно определить, обратившись по диагностическому адресу. Контроль состояния модуля не производится, если переменные ‘Период’ (Guard Time) и ‘Фактор работоспособности’ (Life Time Factor) равны 0.

Раздел сердцебиение (Heartbeat Settings альтернатива механизму Защита узла — Node

guarding): если опция ‘Активировать генерацию сердцебиения’ (Activate Heartbeat generation) активна, то модуль посылает специальные сообщения сердцебиения с периодом ‘Время потребителя’ (Heartbeat Consumer Time) (указывается в миллисекундах). Если активна опция ‘Активация потребителя’ (Activate Heartbeat Consumer), то модуль слушает сообщения сердцебиения, посылаемые мастером. Если эти сообщения до него не доходят, то модуль выключает свои входы/выходы.

Язык ST для C программиста (часть 2)

WHILE и REPEAT

Цикл WHILE совершенно аналогичен циклу while в C. REPEAT UNTIL соответствует do while. Тонкое, отличие состоит в том, что REPEAT выполнятся до тех пор, пока условие не примет значение TRUE.

FOR

Цикл FOR применяется для выполнения группы выражений заранее известное число раз. Цикл включает установку начального значения, конечное значение, опционально шаг (по умолчанию 1) и тело цикла. Пример:

FOR I := 1 TO 100 BY 10 DO x := x*y; END_FOR

На С этому соответствует:

for (I = 1; I <= 100; I += 10) x = x*y;

Бесконечный цикл в ST обычно записывается как WHILE TRUE DO.

Оператору break в циклах ST соответствует оператор EXIT. Оператор continue в CoDeSys V2.3 отсутствует.

main и PLC_PRG

Прекращение выполнения и возврат управления операционной системе был бы для контроллерной программы полным крахом. Поэтому любая контроллерная программа имеет цикл:

while(1)

{ReadInputs();

PLC_PRG();

WriteOutputs();

}

На самом деле в CoDeSys мы видим только PLC_PRG. Сам главный цикл спрятан в системе исполнения. Это наиболее тонкий момент, который нужно очень четко себе представлять. В многозадачных проектах система исполнения создает независимый главный цикл для каждой задачи. Любая ваша программа выполняется в цикле, если вы не предприняли специальных мер. Принимайте это как факт. Сложности в этом нет, устойчивые навыки приобретаются за несколько часов.

Многозадачность.

Многозадачность в CoDeSys доступна даже для ПЛК, выполненных на 8 разрядных микропроцессорах без ОС. В простейшем случае, вместо вызова единственной PLC_PRG, система попеременно подставляет вызовы разных пользовательских программ. Конечно, с учетом их приоритетов и времен циклов выполнения. Так реализуется не вытесняющая многозадачность. В многозадачных проектах необходимо сопоставить программы задачам с помощью менеджера задач в CoDeSys (См. рис. 2). Если этого не сделать, то проект будет однозадачным, с единственной главной функцией PLC_PRG.

Помимо циклических задач в CoDeSys можно создавать задачи, вызываемые по событиям. В контроллерах имеющих ОС, CoDeSys умеет обеспечивать вытесняющую многозадачность. Например, так работает CoDeSys SP RTE [3]. Минимальное время цикла задач и список активирующих событий необходимо уточнить в документации на контроллер.

Рис. 2. Настройка задачи, вызываемой по фронту входной переменной.

Функции

Для возврата значения функции в C используется return(). Часто для подготовки возвращаемого значения приходится объявлять вспомогательную переменную. В МЭК каждая функция имеет неявно объявленную переменную для возврата значения. Ее наименование совпадает с именем функции. То есть int GetX(int x) { … return(x); } на ST будет выглядеть так:

GetX := x; RETURN;

Как и в языке C передавать параметры, при вызове функции, можно перечисляя их в скобках через запятую: GetX(2). Либо путем присваивания значений: GetX(x := 2). Второй способ применяется и для функциональных блоков.

Память для переменных функции выделяется в стеке. Естественно, значения внутренних переменных не сохраняются между вызовами. Объявления локальных static переменных в функциях не предусмотрено. Для функций и функциональных блоков допускается передача параметров по ссылке (VAR_IN_OUT).

Функции МЭК могут иметь переменное число параметров. Типичный пример – это функция MUX, приведенная в таблице 1. Она может работать с переменным числом параметров, причем любого типа. В CoDeSys V2.3 это реализовано только для стандартных функций. Перегрузки стандартных операций нет. Впрочем, этого нет и в языке C.

Типа void в CoDeSys V2.3 нет. Любая функция должна иметь хотя бы один параметр и возвращать значение. Используйте тип BOOL, он обеспечивает минимальные издержки. Как и в С, вызовы функции можно включать в выражения.

Функциональные блоки.

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

Естественно код при этом не увеличивается. В отличие от функции, значения переменных экземпляра функционального блока сохраняются между его вызовами. Это означает, что к переменным экземпляра можно обращаться в любое время, вне зависимости от его вызова.

В объявлении экземпляра можно выполнять дополнительную инициализацию переменных. При трансляции с ST в C, для каждого функционального блока приходится писать функцию инициализации.

Дополнительно CoDeSys V2.3 позволяет добавлять действия в функциональные блоки. Это аналогично методам класса в ООП.

Библиотеки.

CoDeSys поддерживает 2 вида библиотек. Первый вид это внутренние библиотеки. Любой проект можно сохранить как библиотеку. Внутренние библиотеки пишутся и хранятся на языках МЭК. Они компилируются вместе с проектом. Вы можете запретить редактирование и просмотр текстов внутренних библиотек пользователем. Специальный менеджер библиотек позволяет защитить вашу библиотеку лицензией и сделать ее платной. Именно так реализованы библиотеки CANopen и SoftMotion в CoDeSys (язык ST).

Второй тип – это внешние библиотеки. Их код откомпилирован внешними средствами и включен в систему исполнения (например, системные библиотеки) или размещен в obj файлы. Внешние библиотеки могут иметь еще и ‘внутреннюю’ реализацию (на языках МЭК). Это позволяет написать заглушки системных функций, работающие в режиме эмуляции контроллера в среде программирования CoDeSys.

Системные библиотеки.

Указателей на функции в CoDeSys нет. Есть оператор INDEXOF(name), возвращающий внутренний индекс программного компонента (POU). Он используется там, где нужно программно указать POU. Например, это используется в системных библиотеках, выполняющих установку обработчиков аппаратных прерываний, управление задачами и некоторых других.

В CoDeSys можно создать множество задач и программно управлять (разрешать и останавливать) их работой (по событиям или ‘в лоб’ с помощью специальной системной библиотеки). Это является аналогом идеи массива указателей на функции.

Динамическое распределение памяти в МЭК не предусмотрено. В CoDeSys это делается с помощью функций специализированной библиотеки. Аналогично поддерживается работа с файлами, потоками, сокетами TCP/IP, точная синхронизация задач, управление работой контроллера и многое другое. Всего в CoDeSys V2.3 существует 24 системные библиотеки.

На самом деле, в CoDeSys видны лишь интерфейсы системных библиотек. Их код реализован в системе исполнения изготовителем. Он решает, что можно отдавать пользователю и что лучше запретить. В итоге, состав системных библиотек может быть разным для разных типов ПЛК. Общий обзор дан в документе SysLyb_Overview_RU в дистрибутиве CoDeSys. Безусловно, использовать системные библиотеки можно порекомендовать только опытным пользователям.

Обработка ошибок.

CoDeSys имеет специальный набор функции с фиксированными именами, позволяющими организовать обработку критических ошибок (деление на ноль, выход за границы массива, диапазоны значений, ошибочные указатели и др.) в пользовательской программе. Например:

Checkbounds, CheckPointer, CheckRangeSigned, CheckRangeUnsigned, CheckDivByte, CheckDivWord, CheckDivDWord и CheckDivReal и др. Если соответствующая функция отсутствует в проекте, то используется обработчик по умолчанию, имеющийся в системе исполнения.

Средства управления проектом.

Все что входит в рабочий проект, CoDeSys сохраняет в единственном файле. Это достаточно удобно для архивации. В случае аварии питания компьютера, CoDeSys полностью восстанавливает проект. В контроллеры, имеющие достаточный объем памяти, можно загрузить файл проекта вместе с исполняемым кодом.

Средств условной трансляции (#ifdef) в CoDeSys V2.3 нет. Однако есть возможность в менеджере проекта выделить определенные POU и запретить их включение в процесс компиляции. В CoDeSys можно установить дополнительный продукт 3S, так называемый инжиниринговый сервер (ENI). С его помощью реализуется полноценная возможность сетевой многопользовательской работы с проектом и управление версиями программных компонентов пользователей.

Заключение.

По числу типов данных ST превосходит C. Применение стандартных и специализированных операций не вызывает у C программистов ни каких сложностей. Редактор ST в CoDeSys поддерживает синтаксическое цветовое выделение и имеет средства быстрого ввода. Как правило, трансляция C программ в ST проще, чем обратная операция. Может вызвать сложность цикличность вызова главной программы, но это дело привычки. Вы наверняка заметили, что в определенных местах, где речь шла об ограничениях ST в сравнении с C, было написано ‘CoDeSys V2.3’. Все эти моменты доработаны в новой версии CoDeSys V3.0. Безусловно, это радикальный шаг 3S по расширению МЭК. Он сделан под давлением пользователей, являющихся профессиональными программистами. Пожалуй, самое интересное в 3.0 – это оснащение МЭК языков полноценными средствами ООП.

Мой блог находят по следующим фразам

Язык ST для C программиста (часть 1)

Принято считать, что языки программирования ПЛК стандарта МЭК 61131-3 (далее для краткости МЭК) предназначены для применения неспециалистами в области информатики. Но возможности ПЛК растут, соответственно растут и требования, предъявляемые к прикладному программному обеспечению (ПО). Все чаше мы встречаем системы на ПЛК, включающие сложнейший математический аппарат. В ПЛК используют web-технологии, нечеткие регуляторы, многомерные интерполяторы систем управления движением (SoftMotion) и т.д.

Такие технологии требуют специальных знаний. Несмотря на все прогнозы и рассуждения, на сегодняшний день более половины ПО для ПЛК создается профессиональными программистами, имеющими высшее образование. С каждым годом их доля возрастает. Не смотря на это, подавляющее большинство изготовителей МЭК систем упорно продолжают создать простые инструменты «для чайников». Чаще всего это некий редактор FBD и интерпретирующая система исполнения, опирающаяся на вызов заранее откомпилированных модулей. Для расширения состава блоков их пишут на языке C внешними средствами. Если профессиональный программист сталкивается с такой средой, то часто результатом становится МЭК программа, состоящая из одного большого функционального блока, полностью написанного на C.

Стандарт МЭК включает высокоуровневый язык ST, по выразительной мощности не уступающий языкам C и Паскаль. К сожалению, в большинстве систем МЭК программирования он не реализован вовсе либо имеет массу ограничений. Как правило, это ограничение числа поддерживаемых типов данных, упрощенный интерпретирующий транслятор или промежуточный код, ограничения на доступ к аппаратным ресурсам, невозможность обрабатывать прерывания, выполнять динамическое распределение памяти, управлять процессами и др. На самом деле, это не ограничения языка ST. Это именно ограничения среды программирования.

Некоторым особняком в ряду комплексов МЭК стоит CoDeSys производства 3S-Smart Software Solution GmbH. Его уникальность состоит в том, что он изначально задумывался как инструмент для профессионалов. Исходя из собственных соображений, при адаптации CoDeSys для конкретного ПЛК, изготовитель может наложить ряд ограничений на возможности пользователя. Но изначально их нет.

Безусловно, в CoDeSys можно использовать внешние библиотеки, реализованные на C, но необходимость в этом возникает крайне редко. Практически все, что можно написать на C, в CoDeSys можно написать на ST, без изменения методологии проектирования. CoDeSys имеет встроенный компилятор и генераторы машинного кода для всех популярных семейств микропроцессоров. Внешний C компилятор не даст выигрыша по быстродействию, но значительно усложнит разработку.

Очень существенная тонкость стандарта МЭК состоит в том, что он включает только требование однозначности выполнения описанных в нем конструкций. Многие воспринимают это как возможность называть МЭК системой программирования среду, поддерживающую только часть стандарта. Однако справедлив и обратный подход: МЭК система может включать все, что описано в стандарте, плюс дополнительные возможности.

Практика показывает что, профессиональные программисты, работая с CoDeSys, чаше всего выбирают язык ST. Практически все они в совершенстве владеют языком C. Данная статья имеет целью быстро очертить C программистам границы возможностей языка ST в CoDeSys и подсказать типовые методы преодоления затруднений.

Типы данных.

В CoDeSys реализованы все стандартные типы данных МЭК 61131-3. Все типы данных доступны во всех 6 поддерживаемых языках. Специальных расширений для ST нет. Целочисленные типы таковы: SINT (char), USINT (unsigned char), INT (short int), UINT (unsigned int), DINT (long), UDINT (unsigned long), LINT (64 бит целое), ULINT (64 бит целое без знака).

Действительные типы: REAL (float), LREAL (double).

Специальные типы BYTE, WORD, DWORD, LWORD представляют собой битовые строки длиной 8, 16, 32 и 64 бит соответственно. Битовых полей в ST нет. К битовым строкам можно непосредственно обращаться побитно. Например: a.3 := 1; (* Установить бит 3 переменной a *). В C в подобных целях используются целые без знака и битовые логические операции. В CoDeSys к битовым стокам можно применять операции, доступные для целых без знака. Логический тип BOOL. Может иметь значение TRUE или FALSE. Физически переменная типа BOOL может соответствовать одному биту. Обычно так и есть, если речь идет о дискретном входе либо выходе ПЛК или прямоадресуемой переменной (см. ниже). В иных случаях CoDeSys выделяет один байт. Это вызвано тем, что большинство микропроцессоров не умеют непосредственно адресоваться к отдельным битам памяти.

Строки STRING. Являются именно строкой, а не массивом. Поэтому (в версии V2.3) нет возможности обращаться к отдельным символам. Зато можно сравнивать и копировать строки стандартными операторами. Например так: strA := strB. В МЭК есть стандартный набор функций для работы со строками. Внутренний формат строк не стандартизован. CoDeSys использует нуль-терминированные строки.

Специальные типы в стандарте МЭК определены для длительности (TIME), времени суток (TOD), календарной даты (DATE) и временного штампа (DT). Работа со временем и интервалами встречается в ПЛК программах повсеместно.

Применение структур (STRUCT) не отличается от C. Описание структуры должно предшествовать объявлению переменной данного типа. Допускаются вложенные структуры и массивы.

Массивы (ARRAY) строятся из элементов любых типов, включая структуры и массивы. Из особенностей нужно отметить возможность задания повтора значений при инициализации. Например: bX ARRAY[0..20] OF BOOL := TRUE, 10(FALSE), 9(TRUE); Значение FALSE повторено здесь 10 раз и значение TRUE, соответственно 9 раз. Массивы (и структуры) можно копировать с помощью обычной операции присваивания: bY := bX; Перечисления аналогичны перечислениям C. Пример: TYPE TEMPO: (Adagio := 1, Andante := 2); END_TYPE.

На базе целых можно построить типы, имеющие ограниченный диапазон значений.

Например: TYPE DAC10: INT (0..16#3FF); END_TYPE.

Для любого типа можно создать псевдоним (typedef в C). Например: TYPE DEGR : UINT

END_TYPE.

Константы.

В МЭК используются типизированные константы. Например: 2#10001000 (целое, байт в двоичном формате), INT#40, t#10h14m5s (время дня), D#2006-01-31 (дата). Формат констант описан в документации и не вызывает сложностей.

Символьные константы можно объявлять локально или глобально в специальной секции раздела объявлений: VAR CONSTANT.

Идентификаторы.

Идентификаторы имен переменных могут иметь любую длину. Ограничения числа значимых символов нет. Идентификаторы не чувствительны к регистру (XZ и Xz одно и тоже). Идентификаторы не должны начинаться с цифры (12x). Двойные подчеркивания запрещены(__X).

Инициализация переменных.

По умолчанию, все переменные инициализируются нулем. Иное значение переменной можно указать явно при ее объявлении. Например: str1: STRING := ‘Hello world’. Переменные можно объявить как RETAIN или PERSISTENT. Это означает требование их размещения в энергонезависимой памяти контроллера (если она есть). Их инициализация производится только при первом запуске программы или по специальной команде.

Прямая адресация.

Помимо общей памяти данных в контроллере предусмотрены 3 специальные области памяти. Это область входов, выходов и прямо-адресуемая область. Эти области служат для связи системы исполнения контроллера и пользовательской программы. В простейших ПЛК распределение памяти в области входов/выходов фиксировано изготовителем. Мы можем непосредственно обращаться к нужному адресу из программы (например, %QB5 дает 5-й байт в области выходов) или объявить переменную, расположенную в соответствующем месте. Как правило, изготовители ПЛК снабжают CoDeSys конфигурационными файлами. Встроенный графический конфигуратор позволяет настроить и автоматически объявить переменные для всех входов/выходов и диагностических переменных без программирования, включая распределенные модульные системы (См. рис. 1).

Рис. 1. Конфигурирование переменных входов/выходов в CoDeSys

Преобразование типов.

Неявное преобразование типов запрещено. Любое преобразование нужно делать явно с помощью специальных операторов. Запомнить их легко. Пишем исходный тип, далее _TO_ и нужный тип. Например: iX := REAL_TO_INT(rX); .

Операторы и функции.

Наиболее часто используемые операторы и функции ST приведены в таблице 1. В МЭК определен целый ряд общепринятых и специализированных (для ПЛК программ) функций и функциональных блоков. В их числе таймеры, триггеры, счетчики, регуляторы и многое другое.

Написать ++x; или x += 1; в ST, конечно, нельзя. Единственный вариант – это x := x + 1;. Полное описание стандартных операций, функций и функциональных блоков вы найдете в руководстве программиста CoDeSys.

Sizeof В CoDeSys имеется оператор SIZEOF(in). Смысл его должен быть очевиден для C

программистов.

Sprintf Такого оператора в ST нет. Преобразовать любой переменную любого типа в строку можно с помощью …_TO_STRING.

Указатели.

В МЭК указателей нет, в CoDeSys они есть. Адрес переменной можно получить с помощью оператора ADR, разыменовывание дает ‘^’. Например:

pt : POINTER TO INT;

var_int1:INT;

var_int2:INT;

pt := ADR(var_int1);

var_int2 := pt^;

Объединений в CoDeSys V2.3 нет. При необходимости это удается обойти, разместив несколько переменных разного типа по одному адресу в прямо адресуемой памяти либо посредством указателей. Аналогично можно получить доступ к элементам строки ‘совместив’ ее с массивом.

Точка с запятой.

Не смотря на явное родство ST с языком Паскаль, точка с запятой используется в нем также как в языке C. То есть она служит не разделителем, а признаком конца оператора. Естественно, в одной строке может быть любое число операторов. Кроме того, точка с запятой служит пустым оператором. Текст любого программного компонента (POU) на ST должен включать хотя бы один оператор.

Программные скобки.

В ST нет привычных программных скобок ({} в C или begin и end в Паскале). Вместо этого каждая программная конструкция имеет собственную закрывающую программную скобку. Например: END_FUNCTION или END_IF. Каждому кто имел ‘счастье’ видеть многоэтажные лесенки завершающих скобок в C, такое решение должно быть понятно. Некоторая многословность текста компенсируется средствами быстрого ввода CoDeSys.

IF ELSE

Оператор выбора IF почти эквивалентен соответствующему оператору в C. Условием может служить переменная или выражение только логического типа. В ином случае, необходимо выполнить явное приведение к логическому типу.

Дополнительно в IF можно вложить последовательную цепочку условий ELSIF. Это достаточно удобно при анализе сложных разветвляющихся условий.

CASE

Аналогичен switch в C. Альтернативные ветки не имеют закрывающей программной скобки и не могут выполняться одна за другой. Соответственно оператор break не имеет смысла и отсутствует. При указании значений констант альтернативы можно перечислить их через запятую или указать диапазон. Например:

CASE (x + 2)/3 OF

0:

y := 1;

1,2:

y := 4;

z := 5;

3..50:

y := 7

ELSE

y := 0;

END_CASE

 

Мой блог находят по следующим фразам

Неявные переменные визуализации CodeSys

В программе доступны следующие системные переменные, управляющие визуализацией:

CurrentVisu String[40] Имя текущей визуализации. Если имя изменяется, то проводится изменение визуализации. Строку имени визуализации следует всегда вводить прописными буквами.

В зависимости от целевой системы использование этой переменной может активироваться / деактивироваться в настройках целевых систем.

CurrentCaller String[40] Содержит имя предыдущей визуализации (для ZOOMTOCALLER). Устанавивается и изменяется только в целевой визуализации.

CurrentLanguage String[40] Текущий выбранный язык, заданный в языковом файле. Его нужно указывать прописными буквами. Устанавивается и изменяется только в целевой визуализации.

CurrentUser-Level INT Группа пользователя 0.. 7. Значение должно изменяться только в соответствующем диалоге CoDeSys.

CurrentPasswords[0 .. 7] ARRAY [0..7] OF STRING[20] Пароли, заданные в CoDeSys ‘User Group Passwords…’ . Значение должно изменяться только в соответствующем диалоге CoDeSys.

Неявные переменные CurrentLanguage, CurrentUserLevel и CurrentPasswords[0..7] могут быть объявлены

реманентными для использования их в целевой визуализации. Для этого их необходимо объявить явно в списке глобальных переменных. Они должны быть объявлены в самом верхнем списке папки ‘Global Variables’ на вкладке Resources. При размещении объявлений в ином списке, компилятор даст сообщение об ошибке.

Переменные CurrentUserLevel, CurrentPasswords[…] нужно объявлять в одном разделе (normal, RETAIN, PERSISTENT…)! Если они объявлены реманентными, то нужно объявить дополнительно глобальную переменную «VisuDoExecuteUserlevelInit» типа BOOL RETAIN, инициализировав ее TRUE («VisuDoExecuteUserlevelInit : BOOL := TRUE;»).

Мой блог находят по следующим фразам