dev(UML-981): Соединение с контроллером устанавливается.

Однако данные пока до контроллера не доходят.
This commit is contained in:
Vadim Sychev 2022-07-27 13:39:58 +03:00
parent 8f279814df
commit fe8c07e17d
24 changed files with 169 additions and 68 deletions

34
src/flags/flags.hpp Normal file
View File

@ -0,0 +1,34 @@
#pragma once
#include <mutex>
#include <cstdint>
class Flags {
public:
Flags() : flags_{0} {}
void set_flag(uint32_t mask) {
std::lock_guard<std::mutex> guard(mutex_);
flags_ |= mask;
}
uint32_t get_flag(uint32_t mask) {
std::lock_guard<std::mutex> guard(mutex_);
return flags_ & mask;
}
uint32_t get_flags() {
std::lock_guard<std::mutex> guard(mutex_);
return flags_;
}
void clear_flags(uint32_t mask)
{
std::lock_guard<std::mutex> guard(mutex_);
flags_ &= ~mask;
}
private:
uint32_t flags_;
mutable std::mutex mutex_;
};

17
src/log/log.hpp Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <iostream>
#include <string>
class Log {
public:
Log(int log_level) : log_level_(log_level) {}
void put(std::string info) {
if (log_level_ > 0)
std::cout << "log: " << info << std::endl;
}
private:
const int log_level_;
};

View File

