Форум TRACE MODE: техническая поддержка Послать новую тему / Post New Topic  Послать ответ / Post A Reply
мой профиль / my profile авторизация / login | регистрация / register | поиск / search | часто задаваемые вопросы / faq | начало / forum home

  Следующая старая тема / next oldest topic   Следующая новая тема / next newest topic
» Форум TRACE MODE: техническая поддержка » ТЕХНИЧЕСКАЯ ПОДДЕРЖКА / TECHNICAL SUPPORT TRACE MODE 6 » Языки программирования в TRACE MODE 6 / Algorithm Programming Languages » Функции-блоки: как это работает

   
Автор / Author Тема / Topic: Функции-блоки: как это работает
Alexander_
Forum Member / Участник форума
Участник № / Member № 7778


Icon 3 отправлено / posted      Профиль для / Profile for Alexander_           Редактировать/удалить сообщение / Edit/Delete Post   Вставить в ответ текст исходного сообщения  / Reply With Quote 
Здравствуйте, уважаемая техподдержка! Я понимаю, что Техно-языки ТМ6 являются глубоким переосмыслением языков МЭК в сторону сближения с С++. Учитывая, что идейным вдохновителем МЭК-языков можно считать Pasсal, получается весьма занятная сущность. Раньше я программировал на Техно-языках в духе С, и все было нормально. Теперь в образовательных целях я вынужден программировать в духе МЭК, с чем возник ряд вопросов, где ответ вроде «так лучше не работать» меня, как понимаете, не утешит.

Далее привожу ряд тезисов (для подтверждения или опровержения), а также вопросов.

Функция-блок это ни разу не функциональный блок в определениях МЭК (далее – ФБ), но скорее void-функция Си, которая просто может быть помещена на диаграмму Техно-FBD (впрочем, как и функция): при этом аргументы IN будут ножками слева, OUT — справа, IN/OUT — слева и справа (для удобства и во исполнение порядка вычисления). Однако внутренние переменные функции-блока (в IDE названы Вами просто переменными) не являются ни локальными переменными ФБ МЭК, ни static-переменными функции Си. Локальные переменные в ФБ являются частью экземпляра ФБ и доступны изнутри ФБ, а также иногда совне (но только для чтения) и сохраняют свое значение между вызовами программы. Static-переменные функции Си сохраняют свое значение между вызовами функции и доступны только изнутри нее. Переменные же функции-блока (что поначалу воспринимается большим откровением) являются глобальными(!), причем это написано в РП. Их количество в каждой функции-блоке не может превышать четырех (или это только для библиотечных?) Но главным свойством глобальных переменных является их видимость во всех сущностях программы, и действительно: можно обращаться к «внутренним» переменным функции-блока извне: записывать и читать их. К сожалению, напрямую обратиться к ним нельзя, подобно как можно обращаться к локальным переменным ФБ в МЭК (FB_1.var1 не прокатит), — нужно вызвать функцию-блок и только после этого можно будет обратиться через точку. Вопрос 1: зачем мне дозволено делать это, и как это следует использовать, ведь при каждом вызове функция-блок может менять свое состояние?

****************************************************
ФУНКЦИЯ_БЛОК(arg1, arg2, arg3).var1 = 5;
VAR_PRG = ФУНКЦИЯ_БЛОК(arg1, arg2, arg3).var1;
*****************************************************
FUNCTION_BLOCK ФУНКЦИЯ_БЛОК
VAR_INPUT ARG1 : REAL; END_VAR
VAR_OUTPUT ARG2 : REAL; END_VAR
VAR_INOUT ARG3 : REAL; END_VAR
VAR var1 : REAL; END_VAR
******************************************************
PROGRAM
VAR_INPUT ARG1 : REAL; END_VAR
VAR_INPUT ARG2 : REAL; END_VAR
VAR_INPUT ARG3 : REAL; END_VAR
VAR var_prg : SINT; END_VAR
VAR var1 : INT; END_VAR
*******************************************************
После этого переменная VAR_PRG имеет значение 5, несмотря на то, что тип var1 является бОльшим и неявное преобразование работать не должно.

Такое поведение замечеается в отладчике, когда:

1) в программе, вызывающей функцию-блок, есть локальная переменная, одноименная переменной функции блока (тип может не совпадать), иначе программа не компилируется, ругаясь на var1;

2) в функции-блоке не меняется значение соответствующей локальной переменной при обоих вызовах, иначе значение VAR_PRG тупо обнулится, что никак не зависит от значений по умолчанию переменных var1.

