dev(UML-981): Небольшой рефакторинг
1. разработаны абстрактные классы флагов и разделяемых даннных. Модуль profinet их использует. 2. Разделяемые данныне переделаны на использование мьютексов буста
This commit is contained in:
parent
3fdd61b35c
commit
b992c1c3a6
39
src/app.cpp
39
src/app.cpp
@ -38,45 +38,8 @@ bool App::Init(std::string profinet_config_file)
|
|||||||
|
|
||||||
void App::Run()
|
void App::Run()
|
||||||
{
|
{
|
||||||
//пауза
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
||||||
|
|
||||||
uint32_t event_mask = (Profinet::EVENT_CONNECTION_ESTABLISHED |
|
|
||||||
Profinet::EVENT_NEW_CYCLIC_DATA |
|
|
||||||
Profinet::EVENT_NEW_PARAM_DATA |
|
|
||||||
Profinet::EVENT_CONNECTION_ABORT);
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
//std::cout << "App: Waiting event flag" << std::endl;
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
|
|
||||||
uint32_t events = profinet_.EventWait(event_mask);
|
|
||||||
|
|
||||||
//std::cout << "App: New flag = " << std::to_string(events) << std::endl;
|
|
||||||
|
|
||||||
if (events & Profinet::EVENT_CONNECTION_ESTABLISHED)
|
|
||||||
{
|
|
||||||
std::cout << "App: EVENT_CONNECTION_ESTABLISHED" << std::endl;
|
|
||||||
|
|
||||||
profinet_.EventClear(Profinet::EVENT_CONNECTION_ESTABLISHED);
|
|
||||||
|
|
||||||
shared_data_.p_profinet_data_->Events.set_flag(ProfinetEvent::EVENT_CONNECTION_ESTABLISHED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events & Profinet::EVENT_NEW_CYCLIC_DATA)
|
|
||||||
{
|
|
||||||
//std::cout << "App: EVENT_NEW_CYCLIC_DATA" << std::endl;
|
|
||||||
profinet_.EventClear(Profinet::EVENT_NEW_CYCLIC_DATA);
|
|
||||||
|
|
||||||
shared_data_.p_profinet_data_->Events.set_flag(ProfinetEvent::EVENT_NEW_CYCLIC_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events & Profinet::EVENT_NEW_PARAM_DATA)
|
|
||||||
{
|
|
||||||
std::cout << "App: Clear: EVENT_NEW_PARAM_DATA" << std::endl;
|
|
||||||
profinet_.EventClear(Profinet::EVENT_NEW_PARAM_DATA);
|
|
||||||
|
|
||||||
shared_data_.p_profinet_data_->Events.set_flag(ProfinetEvent::EVENT_NEW_PARAM_DATA);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,6 +9,6 @@ public:
|
|||||||
bool Init(std::string profinet_config_file);
|
bool Init(std::string profinet_config_file);
|
||||||
void Run();
|
void Run();
|
||||||
private:
|
private:
|
||||||
Profinet profinet_;
|
|
||||||
ProfinetSharedData shared_data_;
|
ProfinetSharedData shared_data_;
|
||||||
|
Profinet profinet_;
|
||||||
};
|
};
|
||||||
@ -6,24 +6,23 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
class Flags {
|
#include "flags_iface.hpp"
|
||||||
|
|
||||||
|
class Flags : public FlagsIface {
|
||||||
public:
|
public:
|
||||||
Flags() : flags_{0} {
|
Flags() : flags_{0} {
|
||||||
///Блокируем мьютекс ожидания
|
|
||||||
mutex_wait_.lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_flag(uint32_t mask) {
|
virtual void set_flag(uint32_t mask) override
|
||||||
|
{
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
flags_ |= mask;
|
flags_ |= mask;
|
||||||
}
|
}
|
||||||
/// Разблокируем мьютекс ожидания
|
flag_cond_.notify_all();
|
||||||
mutex_wait_.unlock();
|
|
||||||
//flag_cond_.notify_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_flag(uint32_t mask) {
|
virtual uint32_t get_flag(uint32_t mask) override {
|
||||||
uint32_t out;
|
uint32_t out;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
@ -32,7 +31,7 @@ public:
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_flags() {
|
virtual uint32_t get_flags() override {
|
||||||
uint32_t out;
|
uint32_t out;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
@ -42,29 +41,18 @@ public:
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_flags(uint32_t mask)
|
virtual void clear_flags(uint32_t mask) override
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
flags_ &= ~mask;
|
flags_ &= ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t wait_flags(uint32_t mask)
|
|
||||||
{
|
|
||||||
mutex_wait_.lock(); //Ожидаем изменения данных
|
|
||||||
uint32_t out;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
|
||||||
out = flags_ & mask;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Блочит потоки pnet. Нужно разбираться.
|
* @brief Данная реализация блочит потоки pnet.
|
||||||
|
* Нужно разбираться.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*uint32_t wait_condition(uint32_t mask)
|
virtual uint32_t wait_flags(uint32_t mask) override
|
||||||
{
|
{
|
||||||
uint32_t out;
|
uint32_t out;
|
||||||
std::unique_lock<std::mutex> lk(mutex_);
|
std::unique_lock<std::mutex> lk(mutex_);
|
||||||
@ -72,10 +60,9 @@ public:
|
|||||||
out = flags_ & mask;
|
out = flags_ & mask;
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
return out;
|
return out;
|
||||||
}*/
|
}
|
||||||
private:
|
private:
|
||||||
uint32_t flags_;
|
uint32_t flags_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
std::mutex mutex_wait_;
|
std::condition_variable flag_cond_;
|
||||||
//std::condition_variable flag_cond_;
|
|
||||||
};
|
};
|
||||||
19
src/flags/flags_iface.hpp
Normal file
19
src/flags/flags_iface.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class FlagsIface {
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void set_flag(uint32_t mask) = 0;
|
||||||
|
|
||||||
|
virtual uint32_t get_flag(uint32_t mask) = 0;
|
||||||
|
|
||||||
|
virtual uint32_t get_flags() = 0;
|
||||||
|
|
||||||
|
virtual void clear_flags(uint32_t mask) = 0;
|
||||||
|
|
||||||
|
virtual uint32_t wait_flags(uint32_t mask) = 0;
|
||||||
|
|
||||||
|
virtual ~FlagsIface() {}
|
||||||
|
};
|
||||||
@ -3,25 +3,26 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
||||||
|
#include <boost/interprocess/sync/interprocess_condition.hpp>
|
||||||
|
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||||
|
|
||||||
class SharedFlags {
|
#include "flags_iface.hpp"
|
||||||
|
|
||||||
|
class SharedFlags : public FlagsIface {
|
||||||
public:
|
public:
|
||||||
SharedFlags() : flags_{0} {
|
SharedFlags() : flags_{0} {
|
||||||
///Блокируем мьютекс ожидания
|
|
||||||
mutex_wait_.lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_flag(uint32_t mask) {
|
virtual void set_flag(uint32_t mask) override {
|
||||||
{
|
{
|
||||||
std::lock_guard guard(mutex_);
|
std::lock_guard guard(mutex_);
|
||||||
flags_ |= mask;
|
flags_ |= mask;
|
||||||
}
|
}
|
||||||
/// Разблокируем мьютекс ожидания
|
/// Уведомляем об изменении флага
|
||||||
mutex_wait_.unlock();
|
flag_cond_.notify_all();
|
||||||
//flag_cond_.notify_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_flag(uint32_t mask) {
|
virtual uint32_t get_flag(uint32_t mask) override {
|
||||||
uint32_t out;
|
uint32_t out;
|
||||||
{
|
{
|
||||||
std::lock_guard guard(mutex_);
|
std::lock_guard guard(mutex_);
|
||||||
@ -30,7 +31,7 @@ public:
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_flags() {
|
virtual uint32_t get_flags() override{
|
||||||
uint32_t out;
|
uint32_t out;
|
||||||
{
|
{
|
||||||
std::lock_guard guard(mutex_);
|
std::lock_guard guard(mutex_);
|
||||||
@ -40,39 +41,27 @@ public:
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_flags(uint32_t mask)
|
virtual void clear_flags(uint32_t mask) override
|
||||||
{
|
{
|
||||||
std::lock_guard guard(mutex_);
|
std::lock_guard guard(mutex_);
|
||||||
flags_ &= ~mask;
|
flags_ &= ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t wait_flags(uint32_t mask)
|
virtual uint32_t wait_flags(uint32_t mask) override
|
||||||
{
|
{
|
||||||
mutex_wait_.lock(); //Ожидаем изменения данных
|
boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(mutex_wait_);
|
||||||
|
flag_cond_.wait(lock); //Ожидаем изменения данных
|
||||||
|
/// Данные изменились
|
||||||
uint32_t out;
|
uint32_t out;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard guard(mutex_);
|
std::lock_guard guard(mutex_);
|
||||||
out = flags_ & mask;
|
out = flags_ & mask;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Блочит потоки pnet. Нужно разбираться.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/*uint32_t wait_condition(uint32_t mask)
|
|
||||||
{
|
|
||||||
uint32_t out;
|
|
||||||
std::unique_lock<std::mutex> lk(mutex_);
|
|
||||||
flag_cond_.wait(lk, [this, mask]{return static_cast<bool>(flags_ & mask);});
|
|
||||||
out = flags_ & mask;
|
|
||||||
lk.unlock();
|
|
||||||
return out;
|
|
||||||
}*/
|
|
||||||
private:
|
private:
|
||||||
uint32_t flags_;
|
uint32_t flags_;
|
||||||
boost::interprocess::interprocess_mutex mutex_;
|
boost::interprocess::interprocess_mutex mutex_;
|
||||||
boost::interprocess::interprocess_mutex mutex_wait_;
|
boost::interprocess::interprocess_mutex mutex_wait_;
|
||||||
|
boost::interprocess::interprocess_condition flag_cond_;
|
||||||
};
|
};
|
||||||
@ -36,11 +36,11 @@ static uint32_t calc_mem_size(ProfinetData_Map& data_settings)
|
|||||||
|
|
||||||
ProfinetData_Map * ProfinetSharedData::Create(std::string mem_name)
|
ProfinetData_Map * ProfinetSharedData::Create(std::string mem_name)
|
||||||
{
|
{
|
||||||
/// Удаляем существубющий кусок памяти
|
/// Если память уже выделена, удаляем
|
||||||
shared_memory_object::remove(mem_name.c_str());
|
shared_memory_object::remove(mem_name.c_str());
|
||||||
|
|
||||||
shmem_ = managed_shared_memory{create_only, mem_name.c_str(), 65536};
|
|
||||||
|
|
||||||
|
shmem_ = managed_shared_memory{create_only, mem_name.c_str(), 65536};
|
||||||
|
mem_name_ = mem_name;
|
||||||
///Создаем данные в разделяемой памяти
|
///Создаем данные в разделяемой памяти
|
||||||
p_profinet_data_ = shmem_.construct<ProfinetData_Map>("ProfinetData_Map")();
|
p_profinet_data_ = shmem_.construct<ProfinetData_Map>("ProfinetData_Map")();
|
||||||
return p_profinet_data_;
|
return p_profinet_data_;
|
||||||
|
|||||||
@ -7,8 +7,14 @@
|
|||||||
#include "../profinet/profinet_data_map.hpp"
|
#include "../profinet/profinet_data_map.hpp"
|
||||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
class ProfinetSharedData {
|
class ProfinetSharedData {
|
||||||
public:
|
public:
|
||||||
|
~ProfinetSharedData() {
|
||||||
|
///Удаляем память
|
||||||
|
//boost::interprocess::shared_memory_object::remove(mem_name_.c_str());
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Выделяыет раздеяемую память под структуру ProfinetData_Map
|
* @brief Выделяыет раздеяемую память под структуру ProfinetData_Map
|
||||||
*
|
*
|
||||||
@ -27,5 +33,5 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
boost::interprocess::managed_shared_memory shmem_;
|
boost::interprocess::managed_shared_memory shmem_;
|
||||||
|
std::string mem_name_;
|
||||||
};
|
};
|
||||||
@ -3,6 +3,8 @@
|
|||||||
#include "../profinet/profinet_data_map.hpp"
|
#include "../profinet/profinet_data_map.hpp"
|
||||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
class ProfinetSharedDataClient {
|
class ProfinetSharedDataClient {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -11,9 +13,29 @@ public:
|
|||||||
* @param mem_name
|
* @param mem_name
|
||||||
*/
|
*/
|
||||||
ProfinetData_Map * Connect(std::string mem_name) {
|
ProfinetData_Map * Connect(std::string mem_name) {
|
||||||
shmem_ = boost::interprocess::managed_shared_memory{boost::interprocess::open_only, mem_name.c_str()};
|
ProfinetData_Map * out{nullptr};
|
||||||
auto mem = shmem_.find<ProfinetData_Map>("ProfinetData_Map");
|
|
||||||
return mem.first;
|
try
|
||||||
|
{
|
||||||
|
shmem_ = boost::interprocess::managed_shared_memory{boost::interprocess::open_only, mem_name.c_str()};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto mem = shmem_.find<ProfinetData_Map>("ProfinetData_Map");
|
||||||
|
out = mem.first;
|
||||||
|
}
|
||||||
|
catch(const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << '\n';
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << '\n';
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
message("log enable")
|
||||||
|
add_definitions(-DLOG_ENABLE)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(SRC_FILES ${SRC_FILES}
|
set(SRC_FILES ${SRC_FILES}
|
||||||
./profinet/profinet.cpp
|
./profinet/profinet.cpp
|
||||||
|
|||||||
@ -42,8 +42,6 @@ using namespace std;
|
|||||||
|
|
||||||
#define FLAGS_AREP_APP_READY 0x00000001
|
#define FLAGS_AREP_APP_READY 0x00000001
|
||||||
|
|
||||||
#define LOG_ENABLE
|
|
||||||
|
|
||||||
#ifdef LOG_ENABLE
|
#ifdef LOG_ENABLE
|
||||||
#define LOG(STR) log_.put(STR)
|
#define LOG(STR) log_.put(STR)
|
||||||
#else
|
#else
|
||||||
@ -234,6 +232,8 @@ bool Profinet::Config(ProfinetSettings& Settings,
|
|||||||
/// Инициализация библиотеки pnet
|
/// Инициализация библиотеки pnet
|
||||||
m_pnet_data.pnet_ptr = pnet_init (&pnet_cfg);
|
m_pnet_data.pnet_ptr = pnet_init (&pnet_cfg);
|
||||||
|
|
||||||
|
p_events_ = &p_data_map->Events;
|
||||||
|
|
||||||
if (m_pnet_data.pnet_ptr == nullptr)
|
if (m_pnet_data.pnet_ptr == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -611,15 +611,16 @@ void Profinet::cyclicIoData()
|
|||||||
|
|
||||||
if (submodule_ptr->m_data_cfg.outsize > 0)
|
if (submodule_ptr->m_data_cfg.outsize > 0)
|
||||||
{
|
{
|
||||||
|
bool data_updated;
|
||||||
/// Копируем данные от контроллера в m_out_data_ptr
|
/// Копируем данные от контроллера в m_out_data_ptr
|
||||||
submodule_ptr->outputGetData( m_pnet_data.pnet_ptr,
|
submodule_ptr->outputGetData( m_pnet_data.pnet_ptr,
|
||||||
m_pnet_data.api,
|
m_pnet_data.api,
|
||||||
slot_ptr->m_slot_nbr,
|
slot_ptr->m_slot_nbr,
|
||||||
subslot_ptr->m_subslot_nbr);
|
subslot_ptr->m_subslot_nbr, data_updated);
|
||||||
|
|
||||||
if (submodule_ptr->isDataUpdated())
|
if (data_updated)
|
||||||
{
|
{
|
||||||
events_.set_flag(EVENT_NEW_CYCLIC_DATA);
|
p_events_->set_flag(EVENT_NEW_CYCLIC_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,7 +628,6 @@ void Profinet::cyclicIoData()
|
|||||||
{
|
{
|
||||||
uint8_t indata_iocs;
|
uint8_t indata_iocs;
|
||||||
uint8_t indata_iops = PNET_IOXS_GOOD;
|
uint8_t indata_iops = PNET_IOXS_GOOD;
|
||||||
//LOG("CYC: Put data to PLC");
|
|
||||||
/**
|
/**
|
||||||
* @brief Отправляем данные подмодуля в ПЛК
|
* @brief Отправляем данные подмодуля в ПЛК
|
||||||
*
|
*
|
||||||
@ -703,7 +703,7 @@ int Profinet::callbackStateInd ( uint32_t arep, pnet_event_values_t event)
|
|||||||
/// Ошибок нет
|
/// Ошибок нет
|
||||||
}
|
}
|
||||||
|
|
||||||
events_.set_flag(EVENT_CONNECTION_ABORT);
|
p_events_->set_flag(EVENT_CONNECTION_ABORT);
|
||||||
|
|
||||||
m_pnet_data.arep = UINT32_MAX;
|
m_pnet_data.arep = UINT32_MAX;
|
||||||
|
|
||||||
@ -748,7 +748,7 @@ int Profinet::callbackStateInd ( uint32_t arep, pnet_event_values_t event)
|
|||||||
else if (event == PNET_EVENT_STARTUP)
|
else if (event == PNET_EVENT_STARTUP)
|
||||||
{
|
{
|
||||||
LOG("callbackStateInd: PNET_EVENT_STARTUP: A connection has been initiated.");
|
LOG("callbackStateInd: PNET_EVENT_STARTUP: A connection has been initiated.");
|
||||||
events_.set_flag(EVENT_CONNECTION_ESTABLISHED);
|
p_events_->set_flag(EVENT_CONNECTION_ESTABLISHED);
|
||||||
}
|
}
|
||||||
else if (event == PNET_EVENT_APPLRDY)
|
else if (event == PNET_EVENT_APPLRDY)
|
||||||
{
|
{
|
||||||
@ -887,7 +887,7 @@ int Profinet::callbackWriteInd ( uint32_t arep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Устанавливаем событие
|
/// Устанавливаем событие
|
||||||
events_.set_flag(EVENT_NEW_PARAM_DATA);
|
p_events_->set_flag(EVENT_NEW_PARAM_DATA);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,8 +15,9 @@
|
|||||||
#include "../log/log.hpp"
|
#include "../log/log.hpp"
|
||||||
#include "../flags/flags.hpp"
|
#include "../flags/flags.hpp"
|
||||||
|
|
||||||
#include "profinet_data_map.hpp"
|
#include "../flags/flags_iface.hpp"
|
||||||
|
|
||||||
|
#include "profinet_data_map.hpp"
|
||||||
|
|
||||||
class Profinet {
|
class Profinet {
|
||||||
public:
|
public:
|
||||||
@ -30,6 +31,8 @@ public:
|
|||||||
|
|
||||||
Profinet();
|
Profinet();
|
||||||
|
|
||||||
|
~Profinet();
|
||||||
|
|
||||||
bool Config(ProfinetSettings& Settings,
|
bool Config(ProfinetSettings& Settings,
|
||||||
ProfinetDeviceSettings& DevSettings,
|
ProfinetDeviceSettings& DevSettings,
|
||||||
ProfinetData_Map * const p_data_map);
|
ProfinetData_Map * const p_data_map);
|
||||||
@ -153,12 +156,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
void Start();
|
void Start();
|
||||||
|
|
||||||
uint32_t EventWait(uint32_t mask) { return events_.wait_flags(mask); }
|
uint32_t EventWait(uint32_t mask) { return p_events_->wait_flags(mask); }
|
||||||
|
|
||||||
void EventClear(uint32_t mask) { events_.clear_flags(mask); }
|
void EventClear(uint32_t mask) { p_events_->clear_flags(mask); }
|
||||||
|
|
||||||
~Profinet();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProfinetServiceData m_pnet_data;
|
ProfinetServiceData m_pnet_data;
|
||||||
|
|
||||||
@ -185,8 +186,7 @@ private:
|
|||||||
|
|
||||||
Flags flags_; /// Внутренние флаги: взаимодействиe между потоком Profinet и потоком стека Pnet
|
Flags flags_; /// Внутренние флаги: взаимодействиe между потоком Profinet и потоком стека Pnet
|
||||||
|
|
||||||
Flags events_; /// Флаги для внешних событий. Это более общие флаги, например флаг получения данных от ПЛК, а в каком подмодуле, уже не уточняется.
|
FlagsIface * p_events_; /// Флаги для внешних событий. Это более общие флаги, например флаг получения данных от ПЛК, а в каком подмодуле, уже не уточняется.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Проверяет наличие слота slot_nbr в конфигурации и возвращает указатель на него
|
* @brief Проверяет наличие слота slot_nbr в конфигурации и возвращает указатель на него
|
||||||
|
|||||||
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "../flags/shared_flags.hpp"
|
#include "../flags/shared_flags.hpp"
|
||||||
#include "../shared_data/shared_data.hpp"
|
#include "../shared_data/shared_data.hpp"
|
||||||
@ -22,7 +20,7 @@ enum ProfinetEvent
|
|||||||
EVENT_CONNECTION_ESTABLISHED = 0x00000001, /// Установлено соединение с ПЛК
|
EVENT_CONNECTION_ESTABLISHED = 0x00000001, /// Установлено соединение с ПЛК
|
||||||
EVENT_NEW_CYCLIC_DATA = 0x00000002, /// Получение новых циклических данных от ПЛК
|
EVENT_NEW_CYCLIC_DATA = 0x00000002, /// Получение новых циклических данных от ПЛК
|
||||||
EVENT_NEW_PARAM_DATA = 0x00000004, /// Новая запись параметра от ПЛК
|
EVENT_NEW_PARAM_DATA = 0x00000004, /// Новая запись параметра от ПЛК
|
||||||
EVENT_CONNECTION_ABORT = 0x00000008; /// Разрыв соединения
|
EVENT_CONNECTION_ABORT = 0x00000008 /// Разрыв соединения
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProfinetData_Parameter {
|
struct ProfinetData_Parameter {
|
||||||
@ -53,7 +51,7 @@ struct ProfinetData_Module {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ProfinetData_Map {
|
struct ProfinetData_Map {
|
||||||
SharedFlags Events; /// События profinet
|
SharedFlags Events; /// События profinet
|
||||||
ProfinetData_Module * p_mods; /// Модули
|
ProfinetData_Module * p_mods; /// Модули
|
||||||
uint32_t mods_nbr; /// Количество модулей
|
uint32_t mods_nbr; /// Количество модулей
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
#include "profinet_parameter.hpp"
|
#include "profinet_parameter.hpp"
|
||||||
|
|
||||||
ProfinetParameter::ProfinetParameter(uint32_t Index, std::string Name, SharedData * p_data) :
|
ProfinetParameter::ProfinetParameter(uint32_t Index, std::string Name, SharedDataIface * p_data) :
|
||||||
index(Index),
|
index(Index),
|
||||||
name(Name),
|
name(Name),
|
||||||
length(p_data->getSize()),
|
length(p_data->Size()),
|
||||||
p_data_(p_data),
|
p_data_(p_data),
|
||||||
read_buf_(nullptr)
|
read_buf_(nullptr)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,13 +4,13 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "../shared_data/shared_data.hpp"
|
#include "../shared_data/shared_data_iface.hpp"
|
||||||
|
|
||||||
|
|
||||||
class ProfinetParameter
|
class ProfinetParameter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<ProfinetParameter> Create(uint32_t Index, std::string Name, SharedData * p_data)
|
static std::shared_ptr<ProfinetParameter> Create(uint32_t Index, std::string Name, SharedDataIface * p_data)
|
||||||
{
|
{
|
||||||
if (p_data == nullptr)
|
if (p_data == nullptr)
|
||||||
{
|
{
|
||||||
@ -20,7 +20,7 @@ public:
|
|||||||
return std::shared_ptr<ProfinetParameter>(new ProfinetParameter(Index, Name, p_data));
|
return std::shared_ptr<ProfinetParameter>(new ProfinetParameter(Index, Name, p_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfinetParameter(uint32_t Index, std::string Name, SharedData * p_data);
|
ProfinetParameter(uint32_t Index, std::string Name, SharedDataIface * p_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Защищенная запись данных параметра
|
* @brief Защищенная запись данных параметра
|
||||||
@ -58,5 +58,5 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<uint8_t[]> read_buf_; ///Буфер данных для передачи его в стек pnet для операции чтения
|
std::shared_ptr<uint8_t[]> read_buf_; ///Буфер данных для передачи его в стек pnet для операции чтения
|
||||||
SharedData * const p_data_; ///Указатель на данные параметра(в разделяемой области)
|
SharedDataIface * const p_data_; ///Указатель на данные параметра(в разделяемой области)
|
||||||
};
|
};
|
||||||
@ -4,8 +4,8 @@
|
|||||||
ProfinetSubmodule::ProfinetSubmodule(uint32_t submodule_id,
|
ProfinetSubmodule::ProfinetSubmodule(uint32_t submodule_id,
|
||||||
std::string submodule_name,
|
std::string submodule_name,
|
||||||
pnet_data_cfg_t& submodule_data_cfg,
|
pnet_data_cfg_t& submodule_data_cfg,
|
||||||
SharedData * inp_data_ptr,
|
SharedDataIface * inp_data_ptr,
|
||||||
SharedData * out_data_ptr) :
|
SharedDataIface * out_data_ptr) :
|
||||||
m_id(submodule_id),
|
m_id(submodule_id),
|
||||||
m_name(submodule_name),
|
m_name(submodule_name),
|
||||||
m_data_cfg(submodule_data_cfg),
|
m_data_cfg(submodule_data_cfg),
|
||||||
@ -19,7 +19,7 @@ ProfinetSubmodule::ProfinetSubmodule(uint32_t submodule_id,
|
|||||||
{
|
{
|
||||||
if (m_data_cfg.outsize && (out_data_ptr_!=nullptr))
|
if (m_data_cfg.outsize && (out_data_ptr_!=nullptr))
|
||||||
{
|
{
|
||||||
if (m_data_cfg.outsize == out_data_ptr_->getSize())
|
if (m_data_cfg.outsize == out_data_ptr_->Size())
|
||||||
{
|
{
|
||||||
out_data_buf_ = std::shared_ptr<uint8_t[]>(new uint8_t[m_data_cfg.outsize]);
|
out_data_buf_ = std::shared_ptr<uint8_t[]>(new uint8_t[m_data_cfg.outsize]);
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ ProfinetSubmodule::ProfinetSubmodule(uint32_t submodule_id,
|
|||||||
|
|
||||||
if (m_data_cfg.insize && (inp_data_ptr_ != nullptr))
|
if (m_data_cfg.insize && (inp_data_ptr_ != nullptr))
|
||||||
{
|
{
|
||||||
if (m_data_cfg.insize == inp_data_ptr_->getSize())
|
if (m_data_cfg.insize == inp_data_ptr_->Size())
|
||||||
{
|
{
|
||||||
inp_data_buf_ = std::shared_ptr<uint8_t[]>(new uint8_t[m_data_cfg.insize]);
|
inp_data_buf_ = std::shared_ptr<uint8_t[]>(new uint8_t[m_data_cfg.insize]);
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ bool ProfinetSubmodule::inputSetData( pnet_t * pnet_ptr,
|
|||||||
bool ProfinetSubmodule::outputGetData( pnet_t * pnet_ptr,
|
bool ProfinetSubmodule::outputGetData( pnet_t * pnet_ptr,
|
||||||
uint32_t api,
|
uint32_t api,
|
||||||
uint16_t slot_nbr,
|
uint16_t slot_nbr,
|
||||||
uint16_t subslot_nbr )
|
uint16_t subslot_nbr, bool& data_update )
|
||||||
{
|
{
|
||||||
bool out = true;
|
bool out = true;
|
||||||
|
|
||||||
@ -102,15 +102,16 @@ bool ProfinetSubmodule::outputGetData( pnet_t * pnet_ptr,
|
|||||||
|
|
||||||
uint16_t outdata_length = m_data_cfg.outsize;
|
uint16_t outdata_length = m_data_cfg.outsize;
|
||||||
uint8_t outdata_iops;
|
uint8_t outdata_iops;
|
||||||
bool updated{false};
|
/**
|
||||||
|
* @brief Флаг data_updated_ устанавливается внутри pnet_output_get_data_and_iops почему-то с задержкой 1 сек.
|
||||||
|
* Поэтому условием новых данных является не равность нулю outdata_length.
|
||||||
|
*/
|
||||||
/// Копируем данные полученные от контроллера
|
/// Копируем данные полученные от контроллера
|
||||||
pnet_output_get_data_and_iops (pnet_ptr,
|
pnet_output_get_data_and_iops (pnet_ptr,
|
||||||
api,
|
api,
|
||||||
slot_nbr,
|
slot_nbr,
|
||||||
subslot_nbr,
|
subslot_nbr,
|
||||||
&updated,
|
&data_updated_,
|
||||||
out_data_buf_.get(),
|
out_data_buf_.get(),
|
||||||
&outdata_length,
|
&outdata_length,
|
||||||
&outdata_iops);
|
&outdata_iops);
|
||||||
@ -120,19 +121,15 @@ bool ProfinetSubmodule::outputGetData( pnet_t * pnet_ptr,
|
|||||||
if ((out_data_ptr_ != nullptr) && (outdata_length == m_data_cfg.outsize))
|
if ((out_data_ptr_ != nullptr) && (outdata_length == m_data_cfg.outsize))
|
||||||
{
|
{
|
||||||
out_data_ptr_->Write(0, out_data_buf_.get(), m_data_cfg.outsize);
|
out_data_ptr_->Write(0, out_data_buf_.get(), m_data_cfg.outsize);
|
||||||
|
data_update = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data_update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_outdata_iops = outdata_iops;
|
m_outdata_iops = outdata_iops;
|
||||||
|
|
||||||
if ((!data_updated_) && (updated == true))
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @brief Устанавливаем флаг новых данных (данные смогут быть такие-же, но флаг все равно установится)
|
|
||||||
* Флаг сбрасывается в функции getDataFromPlc после прочтения данных устройством
|
|
||||||
*/
|
|
||||||
data_updated_ = updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_data_cfg.outsize != outdata_length)
|
if (m_data_cfg.outsize != outdata_length)
|
||||||
{
|
{
|
||||||
/// Неправильная длина данных
|
/// Неправильная длина данных
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "profinet_parameter.hpp"
|
#include "profinet_parameter.hpp"
|
||||||
#include "../shared_data/shared_data.hpp"
|
#include "../shared_data/shared_data_iface.hpp"
|
||||||
|
|
||||||
#include "../../libs/include/pnet_api.h"
|
#include "../../libs/include/pnet_api.h"
|
||||||
|
|
||||||
@ -17,8 +17,8 @@ public:
|
|||||||
static std::shared_ptr<ProfinetSubmodule> Create(uint32_t submodule_id,
|
static std::shared_ptr<ProfinetSubmodule> Create(uint32_t submodule_id,
|
||||||
std::string submodule_name,
|
std::string submodule_name,
|
||||||
pnet_data_cfg_t& submodule_data_cfg,
|
pnet_data_cfg_t& submodule_data_cfg,
|
||||||
SharedData * inp_data_ptr,
|
SharedDataIface * inp_data_ptr,
|
||||||
SharedData * out_data_ptr)
|
SharedDataIface * out_data_ptr)
|
||||||
{
|
{
|
||||||
return std::shared_ptr<ProfinetSubmodule>(new ProfinetSubmodule(submodule_id,
|
return std::shared_ptr<ProfinetSubmodule>(new ProfinetSubmodule(submodule_id,
|
||||||
submodule_name,
|
submodule_name,
|
||||||
@ -30,8 +30,8 @@ public:
|
|||||||
ProfinetSubmodule(uint32_t submodule_id,
|
ProfinetSubmodule(uint32_t submodule_id,
|
||||||
std::string submodule_name,
|
std::string submodule_name,
|
||||||
pnet_data_cfg_t& submodule_data_cfg,
|
pnet_data_cfg_t& submodule_data_cfg,
|
||||||
SharedData * inp_data_ptr,
|
SharedDataIface * inp_data_ptr,
|
||||||
SharedData * out_data_ptr);
|
SharedDataIface * out_data_ptr);
|
||||||
|
|
||||||
bool addParameter(std::shared_ptr<ProfinetParameter>& param);
|
bool addParameter(std::shared_ptr<ProfinetParameter>& param);
|
||||||
|
|
||||||
@ -46,14 +46,10 @@ public:
|
|||||||
bool outputGetData(pnet_t * pnet_ptr,
|
bool outputGetData(pnet_t * pnet_ptr,
|
||||||
uint32_t api,
|
uint32_t api,
|
||||||
uint16_t slot_nbr,
|
uint16_t slot_nbr,
|
||||||
uint16_t subslot_nbr);
|
uint16_t subslot_nbr, bool& data_update);
|
||||||
|
|
||||||
bool isDataUpdated() {
|
bool isDataUpdated() {
|
||||||
bool out{data_updated_};
|
return data_updated_;
|
||||||
|
|
||||||
data_updated_ = false;
|
|
||||||
|
|
||||||
return out;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -76,8 +72,8 @@ private:
|
|||||||
std::shared_ptr<uint8_t[]> out_data_buf_;
|
std::shared_ptr<uint8_t[]> out_data_buf_;
|
||||||
std::shared_ptr<uint8_t[]> inp_data_buf_;
|
std::shared_ptr<uint8_t[]> inp_data_buf_;
|
||||||
|
|
||||||
SharedData * const inp_data_ptr_; /// Входные циклические данные (DEV->PLC)
|
SharedDataIface * const inp_data_ptr_; /// Входные циклические данные (DEV->PLC)
|
||||||
SharedData * const out_data_ptr_; /// Выходные циклические данные (PLC->DEV)
|
SharedDataIface * const out_data_ptr_; /// Выходные циклические данные (PLC->DEV)
|
||||||
|
|
||||||
bool data_updated_;
|
bool data_updated_;
|
||||||
};
|
};
|
||||||
@ -13,7 +13,7 @@ bool SharedData::Init(uint8_t * p_data, uint32_t size)
|
|||||||
p_data_ = p_data;
|
p_data_ = p_data;
|
||||||
size_ = size;
|
size_ = size;
|
||||||
|
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard guard(mutex_);
|
||||||
std::memset(p_data_, 0, size);
|
std::memset(p_data_, 0, size);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -26,7 +26,7 @@ bool SharedData::Write(uint32_t offset_bytes, void * p_data, uint32_t length)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard guard(mutex_);
|
||||||
std::memcpy(p_data_ + offset_bytes, p_data, length);
|
std::memcpy(p_data_ + offset_bytes, p_data, length);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -39,7 +39,7 @@ bool SharedData::Read(uint32_t offset_bytes, void * p_data, uint32_t length)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard guard(mutex_);
|
||||||
std::memcpy(p_data, p_data_ + offset_bytes, length);
|
std::memcpy(p_data, p_data_ + offset_bytes, length);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
||||||
|
#include "shared_data_iface.hpp"
|
||||||
|
|
||||||
class SharedData {
|
class SharedData : public SharedDataIface {
|
||||||
public:
|
public:
|
||||||
SharedData() : p_data_{nullptr}, size_{0} {};
|
SharedData() : p_data_{nullptr}, size_{0} {};
|
||||||
|
|
||||||
bool Init(uint8_t * p_data, uint32_t size);
|
virtual bool Init(uint8_t * p_data, uint32_t size) override;
|
||||||
|
|
||||||
bool Write(uint32_t offset_bytes, void * p_data, uint32_t length);
|
virtual bool Write(uint32_t offset_bytes, void * p_data, uint32_t length) override;
|
||||||
|
|
||||||
bool Read(uint32_t offset_bytes, void * p_data, uint32_t length);
|
virtual bool Read(uint32_t offset_bytes, void * p_data, uint32_t length) override;
|
||||||
|
|
||||||
uint8_t * get() { return p_data_; }
|
virtual uint32_t Size() const override { return size_; }
|
||||||
|
|
||||||
uint32_t getSize() {return size_; };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex mutex_;
|
boost::interprocess::interprocess_mutex mutex_;
|
||||||
uint8_t * p_data_;
|
uint8_t * p_data_;
|
||||||
uint32_t size_;
|
uint32_t size_;
|
||||||
};
|
};
|
||||||
16
src/shared_data/shared_data_iface.hpp
Normal file
16
src/shared_data/shared_data_iface.hpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class SharedDataIface {
|
||||||
|
public:
|
||||||
|
virtual bool Init(uint8_t * p_data, uint32_t size) = 0;
|
||||||
|
|
||||||
|
virtual bool Write(uint32_t offset_bytes, void * p_data, uint32_t length) = 0;
|
||||||
|
|
||||||
|
virtual bool Read(uint32_t offset_bytes, void * p_data, uint32_t length) = 0;
|
||||||
|
|
||||||
|
virtual uint32_t Size() const = 0;
|
||||||
|
|
||||||
|
virtual ~SharedDataIface() {}
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user