Говоря об особенностях пакета, надо упомянуть о наличии средств симуляции объектов управления. При разработке прикладных программ в пакете активно используются симуляторы, то есть программы, моделирующие работу системы сбора данных для отладки алгоритмов управления без подключения реальной аппаратуры. Симуляторы являются очень важным и подчас незаменимым инструментом для разработки АСКУ, ведь далеко не всегда существует возможность проверки всех алгоритмов управления на реальной аппаратуре, даже если она подключена и работает. Например, бывает затруднительно реализовать условия для проверки системы блокировки в случае радиационной аварии, и здесь симуляторы оказываются незаменимыми.

Симуляторы обычно реализуются в виде набора конфигурационных файлов и программ на языках DAQ Script, DAQ Pascal, которые временно (при отладке) подключаются вместо измерительных модулей, моделируя их работу. Возможность редактирования и компиляции программ в процессе измерений позволяет легко менять алгоритм симуляции «на ходу», что ускоряет отладку. Наличие средств симуляции – важное средство повышения надежности прикладных программ, поскольку они позволяют проверять работу алгоритмов управления в самых жестких условиях, трудно воспроизводимых на реальной аппаратуре.

11. Листинги

Листинг 1. Структура программного интерфейса CrwApi.

unit _CrwApi;

interface

type

TCrwApi = class; // Корень дерева интерфейсов CRW API.

TSysApi = class; // API для функций общего назначения.

TGuiApi = class; // API для создания графического интерфейса.

НЕ нашли? Не то? Что вы ищете?

TDaqApi = class; // API для систем сбора данных.

TDanApi = class; // API для анализа данных.

TCrwApi = class(TObject)

function Version:Cardinal; virtual; abstract; // Версия API

function SysApi:TSysApi; virtual; abstract;

function GuiApi:TGuiApi; virtual; abstract;

function DaqApi:TDaqApi; virtual; abstract;

function DanApi:TDanApi; virtual; abstract;

end;

TGuiApi = class(TObject)

// Вывод текста в консольное окно.

procedure Echo(const Msg:String); virtual; abstract;

... Другие методы...

end;

... Другие классы...

implementation

end.

Листинг 2. Пример вызова DLL библиотеки из программы на языке DAQ Pascal.

program DllDemo;

var handle, cmd:Integer;

begin

cmd:=1;

handle:=DaqDllInit(‘c:\demo\test. dll’);

if handle=0 then writeln(‘Error!’) else

if DaqDllCall(handle, DAQ_CMD_POLL)

then writeln(‘Success DLL call’)

else writeln(‘Could not call DLL!’);

DaqDllFree(handle);

end;

Листинг 3. Пример запуска дочернего процесса и обмена данными с ним.

program TaskDemo;

var line:string; tid:Integer;

begin

if RunCount=1 then begin

tid:=task_init(‘cmd. exe’);

if task_run(tid)

then writeln(‘cmd. exe is running now.’)

else writeln(‘Could not run cmd. exe!’);

end else

if IsInf(RunCount) then begin

if task_free(tid) then tid:=0;

end else begin

if not eof then begin

readln(line);

if task_send(tid, line)

then writeln(‘Data sent:’,line);

end;

line:=task_recv(tid,255);

if Length(Line)>0 then writeln(‘Data received:’,line);

end;

end.

Листинг 4. Пример программы обмена данными по сетевому каналу.

// Инициализация может быть разной:

p:=pipe_init(‘task cmd.exe /c dir’); // Открыть анонимный канал связи

p:=pipe_init(‘pipe daqhost\datapipe’); // Открыть именованный канал связи

p:=pipe_init(‘tcp port 123 server’); // Открыть TCP/IP порт 123 как сервер

p:=pipe_init(‘tcp port 123 client’); // Открыть TCP/IP порт 123 как клиент

p:=pipe_init(‘com port 1 baudrate 9600’); // Открыть RS-232 порт COM1

// Но дальнейшая работа с каналом будет одинаковой:

if pipe_run(p) then writeln(‘Error!’); // Запуск дочернего процесса task

// Серверная часть:

if pipe_connected(p)>0 then // Если канал открыт

for i:=0 to pipe_count(p)-1 do begin // Цикл по клиентам

ps:=pipe_stream(p,i); // Взять i-й клиентский поток

if pipe_connected(ps)>0 then begin // Если он открыт

Data:=pipe_recv(ps,255); // Читать данные

pipe_send(ps,Data); // Записывать данные

end;

end;

// Клиентская часть:

if pipe_connected(p)>0 then begin // Если канал открыт

Data:=pipe_recv(p,255); // Читать данные

pipe_send(p,Data); // Записывать данные

end;

pipe_free(p); // Закрыть канал связи

Листинг 5. Пример объявления защищенного от «пустых» ссылок класса.

TDemo = class(TObject) // Пример защищенного класса

private // Закрытые (приватные) поля:

myData:Integer; // Скрытое поле данных

private // Закрытые (приватные) методы:

function GetData:Integer; // «Обертка» для поля данных

protected // Закрытые виртуальные методы

function DoGetData:Integer;virtual; // Виртуальная функция чтения данных

public // Открытые (публичные) поля:

constructor Create(d:Integer);

property Data:Integer read GetData; // Открытый интерфейс для чтения данных

end;

function TDemo.GetData:Integer; // Защищенная функция – «обертка»

begin

Result:=0; // Значение по умолчанию

if Assigned(Self) // Если ссылка корректна

then Result:=DoGetData; // Тогда вызвать виртуальный метод

end;

function TDemo.DoGetData:Integer; // Виртуальная функция чтения данных

begin

Result:=myData; // Например, просто чтение поля myData

end;

constructor TDemo.Create(d:Integer); // Конструктор объекта

begin

inherited Create;

myData:=d;

end;

// Пример использования:

program Test;

var p:TDemo=nil; // Ссылка объекта с инициализацией при старте

begin

i:=p.Data; // Результат i=0; вызов корректен, хотя p=nil

p:=TDemo.Create(10); // Создание объекта

i:=p.Data; // Результат i=10

end.

Листинг 6. Пример защищенного класса с использованием «умных» ссылок.

TDemo = class(TObject) // Пример защищенного класса

private // Закрытые (приватные) поля и методы:

myMaster:^TObject; // Скрытое поле адреса «умной ссылки»

procedure SetMaster(var M:TObject); // Присвоение «умной ссылки»

public // Открытые (публичные) методы:

constructor Create;

destructor Destroy; override;

property Master:TObject write SetMaster; // Установка «умной ссылки»

end;

constructor TDemo. Create; // Конструктор объекта

begin

inherited Create; // Создание объекта

myMaster:=nil; // Очистка указателя «умной ссылки»

end;

destructor TDemo. Destroy; // Деструктор объекта

begin

if myMaster<>nil // Если адрес «умной ссылки» назначен,

then myMaster^:=nil; // То очистить «умную ссылку» объекта

inherited Destroy; // Уничтожить объект

end;

procedure TDemo. SetMaster(var M:TObject); // Установка «умной ссылки»

begin

if Assigned(Self) then myMaster:=@M; // Запомнить адрес «умной ссылки»

end;

// Пример использования:

program Test;

var p:TDemo=nil; // Ссылка объекта с инициализацией при старте

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37