Не факт, что данные ограничения являются исключительными: полноценных тестов не проводилось.

При этом второй вызов функции-блока никак не обнаруживает изменения значения var1, однако VAR_PRG все равно каким-то магическим образом принимает то значение, которое мы помещаем прежде в переменную функции-блока, при этом одноименная локальная переменная программы, надо заметить, никак не реагирует.

Вопрос 2: переменные пользовательских функций-блоков имеют возможность сохранять значение между вызовами функции-блока, между вызовами программы? Сколько их может быть и как их задать, когда у меня значение переменных функции-блока всякий раз берется по умолчанию при ее вызове в отладчике, тогда как внутренние переменные библиотечных функций-блоков сохраняют свои значения?

Откровения о глобальности переменных функции-блока отчасти обуславливает некоторые вещи, что до того слыли не меньшими откровениями. Так, было обнаружено, что никаких экземпляров функций-блоков подобно экземплярам ФБ нет и быть не может, в чем сходство с void-функцией Си. Вообще, ФБ в МЭК — это упрощение и адаптация идеи классов в ООП под задачи АСУ ТП. В Техно-языках ТМ6 нам для этих целей даны аналоги структур из С++ и не стоит пытаться слепить функциональный блок в духе МЭК из функции-блока. Если Вы привыкли к идеи ФБ из МЭК, то, по-видимому, ничего не отсается, как сделать структуру с единственным методом с аргументами и вызывать его, дублируя аргументы при вызове в переменные-члены (кроме аргов INOUT), чтобы к ним потом можно было обращаться независимо, но все же лучше так не делать. Тем более что вызвать экземпляр структуры в FBD-диаграмме и представить ее в виде привычного блочка с ножками вряд ли удастся.

Таким образом, функция-блок глобальна и единственна во всей программе. Я пытался вызывать экземпляры функции-блока в Техно-FBD, наивно полагая, что они создаются самим фактом существования отдельного блочка на диаграмме, пока не понял, что на деле вызывается один и тот же объект. При этом экземпляры библиотечных функций-блоков (по крайней мере, на Техно-FBD-диаграмме) действительно создаются отдельные и их внутренние статические переменные независимы для отдельных экземпляров: тогда все же что такое библиотечный FBD-блок? Вы их даже по названию различаете: библиотечные FBD-блок и пользовательская функция-блок. Т.е. FBD-блок это больше про МЭК, а функция-блок про Си? (Вопрос 3.)

Итак, в РП написано:

Следующие функции (функции-блоки) могут быть вызваны в основной программе только однократно:
содержащие глобальные переменные программы;
содержащие FBD-блоки с внутренними переменными (см. Редактирование FBD-программ ).
Другие функции могут вызываться в основной программе многократно.

Вопрос 4: как это утверждение РП понимать? Как функция может содержать глобальные переменные? Использовать — понимаю, но содержать? В РП сказано: В частности, глобальными являются переменные FBD- и LD-блоков; а переменные функций-блоков, они являются глобальными? Чем внутренние переменные FBD-блоков тогда отличаются от глобальных? Я в корне запутался. И что значит не могут быть вызваны? Я вызывал пользовательскую функцию-блок, состоящую из библиотечных FBD-блоков, в одной проге на Техно-FBD 3 раза. Смысл в том, что внутренние переменные соответствующих FBD-блоков в памяти занимали одно и то же место — это были одни и те же объекты в рамках различных вызовов моей функции-блока. Не могут вызываться и не следует — это разные вещи. Не могут — прога должна не компилиться, а она компилится.

Потом, с переменными-аргументами не все понятно. В ФБ МЭК они являются атрибутами ФБ и доступны вне его вызовов. INPUT — для чтения и записи, OUTPUT — только для чтения. Иногда также возможно читать локальные переменные ФБ. INOUTPUT при этом передается по ссылке и вообще не являются частью ФБ (можно передать адрес переменной INOUTPUT только при вызове ФБ). В функции-блоке у нас OUT и INOUT передаются по ссылке, и отличие их только на картинке FBD-диаграммы, и то формальное (ножки). Т.е. они частью функции-блока не являются и не имеют смысла вне ее вызова. Однако и об IN-аргументах, судя по всему имеет смысл говорить только в момент вызова, что указывает на сходство с параметром функции, передаваемом по значению, в идеологии Си. Подтвердите или опровергните это, пожалуйста (вопрос 5).

Премного благодарен!

Сообщения / Posts 33 | Из / From: Россия  |  IP / IP: IP адрес / IP address | Report this post to a Moderator
АдАстра. Техподдержка
Administrator
Участник № / Member № 4


