ProfinetConnector/profinet_test/sample_app/app_utils.h
svad05 c9fe825657 dev(UML-981): Автоматизация сборки
1. Добавил скрипт build.sh - собирает библиотеку pnet и группирует
получившиеся файлы в папку install, туда же помещает библиотеку osal.
Теперь все библиотеки и их заголовки в одном месте, а не распизаны по
папкам в папке build.
2. Добавил проект sample_app в папку profinet_test. Он отвязан от
процесса сборки pnet и использует уже собранную библиотеку из папки
install.
2022-07-12 15:59:03 +02:00

429 lines
12 KiB
C

/*********************************************************************
* _ _ _
* _ __ | |_ _ | | __ _ | |__ ___
* | '__|| __|(_)| | / _` || '_ \ / __|
* | | | |_ _ | || (_| || |_) |\__ \
* |_| \__|(_)|_| \__,_||_.__/ |___/
*
* www.rt-labs.com
* Copyright 2018 rt-labs AB, Sweden.
*
* This software is dual-licensed under GPLv3 and a commercial
* license. See the file LICENSE.md distributed with this software for
* full license information.
********************************************************************/
#ifndef APP_UTILS_H
#define APP_UTILS_H
/**
* @file
* @brief Application utilities and helper functions
*
* Functions for getting string representation of
* P-Net events, error codes and more.
*
* API, slot and subslot administration.
*
* Initialization of P-Net configuration from app_gsdml.h.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "osal.h"
#include "pnal.h"
#include <pnet_api.h>
typedef struct app_utils_netif_name
{
char name[PNET_INTERFACE_NAME_MAX_SIZE];
} app_utils_netif_name_t;
typedef struct app_utils_netif_namelist
{
app_utils_netif_name_t netif[PNET_MAX_PHYSICAL_PORTS + 1];
} app_utils_netif_namelist_t;
/* Forward declaration */
typedef struct app_subslot app_subslot_t;
/**
* Callback for updated cyclic data
*
* @param subslot InOut: Subslot structure
* @param tag InOut: Typically a handle to a submodule
*/
typedef void (*app_utils_cyclic_callback) (app_subslot_t * subslot, void * tag);
/**
* Information of submodule plugged into a subslot.
*
* Note that submodule data is not stored here but must
* be handled by the submodule implementation.
*
* All parameters are initialized by the app_utils_plug_submodule()
* function.
*
* The cyclic_callback is used when app_utils_cyclic_data_poll()
* is called. Typically on the tick event in the main task.
* The \a tag parameter is passed with the cyclic_callback and
* is typically a handle to a submodule on application.
*/
typedef struct app_subslot
{
/** True when the position in the subslot array is occupied */
bool used;
/** True when the subslot is plugged */
bool plugged;
uint16_t slot_nbr;
uint16_t subslot_nbr;
uint32_t submodule_id;
const char * submodule_name;
pnet_data_cfg_t data_cfg;
/** Status indicator from PLC */
uint8_t indata_iocs;
/** Status indicator from PLC */
uint8_t outdata_iops;
/** Callback for cyclic input- or output data, or NULL if not implemented */
app_utils_cyclic_callback cyclic_callback;
void * tag;
} app_subslot_t;
/**
* Information of module plugged into a slot,
* and array of subslots for admin of submodules.
*/
typedef struct app_slot
{
bool plugged;
uint32_t module_id;
const char * name; /** Module name */
/** Subslots. Use a separate index, as the subslot number might be large.
* For example the subslot for DAP port 1 has number 0x8001 */
app_subslot_t subslots[PNET_MAX_SUBSLOTS];
} app_slot_t;
/**
* Profinet API state for application
*
* Used to manage plugged modules into slots (and submodules into subslots).
*/
typedef struct app_api_t
{
uint32_t api_id;
uint32_t arep;
/** Slots. Use slot number as index */
app_slot_t slots[PNET_MAX_SLOTS];
} app_api_t;
/**
* Convert IP address to string
* @param ip In: IP address
* @param outputstring Out: Resulting string buffer. Should have size
* PNAL_INET_ADDRSTR_SIZE.
*/
void app_utils_ip_to_string (pnal_ipaddr_t ip, char * outputstring);
/**
* Get string description of data direction
* @param direction In: Submodule data direction
* @return String represention of data direction
*/
const char * app_utils_submod_dir_to_string (pnet_submodule_dir_t direction);
/**
* Get string description of PNIO producer or consumer status
* @param ioxs In: Producer or consumer status (IOPS/IOCS)
* @return String represention of ioxs (IOPS/IOCS)
*/
const char * app_utils_ioxs_to_string (pnet_ioxs_values_t ioxs);
/**
* Convert MAC address to string
* @param mac In: MAC address
* @param outputstring Out: Resulting string buffer. Should have size
* PNAL_ETH_ADDRSTR_SIZE.
*/
void app_utils_mac_to_string (pnet_ethaddr_t mac, char * outputstring);
/**
* Convert error code to string format
* Only common error codes supported.
* Todo: Add rest of error codes.
*
* @param err_cls In: The error class. See PNET_ERROR_CODE_1_*
* @param err_code In: The error code. See PNET_ERROR_CODE_2_*
* @param err_cls_str Out: The error class string
* @param err_code_str Out: The error code string
*/
void app_utils_get_error_code_strings (
uint16_t err_cls,
uint16_t err_code,
const char ** err_cls_str,
const char ** err_code_str);
/**
* Copy an IP address (as an integer) to a struct
* @param destination_struct Out: Destination
* @param ip In: IP address
*/
void app_utils_copy_ip_to_struct (
pnet_cfg_ip_addr_t * destination_struct,
pnal_ipaddr_t ip);
/**
* Return a string representation of
* the given dcontrol command.
* @param event In: control_command
* @return A string representing the command
*/
const char * app_utils_dcontrol_cmd_to_string (
pnet_control_command_t control_command);
/**
* Return a string representation of the given event.
* @param event In: event
* @return A string representing the event
*/
const char * app_utils_event_to_string (pnet_event_values_t event);
/**
* 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
* @return 0 on success, -1 on error
*/
int app_utils_pnet_cfg_init_netifs (
const char * netif_list_str,
app_utils_netif_namelist_t * if_list,
uint16_t * number_of_ports,
pnet_if_cfg_t * if_cfg);
/**
* Parse a comma separated list of network interfaces and check
* that the number of interfaces match the PNET_MAX_PHYSICAL_PORTS
* configuration.
*
* For a single Ethernet interface, the \a arg_str should consist of
* one name. For two Ethernet interfaces, the \a arg_str should consist of
* three names, as we also need a bridge interface.
*
* Does only consider the number of comma separated names. No check of the
* names themselves are done.
*
* Examples:
* arg_str num_ports
* "eth0" 1
* "eth0,eth1" error (We need a bridge as well)
* "br0,eth0,eth1" 2
*
* @param arg_str In: Network interface list as comma separated,
* terminated string. For example "eth0" or
* "br0,eth0,eth1".
* @param max_port In: PNET_MAX_PHYSICAL_PORTS, passed as argument to
* allow test.
* @param p_if_list Out: List of network interfaces
* @param p_num_ports Out: Resulting number of physical ports
* @return 0 on success
* -1 on error
*/
int app_utils_get_netif_namelist (
const char * arg_str,
uint16_t max_port,
app_utils_netif_namelist_t * p_if_list,
uint16_t * p_num_ports);
/**
* Print network configuration using APP_LOG_INFO().
*
* @param if_cfg In: Network configuration
* @param number_of_ports In: Number of used ports
*/
void app_utils_print_network_config (
pnet_if_cfg_t * if_cfg,
uint16_t number_of_ports);
/**
* Print message if IOXS has changed.
*
* Uses APP_LOG_INFO()
*
* @param subslot In: Subslot
* @param ioxs_str In: String description Producer or Consumer
* @param ioxs_current In: Current status
* @param ioxs_new In: New status
*/
void app_utils_print_ioxs_change (
const app_subslot_t * subslot,
const char * ioxs_str,
uint8_t ioxs_current,
uint8_t ioxs_new);
/**
* Init the p-net configuration to default values.
*
* Most values are picked from app_gsdml.h
*
* Network configuration not initialized.
* This means that \a '.if_cfg' must be set by application.
*
* Use this function to init P-Net configuration before
* before passing config to app_init().
*
* @param pnet_cfg Out: Configuration for use by p-net
* @return 0 if the operation succeeded.
* -1 if an error occurred.
*/
int app_utils_pnet_cfg_init_default (pnet_cfg_t * pnet_cfg);
/**
* Plug application module
*
* This is for the application to remember which slots are
* populated in the p-net stack.
*
* @param p_api InOut: API
* @param slot_nbr In: Slot number
* @param id In: Module identity
* @param name In: Module name
* @return 0 on success, -1 on error
*/
int app_utils_plug_module (
app_api_t * p_api,
uint16_t slot_nbr,
uint32_t id,
const char * name);
/**
* Pull any application module in given slot.
*
* This is for the application to remember which slots are
* populated in the p-net stack.
*
* @param p_api InOut: API
* @param slot_nbr In: Slot number
* @return 0 on success, -1 on error
*/
int app_utils_pull_module (app_api_t * p_api, uint16_t slot_nbr);
/**
* Plug application submodule.
*
* This is for the application to remember which subslots are
* populated in the p-net stack.
*
* @param p_api InOut: API
* @param slot_nbr In: Slot number
* @param subslot_nbr In: Subslot number
* @param submodule_id In: Submodule identity
* @param p_data_cfg In: Data configuration,
* direction, in and out sizes
* @param submodule_name In: Submodule name
* @param cyclic_callback In: Submodule data callback
* @param tag In: Tag passed in cyclic callback
* Typically application or
* submodule handle
* @return Reference to allocated subslot,
* NULL if no free subslot is available. This should
* never happen if application is aligned with p-net state.
*/
app_subslot_t * app_utils_plug_submodule (
app_api_t * p_api,
uint16_t slot_nbr,
uint16_t subslot_nbr,
uint32_t submodule_id,
const pnet_data_cfg_t * p_data_cfg,
const char * submodule_name,
app_utils_cyclic_callback cyclic_callback,
void * tag);
/**
* Unplug any application submodule from given subslot.
*
* This is for the application to remember which subslots are
* populated in the p-net stack.
*
* @param p_api InOut: API
* @param slot_nbr In: Slot number
* @param subslot_nbr In: Subslot number
* @return 0 on success, -1 on error.
*/
int app_utils_pull_submodule (
app_api_t * p_api,
uint16_t slot_nbr,
uint16_t subslot_nbr);
/**
* Trigger data callback for all plugged submodules in all slots.
*
* The callbacks given in \a app_utils_plug_submodule() are used.
*
* @param p_api In: API
*/
void app_utils_cyclic_data_poll (app_api_t * p_api);
/**
* Get subslot application information.
*
* @param p_appdata InOut: Application state.
* @param slot_nbr In: Slot number.
* @param subslot_nbr In: Subslot number. Range 0 - 0x9FFF.
* @return Reference to application subslot,
* NULL if subslot is not found/plugged.
*/
app_subslot_t * app_utils_subslot_get (
app_api_t * p_api,
uint16_t slot_nbr,
uint16_t subslot_nbr);
/**
* Return true if subslot is input.
*
* @param p_subslot In: Reference to subslot.
* @return true if subslot is input or input/output.
* false if not.
*/
bool app_utils_subslot_is_input (const app_subslot_t * p_subslot);
/**
* Return true if subslot is neither input or output.
*
* This is applies for DAP submodules/slots
*
* @param p_subslot In: Reference to subslot.
* @return true if subslot is input or input/output.
* false if not.
*/
bool app_utils_subslot_is_no_io (const app_subslot_t * p_subslot);
/**
* Return true if subslot is output.
*
* @param p_subslot In: Reference to subslot.
* @return true if subslot is output or input/output,
* false if not.
*/
bool app_utils_subslot_is_output (const app_subslot_t * p_subslot);
#ifdef __cplusplus
}
#endif
#endif /* APP_UTILS_H */