|
<< Click to Display Table of Contents >> Navigation: API MasterSCADA 4D > Функции, ФБ, Протоколы на С++ > API для ФБ и протоколов > Разработка протоколов > Разработка простого протокола > Реализация простого протокола в C++ |
Пример реализации подключен к Examples.sln как mplc_simple_test_protocol:

Для разработки своих собственных протоколов нужно открыть пример и изменить те части проекта, которые отвечают за логику работы. Вспомогательные файлы, служащие для взаимодействия с исполнительной системой, редактировать не требуется.
В случае протокола наследоваться надо от класса ScadaProtocol. Также как и с ФБ, необходимы макросы регистрации класса MPLC_OBJECT(SimpleTestProtocol) в секции public. Также переопределению подлежат чисто виртуальные методы Execute() и Creatе(), которые отвечают за создание каналов и логику их хранения в самом классе протокола. Метод Connect() отвечает за подключение к устройству.
Для этого в примере был создан заголовочный файл simple_test_protocol.h:

Содержимое файла:
Скриншот |
Текст |
|
#pragma once #include <mplc/api.h>
#include "emulator.h"
class SimpleTestProtocol final : public mplc::api::ScadaProtocol { private: std::vector<mplc::api::ScadaChannel*> channels; Emulator *emulator; bool connected{false}; bool Connect();
public: MPLC_OBJECT(SimpleTestProtocol); SimpleTestProtocol(); ~SimpleTestProtocol(); void Execute() override; mplc::api::ScadaChannel* Create(const mplc::vm::Channel* channel) override; void Init() override; };
|
Протокол и его свойства надо зарегистрировать в файлах исходных кодов макросом MPLC_PROTOCOL_TYPE.
Для этого в примере был создан файл реализации для протокола simple_test_protocol.cpp:

Содержимое файла:
Скриншот |
Текст |
|
#include "simple_test_protocol.h"
SimpleTestProtocol::SimpleTestProtocol() { emulator = new Emulator(); }
SimpleTestProtocol::~SimpleTestProtocol() { emulator->close(); delete emulator; }
bool SimpleTestProtocol::Connect() { if (connected) { return true; } if (!emulator->connect()) { return false; } connected = true; SetFaultState(false, ""); return true; }
void SimpleTestProtocol::Init() { emulator->init(); }
void SimpleTestProtocol::Execute() { if (!isConnect()) { return; } if (!Connect()) { SetFaultState(true, "Failed to connect"); return; } if (!isExecute()) { return; }
std::string buff;
for (auto ch : channels) { // Read value from emulator and write to ScadaChannel buff = emulator->read(); ch->InVar.Update(buff);
// Read value from ScadaChannel and write to emulator if (ch->OutVar.Changed()) { buff = ch->OutVar.Get<std::string>(""); emulator->write(buff); } } AcknowledgeAllChanges(); }
mplc::api::ScadaChannel* SimpleTestProtocol::Create(const mplc::vm::Channel* channel) { auto ch = new mplc::api::ScadaChannel(); channels.push_back(ch); ch->BaseInit(channel); Register(ch); return ch; }
MPLC_PROTOCOL_TYPE(SimpleTestProtocol, SimpleTestProtocol); |
При реализации методов класса нужно учитывать несколько вещей
1.В методе Create при создании каналов необходимо инициализировать канал методом ScadaChannel::BaseInit(const vm::Channel*). Затем проинициализированный канал необходимо зарегистрировать методом ScadaProtocol::Register(ScadaChannel*);
2.В методе Execute должны быть проверки на условие подключения ScadaProtocol::isConnect() и условие исполнения ScadaProtocol::isExecute(). Условие подключения имеет больший приоритет, поэтому проверяется первым. Если условие подключения установлено в true, то можно выполнить метод Connect в зависимости от необходимости
3.После выполнения всех операций с каналами нужно вызывать метод ScadaProtocol::AcknowledgeAllChanges() для подтверждения всех внесённых изменений
4.Для установки отказа протокола используется метод ScadaProtocol::SetFaultState(bool state, std::string err_text). Для снятия отказа применяется тот же метод, но в аргумент state устанавливается значение false, а в err_text пустая строка.
5.Для чтения данных из каналов используется метод Get<T>() поля OutVar класса ScadaChannel T val = ch->OutVar.Get<T>(), где ch это указатель на класс ScadaChannel. Если необходимо, можно проверить, изменилось ли значение в канале методом Changed() поля OutVar класса ScadaChannel ch->OutVar.Changed()
6.Для записи в канал значения применяется два метода поля InVar класса ScadaChannel: Update и Set. Update записывает значение в канал только в случае если оно изменилось, а Set записывает значение в любом случае.
Далее можно компилировать проект.
Для компиляции проекта на ОС Windows нужно выполнить команду Build в контекстном меню проекта:

Скомпилированные файлы появятся в папке проекта: C:\mplc\api\platform\x64\bin\Release (адрес действителен, если название папок, которые делал разработчик, совпадают с названиями, которые давались в этой инструкции).
Чтобы произвести сборку под Linux платформы, нужно сохранить проект и перенести все файлы из папки C:\mplc\api (адрес действителен, если название папок, которые делал разработчик, совпадают с названиями, которые давались в этой инструкции) в созданный каталог на компьютере с ОС Linux. Подробнее смотрите в разделе Сборка под Linux платформы.
После сборки можно приступать к тестированию созданного ФБ.