Icon 1 отправлено / posted      Профиль для / Profile for АдАстра. Техподдержка           Редактировать/удалить сообщение / Edit/Delete Post   Вставить в ответ текст исходного сообщения  / Reply With Quote 
Здравствуйте, Alexander_!

По использованию поддерживаемых языков программирования МЭК мы можем с Вами обсудить вопросы работы и реализации. Остальные вопросы выходят за рамки.

1. При использовании FBD-блоков штатным является использование входов и выходов используемых блоков.

2. При использовании любых FBD-блоков (включая Пользовательские) значения переменных (входы/выходы и внутренние) являются глобальными, т.е. сохраняют свое значение между вызовами программы.
По умолчанию, каждая переменная FBD-блока может сохранить одно свое значение между вызовами программы.

3. Библиотечный FBD-блок - это готовый FBD-блок, который можно сразу использовать.
Пользовательский FBD-блок - это FBD-блок, содержимое которого разрабатывает Автор проекта, его необходимо разработать самостоятельно. Содержимое может быть разработано любыми поддерживаемыми языками, включая ST.

4. Уточните раздел Справочной Системы, в котором Вы прочитали данное описание.

5. Все довольно просто. Так как вопрос о FBD, то IN-аргументы (входа) являются началом программы и их можно записать. OUT-аргументы являются выходом программы и их можно читать. INOUT-аргументы являются и входными и выходными одновременно.

Между входными аргументами и выходными располагаются FBD-блоки со связями между собой.


Что бы было все максимально понятно, рекомендую ознакомиться в Справочной Системе с разделом Быстрый Старт - Часть вторая - Написание программ.

Сообщения / Posts 17293 | Из / From: Россия  |  IP / IP: IP адрес / IP address | Report this post to a Moderator
Alexander_
Forum Member / Участник форума
Участник № / Member № 7778


Icon 1 отправлено / posted      Профиль для / Profile for Alexander_           Редактировать/удалить сообщение / Edit/Delete Post   Вставить в ответ текст исходного сообщения  / Reply With Quote 
Добрый день! Мне и интересны прежде всего вопросы реализации. Можете объяснить это поведение:

ФУНКЦИЯ_БЛОК(arg1, arg2, arg3).var1 = 5;
VAR_PRG = ФУНКЦИЯ_БЛОК(arg1, arg2, arg3).var1;

Условия компиляции и работы описаны выше. При этом если var1 является аргументом функции-блока, то прога вылетает с ошибкой "Нарушение доступа".

Сегодня обнаружил, что если функция-блок на диаграмме Техно-FBD не выполняется (RUN=1, да-да: 1), то выходы блочка все равно передают значения в переменные, что к ним привязаны,(!) т.е. аргументы OUT являются частью блока и сохраняют свои предыдущие значения, но получить их можно только в Техно-FBD -- так?

Как мне обратиться к переменным или аргументам функции-блока на ST, не вызывая ее?

Как мне создать несколько экземпляров пользовательской функции-блока: один код -- несколько воплощений?

2. У меня пользовательская функция-блок, в ней внутренняя переменная -- счетчик вызовов: почему между вызовами функции-блока на ST, равно как и между вызовами программы при циклической отладке, (в отладчике) значение не сохраняется? Можете прислать пример функции-блока с внутренним счетчиком вызовов на ST?

4. Пункт РП "Операторы определения переменных" с. 41. и "Вызов ф. и ф.-б." с. 45 том 2.

Все еще надеюсь на внятное разъяснение. Если есть полноценная документация на Техно-языки, то мне больше ничего и не надо.

Сообщения / Posts 33 | Из / From: Россия  |  IP / IP: IP адрес / IP address | Report this post to a Moderator
   

Quick Reply
Сообщение / Message:

HTML код не разрешен. / HTML is not enabled.
UBB код разрешен. / UBB Code is enabled.

Значки Graemlins / Instant Graemlins
   


Послать новую тему / Post New Topic  Послать ответ / Post A Reply Закрыть тему / Close Topic   Feature Topic   Переместить топик / Move Topic   Удалить топик / Delete Topic Следующая старая тема / next oldest topic   Следующая новая тема / next newest topic
 - Printer-friendly view of this topic
Перейти к / Hop To


Новости АСУ ТП / News | SCADA / HMI | Обучение / Trainings | Свяжитесь с нами / Contact Us



Powered by Infopop Corporation
UBB.classic™ 6.7.2