@ -2,6 +2,7 @@
#include "../libs/include/pnet_api.h"
#include "profinet.hpp"
#include <thread>
#include <iostream>
#define ECHO_MODULE_ID 0x00000040 /// Идентификатор тестового модуля
#define ECHO_SUBMOD_ID 0x00000140 /// Идентификатор тестового подмодуля
@ -13,25 +14,43 @@ using namespace std;
uint32_t Echo_Gain = 0;
struct EchoData
{
struct EchoData {
uint32_t data_i;
float data_f;
float data_f;
};
union EchoDataMem {
union EchoDataMem
{
EchoData data;
uint8_t mem[sizeof(EchoData)];
uint8_t mem[sizeof(EchoData)];
};
EchoDataMem Echo_inpCycData;
EchoDataMem Echo_outCycData;
uint8_t be_data_inp[sizeof(EchoData)];
void endian_convert_32(uint8_t * p_data)
{
uint8_t tmp = p_data[1];
p_data[1] = p_data[2];
p_data[2] = tmp;
tmp = p_data[0];
p_data[0] = p_data[3];
p_data[3] = tmp;
}
int main(int argc, char * argv[])
{
Echo_inpCycData.data.data_f = 54321.9f; /// Преобразовать в big endian
Echo_inpCycData.data.data_i = 876; /// Преобразовать в big endian
endian_convert_32((uint8_t*)&Echo_inpCycData.data.data_f);
endian_convert_32((uint8_t*)&Echo_inpCycData.data.data_i);
Echo_inpCycData.data.data_f = 0.0f;
Echo_inpCycData.data.data_i = 0;
AppSettings app_settings = {
.EthDevName = "enp6s1",
};
@ -90,15 +109,15 @@ int main(int argc, char * argv[])
* Умножает их на определенное число Gain и передает получившиеся значения обратно в контроллер.
*
*/
/// 1. Создаем тестовый модуль ECHO: module_id = 0x40
/// 1. Создаем тестовый модуль ECHO: module_id = 0x40 (64)
auto echo_module_ptr = make_shared<ProfinetModule>(ECHO_MODULE_ID, "Echo module");
/// 2. Создаем конфигурацию циклических данных подмодуля
pnet_data_cfg_t echo_data_cfg = { PNET_DIR_NO_IO, ECHO_INPUT_DATA_SIZE, ECHO_OUTPUT_DATA_SIZE };
pnet_data_cfg_t echo_data_cfg = { PNET_DIR_IO, ECHO_INPUT_DATA_SIZE, ECHO_OUTPUT_DATA_SIZE };
/// 3. Создаем тестовый подмодуль для модуля ECHO
auto echo_submodule_ptr = make_shared<ProfinetSubmodule>(PNET_SUBMOD_DAP_IDENT,
"DAP Identity 1",
/// 3. Создаем тестовый подмодуль ECHO: submodule_id = 0x140 (320)
auto echo_submodule_ptr = make_shared<ProfinetSubmodule>(ECHO_SUBMOD_ID,
"Echo submodule",
echo_data_cfg,
static_cast<void*>(Echo_inpCycData.mem),
static_cast<void*>(Echo_outCycData.mem));
@ -125,9 +144,12 @@ int main(int argc, char * argv[])
/// Запуск потока Profinet
profinet.Start();
uint32_t ix = 0;
while(1)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
++ix;
std::cout << "tick: " << ix << endl;
}
return 0;

View File

@ -41,6 +41,16 @@ using namespace std;
#define APP_BG_WORKER_THREAD_PRIORITY 5
#define APP_BG_WORKER_THREAD_STACKSIZE 4096 /* bytes */
#define FLAGS_AREP_APP_READY 0x00000001
//#define RELEASE
#ifndef RELEASE
#define LOG(STR) log_.put(STR)
#else
#define LOG(STR)
#endif
static void pnetConfigure(pnet_cfg_t& cfg, ProfinetSettings& Settings, ProfinetDeviceSettings& DevSettings)
{
cfg.tick_us = Settings.ticks_us;
@ -150,8 +160,10 @@ static void pnetConfigure(pnet_cfg_t& cfg, ProfinetSettings& Settings, ProfinetD
Profinet::Profinet() : m_pnet_data({nullptr, 0, UINT32_MAX, 0}),
m_cyclic_io_cnt{0},
m_periodic_stop{false}
m_periodic_stop{false},
log_{1}
{
}
bool Profinet::Config(ProfinetSettings& Settings, ProfinetDeviceSettings& DevSettings)
@ -169,9 +181,7 @@ bool Profinet::Config(ProfinetSettings& Settings, ProfinetDeviceSettings& DevSet
m_run_period_us = Settings.ticks_us;
m_cyclic_io_period_ms = Settings.cyclic_ms;
///TODO Определить что передавать в cb_cfg
///В колбэки pnet передается этот объект
pnet_cfg.cb_arg = static_cast<void*>(this);
utils_pnet_cfg_init_netifs(Settings.EthIface.c_str(),
@ -362,7 +372,12 @@ bool Profinet::addSubslotAndPlugSubmodule(uint16_t slot_nbr,
return false;
}
///4. Проверяем, что конфигурация данных совпадает
if (submodule_ptr->m_id != submodule_id)
{
return false;
}
///4. Проверяем, что конфигурация данных подмодуля совпадает
if ((submodule_ptr->m_data_cfg.data_dir != p_exp_data->data_dir) ||
(submodule_ptr->m_data_cfg.insize != p_exp_data->insize) ||
(submodule_ptr->m_data_cfg.outsize != p_exp_data->outsize))
@ -521,6 +536,13 @@ void Profinet::PeriodicOperations()
/// Ждем время в мкс: ticks_period_us, по умолчанию 1мс
std::this_thread::sleep_for(std::chrono::microseconds(m_run_period_us));
if (flags_.get_flag(FLAGS_AREP_APP_READY))
{
pnet_application_ready (m_pnet_data.pnet_ptr, m_pnet_data.arep_for_appl_ready);
flags_.clear_flags(FLAGS_AREP_APP_READY);
LOG("FLAGS_AREP_APP_READY");
}
/// Вызов cyclic io
if (++m_cyclic_io_cnt >= m_cyclic_io_period_ms)
{
@ -613,6 +635,7 @@ void Profinet::cyclicIoData()
void Profinet::Start()
{
LOG("Waiting PLC connection...");
m_periodic_thread = std::move(std::thread(&Profinet::PeriodicOperations, this));
}
@ -635,6 +658,8 @@ Profinet::~Profinet()
*/
int Profinet::callbackStateInd ( uint32_t arep, pnet_event_values_t event)
{
LOG("callbackStateInd: event = " + std::to_string(event));
uint16_t err_cls = 0; /* Error code 1 */
uint16_t err_code = 0; /* Error code 2 */
const char * error_class_description = "";
@ -642,6 +667,7 @@ int Profinet::callbackStateInd ( uint32_t arep, pnet_event_values_t event)
if (event == PNET_EVENT_ABORT)
{
LOG("callbackStateInd:PNET_EVENT_ABORT");
if (pnet_get_ar_error_codes (m_pnet_data.pnet_ptr, arep, &err_cls, &err_code) == 0)
{
/**
@ -654,12 +680,12 @@ int Profinet::callbackStateInd ( uint32_t arep, pnet_event_values_t event)
/// Ошибок нет
}
/* Only abort AR with correct session key */
///os_event_set (app->main_events, APP_EVENT_ABORT);
}
else if (event == PNET_EVENT_PRMEND)
{
LOG("callbackStateInd:PNET_EVENT_PRMEND");
if (isConnectedToController())
{
/// Если уже были подключены и пришел запрос на еще одно подключение
@ -685,11 +711,13 @@ int Profinet::callbackStateInd ( uint32_t arep, pnet_event_values_t event)
Do not call pnet_application_ready() here as it will affect
the internal stack states */
m_pnet_data.arep_for_appl_ready = arep;
flags_.set_flag(FLAGS_AREP_APP_READY);
///os_event_set (app->main_events, APP_EVENT_READY_FOR_DATA); ///
}
else if (event == PNET_EVENT_DATA)
{
LOG("callbackStateInd:PNET_EVENT_DATA");
/// Стартовал обмен cyclic io
}
return 0;
@ -697,6 +725,7 @@ int Profinet::callbackStateInd ( uint32_t arep, pnet_event_values_t event)
int Profinet::callbackConnectInd ( uint32_t arep, pnet_result_t * p_result)
{
LOG("callbackConnectInd");
/**
* @brief
* Если будет возвращено 0, то соединение будет установлено.
@ -710,6 +739,7 @@ int Profinet::callbackConnectInd ( uint32_t arep, pnet_result_t * p_result)
int Profinet::callbackReleaseInd ( uint32_t arep, pnet_result_t * p_result)
{
LOG("callbackReleaseInd");
/**
* @brief
* Cоединение будет разорвано при любом возвращаемом значении
@ -724,6 +754,7 @@ int Profinet::callbackDcontrolInd ( uint32_t arep,
pnet_control_command_t control_command,
pnet_result_t * p_result)
{
LOG("callbackDcontrolInd");
/**
* @brief
* Можно оставить пустым
@ -733,6 +764,7 @@ int Profinet::callbackDcontrolInd ( uint32_t arep,
int Profinet::callbackCcontrolInd ( uint32_t arep, pnet_result_t * p_result)
{
LOG("callbackCcontrolInd");
/**
* @brief
* Можно оставить пустым
@ -749,6 +781,7 @@ int Profinet::callbackReadInd ( uint32_t arep,
uint16_t * p_read_length,
pnet_result_t * p_result)
{
LOG("callbackReadInd");
///1. Проверяем, что у подмодуля есть параметр с индексом idx
auto param_ptr = getSubmoduleParameter(slot_nbr, subslot_nbr, idx);
@ -787,6 +820,7 @@ int Profinet::callbackWriteInd ( uint32_t arep,
const uint8_t * p_write_data,
pnet_result_t * p_result)
{
LOG("callbackWriteInd");
///1. Проверяем, что у подмодуля есть параметр с индексом idx
auto param_ptr = getSubmoduleParameter(slot_nbr, subslot_nbr, idx);
@ -796,6 +830,7 @@ int Profinet::callbackWriteInd ( uint32_t arep,
p_result->pnio_status.error_decode = PNET_ERROR_DECODE_PNIORW;
p_result->pnio_status.error_code_1 = PNET_ERROR_CODE_1_APP_WRITE_ERROR;
p_result->pnio_status.error_code_2 = 0; /* User specific */
LOG("callbackWriteInd: No such parameter with index " + std::to_string(idx));
return -1;
}
///2. Проверяем корректность длины данных
@ -805,6 +840,7 @@ int Profinet::callbackWriteInd ( uint32_t arep,
p_result->pnio_status.error_decode = PNET_ERROR_DECODE_PNIORW;
p_result->pnio_status.error_code_1 = PNET_ERROR_CODE_1_APP_WRITE_ERROR;
p_result->pnio_status.error_code_2 = 0; /* User specific */
LOG("callbackWriteInd: Wrong data length " + std::to_string(write_length) + ", will be " + std::to_string(param_ptr->length));
return -1;
}
@ -816,11 +852,14 @@ int Profinet::callbackWriteInd ( uint32_t arep,
int Profinet::callbackExpModuleInd ( uint16_t slot, uint32_t module_ident)
{
LOG("callbackExpModuleInd: plug module " + std::to_string(slot) + " -> slot " + std::to_string(module_ident));
bool ret = addSlotAndPlugModule(slot, module_ident);
if (ret == false)
{
return -1;
LOG("Error!");
}
return 0;
@ -832,10 +871,13 @@ int Profinet::callbackExpSubmoduleInd ( uint16_t slot,
uint32_t submodule_id,
const pnet_data_cfg_t * p_exp_data)
{
LOG("callbackExpSubmoduleInd: plug submodule " + std::to_string(submodule_id) + " -> subslot " + std::to_string(subslot));
bool ret = addSubslotAndPlugSubmodule(slot, subslot, module_id, submodule_id, p_exp_data);
if (ret == false)
{
LOG("Error!");
return -1;
}
@ -847,6 +889,7 @@ int Profinet::callbackNewDataStatusInd ( uint32_t arep,
uint8_t changes,
uint8_t data_status)
{
LOG("callbackNewDataStatusInd");
/// Пока ничего не делаем
return 0;
}
@ -857,6 +900,7 @@ int Profinet::callbackAlarmInd ( uint32_t arep,
uint16_t data_usi,
const uint8_t * p_data)
{
LOG("callbackAlarmInd");
/**
* @brief Должен быть ответ pnet_alarm_send_ack
* Пока заглушка
@ -871,24 +915,28 @@ int Profinet::callbackAlarmInd ( uint32_t arep,
int Profinet::callbackAlarmCnf ( uint32_t arep, const pnet_pnio_status_t * p_pnio_status)
{
LOG("callbackAlarmCnf");
/// Пока ничего не делаем
return 0;
}
int Profinet::callbackAlarmAckCnf ( uint32_t arep, int res)
{
LOG("callbackAlarmAckCnf");
/// Пока ничего не делаем
return 0;
}
int Profinet::callbackResetInd ( bool should_reset_application, uint16_t reset_mode)
{
LOG("callbackResetInd");
/// Пока ничего не делаем
return 0;
}
int Profinet::callbackSignalLedInd (bool led_state)
{
LOG("callbackSignalLedInd");
/// Пока ничего не делаем
return 0;
}

View File

@ -11,6 +11,10 @@
#include <atomic>
#include <thread>
#include "../log/log.hpp"
#include "../flags/flags.hpp"
class Profinet {
public:
Profinet();
@ -160,6 +164,12 @@ private:
*/
std::map<uint32_t, std::shared_ptr<ProfinetModule>> m_modules;
Log log_;
Flags flags_;
private:
/**
* @brief Проверяет наличие слота slot_nbr в конфигурации

View File

@ -9,7 +9,5 @@ int profinet_cb_alarm_ack_cnf (
{
Profinet * profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackAlarmAckCnf(arep, res);
return 0;
return profinet_ptr->callbackAlarmAckCnf(arep, res);
}

View File

@ -9,7 +9,5 @@ int profinet_cb_alarm_cnf (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackAlarmCnf(arep, p_pnio_status);
return 0;
return profinet_ptr->callbackAlarmCnf(arep, p_pnio_status);
}

View File

@ -12,7 +12,5 @@ int profinet_cb_alarm_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackAlarmInd(arep, p_alarm_arg, data_len, data_usi, p_data);
return 0;
return profinet_ptr->callbackAlarmInd(arep, p_alarm_arg, data_len, data_usi, p_data);
}

View File

@ -9,7 +9,5 @@ int profinet_cb_ccontrol_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackCcontrolInd(arep, p_result);
return 0;
return profinet_ptr->callbackCcontrolInd(arep, p_result);
}

View File

@ -8,7 +8,5 @@ int profinet_cb_connect_ind( pnet_t * net,
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackConnectInd(arep, p_result);
return 0;
return profinet_ptr->callbackConnectInd(arep, p_result);
}

View File

@ -10,7 +10,5 @@ int profinet_cb_dcontrol_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackDcontrolInd(arep, control_command, p_result);
return 0;
return profinet_ptr->callbackDcontrolInd(arep, control_command, p_result);
}

View File

@ -10,7 +10,5 @@ int profinet_cb_exp_module_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackExpModuleInd(slot, module_ident);
return 0;
return profinet_ptr->callbackExpModuleInd(slot, module_ident);
}

View File

@ -13,7 +13,5 @@ int profinet_cb_exp_submodule_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackExpSubmoduleInd(slot, subslot, module_id, submodule_id, p_exp_data);
return 0;
return profinet_ptr->callbackExpSubmoduleInd(slot, subslot, module_id, submodule_id, p_exp_data);
}

View File

@ -12,7 +12,5 @@ int profinet_cb_new_data_status_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackNewDataStatusInd(arep, crep, changes, data_status);
return 0;
return profinet_ptr->callbackNewDataStatusInd(arep, crep, changes, data_status);
}

View File

@ -16,7 +16,7 @@ int profinet_cb_read_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackReadInd( arep,
return profinet_ptr->callbackReadInd( arep,
slot_nbr,
subslot_nbr,
idx,
@ -24,6 +24,4 @@ int profinet_cb_read_ind (
pp_read_data,
p_read_length,
p_result);
return 0;
}

View File

@ -11,7 +11,5 @@ int profinet_cb_release_ind( pnet_t * net,
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackReleaseInd(arep, p_result);
return 0;
return profinet_ptr->callbackReleaseInd(arep, p_result);
}

View File

@ -9,7 +9,5 @@ int profinet_cb_reset_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackResetInd(should_reset_application, reset_mode);
return 0;
return profinet_ptr->callbackResetInd(should_reset_application, reset_mode);
}

View File

@ -5,7 +5,5 @@ int profinet_cb_signal_led_ind (pnet_t * net, void * arg, bool led_state)
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackSignalLedInd(led_state);
return 0;
return profinet_ptr->callbackSignalLedInd(led_state);
}

View File

@ -9,7 +9,5 @@ int profinet_cb_state_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackStateInd(arep, event);
return 0;
return profinet_ptr->callbackStateInd(arep, event);
}

View File

@ -16,7 +16,7 @@ int profinet_cb_write_ind (
{
Profinet * const profinet_ptr = static_cast<Profinet*>(arg);
profinet_ptr->callbackWriteInd( arep,
return profinet_ptr->callbackWriteInd( arep,
slot_nbr,
subslot_nbr,
idx,
@ -24,6 +24,4 @@ int profinet_cb_write_ind (
write_length,
p_write_data,
p_result);
return 0;
}

View File

@ -59,7 +59,7 @@ std::shared_ptr<ProfinetSubslot> ProfinetSlot::addSubslot(uint16_t subslot_nbr)
}
else
{
subslot_ptr = std::make_shared<ProfinetSubslot>(subslot_nbr);
subslot_ptr = std::make_shared<ProfinetSubslot>(subslot_nbr, m_slot_nbr, m_module_ptr->m_id);
}
if (subslot_ptr != nullptr)

View File

@ -1,6 +1,6 @@
#include "profinet_submodule.hpp"
ProfinetSubmodule::ProfinetSubmodule(uint16_t submodule_id,
ProfinetSubmodule::ProfinetSubmodule(uint32_t submodule_id,
std::string submodule_name,
pnet_data_cfg_t& submodule_data_cfg,
void * const inp_data_ptr,

View File

@ -11,7 +11,7 @@
class ProfinetSubmodule {
public:
ProfinetSubmodule(uint16_t submodule_id,
ProfinetSubmodule(uint32_t submodule_id,
std::string submodule_name,
pnet_data_cfg_t& submodule_data_cfg,
void * const inp_data_ptr,
@ -24,7 +24,7 @@ public:
public:
const uint16_t m_id; /// Идентификатор подмодуля
const uint32_t m_id; /// Идентификатор подмодуля
const std::string m_name; /// Имя подмодуля
const pnet_data_cfg_t m_data_cfg; /// Конфигурация циклических данных подмодуля

View File

@ -12,7 +12,7 @@
class ProfinetSubslot
{
public:
ProfinetSubslot(uint16_t subslot_nbr) : m_subslot_nbr(subslot_nbr) {};
//ProfinetSubslot(uint16_t subslot_nbr) : m_subslot_nbr(subslot_nbr) {};
ProfinetSubslot(uint16_t subslot_nbr, uint16_t slot_nbr, uint32_t module_id);