2022-07-19 15:29:56 +03:00
# include "profinet.hpp"
# include "profinet_cb_state_ind.hpp"
# include "profinet_cb_connect_ind.hpp"
# include "profinet_cb_release_ind.hpp"
# include "profinet_cb_dcontrol_ind.hpp"
# include "profinet_cb_ccontrol_ind.hpp"
# include "profinet_cb_read_ind.hpp"
# include "profinet_cb_write_ind.hpp"
# include "profinet_cb_exp_module_ind.hpp"
# include "profinet_cb_exp_submodule_ind.hpp"
# include "profinet_cb_new_data_status_ind.hpp"
# include "profinet_cb_alarm_ind.hpp"
# include "profinet_cb_alarm_cnf.hpp"
# include "profinet_cb_alarm_ack_cnf.hpp"
# include "profinet_cb_reset_ind.hpp"
# include "profinet_cb_signal_led_ind.hpp"
# include "utils.h"
# include <cstring>
# include <cstdio>
2022-07-21 10:05:10 +03:00
# include <cstring>
# include <iostream>
2022-07-19 15:29:56 +03:00
using namespace std ;
# define GET_HIGH_BYTE(id) ((id >> 8) & 0xFF)
# define GET_LOW_BYTE(id) (id & 0xFF)
# define APP_MAIN_SLEEPTIME_US 5000 * 1000
# define APP_SNMP_THREAD_PRIORITY 1
# define APP_SNMP_THREAD_STACKSIZE 256 * 1024 /* bytes */
# define APP_ETH_THREAD_PRIORITY 10
# define APP_ETH_THREAD_STACKSIZE 4096 /* bytes */
# define APP_BG_WORKER_THREAD_PRIORITY 5
# define APP_BG_WORKER_THREAD_STACKSIZE 4096 /* bytes */
static void pnetConfigure ( pnet_cfg_t & cfg , ProfinetSettings & Settings , ProfinetDeviceSettings & DevSettings )
{
cfg . tick_us = Settings . ticks_us ;
cfg . im_0_data . im_vendor_id_hi = GET_HIGH_BYTE ( DevSettings . im_0 . vendor_id ) ;
cfg . im_0_data . im_vendor_id_lo = GET_LOW_BYTE ( DevSettings . im_0 . vendor_id ) ;
cfg . im_0_data . im_hardware_revision = DevSettings . im_0 . hw_revision ;
cfg . im_0_data . im_sw_revision_prefix = DevSettings . im_0 . sw_revision . prefix ;
cfg . im_0_data . im_sw_revision_functional_enhancement = DevSettings . im_0 . sw_revision . functional_enhancement ;
cfg . im_0_data . im_sw_revision_bug_fix = DevSettings . im_0 . sw_revision . bug_fix ;
cfg . im_0_data . im_sw_revision_internal_change = DevSettings . im_0 . sw_revision . internal_change ;
cfg . im_0_data . im_revision_counter = DevSettings . im_0 . revision_counter ;
cfg . im_0_data . im_profile_id = DevSettings . im_0 . profile_id ;
cfg . im_0_data . im_profile_specific_type = DevSettings . im_0 . profile_specific_type ;
cfg . im_0_data . im_version_major = 1 ;
cfg . im_0_data . im_version_minor = 1 ;
cfg . im_0_data . im_supported = DevSettings . im_0 . supported ;
std : : snprintf (
cfg . im_0_data . im_order_id ,
sizeof ( cfg . im_0_data . im_order_id ) ,
" %s " ,
DevSettings . im_0 . order_id . c_str ( ) ) ;
std : : snprintf (
cfg . im_0_data . im_serial_number ,
sizeof ( cfg . im_0_data . im_serial_number ) ,
" %s " ,
DevSettings . im_0 . serial_number . c_str ( ) ) ;
std : : snprintf (
cfg . im_1_data . im_tag_function ,
sizeof ( cfg . im_1_data . im_tag_function ) ,
" %s " ,
DevSettings . im_1 . tag_function . c_str ( ) ) ;
std : : snprintf (
cfg . im_1_data . im_tag_location ,
sizeof ( cfg . im_1_data . im_tag_location ) ,
" %s " ,
DevSettings . im_1 . tag_location . c_str ( ) ) ;
std : : snprintf (
cfg . im_2_data . im_date ,
sizeof ( cfg . im_2_data . im_date ) ,
" %s " ,
DevSettings . im_2 . date . c_str ( ) ) ;
std : : snprintf (
cfg . im_3_data . im_descriptor ,
sizeof ( cfg . im_3_data . im_descriptor ) ,
" %s " ,
DevSettings . im_3 . descriptor . c_str ( ) ) ;
std : : snprintf (
cfg . im_4_data . im_signature ,
sizeof ( cfg . im_4_data . im_signature ) ,
" %s " ,
DevSettings . im_4 . signature . c_str ( ) ) ;
cfg . state_cb = profinet_cb_state_ind ;
cfg . connect_cb = profinet_cb_connect_ind ;
cfg . release_cb = profinet_cb_release_ind ;
cfg . dcontrol_cb = profinet_cb_dcontrol_ind ;
cfg . ccontrol_cb = profinet_cb_ccontrol_ind ;
cfg . read_cb = profinet_cb_read_ind ;
cfg . write_cb = profinet_cb_write_ind ;
cfg . exp_module_cb = profinet_cb_exp_module_ind ;
cfg . exp_submodule_cb = profinet_cb_exp_submodule_ind ;
cfg . new_data_status_cb = profinet_cb_new_data_status_ind ;
cfg . alarm_ind_cb = profinet_cb_alarm_ind ;
cfg . alarm_cnf_cb = profinet_cb_alarm_cnf ;
cfg . alarm_ack_cnf_cb = profinet_cb_alarm_ack_cnf ;
cfg . reset_cb = profinet_cb_reset_ind ;
cfg . signal_led_cb = profinet_cb_signal_led_ind ;
cfg . device_id . vendor_id_hi = GET_HIGH_BYTE ( DevSettings . im_0 . vendor_id ) ;
cfg . device_id . vendor_id_lo = GET_LOW_BYTE ( DevSettings . im_0 . vendor_id ) ;
cfg . device_id . device_id_hi = GET_HIGH_BYTE ( DevSettings . device_id ) ;
cfg . device_id . device_id_lo = GET_LOW_BYTE ( DevSettings . device_id ) ;
cfg . oem_device_id . vendor_id_hi = GET_HIGH_BYTE ( DevSettings . oem_vendor_id ) ;
cfg . oem_device_id . vendor_id_lo = GET_LOW_BYTE ( DevSettings . oem_vendor_id ) ;
cfg . oem_device_id . device_id_hi = GET_HIGH_BYTE ( DevSettings . oem_device_id ) ;
cfg . oem_device_id . device_id_lo = GET_LOW_BYTE ( DevSettings . oem_device_id ) ;
snprintf (
cfg . product_name ,
sizeof ( cfg . product_name ) ,
" %s " ,
DevSettings . product_name . c_str ( ) ) ;
cfg . send_hello = true ;
/* Timing */
cfg . min_device_interval = DevSettings . min_device_interval ;
/* Should be set by application as part of network configuration. */
cfg . num_physical_ports = 1 ;
snprintf (
cfg . station_name ,
sizeof ( cfg . station_name ) ,
" %s " ,
DevSettings . station_name . c_str ( ) ) ;
/* Diagnosis mechanism */
/* We prefer using "Extended channel diagnosis" instead of
* " Qualified channel diagnosis " format on the wire ,
* as this is better supported by Wireshark .
*/
cfg . use_qualified_diagnosis = false ;
}
2022-07-26 13:36:54 +03:00
Profinet : : Profinet ( void ) : m_pnet_data ( { nullptr , 0 , UINT32_MAX } )
2022-07-19 15:29:56 +03:00
{
}
bool Profinet : : Config ( ProfinetSettings & Settings , ProfinetDeviceSettings & DevSettings )
{
2022-07-21 17:00:41 +03:00
bool ret = true ;
2022-07-19 15:29:56 +03:00
pnet_cfg_t pnet_cfg = { 0 } ;
utils_netif_namelist_t netif_name_list ;
uint16_t number_of_ports = 1 ;
pnet_if_cfg_t netif_cfg = { 0 } ;
std : : memset ( & pnet_cfg , 0 , sizeof ( pnet_cfg ) ) ;
pnetConfigure ( pnet_cfg , Settings , DevSettings ) ;
///TODO Определить что передавать в cb_cfg
pnet_cfg . cb_arg = static_cast < void * > ( this ) ;
utils_pnet_cfg_init_netifs ( Settings . EthIface . c_str ( ) ,
& netif_name_list ,
& number_of_ports ,
& netif_cfg ,
0x10 /* Copper 100 Mbit/s Full duplex */
) ;
pnet_cfg . if_cfg = netif_cfg ;
pnet_cfg . num_physical_ports = number_of_ports ;
pnet_cfg . pnal_cfg . snmp_thread . prio = APP_SNMP_THREAD_PRIORITY ;
pnet_cfg . pnal_cfg . snmp_thread . stack_size = APP_SNMP_THREAD_STACKSIZE ;
pnet_cfg . pnal_cfg . eth_recv_thread . prio = APP_ETH_THREAD_PRIORITY ;
pnet_cfg . pnal_cfg . eth_recv_thread . stack_size = APP_ETH_THREAD_STACKSIZE ;
pnet_cfg . pnal_cfg . bg_worker_thread . prio = APP_BG_WORKER_THREAD_PRIORITY ;
pnet_cfg . pnal_cfg . bg_worker_thread . stack_size = APP_BG_WORKER_THREAD_STACKSIZE ;
/// Инициализация библиотеки pnet
m_pnet_data . pnet_ptr = pnet_init ( & pnet_cfg ) ;
if ( m_pnet_data . pnet_ptr = = nullptr )
return false ;
2022-07-21 17:00:41 +03:00
///
pnet_data_cfg_t dap_data_cfg = { PNET_DIR_NO_IO , 0 , 0 } ;
/// Создаем обязательный модуль DAP
auto dap_module = make_shared < ProfinetModule > ( PNET_MOD_DAP_IDENT , " DAP 1 " ) ;
/// Создаем обязательный подмодуль DAP Identity 1
2022-07-26 13:36:54 +03:00
auto dap_submodule_indent_1 = make_shared < ProfinetSubmodule > ( PNET_SUBMOD_DAP_IDENT , " DAP Identity 1 " , dap_data_cfg , nullptr , nullptr ) ;
2022-07-21 17:00:41 +03:00
/// Создаем обязательный подмодуль DAP IFACE1 IDENT
2022-07-26 13:36:54 +03:00
auto dap_submodule_iface_1_indent_1 = make_shared < ProfinetSubmodule > ( PNET_SUBMOD_DAP_INTERFACE_1_IDENT , " DAP IFACE1 IDENT " , dap_data_cfg , nullptr , nullptr ) ;
2022-07-21 17:00:41 +03:00
/// Создаем обязательный подмодуль DAP Port 1
2022-07-26 13:36:54 +03:00
auto dap_subslot_iface_1_port1_ident = make_shared < ProfinetSubmodule > ( PNET_SUBMOD_DAP_INTERFACE_1_PORT_1_IDENT , " DAP Port 1 " , dap_data_cfg , nullptr , nullptr ) ;
2022-07-21 17:00:41 +03:00
/// Добавляем подмодули к модулю
ret & = dap_module - > addSubmodule ( dap_submodule_indent_1 ) ;
ret & = dap_module - > addSubmodule ( dap_submodule_iface_1_indent_1 ) ;
ret & = dap_module - > addSubmodule ( dap_subslot_iface_1_port1_ident ) ;
/// Создаем слот для модуля DAP и доключаем к нему модуль dap_module
ret & = addSlotAndPlugModule ( PNET_SLOT_DAP_IDENT , dap_module ) ;
2022-07-26 13:36:54 +03:00
/// Добавляем подслоты к слоту PNET_SLOT_DAP_IDENT и подключаем к подслотам подмодули
2022-07-21 17:00:41 +03:00
/// 1. Подмодуль "DAP Identity 1"
ret & = addSubslotAndPlugSubmodule ( PNET_SLOT_DAP_IDENT , PNET_SUBSLOT_DAP_IDENT , dap_submodule_indent_1 ) ;
/// 2. Подмодуль "DAP IFACE1 IDENT"
ret & = addSubslotAndPlugSubmodule ( PNET_SLOT_DAP_IDENT , PNET_SUBSLOT_DAP_INTERFACE_1_IDENT , dap_submodule_iface_1_indent_1 ) ;
/// 3. Подмодуль "DAP Port 1"
ret & = addSubslotAndPlugSubmodule ( PNET_SLOT_DAP_IDENT , PNET_SUBSLOT_DAP_INTERFACE_1_PORT_1_IDENT , dap_subslot_iface_1_port1_ident ) ;
2022-07-19 15:29:56 +03:00
2022-07-21 17:00:41 +03:00
return ret ;
2022-07-19 15:29:56 +03:00
}
bool Profinet : : addSlot ( std : : shared_ptr < ProfinetSlot > & slot_ptr )
{
if ( slot_ptr = = nullptr )
return false ;
m_slots [ slot_ptr - > m_slot_nbr ] = slot_ptr ;
return true ;
}
2022-07-21 17:00:41 +03:00
std : : shared_ptr < ProfinetSlot > Profinet : : addSlot ( uint16_t slot_nbr )
{
std : : shared_ptr < ProfinetSlot > slot_ptr ( nullptr ) ;
if ( m_slots . count ( slot_nbr ) )
{
slot_ptr = m_slots [ slot_nbr ] ;
}
else
{
slot_ptr = make_shared < ProfinetSlot > ( slot_nbr ) ;
}
if ( slot_ptr ! = nullptr )
{
m_slots [ slot_nbr ] = slot_ptr ;
}
return slot_ptr ;
}
bool Profinet : : addModule ( std : : shared_ptr < ProfinetModule > & module_ptr )
2022-07-19 15:29:56 +03:00
{
2022-07-21 17:00:41 +03:00
if ( module_ptr = = nullptr )
2022-07-19 15:29:56 +03:00
return false ;
2022-07-21 17:00:41 +03:00
m_modules [ module_ptr - > m_id ] = module_ptr ;
2022-07-19 15:29:56 +03:00
return true ;
2022-07-20 11:25:48 +03:00
}
2022-07-21 17:00:41 +03:00
std : : shared_ptr < ProfinetModule > Profinet : : getModule ( uint32_t module_id )
2022-07-20 11:25:48 +03:00
{
2022-07-21 17:00:41 +03:00
if ( ! m_modules . count ( module_id ) )
{
return nullptr ;
}
return m_modules [ module_id ] ;
}
bool Profinet : : addSlotAndPlugModule ( uint16_t slot_nbr , std : : shared_ptr < ProfinetModule > & module_ptr )
{
auto slot = addSlot ( slot_nbr ) ;
if ( slot = = nullptr )
{
return false ;
}
return slot - > plugModule ( m_pnet_data , module_ptr ) ;
}
bool Profinet : : addSlotAndPlugModule ( uint16_t slot_nbr , uint32_t module_id )
{
/// 1. Проверяем, что module_id поддерживается
auto module_ptr = getModule ( module_id ) ;
if ( module_ptr = = nullptr )
{
return false ;
}
///2. Добавляет слот
auto slot = addSlot ( slot_nbr ) ;
if ( slot = = nullptr )
{
return false ;
}
/// 3. Подключаем модуль к слоту
return slot - > plugModule ( m_pnet_data , module_ptr ) ;
}
bool Profinet : : addSubslotAndPlugSubmodule ( uint16_t slot_nbr , uint16_t subslot_nbr , std : : shared_ptr < ProfinetSubmodule > & submodule_ptr )
{
auto slot_ptr = getSlotPtr ( slot_nbr ) ;
2022-07-21 10:05:10 +03:00
if ( slot_ptr = = nullptr )
2022-07-20 11:25:48 +03:00
{
2022-07-21 17:00:41 +03:00
return false ;
2022-07-20 11:25:48 +03:00
}
2022-07-21 17:00:41 +03:00
auto subslot_ptr = slot_ptr - > addSubslot ( subslot_nbr ) ;
if ( subslot_ptr = = nullptr )
2022-07-20 11:25:48 +03:00
{
2022-07-21 17:00:41 +03:00
return false ;
2022-07-20 11:25:48 +03:00
}
2022-07-21 17:00:41 +03:00
return subslot_ptr - > plugSubmodule ( m_pnet_data , submodule_ptr ) ;
}
bool Profinet : : addSubslotAndPlugSubmodule ( uint16_t slot_nbr ,
uint16_t subslot_nbr ,
uint32_t module_id ,
uint32_t submodule_id ,
const pnet_data_cfg_t * p_exp_data )
{
///1. Проверяем наличие слота
auto slot_ptr = getSlotPtr ( slot_nbr ) ;
if ( slot_ptr = = nullptr )
{
return false ;
}
///2. Проверяем, что к слоту подключен модуль с идентификатором module_id
auto module_ptr = slot_ptr - > getModulePtr ( ) ;
if ( module_ptr = = nullptr )
{
return false ;
}
if ( module_ptr - > m_id ! = module_id )
{
return false ;
}
///3. Проверяем, что в модуль входит подмодуль с идентфикатором submodule_id
auto submodule_ptr = module_ptr - > getSubmodulePtr ( submodule_id ) ;
if ( submodule_ptr = = nullptr )
{
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 ) )
{
return false ;
}
return addSubslotAndPlugSubmodule ( slot_nbr , subslot_nbr , submodule_ptr ) ;
2022-07-20 11:25:48 +03:00
}
2022-07-21 17:00:41 +03:00
std : : shared_ptr < ProfinetSlot > Profinet : : getSlotPtr ( uint16_t slot_nbr )
2022-07-21 10:05:10 +03:00
{
/// 1. Проверить, что слот slot добавлен в конфигурацию
if ( ! m_slots . count ( slot_nbr ) )
{
return nullptr ;
}
2022-07-21 17:00:41 +03:00
return m_slots [ slot_nbr ] ;
2022-07-21 10:05:10 +03:00
}
2022-07-21 17:00:41 +03:00
std : : shared_ptr < ProfinetSubslot > Profinet : : getSubslotPtr ( uint16_t slot_nbr , uint16_t subslot_nbr )
2022-07-21 10:05:10 +03:00
{
2022-07-21 17:00:41 +03:00
auto slot_ptr = getSlotPtr ( slot_nbr ) ;
2022-07-21 10:05:10 +03:00
if ( slot_ptr = = nullptr )
{
return nullptr ;
}
return slot_ptr - > getSubslotPtr ( subslot_nbr ) ;
}
2022-07-20 11:25:48 +03:00
2022-07-21 17:00:41 +03:00
std : : shared_ptr < ProfinetParameter > Profinet : : getSubmoduleParameter ( uint16_t slot_nbr , uint16_t subslot_nbr , uint32_t param_index )
{
///1. Проверяем что существует подслот \a subslot_nbr входящий к \a slot_nbr
auto subslot_ptr = getSubslotPtr ( slot_nbr , subslot_nbr ) ;
if ( subslot_ptr = = nullptr )
{
return nullptr ;
}
///2. Проверяем что к подслоту \a subslot_nbr подключен подмодуль
auto submodule_ptr = subslot_ptr - > getSubmodulePtr ( ) ;
if ( submodule_ptr = = nullptr )
{
return nullptr ;
}
///3. Проверяем, что у подмодуля есть параметр с индексом idx
auto param_ptr = submodule_ptr - > getParameterPtr ( param_index ) ;
if ( param_ptr = = nullptr )
{
return nullptr ;
}
return param_ptr ;
}
2022-07-26 13:36:54 +03:00
void Profinet : : initDataAndIoxs ( )
{
uint8_t indata_iops ;
/**
* И т е р и р у е м с я п о в с е м с л о т а м .
* Е с л и с л о т ы е с т ь , т о и м о д у л и к н и м у ж е п о д к л ю ч е н ы , т . к . э т о д е л а е т к о н т р о л л е р .
*/
for ( auto slot : m_slots )
{
shared_ptr < ProfinetSlot > & slot_ptr = slot . second ;
auto & subslots = slot_ptr - > getSubslotsPtr ( ) ;
/// Итерируемся по всем подслотам
for ( auto subslot : subslots )
{
shared_ptr < ProfinetSubslot > & subslot_ptr = subslot . second ;
auto submodule_ptr = subslot_ptr - > getSubmodulePtr ( ) ;
/// Н а всякий случай. Вообще если подслоты есть, то и подмодули уже к ним подключены.
if ( submodule_ptr = = nullptr )
continue ;
indata_iops = PNET_IOXS_BAD ;
/**
* @ brief Е с л и д л я п о д м о д у л я с у щ е с т в у ю т в х о д н ы е д а н н ы е ( д а н н ы е о т у с т р о й с т в а к к о н т р о л л е р у ) и л и
* ц и к л и ч е с к и х д а н н ы х н е т ( DAP ) , т о н у ж н о у с т а н о в и т ь с т а т у с IOPS .
* submodule_ptr - > m_data_cfg . data_dir = = PNET_DIR_NO_IO - в о т э т о у с л о в и е н у ж н о д л я у с т а н о в к и с т а т у с а д л я DAP
*/
if ( submodule_ptr - > m_data_cfg . insize > 0 | |
submodule_ptr - > m_data_cfg . data_dir = = PNET_DIR_NO_IO )
{
/// Для данных DAP статус всегда О К
if ( slot_ptr - > m_slot_nbr = = PNET_SLOT_DAP_IDENT )
{
/// Для данных DAP статус О К
indata_iops = PNET_IOXS_GOOD ;
}
else if ( submodule_ptr - > m_data_cfg . insize > 0 )
{
/// Проверка, что данные есть
if ( submodule_ptr - > m_inp_data_ptr ! = nullptr )
{
indata_iops = PNET_IOXS_GOOD ;
}
}
int ret = pnet_input_set_data_and_iops ( m_pnet_data . pnet_ptr ,
m_pnet_data . api ,
slot_ptr - > m_slot_nbr ,
subslot_ptr - > m_subslot_nbr ,
( uint8_t * ) submodule_ptr - > m_inp_data_ptr , /// Указатель на данные
submodule_ptr - > m_data_cfg . insize , /// Размер данных
indata_iops ) ;
/*
* If a submodule is still plugged but not used in current AR ,
* setting the data and IOPS will fail .
* This is not a problem .
* Log message below will only be printed for active submodules .
*/
if ( ret = = 0 )
{
/// Успешно
}
}
/**
* @ brief Е с л и д а н н ы е п о д м о д у л я в к л ю ч а ю т с я в с е б я в ы х о д н ы е д а н н ы е ( д а н н ы е о т к о н т р о л л е р а к у с т р о й с т в у )
* Т о н у ж н о у с т а н о в и т ь д л я н и х с т а т у с IOCS в PNET_IOXS_GOOD .
*
*/
if ( submodule_ptr - > m_data_cfg . outsize > 0 )
{
int ret = pnet_output_set_iocs ( m_pnet_data . pnet_ptr ,
m_pnet_data . api ,
slot_ptr - > m_slot_nbr ,
subslot_ptr - > m_subslot_nbr ,
PNET_IOXS_GOOD ) ;
if ( ret = = 0 )
{
/// Успешно
}
}
}
}
}
2022-07-20 11:25:48 +03:00
/**\
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* Callbacks
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int Profinet : : callbackStateInd ( uint32_t arep , pnet_event_values_t event )
{
2022-07-26 13:36:54 +03:00
uint16_t err_cls = 0 ; /* Error code 1 */
uint16_t err_code = 0 ; /* Error code 2 */
const char * error_class_description = " " ;
const char * error_code_description = " " ;
if ( event = = PNET_EVENT_ABORT )
{
if ( pnet_get_ar_error_codes ( m_pnet_data . pnet_ptr , arep , & err_cls , & err_code ) = = 0 )
{
/**
* @ brief К о д ы о ш и б о к в err_cls и err_code
* TODO : Н у ж н о п е р е д а в а т ь в у п р а в л я ю щ е е п р и л о ж е н и е
*/
}
else
{
/// Ошибок нет
}
/* Only abort AR with correct session key */
///os_event_set (app->main_events, APP_EVENT_ABORT);
}
else if ( event = = PNET_EVENT_PRMEND )
{
if ( isConnectedToController ( ) )
{
/// Если уже были подключены и пришел запрос на еще одно подключение
}
m_pnet_data . arep = arep ;
initDataAndIoxs ( ) ;
( void ) pnet_set_provider_state ( m_pnet_data . pnet_ptr , true ) ;
/**
* @ brief К о с т ы л ь б и б л и о т е к и pnet :
* П о п р а в и л а м Profinet н у ж н о о т в е т и т ь Application ready .
* О д н а к о т у т н е л ь з я в ы з в а т ь pnet_application_ready , т . к . э т о и с п о р т и т
* в н у т р е н н е е с о с т о я н и е с т э к а pnet .
* Э т о н у ж н о д е л а т ь н а с л е д у ю щ е м " тике " .
* С м . о п и с а н и е pnet_application_ready :
* This function must be called after the application has received the pnet_state_ind ( )
* user callback with PNET_EVENT_PRMEND , in order for a connection to be established .
*
*/
/* Send application ready at next tick
Do not call pnet_application_ready ( ) here as it will affect
the internal stack states */
m_pnet_data . arep_for_appl_ready = arep ;
///os_event_set (app->main_events, APP_EVENT_READY_FOR_DATA); ///
}
else if ( event = = PNET_EVENT_DATA )
{
/// Стартовал обмен cyclic io
}
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackConnectInd ( uint32_t arep , pnet_result_t * p_result )
{
2022-07-20 14:21:00 +03:00
/**
2022-07-21 10:05:10 +03:00
* @ brief
2022-07-20 14:21:00 +03:00
* Е с л и б у д е т в о з в р а щ е н о 0 , т о с о е д и н е н и е б у д е т у с т а н о в л е н о .
* Е с л и б у д е т в о з в р а щ е н о з н а ч е н и е о т л и ч н о е о т 0 , т о н е б у д е т , в э т о м с л у ч а е н у ж н о у к а з а т ь p_result .
*/
2022-07-21 10:05:10 +03:00
/// Сообщить приложению о б установлении связи с контроллером.
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackReleaseInd ( uint32_t arep , pnet_result_t * p_result )
{
2022-07-21 10:05:10 +03:00
/**
* @ brief
* Cо е дине ние б у д е т р а з о р в а н о п р и л ю б о м в о з в р а щ а е м о м з н а ч е н и и
*/
/// Сообщить приложению о б разрыве связи с контроллером.
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackDcontrolInd ( uint32_t arep ,
pnet_control_command_t control_command ,
pnet_result_t * p_result )
{
2022-07-21 10:05:10 +03:00
/**
* @ brief
* М о ж н о о с т а в и т ь п у с т ы м
*/
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackCcontrolInd ( uint32_t arep , pnet_result_t * p_result )
{
2022-07-21 10:05:10 +03:00
/**
* @ brief
* М о ж н о о с т а в и т ь п у с т ы м
*/
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackReadInd ( uint32_t arep ,
uint16_t slot_nbr ,
uint16_t subslot_nbr ,
uint16_t idx ,
uint16_t sequence_number ,
uint8_t * * pp_read_data ,
uint16_t * p_read_length ,
pnet_result_t * p_result )
2022-07-21 10:05:10 +03:00
{
2022-07-21 17:00:41 +03:00
///1. Проверяем, что у подмодуля есть параметр с индексом idx
auto param_ptr = getSubmoduleParameter ( slot_nbr , subslot_nbr , idx ) ;
2022-07-21 10:05:10 +03:00
if ( param_ptr = = nullptr )
{
p_result - > pnio_status . error_code = PNET_ERROR_CODE_READ ;
p_result - > pnio_status . error_decode = PNET_ERROR_DECODE_PNIORW ;
p_result - > pnio_status . error_code_1 = PNET_ERROR_CODE_1_APP_READ_ERROR ;
p_result - > pnio_status . error_code_2 = 0 ; /* User specific */
return - 1 ;
}
2022-07-21 17:00:41 +03:00
///2. Проверяем корректность длины данных (меньше быть не должно, если больше - это норм)
2022-07-21 10:05:10 +03:00
if ( * p_read_length < param_ptr - > length )
{
p_result - > pnio_status . error_code = PNET_ERROR_CODE_READ ;
p_result - > pnio_status . error_decode = PNET_ERROR_DECODE_PNIORW ;
p_result - > pnio_status . error_code_1 = PNET_ERROR_CODE_1_APP_READ_ERROR ;
p_result - > pnio_status . error_code_2 = 0 ; /* User specific */
return - 1 ;
}
2022-07-21 17:00:41 +03:00
///3. Передаем данные параметра
2022-07-21 10:05:10 +03:00
* pp_read_data = param_ptr - > data_ptr ;
* p_read_length = param_ptr - > length ;
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackWriteInd ( uint32_t arep ,
uint16_t slot_nbr ,
uint16_t subslot_nbr ,
uint16_t idx ,
uint16_t sequence_number ,
uint16_t write_length ,
const uint8_t * p_write_data ,
pnet_result_t * p_result )
2022-07-21 17:00:41 +03:00
{
///1. Проверяем, что у подмодуля есть параметр с индексом idx
auto param_ptr = getSubmoduleParameter ( slot_nbr , subslot_nbr , idx ) ;
2022-07-20 11:25:48 +03:00
2022-07-21 10:05:10 +03:00
if ( param_ptr = = nullptr )
2022-07-21 17:00:41 +03:00
{
2022-07-21 10:05:10 +03:00
p_result - > pnio_status . error_code = PNET_ERROR_CODE_WRITE ;
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 */
return - 1 ;
}
2022-07-21 17:00:41 +03:00
///2. Проверяем корректность длины данных
2022-07-21 10:05:10 +03:00
if ( write_length ! = param_ptr - > length )
{
p_result - > pnio_status . error_code = PNET_ERROR_CODE_WRITE ;
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 */
return - 1 ;
}
2022-07-21 17:00:41 +03:00
///3. Копируем данные
2022-07-21 10:05:10 +03:00
std : : memcpy ( param_ptr - > data_ptr , p_write_data , param_ptr - > length ) ;
return 0 ;
}
2022-07-20 11:25:48 +03:00
int Profinet : : callbackExpModuleInd ( uint16_t slot , uint32_t module_ident )
{
2022-07-21 17:00:41 +03:00
bool ret = addSlotAndPlugModule ( slot , module_ident ) ;
if ( ret = = false )
2022-07-20 11:25:48 +03:00
{
return - 1 ;
}
2022-07-21 17:00:41 +03:00
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackExpSubmoduleInd ( uint16_t slot ,
uint16_t subslot ,
uint32_t module_id ,
uint32_t submodule_id ,
const pnet_data_cfg_t * p_exp_data )
{
2022-07-21 17:00:41 +03:00
bool ret = addSubslotAndPlugSubmodule ( slot , subslot , module_id , submodule_id , p_exp_data ) ;
2022-07-20 11:25:48 +03:00
2022-07-21 17:00:41 +03:00
if ( ret = = false )
2022-07-20 11:25:48 +03:00
{
return - 1 ;
}
return 0 ;
}
int Profinet : : callbackNewDataStatusInd ( uint32_t arep ,
uint32_t crep ,
uint8_t changes ,
uint8_t data_status )
{
2022-07-21 10:05:10 +03:00
/// Пока ничего не делаем
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackAlarmInd ( uint32_t arep ,
const pnet_alarm_argument_t * p_alarm_arg ,
uint16_t data_len ,
uint16_t data_usi ,
const uint8_t * p_data )
{
2022-07-21 10:05:10 +03:00
/**
* @ brief Д о л ж е н б ы т ь о т в е т pnet_alarm_send_ack
* П о к а з а г л у ш к а
*
*/
pnet_pnio_status_t pnio_status = { 0 , 0 , 0 , 0 } ;
pnet_alarm_send_ack ( m_pnet_data . pnet_ptr , arep , p_alarm_arg , & pnio_status ) ;
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackAlarmCnf ( uint32_t arep , const pnet_pnio_status_t * p_pnio_status )
{
2022-07-21 10:05:10 +03:00
/// Пока ничего не делаем
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackAlarmAckCnf ( uint32_t arep , int res )
{
2022-07-21 10:05:10 +03:00
/// Пока ничего не делаем
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackResetInd ( bool should_reset_application , uint16_t reset_mode )
{
2022-07-21 10:05:10 +03:00
/// Пока ничего не делаем
2022-07-20 11:25:48 +03:00
return 0 ;
}
int Profinet : : callbackSignalLedInd ( bool led_state )
{
2022-07-21 10:05:10 +03:00
/// Пока ничего не делаем
2022-07-20 11:25:48 +03:00
return 0 ;
2022-07-19 15:29:56 +03:00
}