ISaGRAF. Version 3.4

         

“C” функциональные блоки


“C” функциональные блоки объединяют операции и статические данные. Они дополняют набор “C” функций, допуская обработку статических объектов. “C” функции, обычно, используются для расширения стандартных возможностей языков ST и FBD. В отличие от функций, они могут работать со статическими данными. Это означает, что алгоритм функционального блока может меняться с течением времени.

Функциональные блоки, написанные на языке “C” компилируются и линкуются с ядром ISaGRAF.  Приращенное ядро должно быть инсталлировано на целевой PLC прежде, чем функция будет использована в проекте ISaGRAF. Новые функциональные блоки не могут быть интегрированы в симулятор ISaGRAF. Приложения ISaGRAF нужно симулировать до ввода нестандартных функций.

Предупреждение:

Функциональные блоки выполняют синхронные

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

       Объявление экземпляров функционального блока

Функциональный блок - это объект, который объединяет операции и статические данные. Ниже представлен пример функционального блока R_TRIG, который определяет передний фронт булевского выражения. Вот его описание:

Скрытая статическая  переменная “previous_state”

нужна для определения фронта. Эта переменная должна быть различной в каждом использовании функционального блока “R_TRIG” в приложении. Экземпляр функционального блока, используемого в языке ST, должен быть объявлен в словаре.  Так как функциональный блок имеет внутренние скрытые данные, каждая копия (экземпляр) функционального блока должна быть идентифицирована уникальным именем. Наименование типа блока осуществляется при помощи менеджера библиотек. Наименование экземпляров осуществляется при помощи редактора словаря.

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

       Добавление функционального блока в библиотеку ISaGRAF



Для добавления функционального блока в библиотеку ISaGRAF нужно использовать менеджер библиотек ISaGRAF. Используется команда “Новый” из меню “Файл”, когда выбрана библиотека функциональных блоков. Когда новый функциональный блок создан, должно быть написано его техническое замечание. Скелет исходного текста нового функционального блока автоматически генерируется менеджером библиотек ISaGRAF. Для того чтобы определить параметры вызова и возврата нового функционального блока используется команда “Параметры” из меню “Редактировать”.

       
Добавление функционального блока в библиотеку ISaGRAF

Для добавления функционального блока в библиотеку ISaGRAF нужно использовать менеджер библиотек ISaGRAF (Library Manager). Используется команда “Новый” из меню “Файл”, когда выбрана библиотека функциональных блоков. Когда новый функциональный блок создан, должно быть написано его техническое замечание. Скелет исходного текста нового функционального блока автоматически генерируется менеджером библиотек ISaGRAF. Для того чтобы определить параметры вызова и возврата нового функционального блока используется команда “Parameters” из меню “Редактировать”.

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

FBINSTNAME.parname

используется, чтобы представить возвращаемый параметр “parname”, экземпляра функционального блока “FBINSTNAME”.

Экземпляры функционального блока, используемого в языке ST, должны быть объявлены в словаре.  Каждая копия (экземпляр) функционального блока должна быть идентифицирована уникальным именем.


Вот пример объявлений в библиотеке ISaGRAF:

instance:                 TRIG1                                               type:                 R_TRIG

                                TRIG2                                                                        R_TRIG

И пример использования, объявленных экземпляров в ST программе:

TRIG1 (boo_input1);

TRIG2 (boo_input2);

Command := (TRIG1.Q & TRIG2.Q);

Программа FBD может вызывать любой функциональный блок. Функциональный блок используется как стандартный функциональный ящик. Его параметры вызова соединяются с левой стороной функционального ящика. Возвращаемые параметры соединяется с правой стороной ящика. Вот стандартный вид такого функционального ящика:



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



       
Определение интерфейса “C” функционального блока

Команда “Параметры”

меню “Edit” используется для определения параметров вызова и возврата нового функционального блока. Функциональный блок может иметь до 32

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

Список в верхней части окна показывает параметры “C” функционального блока, в соответствии с порядком прототипа: сначала параметры вызова, в конце параметры возврата. Нижняя часть окна показывает детальное описание параметров выбранных, в настоящее время, в списке:

- имя параметра

- направление параметра (вызов/возврат)

- тип параметра

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

Ниже представлено соответствие между типами ISaGRAF и “C”:



BOOLEAN

unsigned long

32 битовое беззнаковое слово: 1=true / 0=false

ANALOG

long

32 битное знаковое целое слово

REAL

float

плавающее значение с одиночной точностью

TIMER

unsigned long

32 битное беззнаковое слово (единица - это 1 миллисекунда)

MESSAGE

char *

строка символов

Когда значение сообщения приходит в “C” функцию, оно не может содержать нулевого символа. Строка приходящая в “C” код заканчивается нулем. Не забывайте, что возвращаемые параметры должны быть последними в списке. Имена параметров должны удовлетворять следующим правилам:

- имя не может быть длиннее 16 символов

- первым символом должна быть буква

- последующими символами могут быть буквы, цифры или символ подчеркивания

- заглавные и прописные буквы не различаются

Одно и то же имя не может быть использовано более чем для одного параметра функционального блока. Параметр вызова не может иметь тот же тип, что и имя возвращаемого параметра. Одно и то же имя может быть использовано для параметров различных функциональных блоков. Имя возвращаемого параметра по умолчанию - “Q”. Это имя может быть изменено. Имя параметра используется для идентификации исходного текста “C”.

Команда “Вставить” используется для ввода нового параметра перед выбранным параметром. Команда “Удалить” используется для уничтожения выбранного параметра. Команда “Упорядочить”

автоматически сортирует параметры так, что возвращаемые параметры оказываются в конце списка. При нажатии кнопки “Принять” определение интерфейса функционального блока запоминается, и диалог закрывается. Нажатие кнопки “Отказ” закрывает диалог, без изменения интерфейса функционального блока.

       Интерфейс ”C” функционального блока

Интерфейс функционального блока зависит от определения его параметров. Параметры передаются через структуру. Эта структура определена в файле “GRFB0nnn.H”, где “nnn” - это логический номер функции в библиотеке ISaGRAF. Вот пример “C” интерфейса функционального блока “LIM_ALRM” (тревога предела):



/* function block interface - name: sample */

/* standard ISaGRAF data types */

typedef                                                 long       T_BOO;

typedef                                                 long       T_ANA;

typedef                                                 float       T_REAL;

typedef                                                 long       T_TMR;

typedef                                                 char        *T_MSG;

/* structure of calling parameters */

typedef struct {

             /* CALL   */                            T_BOO  _par1;

             /* CALL   */                            T_BOO  _par2;

} str_arg;

/* access to fields of str_arg structure */

#define                                                  PAR1     (arg->_par1)

#define                                                  PAR2     (arg->_par2)

/* return parameter logical numbers */

#define                                                  FBLPNO_Q1        0

#define                                                  FBLPNO_Q2        1

/* конец файла*/

Ниже представлено соответствие между типами ISaGRAF и “C”. Типы ISaGRAF определены как типы “C” в файле определения функционального блока:

boolean

T_BOO

long (32 бита)

analog

T_ANA

long

real

T_REAL

float (32 бита, плавающее значение с одиночной точностью)

timer

T_TMR

long

message

T_MSG

char* (32 битный указатель)

Каждое поле структуры “str_srg” соответствует одному параметру функционального блока.  Параметры вызова в структуре в том же порядке, в котором они были установлены в определении функционального блока. Идентификатор, написанный заглавными буквами, определяется для того, чтобы иметь прямой доступ к параметрам структуры передающейся в “C” реализацию службы активизации функционального блока. Имена идентификаторов вводятся во время определения функции в менеджере библиотек ISaGRAF.



Порядок нумерации возвращаемых параметров тот же который был установлен в определении функционального блока. Логический номер первого возвращаемого параметра всегда равен 0.

Определенные идентификаторы нужно использовать вместо численных значений для того, чтобы представить возвращаемые параметры в исходном тексте “C” программы. Это гарантирует, что исходный файл может быть легко перекомпилирован после изменений интерфейсных определений.

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

       Исходный текст

Реализация функционального блока на “C” делится на три входные точки:

службы инициализации

службы активизации - обработка параметров вызова

службы чтения возвращаемых параметров

Один и тот же код используется для каждого экземпляра одного функционального блока и не дублируется. С каждым экземпляром связана структура статических данных. К этим данным нет прямого доступа из ISaGRAF. Они содержат “скрытые переменные” функционального блока.

“Служба активизации” вызываются однажды для каждого экземпляра каждого использующегося блока, на каждом цикле целевой задачи. Она обрабатывает параметры вызова и изменяет соответствующие данные. Она представляет “основной алгоритм” функционального блока.

“Служба чтения” вызывается ядром ISaGRAF для чтения текущего значения одного возвращаемого параметра для одного экземпляра. В такой службе не нужно выполнять никаких специальных вычислений. Она только осуществляет передачу между скрытыми данными и приложением ISaGRAF.

Функциональная схема:



·       Статические данные функционального блока

Функциональный блок связывает операции и статические данные. С каждым экземпляром одного и того же функционального блока связана структура данных. Каждый раз, когда функциональный блок используется в программах ST или FBD, он соответствует одному экземпляру и одной структуре данных.


Следующий пример показывает соответствие между структурами данных “C” и экземплярами функционального блока, использующимися в FBD программе:



Память, требующаяся для структуры данных каждого экземпляра, размещается системой ISaGRAF, при запуске приложения. Указатель на соответствующую структуру данных экземпляра передается в службы “активизации” и “чтения”.

Менеджер библиотек ISaGRAF автоматически генерирует скелет исходного текста “C” для определения типа структуры данных. Тип структуры данных всегда называется “str_data”. Программист не должен изменять это имя для того, чтобы обеспечить совместимость с заголовками службы. Скрытые данные, обычно, группируют внутренние переменные с образом возвращаемых параметров. Служба “чтения” функционального блока используется для доступа к возвращаемым параметрам и  не может быть использована для других операций.

·       Служба инициализации

Служба инициализации функционального блока вызывается ядром ISaGRAF при запуске приложения. Она позволяет “C” программисту запросить систему разместить память для экземпляра. Ниже - стандартная программа службы инициализации:

uint16 FBINIT_xxx (uint16 hinstance)

/* "xxx" is the name of the f. block */

{

   return (sizeof (str_data));

}

Аргумент “hinstance” - это логический номер экземпляра. Он резервируется ISaGRAF для внутренних операций и не должен использоваться для программирования службы. Служба инициализации возвращает количество байт памяти требуемое для данных одного экземпляра. Объем требуемой памяти (возвращаемое значение) не может превышать 64K. Никакие другие операции не должны выполняться в этой службе. Исходный текст этой службы автоматически генерируется менеджером библиотек ISaGRAF при создании функционального блока.

·       Служба активизации

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


Ниже - стандартный скелет службы активизации:

void FBACT_xxx (

uint16 hinstance,                                 /* "xxx" is the name of the function block

*/

                                                               /* logical number of the instance */

str_data *data,                                    /* data: pointer to the instance data structure

*/

str_arg *arg                                         /* pointer to the calling parameters structure

*/

)

{

}

Аргумент “hinstance” - это логический номер экземпляра. Он резервируется ISaGRAF для внутренних операций и не должен использоваться для программирования службы. Аргумент “data” - это дальний указатель на структуру данных связанных с экземпляром. Аргумент “arg” это дальний указатель на структуру, которая содержит значения параметров вызова. Программист должен использовать идентификаторы, определенные в “C” заголовке функционального блока для доступа к полям структуры “arg”.

Алгоритм “активизации” обрабатывает параметры вызова (сохраненные в структуре “arg”) и изменяет поля структуры “data”.

Следующий пример показывает службу активизации функционального блока TRIG (определение переднего фронта):

/* definitions stored in the function block "C" header */

typedef struct {                                   /* calling parameters */

             T_BOO  _clk;                          /* trigger input */

} str_arg;

#define CLK       (arg->_clk)

/* function block instance data structure */

typedef struct {

             T_BOO prev_state;               /* previous state of the trigger input */

             T_BOO edge_detect;            /* edge value: image of return param */

} str_data;

