| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- /*********************************************************************
- * _ _ _
- * _ __ | |_ _ | | __ _ | |__ ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | | | |_ _ | || (_| || |_) |\__ \
- * |_| \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 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 representation 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 representation of ioxs (IOPS/IOCS)
- */
- const char * app_utils_ioxs_to_string (pnet_ioxs_values_t ioxs);
- /**
- * Get string representation of application subslot in format
- * [slot,subslot,module name]
- * This function has an internal buffer for temp storage
- * of the generated string.
- * @param subslot In: Subslot
- * @return String representation of subslot.
- */
- char * app_utils_get_subslot_string (const app_subslot_t * subslot);
- /**
- * 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 */
|