ProfinetConnector/src/profinet/profinet_submodule.cpp

137 lines
4.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}