Содержание


Расширения crwdaq: плагины и утилиты …

Здесь содержится информация о расширениях пакета CrwDaq.

Расширения (плагины, утилиты) могут быть весьма полезными, т.к. позволяют использовать высокую скорость и огромные возможности натурального кода, создаваемого с помощью компилятора Free Pascal.

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

Расширения делятся на два основных класса:

  1. Плагины (plugin) - динамически загружаемые модули в виде библиотек *.dll или lib*.so, которые загружаются по мере необходимости и работают в адресном пространстве основного исполняемого файла пакета.

  2. Утилиты (utility) - автономные программы (как правило, консольные), выполняющие четко определенную (утилитарную) задачу, запускаемые из среды пакета и работающие параллельно с пакетом для решения общей задачи управления.

Все расширения пишутся в среде пакета crwdaq на Free Pascal, по шаблонам. Компилятор Free Pascal интегрирован с пакетом, хотя устанавливается отдельно. Редактирование, компиляция и запуск расширений деляется из среды пакета crwdaq.

Подробнее см. типы расширений.

Перейти к Содержанию


Типы расширений пакета …

Расширения пакета делятся на такие типы:

Перейти к Содержанию


Плагины: общие принципы …

Плагины - это загружаемые динамические библиотеки с кодом, построенным по определенным правилам.

Общие правила работы …

  1. Плагин оформляется в виде динамической библиотеки *.dll или lib*.so.
    Библиотека загружается по требованию пользователя и создается на языке Free Pascal.

  2. Библиотека экспортирует одну функцию плагина:
    function CRWDAQ_PLUGIN(CrwApi:ICrwApi):Integer;

  3. Функция принимает аргумент CrwApi - интерфейс ICrwApi для доступа к пакету.
    Переданный экземпляр интерфейса содержит в себе большой список (около 1000) функций.
    В совокупности эти функции содержат в себе библиотеку для доступа к данным вызывающего пакета.
    Интерфейс описан в модуле _crw_crwapi.pas.

  4. Всё взаимодействие плагина с вызывающим пакетом выполняется с помощью функций интерейса ICrwApi.
    Ввод-вывод также обеспечивается функциями этого интерфейса.

  5. Функция плагина при вызове выполняет требуемую работу и возвращает как результат статус операции:
    обычно 0 при успехе или ненулевой код ошибки при возникновении проблем.

Интерфейс ICrwApi

Интерфейс ICrwApi описан в модуле _crw_crwapi.pas.
В основном он содержит функции идентификации и другие (предметные) интерфейсы.
Некоторые важные методы ICrwApi приведены в следующей таблице:

Методы ICrwApi Описание
Version:Cardinal Версия API плагина в виде числа - даты вида 20241121.
Target:Cardinal Целевой контекст вызова: ForDataAnalysis, ForDataAcquisition.
SysApi:ISysApi Интерфейс с набором системных (system) функций общего назначения.
GuiApi:IGuiApi Интерфейс с функциями графического интерфейса пользователя (GUI).
DanApi:IDanApi Интерфейс с функциями анализа данных (data analusis) в окне с кривыми.
DaqApi:IDaqApi Интерфейс с функциями сбора данных (data acquisition) и управления.
PluginName:LongString Короткое имя плагина.
PluginSourceFileName:LongString Полное имя файла исходного кода .lpr плагина.
PluginBinaryFileName:LongString Полное имя исполняемого файла *.dll/lib*.so плагина.

Метод Target служит для опрелеления целевого контекста вызова. Если он равен ForDataAnalysis, то это вызов обработки данных, находящихся в окне с кривыми. В этом случае надо использовать интерфейс DanApi для достура к данным окна. Если же метод Target вернул ForDataAcquisition, то это вызов из DAQ-системы сбора данных. В этом случае надо использовать интерфейс DaqApi для доступа к данным DAQ-системы.

Методы Version, PluginName, PluginSourceFileName, PluginBinaryFileName служат для идентификации плагина, позволяя определять его точное расположение, название и т.д. Это може помочь, например, для диагностики или для поиска дополнительных файлов или ресурсов.

