ProfinetConnector/src/profinet/profinet_submodule.cpp

137 lines
4.0 KiB
C++
Raw Normal View History

#include "profinet_submodule.hpp"
#include <cstring>
ProfinetSubmodule::ProfinetSubmodule(uint32_t submodule_id,
std::string submodule_name,
pnet_data_cfg_t& submodule_data_cfg) :
m_id(submodule_id),
m_name(submodule_name),
m_data_cfg(submodule_data_cfg),
inp_data_ptr_(nullptr),
out_data_ptr_(nullptr),
m_indata_iocs(0),
m_outdata_iops(0)
{
/// Могут быть подмодули без данных, например DAP
if (m_data_cfg.insize > 0)
{
inp_data_ptr_ = std::shared_ptr<uint8_t[]>(new uint8_t[m_data_cfg.insize]);
}
if (m_data_cfg.outsize > 0)
{
out_data_ptr_ = std::shared_ptr<uint8_t[]>(new uint8_t[m_data_cfg.outsize]);
}
}
bool ProfinetSubmodule::addParameter(std::shared_ptr<ProfinetParameter>& param)
{
auto ret = m_params.emplace(param->index, param);
return ret.second;
}
std::shared_ptr<ProfinetParameter> ProfinetSubmodule::getParameterPtr(uint32_t index)
{
if (!m_params.count(index))
{
return nullptr;
}
return m_params[index];
}
bool ProfinetSubmodule::inputSetData( pnet_t * pnet_ptr,
uint32_t api,
uint16_t slot_nbr,
uint16_t subslot_nbr,
uint8_t iops)
{
std::lock_guard<std::mutex> guard(inp_data_mutex_);
if ((pnet_ptr == nullptr) || (inp_data_ptr_ == nullptr))
{
return false;
}
/// Копируем данные для передачи в ПЛК
pnet_input_set_data_and_iops( pnet_ptr,
api,
slot_nbr,
subslot_nbr,
inp_data_ptr_.get(),
m_data_cfg.insize,
iops);
return true;
}
bool ProfinetSubmodule::outputGetData( pnet_t * pnet_ptr,
uint32_t api,
uint16_t slot_nbr,
uint16_t subslot_nbr )
{
/// Существуют подмодули без данных, например DAP
if ((pnet_ptr == nullptr) || (out_data_ptr_ == nullptr))
{
return false;
}
std::lock_guard<std::mutex> guard(out_data_mutex_);
uint16_t outdata_length = m_data_cfg.outsize;
uint8_t outdata_iops;
bool updated;
/// Копируем данные от полученные от контроллера
pnet_output_get_data_and_iops (pnet_ptr,
api,
slot_nbr,
subslot_nbr,
&updated,
out_data_ptr_.get(),
&outdata_length,
&outdata_iops);
m_outdata_iops = outdata_iops;
data_updated_ = updated;
if (m_data_cfg.outsize != outdata_length)
{
/// Неправильная длина данных
}
else if (outdata_iops == PNET_IOXS_BAD)
{
/// Что-то не так с данными от контроллера
}
return true;
}
bool ProfinetSubmodule::getDataFromPlc(uint8_t * data_ptr)
{
std::lock_guard<std::mutex> guard(out_data_mutex_);
if ((data_ptr == nullptr) || (out_data_ptr_ == nullptr))
{
return false;
}
memcpy(data_ptr, out_data_ptr_.get(), m_data_cfg.outsize);
return true;
}
bool ProfinetSubmodule::putDataToPlc(uint8_t * data_ptr)
{
std::lock_guard<std::mutex> guard(inp_data_mutex_);
if ((data_ptr == nullptr) || (inp_data_ptr_ == nullptr))
{
return false;
}
memcpy(inp_data_ptr_.get(), data_ptr, m_data_cfg.insize);
return true;
}