TwinCAT 3 совсем двинулся на рельсы виртуализации, благодаря чему, разработчики получили очередную головоломку с многозадачностью. Если быть точнее, то все закручено вокруг TcCOM-модулей, но мы попробуем быть ближе к терминологии TwinCAT 2, которая значительно проще и понятнее.
Задачи
SYSTEM → Tasks или просто задачи — содержат несколько описаний задач с произвольными именами. Это не сами задачи, а описания того, как необходимо крутить в цикле подпрограммы проекта: с каким временем цикла и приоритетом, настроить циклы сторожевого таймера (watchdog) и номер порта, на каком ядре процессора выполнять (это уже в разделе Real-Time). Можно сказать, что задачи — это шаблоны для создания циклических процессов TwinCAT, но на самом деле это просто наборы параметров для создания задачи — повторяй такую-то подпрограмму с временем цикла таким-то. Описание задачи одно, но задач из него можно создать множество.
Здесь же можно создать самостоятельную задачу, достаточно выбрать
TwinCAT Task With Image. У такой задачи уже будет собственный мапинг и она сможет самостоятельно транслировать данные с шины. Во втором твинкате это называлось
Additional Tasks.
Запуская задачу, TwinCAT собирает из проекта модуль, загружает его в память, выделяет ему то или иное количество ресурсов, а затем начинает циклически вызывать его подпрограммы. Модуль всегда один, несмотря на количество задач, вызывающих его подпрограммы.
Минутка тавтологии: параметры относящиеся к выполнению задач находятся в задачах (Tasks), а настройки подпрограмм проекта находятся в ПЛК-проекте (PLC, см. ниже).
Программы
PLC (
TwinCAT PLC Server) может содержать несколько проектов. Каждый проект владеет своим собственным контекстом окружения — описанием, адресным пространством и другими штуками из мира виртуализации.
Каждый проект — это отдельный модуль (или рантайм) со своим Id: 1...; портом ADS: 851, ...; уникальным идентификатором GUID: {xxxxxx}, и пр. Проект может содержать ряд программных блоков (POU), среди которых обязательно встретятся (под)программы, именно они и будут отрабатывать алгоритмы проекта. Традиционно, главная подпрограмма называется
MAIN.
Чтобы TwinCAT знал — как именно и что именно необходимо сделать с программой, необходимо создать в проекте ссылку на задачу —
Referenced Task. К ссылке мы прикрепляем вызов главной подпрограммы. Позже, при запуске программы, TwinCAT соберет из проекта модуль, загрузит его в память, а затем создаст одну или несколько задач, которые будут циклически выполнять закрепленные за ними подпрограммы проекта.
В одну ссылку можно добавить несколько вызовов подпрограмм, тогда они будут выполняться последовательно, пытаясь успеть отработать за время цикла задачи к которой они прикреплены.
Проект (рантайм) обеспечивает единое адресное пространство, также говорят — выполняется в рамках единого контекста. Можно спокойно использовать переменные одной подпрограммы из другой подпрограммы, лишь бы они все находились в одном проекте/рантайме. Можно циклически вызывать подпрограммы одного проекта из разных задач, а разные задачи можно крутить на разных ядрах процессора/процессоров, да еще и с разным временем цикла, и вся эта карусель будет плавно и равномерно вращаться вокруг ядра TwinCAT.
Задачи на ядре по умолчанию (Default) будут неспешно перетягивать одеяло на себя и работать чуть быстрее, да и вообще — никто не обещал синхронной работы задач на разных ядрах. Вся эта матрешка необходима для независимой работы задач друг от друга. Противоположная ситуация при выполнении задач на одном ядре — здесь все синхронно. Ну и как обычно, между контекстами... извините... между модулями-проектами-рантаймами связь через функции протокола ADS.
В итоге, система многозадачности получилась очень гибкая, но излишне и чересчур. Зато, в MatLab'е можно нарисовать модуль для TwinCAT, а на C++ написать модули реального времени. На МЭК'овских же языках (ST, LD, FBD, CFC,...) эти модули собираются и загружаются автоматически и незаметно для разработчика.