2022-07-21 17:00:41 +03:00
|
|
|
|
#include "profinet_submodule.hpp"
|
2022-07-29 09:25:07 +03:00
|
|
|
|
#include <cstring>
|
2022-07-21 17:00:41 +03:00
|
|
|
|
|
2022-07-27 13:39:58 +03:00
|
|
|
|
ProfinetSubmodule::ProfinetSubmodule(uint32_t submodule_id,
|
2022-07-21 17:00:41 +03:00
|
|
|
|
std::string submodule_name,
|
2022-07-29 09:25:07 +03:00
|
|
|
|
pnet_data_cfg_t& submodule_data_cfg) :
|
2022-07-21 17:00:41 +03:00
|
|
|
|
m_id(submodule_id),
|
|
|
|
|
|
m_name(submodule_name),
|
2022-07-26 13:36:54 +03:00
|
|
|
|
m_data_cfg(submodule_data_cfg),
|
2022-07-29 09:25:07 +03:00
|
|
|
|
inp_data_ptr_(nullptr),
|
|
|
|
|
|
out_data_ptr_(nullptr),
|
2022-07-27 09:12:31 +03:00
|
|
|
|
m_indata_iocs(0),
|
|
|
|
|
|
m_outdata_iops(0)
|
2022-07-21 17:00:41 +03:00
|
|
|
|
{
|
2022-07-29 09:25:07 +03:00
|
|
|
|
/// Могут быть подмодули без данных, например DAP
|
|
|
|
|
|
if (m_data_cfg.insize > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
inp_data_ptr_ = std::shared_ptr<uint8_t[]>(new uint8_t[m_data_cfg.insize]);
|
|
|
|
|
|
}
|
2022-07-21 17:00:41 +03:00
|
|
|
|
|
2022-07-29 09:25:07 +03:00
|
|
|
|
if (m_data_cfg.outsize > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
out_data_ptr_ = std::shared_ptr<uint8_t[]>(new uint8_t[m_data_cfg.outsize]);
|
|
|
|
|
|
}
|
2022-07-21 17:00:41 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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];
|
2022-07-29 09:25:07 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|