/* activation service */

void FBACT_trig (uint16 hinstance, str_data *data, str_arg *arg)

{

             data->edge_detect = (T_BOO)(CLK && !data->prev_state);

             data->prev_state = CLK;  /* calling parameter */



}

Исходный текст этой службы автоматически генерируется менеджером библиотек ISaGRAF при создании функционального блока.

·       Чтение возвращаемых параметров

Служба “чтение’ вызывается каждый раз, когда ST или FBD программа ссылается на возвращаемый параметр функционального блока. Она используется для того, чтобы получить один возвращаемый параметр. Следующий пример показывает вызов “чтения”, исполняющийся во время работы ST программы:



Так как служба “чтение”  может быть вызвана более одного раза в течение цикла, для одного и того же возвращаемого параметра или экземпляра функционального блока, никаких специальных вычислений не должно выполняться в такой службе. Она только осуществляет передачу между скрытыми данными и приложением ISaGRAF. Ниже - стандартный скелет для службы чтения:

/* cast operation used to copy the value of a return parameter */

#define BOO_VALUE                        ((T_BOO *)value)

#define ANA_VALUE                       ((T_ANA *)value)

#define REAL_VALUE                      ((T_REAL *)value)

#define TMR_VALUE                       ((T_TMR *)value)

#define MSG_VALUE                        ((T_MSG *)value)

/* return parameters read service: called for each return parameter */

void FBREAD_xxx (                            /* "xxx" is the name of the function block */

uint16 hinstance,                                 /* logical number of the instance */

str_data *data,                                    /* pointer to the instance data structure */

uint16 parno,                                        /* logical number of read parameter */

void *value)                                         /* buffer where to copy the value of the param */

{

             switch (parno) {

                   case FBLPNO_XX: /* ... */ break;

                   case FBLPNO_YY: /* ... */ break;

                    /* .... */

             }

}

Аргумент “hinstance” - это логический номер экземпляра.


Он резервируется ISaGRAF для внутренних операций и не должен использоваться для программирования службы. Аргумент “data” - это дальний указатель на структуру данных связанных с экземпляром.

Аргумент “parno” - это логический номер возвращаемого параметра, значение которого требуется. Используйте идентификаторы, определенные в “C” заголовке функционального блока для идентификации возвращаемого параметраТип данных, на которые указывает этот аргумент, зависит от типа возвращаемого параметра.

Ниже представлено соответствие между типами ISaGRAF и “C”:

boolean

long

32 битное беззнаковое слово: 1=true / 0=false

analog

long

32 битное знаковое целое слово

real

float

плавающее значение с одиночной точностью

timer

long

32 битное беззнаковое слово (единица - это 1 миллисекунда)

message

char *

строка символов

Следующие макроопределения  используются для доступа к буферу копирования, в соответствии с типом возвращаемого параметра:

#define             BOO_VALUE                       ((T_BOO *)value)

#define             ANA_VALUE                       ((T_ANA *)value)

#define             REAL_VALUE                      ((T_REAL *)value)

#define             TMR_VALUE                        ((T_TMR *)value)

#define             MSG_VALUE                       ((T_MSG *)value)

Вот общие программные операции для копирования значения или параметра к буферу ISaGRAF:

/* for a boolean parameter: */

   *BOO_VALUE = parameter_value;

/* for an integer analog parameter: */

   *ANA_VALUE = parameter_value;

/* for a real integer parameter: */

   *REAL_VALUE = parameter_value;

/* for a time parameter: */

   *TMR_VALUE = parameter_value;

/* for a string parameter: */

   strcpy (*MSG_VALUE, parameter_value);

Исходный текст этой службы автоматически генерируется менеджером библиотек ISaGRAF при создании функционального блока.

·       Пример исходного текста

Ниже представлен стандартный скелет “C” функционального блока:



/* function block (xxx is the name of the function block) */

#include <tasy0def.h>

#include <grfb0nnn.h>   /* nnn is the number of the f.block in library */

/* structure of hidden data for each instance of the block */

typedef struct {

             /* fields definition */

} str_data;