Методы CrwApi.SysApi, CrwApi.GuiApi содержат большое число функций общего назначения, которые можно использовать для решения задач, выполняемых плагином.

Полный список и описание интерфейсов, классов, функций, переменных, констант модуля _crw_crwapi с описанием интерфейса ICrwApi подключения плагинов см. тут или там.

Дисциплина при создании плагинов

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

Поэтому программировать плагины надо очень аккуратно и ответственно.

Перейти к Содержанию


Плагины dan для обработки данных …

Плагины для обработки данных dan - data analysis plugin - это динамически загружаемые библиотеки *.dll или lib*.so, загружаемые по команде пользователя для выполнения обработки данных в окне с графиками кривых. Эти плагины привязаны к окнам с данными (графиками кривых) и служат для обработки данных, которые в этих окнах содержатся. Их вызов происходит по команде пользователя - обычно по кнопке Exec.

Плагины обработки данных пишутся по определенному шаблону на языке Free Pascal. Написанный или отредактированный в среде пакета плагин затем можно сразу скомпилировать, а затем загрузить и исполнить. Это делает пакет crwdaq саморасширяемой средой разработки и исполнения, позволяющей прикладному программисту самостоятельно дополнять пакет разработанными средствами, если имеющихся средств не хватает.

Плагины обработки данных находятся в папке resource/plugin/dan/.

Общая логика работы dan плагинов

Пример плагина _curve_integral

Рассмотрим протейший плагин обработки данных _curve_integral, выполняющий интегрирование (вычисление первообразной):

Разберем приведенный выше плагин подробнее.


Структура плагина обработки данных

Плагин обработки данных должен иметь чёткую структуру, описанную ниже.

Блок справки и аргументов

В начале кода идет помещенный в комментариях блок секций Русской/Английской справки - [Manual.Rus]/[Manual.Eng], а также секций аргументов на Русском/Агнглийском [Arguments.Rus]/[Arguments.Eng].

{
[Manual.Rus]

[Manual.Eng]

[Arguments.Rus]
Имя окна = …
Заголовок = …
Легенда = …
[Arguments.Eng]
Caption = …
Title = …
Legend = …
}

Справка отображаются в диалоге вызова плагина для пояснения того, что он делает.
Аргументы - это редактируемые в диалоге параметры, нужные для проведения расчетов.
Значения аргументов извлекаются вызовами типа GetArgumentAsString(RusEng('Имя окна','Caption'));.

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

crwdaq Run Plugin Dialog
Команда Действие Комментарий
Exec Запуск Запуск выбранного плагина на выполнение.
Edit Изменить Открыть окно редактирования плагина.
Delete Удалить Удалить выбранный плагин.
Clone Клонировать Клонировать выбранный плагин в новый.
Compile Компилировать Компилировать выбранный плагин.
CompileAll Компил-ть Все Компилировать все доступные плагины.
Exit Выход Закрыть диалог запуска плагинов.

Блок определений и режимов

