dev(UML-981): Разработка класса Profinet
1. Разработан классы слота и подслота Profinet 2. Разарботан метод инициализации Profinet с инициализацией обязательного модуля DAP 1 и его подмодулей. Пока все в дрова. В процессе.
This commit is contained in:
parent
714548ef91
commit
f7ced70272
37
src/CMakeLists.txt
Normal file
37
src/CMakeLists.txt
Normal file
@ -0,0 +1,37 @@
|
||||
#********************************************************************
|
||||
# _ _ _
|
||||
# _ __ | |_ _ | | __ _ | |__ ___
|
||||
# | '__|| __|(_)| | / _` || '_ \ / __|
|
||||
# | | | |_ _ | || (_| || |_) |\__ \
|
||||
# |_| \__|(_)|_| \__,_||_.__/ |___/
|
||||
#
|
||||
# http://www.rt-labs.com
|
||||
# Copyright 2017 rt-labs AB, Sweden.
|
||||
# See LICENSE file in the project root for full license information.
|
||||
#*******************************************************************/
|
||||
cmake_minimum_required (VERSION 3.14)
|
||||
|
||||
project (PN_DEV_TEST VERSION 0.0.1)
|
||||
|
||||
set(LIBS_INSTALL_PATH ../libs)
|
||||
set(PNET_PATH ../profinet_stack/p-net)
|
||||
|
||||
include(./utils/utils.cmake)
|
||||
include(./profinet/profinet.cmake)
|
||||
|
||||
add_executable(pn_dev_test
|
||||
./main.cpp ${SRC_FILES})
|
||||
|
||||
target_include_directories(pn_dev_test PRIVATE
|
||||
./
|
||||
${INC_DIRS}
|
||||
${LIBS_INSTALL_PATH}/include
|
||||
${LIBS_INSTALL_PATH}/include/sys
|
||||
${PNET_PATH}/build/src
|
||||
${PNET_PATH}/src
|
||||
${PNET_PATH}/src/ports/linux
|
||||
)
|
||||
|
||||
target_link_directories(pn_dev_test PUBLIC ${LIBS_INSTALL_PATH}/lib)
|
||||
|
||||
target_link_libraries (pn_dev_test PUBLIC profinet osal)
|
8
src/app_settings.hpp
Normal file
8
src/app_settings.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
struct AppSettings
|
||||
{
|
||||
std::string EthDevName; /// Имя адаптера
|
||||
};
|
61
src/main.cpp
Normal file
61
src/main.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "app_settings.hpp"
|
||||
#include "../libs/include/pnet_api.h"
|
||||
#include "profinet.hpp"
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
AppSettings app_settings = {
|
||||
.EthDevName = "enp6s1",
|
||||
};
|
||||
|
||||
ProfinetSettings settings = {
|
||||
.EthIface = "enp6s1",
|
||||
.ticks_us = 1000
|
||||
};
|
||||
|
||||
ProfinetDeviceSettings profinet_settings = {
|
||||
.im_0 = {
|
||||
.vendor_id = 0x0493,
|
||||
.hw_revision = 3,
|
||||
.sw_revision = {
|
||||
.prefix = 'V',
|
||||
.functional_enhancement = 0,
|
||||
.internal_change = 0,
|
||||
.bug_fix = 2
|
||||
},
|
||||
.revision_counter = 0,
|
||||
.profile_id = 0x1234,
|
||||
.profile_specific_type = 0x5678,
|
||||
.supported = (PNET_SUPPORTED_IM1 | PNET_SUPPORTED_IM2 | PNET_SUPPORTED_IM3),
|
||||
.order_id = "12345 Abcdefghijk",
|
||||
.serial_number = "007",
|
||||
},
|
||||
.im_1 = {
|
||||
.tag_function = "my function",
|
||||
.tag_location = "my location"
|
||||
},
|
||||
.im_2 = {
|
||||
.date = "2022-03-01 10:03"
|
||||
},
|
||||
.im_3 = {
|
||||
.descriptor = "my descriptor"
|
||||
},
|
||||
.im_4 = {
|
||||
.signature = ""
|
||||
},
|
||||
.device_id = 0x0002,
|
||||
.oem_vendor_id = 0xcafe,
|
||||
.oem_device_id = 0xee02,
|
||||
.product_name = "P-Net Sample Application",
|
||||
.station_name = "rt-labs-dev",
|
||||
.send_hello = true,
|
||||
.min_device_interval = 32 //1ms ??
|
||||
};
|
||||
|
||||
Profinet profinet;
|
||||
/// Настройка Profinet: Инициализация pnet, добавление DAP слотов и подслотов и подключение к ним модулей и подмодулей
|
||||
if (!profinet.Config(settings, profinet_settings))
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
23
src/profinet/profinet.cmake
Normal file
23
src/profinet/profinet.cmake
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
set(SRC_FILES ${SRC_FILES}
|
||||
./profinet/profinet.cpp
|
||||
./profinet/profinet_cb_alarm_ack_cnf.cpp
|
||||
./profinet/profinet_cb_alarm_cnf.cpp
|
||||
./profinet/profinet_cb_alarm_ind.cpp
|
||||
./profinet/profinet_cb_ccontrol_ind.cpp
|
||||
./profinet/profinet_cb_connect_ind.cpp
|
||||
./profinet/profinet_cb_dcontrol_ind.cpp
|
||||
./profinet/profinet_cb_exp_module_ind.cpp
|
||||
./profinet/profinet_cb_exp_submodule_ind.cpp
|
||||
./profinet/profinet_cb_new_data_status_ind.cpp
|
||||
./profinet/profinet_cb_read_ind.cpp
|
||||
./profinet/profinet_cb_release_ind.cpp
|
||||
./profinet/profinet_cb_reset_ind.cpp
|
||||
./profinet/profinet_cb_signal_led_ind.cpp
|
||||
./profinet/profinet_cb_state_ind.cpp
|
||||
./profinet/profinet_cb_write_ind.cpp
|
||||
./profinet/profinet.cpp
|
||||
./profinet/profinet_slot.cpp
|
||||
./profinet/profinet_subslot.cpp)
|
||||
|
||||
set(INC_DIRS ${INC_DIRS} ./profinet)
|
259
src/profinet/profinet.cpp
Normal file
259
src/profinet/profinet.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
#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>
|
||||
#include <iostream>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Profinet::Profinet(void) : m_pnet_data({nullptr, 0})
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Profinet::Config(ProfinetSettings& Settings, ProfinetDeviceSettings& DevSettings)
|
||||
{
|
||||
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;
|
||||
/**
|
||||
* @brief Создаем стандартный слот для модуля DAP 1 (Device Access Point)
|
||||
* Это обязательный модуль для profinet device
|
||||
*/
|
||||
auto dap_slot = make_shared<ProfinetSlot>(PNET_SLOT_DAP_IDENT, PNET_MOD_DAP_IDENT, "DAP 1");
|
||||
/**
|
||||
* @brief Добавляем слот и подключаем модуль
|
||||
*
|
||||
*/
|
||||
if (!addSlotAndPlugModule(dap_slot))
|
||||
return false;
|
||||
|
||||
pnet_data_cfg_t dap_data_cfg = { PNET_DIR_NO_IO, 0, 0 };
|
||||
|
||||
/**
|
||||
* @brief Создаем стандартный подслот для подмодуля identity 1 который входит в модуль DAP 1
|
||||
* Это обязательный подслот для profinet device
|
||||
*/
|
||||
auto dap_subslot_identity_1 = make_shared<ProfinetSubslot>( PNET_SUBSLOT_DAP_IDENT,
|
||||
PNET_SUBMOD_DAP_IDENT,
|
||||
"DAP Identity 1",
|
||||
dap_data_cfg );
|
||||
/**
|
||||
* @brief Создаем стандартный подслот для подмодуля iface 1 ident который входит в модуль DAP 1
|
||||
* Это обязательный подслот для profinet device
|
||||
*/
|
||||
auto dap_subslot_iface_1_ident = make_shared<ProfinetSubslot>( PNET_SUBSLOT_DAP_INTERFACE_1_IDENT,
|
||||
PNET_SUBMOD_DAP_INTERFACE_1_IDENT,
|
||||
"DAP IFACE1 IDENT",
|
||||
dap_data_cfg );
|
||||
/**
|
||||
* @brief Создаем стандартный подслот для подмодуля iface 1.port 1 ident который входит в модуль DAP 1
|
||||
* Это обязательный подслот для profinet device
|
||||
*/
|
||||
auto dap_subslot_iface_1_port1_ident = make_shared<ProfinetSubslot>( PNET_SUBSLOT_DAP_INTERFACE_1_PORT_1_IDENT,
|
||||
PNET_SUBMOD_DAP_INTERFACE_1_PORT_1_IDENT,
|
||||
"DAP Port 1",
|
||||
dap_data_cfg );
|
||||
/**
|
||||
* @brief Добавляем подслоты в слот и поключаем подмодули в подслоты
|
||||
*
|
||||
*/
|
||||
if (!dap_slot->addSubslotAndPlugSubmodule(m_pnet_data, dap_subslot_identity_1))
|
||||
return false;
|
||||
|
||||
if (!dap_slot->addSubslotAndPlugSubmodule(m_pnet_data, dap_subslot_iface_1_ident))
|
||||
return false;
|
||||
|
||||
if (!dap_slot->addSubslotAndPlugSubmodule(m_pnet_data, dap_subslot_iface_1_port1_ident))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool Profinet::addSlotAndPlugModule(std::shared_ptr<ProfinetSlot>& slot_ptr)
|
||||
{
|
||||
if (!addSlot(slot_ptr))
|
||||
return false;
|
||||
|
||||
if (!slot_ptr->plugModule(m_pnet_data))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
275
src/profinet/profinet.hpp
Normal file
275
src/profinet/profinet.hpp
Normal file
@ -0,0 +1,275 @@
|
||||
#pragma once
|
||||
|
||||
#include "../libs/include/pnet_api.h"
|
||||
#include "profinet_settings.hpp"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "profinet_slot.hpp"
|
||||
#include "profinet_serv_data.hpp"
|
||||
|
||||
class Profinet {
|
||||
public:
|
||||
Profinet();
|
||||
|
||||
bool Config(ProfinetSettings& Settings, ProfinetDeviceSettings& DevSettings);
|
||||
|
||||
bool addSlot(std::shared_ptr<ProfinetSlot>& slot_ptr);
|
||||
|
||||
bool addSlotAndPlugModule(std::shared_ptr<ProfinetSlot>& slot_ptr);
|
||||
|
||||
private:
|
||||
ProfinetServiceData m_pnet_data;
|
||||
/**
|
||||
* @brief Ключ - идентификатор модуля, Значение - структура слота
|
||||
*
|
||||
*/
|
||||
std::map<uint16_t, std::shared_ptr<ProfinetSlot>> m_slots;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
public:
|
||||
/// AREP Application Relationship End Point
|
||||
/**
|
||||
* @brief This application call-back function is called by the Profinet stack on
|
||||
* specific state transitions within the Profinet stack.
|
||||
*
|
||||
* @param arep In: The AREP.
|
||||
* @param event In: The state transition event. See pnet_event_values_t
|
||||
* @return 0 on success. Other values are ignored.
|
||||
*/
|
||||
int callbackStateInd ( uint32_t arep, pnet_event_values_t event);
|
||||
|
||||
/**
|
||||
* @brief This application call-back function is called by the Profinet stack on every
|
||||
* Connect request from the Profinet controller.
|
||||
*
|
||||
* @param arep In: The AREP.
|
||||
* @param p_result Out: Detailed error information if return != 0.
|
||||
* @return 0 on success.
|
||||
* -1 if an error occurred.
|
||||
*/
|
||||
int callbackConnectInd (
|
||||
uint32_t arep,
|
||||
pnet_result_t * p_result);
|
||||
|
||||
/**
|
||||
* @brief This application call-back function is called by the Profinet stack on every
|
||||
* Release request from the Profinet controller.
|
||||
*
|
||||
* @param arep In: The AREP.
|
||||
* @param p_result Out: Detailed error information if return != 0.
|
||||
* @return 0 on success.
|
||||
* -1 if an error occurred.
|
||||
*/
|
||||
int callbackReleaseInd (
|
||||
uint32_t arep,
|
||||
pnet_result_t * p_result);
|
||||
|
||||
/**
|
||||
* @brief This application call-back function is called by the Profinet stack on every
|
||||
* DControl request from the Profinet controller.
|
||||
*
|
||||
* @param net InOut: The p-net stack instance
|
||||
* @param arg InOut: User-defined data (not used by p-net)
|
||||
* @param arep In: The AREP.
|
||||
* @param control_command In: The DControl command code.
|
||||
* @param p_result Out: Detailed error information if return != 0.
|
||||
* @return 0 on success.
|
||||
* -1 if an error occurred.
|
||||
*/
|
||||
int callbackDcontrolInd (
|
||||
uint32_t arep,
|
||||
pnet_control_command_t control_command,
|
||||
pnet_result_t * p_result);
|
||||
|
||||
/**
|
||||
* @brief * This application call-back function is called by the Profinet stack on every
|
||||
* CControl confirmation from the Profinet controller.
|
||||
*
|
||||
* @param arg InOut: User-defined data (not used by p-net)
|
||||
* @param arep In: The AREP.
|
||||
* @param p_result Out: Detailed error information.
|
||||
* @return 0 on success. Other values are ignored.
|
||||
*/
|
||||
int callbackCcontrolCnf (
|
||||
uint32_t arep,
|
||||
pnet_result_t * p_result);
|
||||
/**
|
||||
* @brief This application call-back function is called by the Profinet stack on every
|
||||
* IODRead request from the Profinet controller which specify an
|
||||
* application-specific value of \a idx (0x0000 - 0x7fff). All other values of
|
||||
* \a idx are handled internally by the Profinet stack.
|
||||
*
|
||||
* @param arep In: The AREP.
|
||||
* @param slot In: The slot number.
|
||||
* @param subslot In: The sub-slot number.
|
||||
* @param idx In: The data record index.
|
||||
* @param sequence_number In: The sequence number.
|
||||
* @param pp_read_data Out: A pointer to the binary value.
|
||||
* @param p_read_length InOut: The maximum (in) and actual (out) length in
|
||||
* bytes of the binary value.
|
||||
* @param p_result Out: Detailed error information if returning != 0
|
||||
* @return 0 on success.
|
||||
* -1 if an error occurred.
|
||||
*/
|
||||
int 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);
|
||||
/**
|
||||
* @brief This application call-back function is called by the Profinet stack on every
|
||||
* IODWrite request from the Profinet controller which specify an
|
||||
* application-specific value of \a idx (0x0000 - 0x7fff). All other values of
|
||||
* \a idx are handled internally by the Profinet stack.
|
||||
*
|
||||
* @param arep In: The AREP.
|
||||
* @param slot In: The slot number.
|
||||
* @param subslot In: The sub-slot number.
|
||||
* @param idx In: The data record index.
|
||||
* @param sequence_number In: The sequence number.
|
||||
* @param write_length In: The length in bytes of the binary value.
|
||||
* @param p_write_data In: A pointer to the binary value.
|
||||
* @param p_result Out: Detailed error information if returning != 0
|
||||
* @return 0 on success.
|
||||
* -1 if an error occurred.
|
||||
*/
|
||||
int 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);
|
||||
|
||||
/**
|
||||
* @brief * This application call-back function is called by the Profinet stack to
|
||||
* indicate that the controller has requested the presence of a specific module,
|
||||
* ident number \a module_ident, in the slot number \a slot.
|
||||
*
|
||||
* @param slot
|
||||
* @param module_ident
|
||||
* @return int
|
||||
*/
|
||||
int callbackExpModuleInd (
|
||||
uint16_t slot,
|
||||
uint32_t module_ident);
|
||||
|
||||
/**
|
||||
* @brief This application call-back function is called by the Profinet stack to
|
||||
* indicate that the controller has requested the presence of a specific
|
||||
* sub-module with ident number \a submodule_ident, in the sub-slot number
|
||||
* \a subslot, with module ident number \a module_ident in slot \a slot.
|
||||
*
|
||||
* @param slot In: The slot number.
|
||||
* @param subslot In: The sub-slot number.
|
||||
* @param module_ident In: The module ident number.
|
||||
* @param submodule_ident In: The sub-module ident number.
|
||||
* @param p_exp_data In: The expected data configuration (sizes and
|
||||
* direction)
|
||||
* @return 0 on success.
|
||||
* -1 if an error occurred.
|
||||
*/
|
||||
int callbackExpSubmoduleInd (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t api,
|
||||
uint16_t slot,
|
||||
uint16_t subslot,
|
||||
uint32_t module_id,
|
||||
uint32_t submodule_id,
|
||||
const pnet_data_cfg_t * p_exp_data);
|
||||
|
||||
/**
|
||||
* @brief This application call-back function is called by the Profinet stack to
|
||||
* indicate that the received data status has changed.
|
||||
*
|
||||
* @param arep In: The AREP.
|
||||
* @param crep In: The CREP.
|
||||
* @param changes In: The changed bits in the received data status.
|
||||
* See pnet_data_status_bits_t
|
||||
* @param data_status In: Current received data status (after changes).
|
||||
* See pnet_data_status_bits_t
|
||||
* @return 0 on success. Other values are ignored.
|
||||
*/
|
||||
int callbackNewDataStatusInd (
|
||||
uint32_t arep,
|
||||
uint32_t crep,
|
||||
uint8_t changes,
|
||||
uint8_t data_status);
|
||||
|
||||
/**
|
||||
* @brief This functionality is used for alarms triggered by the IO-controller.
|
||||
*
|
||||
* @param arep In: The AREP.
|
||||
* @param p_alarm_argument In: The alarm argument (with slot, subslot,
|
||||
* alarm_type etc)
|
||||
* @param data_len In: Data length
|
||||
* @param data_usi In: Alarm USI
|
||||
* @param p_data In: Alarm data
|
||||
* @return 0 on success.
|
||||
* Other values are ignored.
|
||||
*/
|
||||
int 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);
|
||||
|
||||
/**
|
||||
* @brief This functionality is used for alarms triggered by the IO-device.
|
||||
*
|
||||
* @param arep In: The AREP.
|
||||
* @param p_pnio_status In: Detailed ACK information.
|
||||
* @return 0 on success. Other values are ignored.
|
||||
*/
|
||||
int callbackAlarmCnf (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
const pnet_pnio_status_t * p_pnio_status);
|
||||
|
||||
/**
|
||||
* @brief This functionality is used for alarms triggered by the IO-controller.
|
||||
*
|
||||
* @param arep In: The AREP.
|
||||
* @param res In: 0 if ACK was received by the remote side.
|
||||
* This is cnf(+).
|
||||
* -1 if ACK was not received by the remote
|
||||
* side. This is cnf(-).
|
||||
* @return 0 on success. Other values are ignored.
|
||||
*/
|
||||
int callbackAlarmAckCnf (
|
||||
uint32_t arep,
|
||||
int res);
|
||||
/**
|
||||
* @brief This application call-back function is called by the Profinet stack on every
|
||||
* reset request (via the DCP "Set" command) from the Profinet controller.
|
||||
*
|
||||
* @param should_reset_application In: True if the user should reset the
|
||||
* application data.
|
||||
* @param reset_mode In: Detailed reset information.
|
||||
* @return 0 on success. Other values are ignored.
|
||||
*/
|
||||
int callbackResetInd (
|
||||
bool should_reset_application,
|
||||
uint16_t reset_mode);
|
||||
|
||||
/**
|
||||
* @brief Use this callback to implement control of the LED.
|
||||
*
|
||||
* @param led_state In: True if the signal LED should be on.
|
||||
* @return 0 on success.
|
||||
* -1 if an error occurred. Will trigger a log message.
|
||||
*/
|
||||
int callbackSignalLedInd (bool led_state);
|
||||
};
|
15
src/profinet/profinet_cb_alarm_ack_cnf.cpp
Normal file
15
src/profinet/profinet_cb_alarm_ack_cnf.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "./profinet/profinet_cb_alarm_ack_cnf.hpp"
|
||||
#include "./profinet/profinet.hpp"
|
||||
|
||||
int profinet_cb_alarm_ack_cnf (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
int res)
|
||||
{
|
||||
Profinet * profinet_ptr = static_cast<Profinet*>(arg);
|
||||
|
||||
profinet_ptr->callbackAlarmAckCnf(arep, res);
|
||||
|
||||
return 0;
|
||||
}
|
9
src/profinet/profinet_cb_alarm_ack_cnf.hpp
Normal file
9
src/profinet/profinet_cb_alarm_ack_cnf.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_alarm_ack_cnf (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
int res);
|
10
src/profinet/profinet_cb_alarm_cnf.cpp
Normal file
10
src/profinet/profinet_cb_alarm_cnf.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "./profinet/profinet_cb_alarm_cnf.hpp"
|
||||
|
||||
int profinet_cb_alarm_cnf (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
const pnet_pnio_status_t * p_pnio_status)
|
||||
{
|
||||
return 0;
|
||||
}
|
9
src/profinet/profinet_cb_alarm_cnf.hpp
Normal file
9
src/profinet/profinet_cb_alarm_cnf.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_alarm_cnf (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
const pnet_pnio_status_t * p_pnio_status);
|
14
src/profinet/profinet_cb_alarm_ind.cpp
Normal file
14
src/profinet/profinet_cb_alarm_ind.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "./profinet/profinet_cb_alarm_ind.hpp"
|
||||
|
||||
int profinet_cb_alarm_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
const pnet_alarm_argument_t * p_alarm_arg,
|
||||
uint16_t data_len,
|
||||
uint16_t data_usi,
|
||||
const uint8_t * p_data)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
12
src/profinet/profinet_cb_alarm_ind.hpp
Normal file
12
src/profinet/profinet_cb_alarm_ind.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_alarm_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
const pnet_alarm_argument_t * p_alarm_arg,
|
||||
uint16_t data_len,
|
||||
uint16_t data_usi,
|
||||
const uint8_t * p_data);
|
11
src/profinet/profinet_cb_ccontrol_ind.cpp
Normal file
11
src/profinet/profinet_cb_ccontrol_ind.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "./profinet/profinet_cb_ccontrol_ind.hpp"
|
||||
|
||||
int profinet_cb_ccontrol_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_result_t * p_result)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
9
src/profinet/profinet_cb_ccontrol_ind.hpp
Normal file
9
src/profinet/profinet_cb_ccontrol_ind.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_ccontrol_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_result_t * p_result);
|
19
src/profinet/profinet_cb_connect_ind.cpp
Normal file
19
src/profinet/profinet_cb_connect_ind.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "./profinet/profinet_cb_connect_ind.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int profinet_cb_connect_ind( pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_result_t * p_result)
|
||||
{
|
||||
cout << "profinet_cb_connect_ind: PLC connect indication. AREP:" << arep << endl;
|
||||
/*
|
||||
* Handle the request on an application level.
|
||||
* This is a very simple application which does not need to handle anything.
|
||||
* All the needed information is in the AR data structure.
|
||||
*/
|
||||
return 0;
|
||||
}
|
8
src/profinet/profinet_cb_connect_ind.hpp
Normal file
8
src/profinet/profinet_cb_connect_ind.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_connect_ind( pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_result_t * p_result);
|
12
src/profinet/profinet_cb_dcontrol_ind.cpp
Normal file
12
src/profinet/profinet_cb_dcontrol_ind.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "./profinet/profinet.hpp"
|
||||
|
||||
int profinet_cb_dcontrol_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_control_command_t control_command,
|
||||
pnet_result_t * p_result)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
10
src/profinet/profinet_cb_dcontrol_ind.hpp
Normal file
10
src/profinet/profinet_cb_dcontrol_ind.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_dcontrol_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_control_command_t control_command,
|
||||
pnet_result_t * p_result);
|
11
src/profinet/profinet_cb_exp_module_ind.cpp
Normal file
11
src/profinet/profinet_cb_exp_module_ind.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "./profinet/profinet_cb_exp_module_ind.hpp"
|
||||
|
||||
int profinet_cb_exp_module_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t api,
|
||||
uint16_t slot,
|
||||
uint32_t module_ident)
|
||||
{
|
||||
return 0;
|
||||
}
|
10
src/profinet/profinet_cb_exp_module_ind.hpp
Normal file
10
src/profinet/profinet_cb_exp_module_ind.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_exp_module_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t api,
|
||||
uint16_t slot,
|
||||
uint32_t module_ident);
|
15
src/profinet/profinet_cb_exp_submodule_ind.cpp
Normal file
15
src/profinet/profinet_cb_exp_submodule_ind.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "./profinet/profinet_cb_exp_submodule_ind.hpp"
|
||||
|
||||
int profinet_cb_exp_submodule_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t api,
|
||||
uint16_t slot,
|
||||
uint16_t subslot,
|
||||
uint32_t module_id,
|
||||
uint32_t submodule_id,
|
||||
const pnet_data_cfg_t * p_exp_data)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
13
src/profinet/profinet_cb_exp_submodule_ind.hpp
Normal file
13
src/profinet/profinet_cb_exp_submodule_ind.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_exp_submodule_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t api,
|
||||
uint16_t slot,
|
||||
uint16_t subslot,
|
||||
uint32_t module_id,
|
||||
uint32_t submodule_id,
|
||||
const pnet_data_cfg_t * p_exp_data);
|
13
src/profinet/profinet_cb_new_data_status_ind.cpp
Normal file
13
src/profinet/profinet_cb_new_data_status_ind.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "./profinet/profinet_cb_new_data_status_ind.hpp"
|
||||
|
||||
int profinet_cb_new_data_status_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
uint32_t crep,
|
||||
uint8_t changes,
|
||||
uint8_t data_status)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
11
src/profinet/profinet_cb_new_data_status_ind.hpp
Normal file
11
src/profinet/profinet_cb_new_data_status_ind.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_new_data_status_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
uint32_t crep,
|
||||
uint8_t changes,
|
||||
uint8_t data_status);
|
19
src/profinet/profinet_cb_read_ind.cpp
Normal file
19
src/profinet/profinet_cb_read_ind.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "./profinet/profinet_cb_read_ind.hpp"
|
||||
|
||||
|
||||
int profinet_cb_read_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
uint32_t api,
|
||||
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)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
16
src/profinet/profinet_cb_read_ind.hpp
Normal file
16
src/profinet/profinet_cb_read_ind.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_read_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
uint32_t api,
|
||||
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);
|
15
src/profinet/profinet_cb_release_ind.cpp
Normal file
15
src/profinet/profinet_cb_release_ind.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "./profinet/profinet_cb_release_ind.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int profinet_cb_release_ind( pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_result_t * p_result)
|
||||
{
|
||||
cout << "profinet_cb_release_ind: PLC release (disconnect) indication. AREP: " << arep << endl;
|
||||
/// По идее погасить светодиод наличия связи
|
||||
return 0;
|
||||
}
|
8
src/profinet/profinet_cb_release_ind.hpp
Normal file
8
src/profinet/profinet_cb_release_ind.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_release_ind( pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_result_t * p_result);
|
11
src/profinet/profinet_cb_reset_ind.cpp
Normal file
11
src/profinet/profinet_cb_reset_ind.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "./profinet/profinet_cb_reset_ind.hpp"
|
||||
|
||||
int profinet_cb_reset_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
bool should_reset_application,
|
||||
uint16_t reset_mode)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
9
src/profinet/profinet_cb_reset_ind.hpp
Normal file
9
src/profinet/profinet_cb_reset_ind.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_reset_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
bool should_reset_application,
|
||||
uint16_t reset_mode);
|
7
src/profinet/profinet_cb_signal_led_ind.cpp
Normal file
7
src/profinet/profinet_cb_signal_led_ind.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "./profinet/profinet_cb_signal_led_ind.hpp"
|
||||
|
||||
int profinet_cb_signal_led_ind (pnet_t * net, void * arg, bool led_state)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
5
src/profinet/profinet_cb_signal_led_ind.hpp
Normal file
5
src/profinet/profinet_cb_signal_led_ind.hpp
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_signal_led_ind (pnet_t * net, void * arg, bool led_state);
|
11
src/profinet/profinet_cb_state_ind.cpp
Normal file
11
src/profinet/profinet_cb_state_ind.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "./profinet/profinet_cb_state_ind.hpp"
|
||||
|
||||
int profinet_cb_state_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_event_values_t event)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
8
src/profinet/profinet_cb_state_ind.hpp
Normal file
8
src/profinet/profinet_cb_state_ind.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_state_ind( pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
pnet_event_values_t event);
|
18
src/profinet/profinet_cb_write_ind.cpp
Normal file
18
src/profinet/profinet_cb_write_ind.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "./profinet/profinet_cb_write_ind.hpp"
|
||||
|
||||
int profinet_cb_write_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
uint32_t api,
|
||||
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)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
16
src/profinet/profinet_cb_write_ind.hpp
Normal file
16
src/profinet/profinet_cb_write_ind.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
int profinet_cb_write_ind (
|
||||
pnet_t * net,
|
||||
void * arg,
|
||||
uint32_t arep,
|
||||
uint32_t api,
|
||||
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);
|
8
src/profinet/profinet_serv_data.hpp
Normal file
8
src/profinet/profinet_serv_data.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
struct ProfinetServiceData {
|
||||
pnet_t * pnet_ptr;
|
||||
uint32_t api; /// Непонятно что это, обязательно посмотреть в коде либы pnet
|
||||
};
|
87
src/profinet/profinet_settings.hpp
Normal file
87
src/profinet/profinet_settings.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
struct ProfinetSettingsSwRevision
|
||||
{
|
||||
/* Allowed: 'V', 'R', 'P', 'U', 'T' */
|
||||
char prefix;
|
||||
uint8_t functional_enhancement;
|
||||
uint8_t bug_fix;
|
||||
uint8_t internal_change;
|
||||
};
|
||||
|
||||
struct ProfinetSettingsIm0
|
||||
{
|
||||
uint16_t vendor_id;
|
||||
|
||||
uint16_t hw_revision;
|
||||
ProfinetSettingsSwRevision sw_revision;
|
||||
|
||||
uint16_t revision_counter;
|
||||
uint16_t profile_id;
|
||||
uint16_t profile_specific_type;
|
||||
/** One bit for each supported I&M1..15. I&M0 is always supported.
|
||||
Use pnet_im_supported_values_t. */
|
||||
uint16_t supported;
|
||||
|
||||
std::string order_id;
|
||||
std::string serial_number;
|
||||
};
|
||||
|
||||
struct ProfinetSettingsIm1
|
||||
{
|
||||
std::string tag_function;
|
||||
std::string tag_location;
|
||||
};
|
||||
|
||||
struct ProfinetSettingsIm2
|
||||
{
|
||||
std::string date;
|
||||
};
|
||||
|
||||
struct ProfinetSettingsIm3
|
||||
{
|
||||
std::string descriptor;
|
||||
};
|
||||
|
||||
struct ProfinetSettingsIm4
|
||||
{
|
||||
std::string signature;
|
||||
};
|
||||
|
||||
struct ProfinetDeviceSettings {
|
||||
/**
|
||||
* Product name
|
||||
*
|
||||
* This is known as DeviceVendorValue and DeviceType in the Profinet
|
||||
* specification. It constitutes the first part of SystemIdentification
|
||||
* (sysDescr in SNMP). It may also be used to construct the Chassis ID.
|
||||
* See IEC CDV 61158-6-10 ch. 4.10.3.3.1.
|
||||
*
|
||||
* Terminated string.
|
||||
*/
|
||||
std::string product_name;
|
||||
/** Default station name.*/
|
||||
std::string station_name;
|
||||
|
||||
ProfinetSettingsIm0 im_0;
|
||||
ProfinetSettingsIm1 im_1;
|
||||
ProfinetSettingsIm2 im_2;
|
||||
ProfinetSettingsIm3 im_3;
|
||||
ProfinetSettingsIm4 im_4;
|
||||
|
||||
uint16_t device_id;
|
||||
uint16_t oem_vendor_id;
|
||||
uint16_t oem_device_id;
|
||||
|
||||
bool send_hello;
|
||||
uint16_t min_device_interval;
|
||||
};
|
||||
|
||||
/// Настройки не зависящие от описания данных Profinet
|
||||
struct ProfinetSettings {
|
||||
uint32_t ticks_us = 1000; /// Устанавливает время в мкс между вызовами pnet_handle_periodic()
|
||||
std::string EthIface = ""; /// Имя интерфейса ethernet
|
||||
};
|
59
src/profinet/profinet_slot.cpp
Normal file
59
src/profinet/profinet_slot.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "profinet_slot.hpp"
|
||||
|
||||
ProfinetSlot::ProfinetSlot ( uint16_t slot_nbr,
|
||||
uint32_t module_id,
|
||||
std::string module_name) : m_slot_nbr(slot_nbr),
|
||||
m_module_id(module_id),
|
||||
m_module_name(module_name)
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ProfinetSlot::pullModule(ProfinetServiceData& pnet_data)
|
||||
{
|
||||
int result = pnet_pull_module (pnet_data.pnet_ptr, pnet_data.api, m_slot_nbr);
|
||||
|
||||
m_module_plugged = false;
|
||||
|
||||
return (result == 0);
|
||||
}
|
||||
|
||||
bool ProfinetSlot::plugModule(ProfinetServiceData& pnet_data)
|
||||
{
|
||||
/// Сначала отключаем модуль
|
||||
pullModule(pnet_data);
|
||||
/// Затем подключаем модуль
|
||||
int result = pnet_plug_module (pnet_data.pnet_ptr, pnet_data.api, m_slot_nbr, m_module_id);
|
||||
|
||||
m_module_plugged = (result == 0);
|
||||
|
||||
return m_module_plugged;
|
||||
}
|
||||
|
||||
bool ProfinetSlot::addSubslot(std::shared_ptr<ProfinetSubslot>& subslot_ptr)
|
||||
{
|
||||
if (subslot_ptr == nullptr)
|
||||
return false;
|
||||
|
||||
subslot_ptr->setSlotNumber(m_slot_nbr);
|
||||
subslot_ptr->setModuleId(m_module_id);
|
||||
|
||||
m_subslots[subslot_ptr->m_submodule_id] = subslot_ptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ProfinetSlot::addSubslotAndPlugSubmodule(ProfinetServiceData& pnet_data, std::shared_ptr<ProfinetSubslot>& subslot_ptr)
|
||||
{
|
||||
if (!addSubslot(subslot_ptr))
|
||||
return false;
|
||||
|
||||
if (!subslot_ptr->plugSubmodule(pnet_data))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
62
src/profinet/profinet_slot.hpp
Normal file
62
src/profinet/profinet_slot.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include "profinet_serv_data.hpp"
|
||||
#include "profinet_subslot.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
class ProfinetSlot
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Profinet Slot object
|
||||
*
|
||||
* @param slot_nbr номер слота
|
||||
* @param module_id идентификатор модуля который может поключиться к этому слоту
|
||||
* @param module_name имя модуля
|
||||
*/
|
||||
ProfinetSlot (
|
||||
uint16_t slot_nbr,
|
||||
uint32_t module_id,
|
||||
std::string module_name
|
||||
);
|
||||
/**
|
||||
* @brief Подключает модуль к слоту
|
||||
*
|
||||
* @param pnet_data Данные pnet
|
||||
* @return true модуль подключен
|
||||
* @return false модуль не подключен
|
||||
*/
|
||||
bool plugModule(ProfinetServiceData& pnet_data);
|
||||
/**
|
||||
* @brief Отключает модуль от слота
|
||||
*
|
||||
* @param pnet_data Данные pnet
|
||||
* @return true модуль был поключен и теперь отключен
|
||||
* @return false модуль не был подключен
|
||||
*/
|
||||
bool pullModule(ProfinetServiceData& pnet_data);
|
||||
|
||||
bool addSubslot(std::shared_ptr<ProfinetSubslot>& subslot_ptr);
|
||||
|
||||
bool addSubslotAndPlugSubmodule(ProfinetServiceData& pnet_data, std::shared_ptr<ProfinetSubslot>& subslot_ptr);
|
||||
|
||||
public:
|
||||
/// Номер слота
|
||||
const uint16_t m_slot_nbr;
|
||||
|
||||
/// Идентификатор модуля который может быть подключен к данному слоту
|
||||
const uint32_t m_module_id;
|
||||
|
||||
/// Имя подключаемого модуля
|
||||
const std::string m_module_name;
|
||||
|
||||
private:
|
||||
/// Флаг подключения модуля к слоту
|
||||
bool m_module_plugged;
|
||||
/// множество подслотов
|
||||
std::map<uint16_t, std::shared_ptr<ProfinetSubslot>> m_subslots;
|
||||
};
|
44
src/profinet/profinet_subslot.cpp
Normal file
44
src/profinet/profinet_subslot.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "profinet_subslot.hpp"
|
||||
|
||||
ProfinetSubslot::ProfinetSubslot(uint16_t subslot_nbr,
|
||||
uint32_t submodule_id,
|
||||
std::string submodule_name,
|
||||
pnet_data_cfg_t data_cfg) :
|
||||
m_subslot_nbr(subslot_nbr),
|
||||
m_submodule_id(submodule_id),
|
||||
m_submodule_name(submodule_name),
|
||||
m_data_cfg(data_cfg),
|
||||
m_submodule_plugged(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ProfinetSubslot::pullSubmodule(ProfinetServiceData& pnet_data)
|
||||
{
|
||||
int result = pnet_pull_submodule (pnet_data.pnet_ptr, pnet_data.api, m_slot_nbr, m_subslot_nbr);
|
||||
|
||||
m_submodule_plugged = false;
|
||||
|
||||
return (result == 0);
|
||||
}
|
||||
|
||||
bool ProfinetSubslot::plugSubmodule(ProfinetServiceData& pnet_data)
|
||||
{
|
||||
/// Сначала отключаем подмодуль
|
||||
pullSubmodule(pnet_data);
|
||||
/// Подключаем подмодуль
|
||||
int result = pnet_plug_submodule (
|
||||
pnet_data.pnet_ptr,
|
||||
pnet_data.api,
|
||||
m_slot_nbr,
|
||||
m_subslot_nbr,
|
||||
m_module_id,
|
||||
m_submodule_id,
|
||||
m_data_cfg.data_dir,
|
||||
m_data_cfg.insize,
|
||||
m_data_cfg.outsize);
|
||||
|
||||
m_submodule_plugged = (result == 0);
|
||||
|
||||
return m_submodule_plugged;
|
||||
}
|
71
src/profinet/profinet_subslot.hpp
Normal file
71
src/profinet/profinet_subslot.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "profinet_serv_data.hpp"
|
||||
#include "../../libs/include/pnet_api.h"
|
||||
|
||||
/**
|
||||
* Callback for updated cyclic data
|
||||
*
|
||||
* @param subslot InOut: Subslot structure
|
||||
* @param tag InOut: Typically a handle to a submodule
|
||||
*/
|
||||
typedef void (*ProfinetSubslotCallback) (ProfinetSubslot * subslot, void * tag);
|
||||
|
||||
class ProfinetSubslot
|
||||
{
|
||||
public:
|
||||
ProfinetSubslot(uint16_t subslot_nbr,
|
||||
uint32_t submodule_id,
|
||||
std::string submodule_name,
|
||||
pnet_data_cfg_t data_cfg);
|
||||
|
||||
bool plugSubmodule(ProfinetServiceData& pnet_data);
|
||||
|
||||
bool pullSubmodule(ProfinetServiceData& pnet_data);
|
||||
|
||||
void setSlotNumber(uint16_t slot_nbr) { m_slot_nbr = slot_nbr; };
|
||||
|
||||
void setModuleId(uint16_t module_id) { m_module_id = module_id; };
|
||||
|
||||
public:
|
||||
/// Номер подслота
|
||||
const uint16_t m_subslot_nbr;
|
||||
|
||||
/// Идентификатор подмодуля который вставлен в данный подслот
|
||||
const uint32_t m_submodule_id;
|
||||
|
||||
/// Имя этого подмодуля
|
||||
const std::string m_submodule_name;
|
||||
|
||||
/// Конфигурация данных подмодуля (направление данных, размер данных)
|
||||
const pnet_data_cfg_t m_data_cfg;
|
||||
|
||||
private:
|
||||
|
||||
/// Флаг подключения подмодуля к подслоту
|
||||
bool m_submodule_plugged;
|
||||
|
||||
/// Номер слота куда входит данный подслот
|
||||
uint16_t m_slot_nbr;
|
||||
|
||||
/// Идентификатор модуля куда входит подключаемый подмодуль
|
||||
uint16_t m_module_id;
|
||||
|
||||
/// iocs = I/O consumer status data (формат данных из pnet_ioxs_values_t)
|
||||
uint8_t m_indata_iocs;
|
||||
|
||||
/// iops = I/O provider status data (формат данных из pnet_ioxs_values_t)
|
||||
uint8_t m_outdata_iops;
|
||||
|
||||
/** Callback for cyclic input- or output data, or NULL if not implemented */
|
||||
ProfinetSubslotCallback m_cyclic_callback;
|
||||
|
||||
/// данные передающиеся в cyclic_callback вторым параметром.
|
||||
void * m_tag;
|
||||
};
|
||||
|
||||
|
||||
|
151
src/utils/utils.c
Normal file
151
src/utils/utils.c
Normal file
@ -0,0 +1,151 @@
|
||||
#include "utils.h"
|
||||
|
||||
static void utils_copy_ip_to_struct (
|
||||
pnet_cfg_ip_addr_t * destination_struct,
|
||||
uint32_t ip)
|
||||
{
|
||||
destination_struct->a = ((ip >> 24) & 0xFF);
|
||||
destination_struct->b = ((ip >> 16) & 0xFF);
|
||||
destination_struct->c = ((ip >> 8) & 0xFF);
|
||||
destination_struct->d = (ip & 0xFF);
|
||||
}
|
||||
|
||||
static int utils_get_netif_namelist (
|
||||
const char * arg_str,
|
||||
uint16_t max_port,
|
||||
utils_netif_namelist_t * p_if_list,
|
||||
uint16_t * p_num_ports)
|
||||
{
|
||||
int ret = 0;
|
||||
uint16_t i = 0;
|
||||
uint16_t j = 0;
|
||||
uint16_t if_index = 0;
|
||||
uint16_t number_of_given_names = 1;
|
||||
uint16_t if_list_size = max_port + 1;
|
||||
char c;
|
||||
|
||||
if (max_port == 0)
|
||||
{
|
||||
printf ("Error: max_port is 0.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset (p_if_list, 0, sizeof (*p_if_list));
|
||||
c = arg_str[i++];
|
||||
while (c != '\0')
|
||||
{
|
||||
if (c != ',')
|
||||
{
|
||||
if (if_index < if_list_size)
|
||||
{
|
||||
p_if_list->netif[if_index].name[j++] = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (if_index < if_list_size)
|
||||
{
|
||||
p_if_list->netif[if_index].name[j++] = '\0';
|
||||
j = 0;
|
||||
if_index++;
|
||||
}
|
||||
number_of_given_names++;
|
||||
}
|
||||
|
||||
c = arg_str[i++];
|
||||
}
|
||||
|
||||
if (max_port == 1 && number_of_given_names > 1)
|
||||
{
|
||||
printf ("Error: Only 1 network interface expected as max_port is 1.\n");
|
||||
return -1;
|
||||
}
|
||||
if (number_of_given_names == 2)
|
||||
{
|
||||
printf ("Error: It is illegal to give 2 interface names. Use 1, or one "
|
||||
"more than the number of physical interfaces.\n");
|
||||
return -1;
|
||||
}
|
||||
if (number_of_given_names > max_port + 1)
|
||||
{
|
||||
printf (
|
||||
"Error: You have given %u interface names, but max is %u as "
|
||||
"PNET_MAX_PHYSICAL_PORTS is %u.\n",
|
||||
number_of_given_names,
|
||||
max_port + 1,
|
||||
max_port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (number_of_given_names == 1)
|
||||
{
|
||||
if (strlen (p_if_list->netif[0].name) == 0)
|
||||
{
|
||||
printf ("Error: Zero length network interface name.\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_if_list->netif[1] = p_if_list->netif[0];
|
||||
*p_num_ports = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < number_of_given_names; i++)
|
||||
{
|
||||
if (strlen (p_if_list->netif[i].name) == 0)
|
||||
{
|
||||
printf ("Error: Zero length network interface name (%d).\n", i);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*p_num_ports = number_of_given_names - 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int utils_pnet_cfg_init_netifs (
|
||||
const char * netif_list_str,
|
||||
utils_netif_namelist_t * if_list,
|
||||
uint16_t * number_of_ports,
|
||||
pnet_if_cfg_t * if_cfg,
|
||||
uint16_t default_mau_type)
|
||||
{
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
uint32_t ip;
|
||||
uint32_t netmask;
|
||||
uint32_t gateway;
|
||||
|
||||
ret = app_utils_get_netif_namelist (
|
||||
netif_list_str,
|
||||
PNET_MAX_PHYSICAL_PORTS,
|
||||
if_list,
|
||||
number_of_ports);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if_cfg->main_netif_name = if_list->netif[0].name;
|
||||
|
||||
for (i = 1; i <= *number_of_ports; i++)
|
||||
{
|
||||
if_cfg->physical_ports[i - 1].netif_name = if_list->netif[i].name;
|
||||
if_cfg->physical_ports[i - 1].default_mau_type = default_mau_type;
|
||||
}
|
||||
|
||||
/* Read IP, netmask, gateway from operating system */
|
||||
ip = pnal_get_ip_address (if_cfg->main_netif_name);
|
||||
netmask = pnal_get_netmask (if_cfg->main_netif_name);
|
||||
gateway = pnal_get_gateway (if_cfg->main_netif_name);
|
||||
|
||||
utils_copy_ip_to_struct (&if_cfg->ip_cfg.ip_addr, ip);
|
||||
utils_copy_ip_to_struct (&if_cfg->ip_cfg.ip_gateway, gateway);
|
||||
utils_copy_ip_to_struct (&if_cfg->ip_cfg.ip_mask, netmask);
|
||||
|
||||
return ret;
|
||||
}
|
3
src/utils/utils.cmake
Normal file
3
src/utils/utils.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
set(SRC_FILES ${SRC_FILES} ./utils/utils.c)
|
||||
set(INC_DIRS ${INC_DIRS} ./utils)
|
46
src/utils/utils.h
Normal file
46
src/utils/utils.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "pnet_api.h"
|
||||
#include "osal.h"
|
||||
|
||||
typedef struct utils_netif_name
|
||||
{
|
||||
char name[PNET_INTERFACE_NAME_MAX_SIZE];
|
||||
} utils_netif_name_t;
|
||||
|
||||
typedef struct utils_netif_namelist
|
||||
{
|
||||
utils_netif_name_t netif[PNET_MAX_PHYSICAL_PORTS + 1];
|
||||
} utils_netif_namelist_t;
|
||||
|
||||
/**
|
||||
* Update network configuration from a string
|
||||
* defining a list of network interfaces examples:
|
||||
* "eth0" or "br0,eth0,eth1"
|
||||
*
|
||||
* Read IP, netmask etc from operating system.
|
||||
*
|
||||
* @param netif_list_str In: Comma separated string of network ifs
|
||||
* @param if_list Out: Array of network ifs
|
||||
* @param number_of_ports Out: Number of ports
|
||||
* @param if_cfg Out: P-Net network configuration to be updated
|
||||
* @param default_mau_type
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int utils_pnet_cfg_init_netifs (
|
||||
const char * netif_list_str,
|
||||
utils_netif_namelist_t * if_list,
|
||||
uint16_t * number_of_ports,
|
||||
pnet_if_cfg_t * if_cfg,
|
||||
uint16_t default_mau_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user