/* initialization service: returns the size of needed hidden data */

word FBINIT_xxx (uint16 hinstance)

{

             return (sizeof (str_data));

}

/* activation service: processes the calling parameters */

void FBACT_xxx (uint16 hinstance, str_data *data, str_arg *arg)

{

             /* ... */

}

/* cast operation used to copy the value of a return parameter */

#define BOO_VALUE   ((T_BOO *)value)

#define ANA_VALUE   ((T_ANA *)value)

#define REAL_VALUE  ((T_REAL *)value)

#define TMR_VALUE   ((T_TMR *)value)

#define MSG_VALUE   ((T_MSG *)value)

/* return parameters read service: called for each return parameter */

void FBREAD_xxx (uint16 hinstance, str_data *data, uint16 parno, void *value)

{

             switch(parno)

             {

                case FBLPNO_XX: *???_VALUE = ...; break;

                case FBLPNO_YY: *???_VALUE = ...; break;

             ....

            

}

/*Следующая функция используется для инициализации функционального блока и объявления его реализации. Она реализует связь с ядром ISaGRAF, используя имя функции. Эта функция полностью генерируется менеджером библиотек ISaGRAF*/

ABP fbldef_xxx (char *name, IBP *initproc, RBP *readproc)

{

             strcpy (name, "XXX");

             *initproc = (IBP)FBINIT_xxx;

             *readproc = (RBP)FBREAD_xxx;

             return ((ABP)FBACT_xxx);

}

/* end of file */

Включенный файл “TASY0DEF.h” из ядра ISaGRAF требуется для системозависимых определений. Он, также содержит определения типов данных, которые представляют дальние указатели на  реализованные службы.

       Связь  между проектами и “C” реализацией



Логическая связь между реализацией функции и ее использованием в программах проекта ISaGRAF осуществляется через имя функции. Служба объявления добавляется в исходный “C” код функционального блока. Эта служба вызывается только один раз, когда приложение стартует и сообщает ядру ISaGRAF имя, которое соответствует реализованной службе. Вот стандартный формат такой службы объявления:

ABP fbldef_xxx (char *name, IBP *initproc, RBP *readproc)

{

             strcpy (name, "XXX");                         /* name of the f.block */

             *initproc = (IBP)FBINIT_xxx;                              /* initialization service */

             *readproc = (RBP)FBREAD_xxx;                        /* read service */

             return ((ABP)FBACT_xxx);                  /* activation service */

}

/* xxx is the name of the function block */

Имя функционального блока, использующееся оператором strcpy, должно быть написано заглавными буквами. Оно должно быть написано маленькими буквами в реализации служб и в имени службы объявления.

Использование префиксов ”FBACT_”, ”FBINIT_”, ”FBREAD_” и “fbldef_” для реализации служб и определения службы позволяет пользователю именовать функции ключевыми словами языка “C” или именами существующих функций из “C” библиотек ISaGRAF.  Никакие другие операторы нельзя добавлять в службу объявления.

Служба объявления вызывается для любого интегрированного функционального блока, даже если он не используется в приложении ISaGRAF.  Ядро  ISaGRAF выдает ошибку, если в приложении используется не реализованный функциональный блок.

Прежде чем линковать новые функциональные блоки с ядром, пользователь должен написать другой файл с исходным текстом, под именем “GRFB0LIB.C” и вставить его с сохраненным функциональным блоком в список файлов для линкера. “GRFB0LIB.C” содержит только массив служб объявления. Этот массив читается во время инициализации приложения, для того чтобы создать динамические связи с функциональными блоками написанными на “C”.


Вот пример такого файла:

/* Файл: grfb0lib.c - implemented function blocks */

#include <tasy0def.h>

extern ABP fbldef_fb1(char *name, IBP *init, RBP *read);

extern ABP fbldef_fb2(char *name, IBP *init, RBP *read);

FBL_LIST FBLDEF[ ] = {

             fbldef_fb1,

             fbldef_fb2,

NULL };

/* конец файла */

Массив FBLDEF должен заканчиваться указателем NULL. Если это условие не выполнено, то могут возникнуть некоторые проблемы. Если массив FBLDEF не определен, то во время линковки нового ядра ISaGRAF появятся неразрешенные ссылки.

Написав этот файл, можно построить новое ядро, включая все существующие функции. Можно, также построить ядро, приспособленное для одного проекта, путем введения в массив FBLDEF только тех преобразований, которые используются в проекте. Файл “GRFB0LIB.C” автоматически генерируется генератором кодов ISaGRAF, когда создается код приложения. Файл помещается в директорию проекта ISaGRAF и объединяет только те функции, которые используются в проекте.

       Ограничения

Библиотека ISaGRAF может содержать до 255 “C” функциональных блоков. Функция может выполнять любой тип операции. Каждый тип функционального блока может быть скопирован (сделано экземпляров) до 255 раз в одном проекте.

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

       Полный пример

Ниже представлен пример функционального блока “sample”, который выполняет счет вверх.

Техническое замечание:

имя:                    Sample                                             

описание:          счетчик вверх

дата:                  18 мая 1995

автор:                CJ International

вызов:               CU: считающийся вход

                        R:    команда сброса

                           PV:  максимальная планируемая величина

возврат:            Q: определение максимума

                           СV: результат счета



прототип:          sample (count, reset_command, maximum_value);

                           max_detect := SAMPLE.Q;

                           count_result := SAMPLE.CV;

Интерфейс функционального блока:



Заголовок функционального блока:

/* function block interface - name: SAMPLE */

/* определение стандартных типов ISaGRAF  */

typedef long  T_BOO;

typedef long  T_ANA;

typedef float T_REAL;

typedef long  T_TMR;

typedef char  *T_MSG;

/* определение структуры параметров вызова */

typedef struct {

   T_BOO  _cu;

   T_BOO  _r;

   T_ANA  _pv;

} str_arg;

/* идентификаторы использующиеся для доступа к параметрам вызова*/

#define CU                                           (arg->_cu)

#define R                                              (arg->_r)

#define PV                                            (arg->_pv)

/* логические номера возвращаемых параметров */

#define FBLPNO_Q                            0

#define FBLPNO_CV                         1

/* end of file */

Исходный текст функционального блока:

( Только строки напечатанные жирным шрифтом вводятся программистом)

/* function block - name: SAMPLE */

#include <tasy0def.h>                       /* требуется для определения типов */

#include <grfb0255.h>                       /* заголовок*/

/* definition of the structure which contains the data for one instance */

typedef struct {

             T_BOO overflow;                  /* true:counting value >= programmed value */

             T_ANA value;                         /* counting current value */

} str_data;

/* initialization service: requires memory for instance data */

word FBINIT_sample (uint16 hinstance)

{

             return (sizeof (str_data));

}

/* activation service: up-counting algorithm */

void FBACT_sample (uint16 hinstance, str_data *data, str_arg *arg)

{

             if (R) data->value = 0;



             else if (CU && data->value < PV) (data->value)++;

             data->overflow = (data->value >= PV) ? (T_BOO)1 : (T_BOO)0;

}

/* cast operation required to copy parameters to ISaGRAF buffer */

#define BOO_VALUE   ((T_BOO *)value)

#define ANA_VALUE   ((T_ANA *)value)

#define REAL_VALUE  ((T_REAL *)value)

#define TMR_VALUE   ((T_TMR *)value)

#define MSG_VALUE   ((T_MSG *)value)

/* read service: get the value of one return parameter */

void FBREAD_sample (uint16 hinstance, str_data *data, uint16 parno, void *value)

{

             switch (parno) {

                case FBLPNO_Q   : *BOO_VALUE = data->overflow; break;

                case FBLPNO_CV : *ANA_VALUE = data->value; break;

             }

}

/* declaration service used for dynamic link with the ISaGRAF kernel */

ABP fbldef_sample (char *name, IBP *initproc, RBP *readproc)

{

             strcpy (name, "SAMPLE");

             *initproc = (IBP)FBINIT_sample;

             *readproc = (RBP)FBREAD_sample;

             return ((ABP)FBACT_sample);

}

/* end of file */


Содержание раздела