После блока справки и аргументов идет объявление библиотеки library …;, затем обязательная вставка общих определений {$I _crw_sysdef.inc}](../../../crwlib/_crw_sysdef.inc)** и режима компиляции **[{$I _crw_sysmode.inc}.

library _curve_integral;

{$I _crw_sysdef.inc}

{$I _crw_sysmode.inc}

Этот блок кода обязателен, т.к. он задает необходимые режимы компиляции.

Блок uses

После определений и режимов компиляции обязательно идет блок uses:

uses
 //////////////////////////////////////////////////////
 {$I _crw_uses_first.inc} // NB: MUST BE FIRST USES !!!
 //////////////////////////////////////////////////////
 sysutils, classes, math, graphics,
 _crw_crwapi;

Очень важно соблюдать следующие правила:

  1. Первым выражением uses идет вставка {$I _crw_uses_first.inc}.
    Это обеспечивает правильную инициализацию менеджера памяти и библиотеки поддержки потоков.
  2. Затем идет список стандартных модулей, в который обычно входят:
    sysutils, classes, math, graphics. Но могут добавляться и другие.
  3. Обязательно включение в uses модуля _crw_crwapi.
    В этом модуле описан интерфейс для доступа к функциям пакета.
  4. Список модулей должен быть минимально необходимым для решения данной задачи.
  5. Функция плагина должна освобождать все (явно) занятые в процессе исполнения ресурсы.

Минимизация списка используемых модулей необходима по следующей причине.
Плагин должен освобождать все занятые ресурсы, т.к. библиотека с кодом плагина загружается динамически и затем освобождается. Прикладной код должен освобождать все (явно) занятые ресурсы, однако при использовании модулей при загрузке библиотек будут неявно (скрыто) выполняться код initialization модуля при загрузке и finalization при выгрузке библиотеки. Далеко не все библиотеки написаны чисто в смысле освобождения ресурсов. Это связанос тем, что модули чаще всего ориентируются на исполняемые приложения *.exe, а не на библиотеки. Освобождать все ресурсы в конце работы программы не столь необходимо, т.к. программа всё равно уже завершается. А вот при выгрузке библиотек выполнение программы продолжается. Всё, что не освободил любой из модулей библиотеки, будет утечкой ресурсов. Поэтому число модулей uses нужно по возможности минимизировать.

Интерфейс CrwApi, переданный в плагин при его вызове, содержит в себе порядка 1000 функций, дающих доступ к библиотеке crwlib, уже скомпилированных в ядре пакета. Поэтому для плагинов крайне желательно по мере возможности ограничиться этим набором вместо подключения дополнительных модулей. Это не только сократит объем кода плагина (т.к. вместо компиляции нового кода интерфейс ссылается на уже скомпилированный код), но и сократит использование ресурсов (которые уже выделены в коде пакета). А главное, будет меньше проблем с освобождением ресурсов, занятых модулями, а потому меньше вероятность утечки памяти.

Блок декларации функции плагина

После uses необходим блок декларации функции плагина.

/////////////////////////////////////////////////////////
{$I _crw_plugin_declare.inc} // Declare CRWDAQ_PLUGIN. //
/////////////////////////////////////////////////////////
// function CRWDAQ_PLUGIN(CrwApi:ICrwApi):Integer;     //
/////////////////////////////////////////////////////////

Для обеспечения централизации и единства кода декларация делается с помощью включаемого файла {$I _crw_plugin_declare.inc}. Это позволяет управлять кодом декларации всех плагинов в одном файле. А также обеспечивает правильность декларации во всех плагинах. Заметим, что плагин использует соглашение о вызовах ABI call (application binary interface), заданное в файле _crw_plugin_abicall.inc.

Блок тела (содержания) плагина

После декларации функции плагина следует тело плагина, т.е. его содержательная часть.

В начале этого блока следует:

Это выглядит примерно так:

begin
 Result:=0;                 
 with CrwApi,SysApi,GuiApi,DanApi do
 try
  RedirectStdIn(Input);             
  RedirectStdOut(Output);
  VerifyPluginDate(CrwApiEdition,Version);
  VerifyPluginType(Target,ForDataAnalysis);

  … код плагина …

 except
  on E:Exception do begin
   if WindowExists(twin) then CurvesCount[twin]:=0;
   Echo(PluginName+RusEng(': ОШИБКА!',': ERROR!')); 
   if UsesBlaster then Voice('EXCEPTION');
   Echo(E.Message); Error(E.Message);
   Result:=-1;
  end;
 end;           
end;

В теле плагина используются данные (кривые) из активного окна и данные из буфера обмена. Результат (новые кривые) помещается в новое окно. Кривые и окна идентифицируются целочисленными номерами: положительные числа нумеруют кривые в окне источника (source), отрицательные - приемника (target), ноль ссылается на буфер обмена (clipboard).

const
 swin = +1; // Source window reference
 twin = -1; // Target window reference
 cwin =  0; // Clipboard window reference

Например, вызов WindowExists(twin) проверяет наличие окна приемника, а CurvesCount[twin] - возвращает число кривых в окне приемника.

Как правило, назначение функций и их аргументов понятно из названий.

Полный список и описание интерфейсов, классов, функций, переменных, констант модуля _crw_crwapi с описанием интерфейса ICrwApi подключения плагинов см. тут или там.

Блок экспорта функции плагина

В конце, после завершения функции плагина, необходимо экспортировать её:

/////////////////////////////////////////////////////////
{$I _crw_plugin_exports.inc} // Exports CRWDAQ_PLUGIN. //
/////////////////////////////////////////////////////////
// exports CRWDAQ_PLUGIN name CRWDAQ_PLUGIN_ID;        //
/////////////////////////////////////////////////////////
begin
end.

Экспорт выполняется вставкой {$I _crw_plugin_exports.inc}, что обеспечивает централизованное управление кодом плагинов.

Шаблоны плагинов dan

Пакет содержит большую библиотеку (более 30) готовых плагинов обработки данных dan, созданных по одному шаблону. Средства клонирования (копирования и сохранения под другим именем) позволяют создавать новые плагины, взяв существующие плагины в качестве образца (шаблона).

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

Перейти к Содержанию


Плагины daq для сбора данных …

Плагины для сбора данных - daq - data acquisition plugin - это динамически загружаемые библиотеки *.dll или lib*.so, загружаемые в составе DAQ системы и работающие для решения задач сбора данных и управления физическими установками. Эти плагины привязаны к устройствам DAQ системы devices software program, т.е. к программам на языке DaqPascal и служат для сбора и обработки данных в режиме online. Они вызываются и выполняются в контесте потока программы DaqPascal.

Плагины обработки данных пишутся по определенному шаблону на языке Free Pascal. Написанный или отредактированный в среде пакета плагин затем можно сразу скомпилировать, а затем загрузить и исполнить в составе конфигурации DAQ-системы. Это делает пакет crwdaq саморасширяемой средой разработки и исполнения, позволяющей прикладному программисту самостоятельно дополнять пакет разработанными средствами, если имеющихся средств не хватает.

Шаблоны плагинов сбора данных находятся в папке resource/plugin/daq/. Также есть плагины сбора данных в демо конфигурациях demo_dll_min, demo_dll_sin и ряда других.

Общая логика работы daq плагинов

Вызов плагинов с помощью Стандартной Библиотеки

Загружать, освобождать и вызывать daq плагины можно в принципе из любой программы на языке DaqPascal. Это удобно делать с помощью функций стандартной библиотеки. Если использовать стандартный шаблон программы, достаточно вызвать STD_DLL_INIT при старте программы, инициировав загрузку DLL.

procedure InitApplication;
begin

 // Initialize DAQ plugin DLL:
 STD_DLL_INIT('DLL_FILE_PATH');

end;

Дальше стандартная библиотека возьмет на себя вызов плагина в каждом цикле опроса и его освобождение в конце работы DAQ-системы.

Стандартная библиотека после вызова STD_DLL_INIT выполняет вызов плагина к каждом цикле опроса. Если нужна другая логика работы (например, вызов плагина только по событиям), то лучше использовать функции DLL_INIT/FREE/POLL, которые позволяют вызывать плагин тогда, когда требуется прикладному алгоритму. Но и следить за логикой работы плагина тогда придется самостоятельно.

Программа _dllhost.pas - рекомендуемая оболочка для вызова плагина

Как уже было сказано, для вызова daq плагина требуется DAQ-программа на языке DaqPascal, которая его вызывает, так как плагин выполняется в контексте вызывающей его DAQ-программы. Код вызова daq плагина можно вставить в любую программу, однако в стандартной библиотеке есть готовая программа _dllhost.pas, которая специально предназначена для вызова daq плагина.



Программа - оболочка конфигурируется примерно так:

[DeviceList]
&DEMO_DLL_HOST = device software program
[]
[&DEMO_DLL_HOST]
InquiryPeriod = 10                                              ; период опроса
DevicePolling = 100, tpNormal                                   ; период, приоритет потока
DLL_FILE_PATH = demo_dll_min_plugin\demo_dll_min_plugin.dll     ; расположение DLL плагина
ProgramSource = ~~/resource/daqsite/stdlib/daqpas/_dllhost.pas  ; программа-владелец(обертка)
StdIn_EnablePoll = 1 ; Разрешение опроса StdIn в коде DaqPascal, иначе опрос делает код плагина

… и другие параметры …

[]

В конфигурации задается ссылка DLL_FILE_PATH на бинарный файл плагина, а также ссылка ProgramSource на программу-оболочку _dllhost.pas. Также задается флаг StdIn_EnablePoll, который разрешает опрос консольного ввода StdIn в программе DaqPascal. Если он сброшен в ноль, то обрабатывать консольный ввод должен сам плагин.

Использование программы - оболочки упрощает использование daq плагинов, предоставляя готовую клиентскую часть для подключения плагина к DAQ системе.

Программа _dllwrap.pas - запасная (устаревшая) оболочка для вызова плагина

В стандартной библиотеке есть запасная (несколько устаревшая, но вполне рабочая) готовая программа _dllwrap.pas, которая специально предназначена для вызова daq плагина.



Программа - оболочка конфигурируется примерно так:

[DeviceList]
&DEMO_DLL_MIN = device software program
[]
[&DEMO_DLL_MIN]
InquiryPeriod = 10                                              ; период опроса
DevicePolling = 100, tpNormal                                   ; период, приоритет потока
DLL_FILE_PATH = demo_dll_min_plugin\demo_dll_min_plugin.dll     ; распположение DLL
ProgramSource = ~~/resource/daqsite/stdlib/daqpas/_dllwrap.pas  ; программа-оболочка

… и другие параметры …

[]

В конфигурации задается ссылка DLL_FILE_PATH на бинарный файл плагина, а также ссылка ProgramSource на программу-оболочку _dllwrap.pas.

Использование программы - оболочки упрощает использование daq плагинов, предоставляя готовую клиентскую часть для подключения плагина к DAQ системе.

Пример плагина demo_dll_min_plugin

Рассмотрим протейший плагин сбора данных demo_dll_min_plugin, просто выводящий в консоль устройства синусоиду - значение sin(omega*time):

Разберем приведенный выше плагин подробнее.


Структура плагина сбора данных

Плагин сбора данных должен иметь чёткую структуру, описанную ниже.

Блок определений и режимов daq плагина

Первым идет объявление библиотеки library …;, затем обязательная вставка общих определений {$I _crw_sysdef.inc}](../../../crwlib/_crw_sysdef.inc)** и режима компиляции **[{$I _crw_sysmode.inc}.

library demo_dll_min_plugin;

{$I _crw_sysdef.inc}

{$I _crw_sysmode.inc}

Этот блок кода обязателен, т.к. он задает необходимые режимы компиляции.

Блок uses для daq плагина

После определений и режимов компиляции обязательно идет блок uses:

uses
 //////////////////////////////////////////////////////
 {$I _crw_uses_first.inc} // NB: MUST BE FIRST USES !!!
 //////////////////////////////////////////////////////
 sysutils, classes, math, graphics,
 _crw_crwapi;

Очень важно соблюдать следующие правила:

  1. Первым выражением uses идет вставка {$I _crw_uses_first.inc}.
    Это обеспечивает правильную инициализацию менеджера памяти и библиотеки поддержки потоков.
  2. Затем идет список стандартных модулей, в который обычно входят:
    sysutils, classes, math, graphics. Но могут добавляться и другие.
  3. Обязательно включение в uses модуля _crw_crwapi.
    В этом модуле описан интерфейс для доступа к функциям пакета.
  4. Список модулей должен быть минимально необходимым для решения данной задачи.
  5. Функция плагина должна освобождать все (явно) занятые в процессе исполнения ресурсы.

Минимизация списка используемых модулей необходима по следующей причине.
Плагин должен освобождать все занятые ресурсы, т.к. библиотека с кодом плагина загружается динамически и затем освобождается. Прикладной код должен освобождать все (явно) занятые ресурсы, однако при использовании модулей при загрузке библиотек будут неявно (скрыто) выполняться код initialization модуля при загрузке и finalization при выгрузке библиотеки. Далеко не все библиотеки написаны чисто в смысле освобождения ресурсов. Это связанос тем, что модули чаще всего ориентируются на исполняемые приложения *.exe, а не на библиотеки. Освобождать все ресурсы в конце работы программы не столь необходимо, т.к. программа всё равно уже завершается. А вот при выгрузке библиотек выполнение программы продолжается. Всё, что не освободил любой из модулей библиотеки, будет утечкой ресурсов. Поэтому число модулей uses нужно по возможности минимизировать.

Интерфейс CrwApi, переданный в плагин при его вызове, содержит в себе порядка 1000 функций, дающих доступ к библиотеке crwlib, уже скомпилированных в ядре пакета. Поэтому для плагинов крайне желательно по мере возможности ограничиться этим набором вместо подключения дополнительных модулей. Это не только сократит объем кода плагина (т.к. вместо компиляции нового кода интерфейс ссылается на уже скомпилированный код), но и сократит использование ресурсов (которые уже выделены в коде пакета). А главное, будет меньше проблем с освобождением ресурсов, занятых модулями, а потому меньше вероятность утечки памяти.

Блок декларации функции daq плагина

После uses необходим блок декларации функции плагина.

/////////////////////////////////////////////////////////
{$I _crw_plugin_declare.inc} // Declare CRWDAQ_PLUGIN. //
/////////////////////////////////////////////////////////
// function CRWDAQ_PLUGIN(CrwApi:ICrwApi):Integer;     //
/////////////////////////////////////////////////////////

Для обеспечения централизации и единства кода декларация делается с помощью включаемого файла {$I _crw_plugin_declare.inc}. Это позволяет управлять кодом декларации всех плагинов в одном файле. А также обеспечивает правильность декларации во всех плагинах. Заметим, что плагин использует соглашение о вызовах ABI call (application binary interface), заданное в файле _crw_plugin_abicall.inc.

Блок определения области данных daq плагина

После объявления функции плагина надо определить область данных daq плагина, обычно это тип записи TDaqDataSheet.

 ////////////////////////////
 // Comment on TDaqDataSheet:
 // Hold all DAQ data there!!
 // Init all on DAQ_CMD_INIT.
 // Free all on DAQ_CMD_FREE.
 // Use data on DAQ_CMD_POLL.
 ////////////////////////////
type ////////////////////////
 TDaqDataSheet = packed record
  Sinus    : Double;
  Omega    : Double;
  timeSec  : Double;
  dllName  : LongString;
 end; //// TDaqDataSheet /////
 ////////////////////////////

Запись TDaqDataSheet должна содержать ВСЕ данные, нужные в процессе работы daq плагина. Необходимость области данных TDaqDataSheet связана с тем, что плагин сбора данных, в отличие от плагина обработки данных, вызывается многократно - в цикле опроса потока DAQ устройства. Данные между вызовами надо где-то хранить - но не в стеке, который освобождается после вызова. Разумно использовать для хранения данных интерфейс CrwApi, время жизни которого глобально - точнее, оно совпадает с временем жизни загруженного плагина. Поэтому все данные daq плагина хранятся в буфере памяти, доступ к которому дает функция интерфейса CrwApi.DaqApi.DaqDataSheet(n), где n - размер буфера памяти. При этом, если значение n меняется, происходит перераспределение памяти. Поэтому важно, чтобы значение n было постоянным в процессе опроса. Для этого обычно используется конструкция with TDaqDataSheet(DaqDataSheet(SizeOf(TDaqDataSheet))^) do …, которая ипользует SizeOf(TDaqDataSheet) для выделения буфера и приведение типа TDaqDataSheet(DaqDataSheet(…)^) для доступа к данным в буфере.

Подчеркнем еще раз - все данные плагина надо размещать в TDaqDataSheet.
Затем эти данные надо:

Клиентская часть программы DaqPascal должна обеспечить вызов этих команд в процессе работы DAQ-системы.

Блок тела (содержания) daq плагина

После декларации функции плагина следует тело плагина, т.е. его содержательная часть.

В этом блоке следует:

На практике это выглядит примерно так:

begin
 Result:=0;
 with CrwApi,SysApi,GuiApi,DaqApi do
 try
  VerifyPluginDate(CrwApiEdition,Version);
  VerifyPluginType(Target,ForDataAcquisition);
  ///////////////////////////////////////////////////////////////
  // Nota Bene: all driver data must be located in DaqDataSheet!!
  ///////////////////////////////////////////////////////////////
  with TDaqDataSheet(DaqDataSheet(SizeOf(TDaqDataSheet))^) do begin
   case DaqCommand of
    ////////////////////
    // Initialize driver
    ////////////////////
    DAQ_CMD_INIT: begin
     RedirectStdIn(Input);
     RedirectStdOut(Output);
     //////////////////////////////////////////////////
     // Initialize USER data located in DaqDataSheet //
     //////////////////////////////////////////////////
     dllName:=ExtractFileNameExt(PluginBinaryFileName);
     GuiApi.Echo(Format('Starting %s …',[dllName]));

     … Инициализация данных TDaqDataSheet

     //////////////////
     GuiApi.Echo('Ok');
    end;
    //////////////////
    // Finalize driver
    //////////////////
    DAQ_CMD_FREE: begin
     GuiApi.Echo(Format('Stopping %s …',[dllName]));
     //////////////////
     // Don`t forget to
     // Clear all data:
     //////////////////

     … Освобождение данных TDaqDataSheet

     //////////////////
     // Free DataSheet:
     //////////////////
     DaqDataSheet(0);//
     //////////////////
     GuiApi.Echo('Ok');
    end;
    ////////////////////
    // Main polling loop
    ////////////////////
    DAQ_CMD_POLL: begin
     /////////////////////////////
     // USER data processing code:
     /////////////////////////////

     … Цикл сбора и обработки данных TDaqDataSheet

     /////////////////////////////
     // USER data processing done.
     /////////////////////////////
    end;
   end; // case
  end; // with
 except
  on E:Exception do begin
   Echo(PluginName+RusEng(': ОШИБКА!',': ERROR!')); 
   if UsesBlaster then Voice('EXCEPTION');
   Echo(E.Message);
   Result:=-1;
  end;
 end;
end;

Для выполнения полезной работы по сбору и обработке данных используются интерфейсы ICrwApi, ISysApi, IGuiApi, IDaqApi, содержащие большой набор функций для доступа к данным пакета. Например, для доступа к последней точке (x,y) кривой, подключенной к аналоговому входу (analog input) используются функции getai_xn(i), getai_yn(i), где i - номер аналогового входа.

Как правило, назначение функций и их аргументов понятно из названий. Многие функции интерфейсов ICrwApi, ISysApi, IDaqApi совпадают или имеют аналоги

Полный список и описание интерфейсов, классов, функций, переменных, констант модуля _crw_crwapi с описанием интерфейса ICrwApi подключения плагинов см. тут или там.

Блок экспорта функции daq плагина

В конце, после завершения функции плагина, необходимо экспортировать её:

/////////////////////////////////////////////////////////
{$I _crw_plugin_exports.inc} // Exports CRWDAQ_PLUGIN. //
/////////////////////////////////////////////////////////
// exports CRWDAQ_PLUGIN name CRWDAQ_PLUGIN_ID;        //
/////////////////////////////////////////////////////////
begin
end.

Экспорт выполняется вставкой {$I _crw_plugin_exports.inc}, что обеспечивает централизованное управление кодом плагинов.

Шаблоны плагинов daq

Пакет содержит библиотеку образцов плагинов сбора данных daq, созданных по одному шаблону. Средства клонирования (копирования и сохранения под другим именем) позволяют создавать новые плагины, взяв эти образцы плагинов в качестве шаблона.

Шаблоны уже содержат необходимую структуру для работы плагинов сбора данных. Прикладному программисту нужно дополнить шаблон своим кодом, решающим требуемую задачу. Большинство потребностей прикладного программирования закрывает интерфейс ICrwApi, в состав которого входит еще ряд предметных интерфейсов:

Полный список и описание интерфейсов, классов, функций, переменных, констант модуля _crw_crwapi с описанием интерфейса ICrwApi подключения плагинов см. тут или там.

Перейти к Содержанию


Консольные утилиты

Используйте шаблон hello_world.lpr.
А также модули библиотеки crwlib.

Полный список и описание интерфейсов, классов, функций, переменных, констант библиотеки crwlib см. тут или там.

Перейти к Содержанию


Консольные драйверы

Используйте шаблон daq_user_task.lpr.
А также модули библиотеки crwlib.

Полный список и описание интерфейсов, классов, функций, переменных, констант библиотеки crwlib см. тут или там.

Перейти к Содержанию