This is an old revision of the document!
The “Connected Motion Reference Design” is a solution that is customizable to fit the needs of an Industrial Ethernet Device. The user may modify the Peripherals and the I/O Application to match the system requirements. The User I/O Application communicates to the Network Application using the Common Interface. This document describes what is contained in the Common Interface and the needed Application Programming Interface (API) calls for an Industrial Ethernet Device.
The Common Interface provides a single Application Programming Interface (API) to adapt, and a precompiled executable that runs as the network application for a given Industrial Ethernet protocol. Because the interface is common, a single user application can be created and operate on any of the supported protocols. The user implements the Common Interface functions in their code as needed to get data to and from the network. The Network Application is treated as a black box; users do not need to worry about the Ethernet aspect of communication.
The developer produces two elements to make up a working device. Configuration Data (created using the Configuration Tool) and an I/O application using other peripherals of the processor or to perform other tasks as required. The Configuration Data is used by the Network Application to map the elements of the I/O application to Industrial Ethernet protocols. The developer modifies the sample application to fit the needs of the device. On the Connected Motion Reference Design, an example workspace which uses sample configuration implements an application that echoes Output Data from the PLC back to the device Input Data which is then sent back to the PLC.
The environment provided uses the freeRTOS in the ADSP-CM408 (CM408) processor. The software in CM408 is open source and has been widely used in many industrial fields. A single thread is made available to the user’s own application, while the others are utilized for management of the lower-level protocols/etc. The development model is similar to writing an application for a standard operating system (e.g. Linux or Windows). Figure 2 shows the major components.
IMAGE HERE
Figure 1 - Device Software Components
The Network Application uses four GPIOs of CM408, MDIO, 16-bit parallel BUS (SMC) and the System Timer to implement the network interface. This leaves the other hardware sources, like GPIOs, Timers, ADC, several external interrupt lines, PWM, UART, SPI, GPIO, I2C and Other ADSP-CM408 peripherals at the disposal of the I/O application.
The Common Interface Software Development Kit (SDK) is distributed as an integrated project compatible with IAR IDE (IAR ARM 8.10 or later). IAR is widely used for ARM core development. This project is the starting point for application development. The provided project is a simple example Common Interface application. Regarding this project, it includes several different components.
NOTE: It is imperative that a user not modify the .icf file that is included in the zip file as it defines the memory map for the Connected Motion Reference Design.
This is a binary application that includes the network protocol implementation and associated protocol stack and interfaces.
This is an application that includes simple data I/O implementation example and users are expected to add their own application layer in this thread. In this application example, there are also .rpc files and a .eds file for EtherNet/IP. The user is expected to modify these files as well to fit the needs of their application.
This zip file also includes several IAR projects. These are not intended to be modified and should just be left as part of the build environment. • libdrv40z • libssl50z • libosal40z_freertos • adsp-cm40x-sms-srv • adsp-cm40x-startup-srv • io-example-srv
This workspace also includes several binary files with include files only so that the user can use the API and be aware of what it is but not modify the source.
The Common Interface is built around a few basic element types used to model an I/O device. • Device – The Common Interface device element is used to define the global parameters for a device with respect to a particular protocol. There can only be one device added per implementation of a user application. • Items – Common Interface items are used to map different pieces and types of I/O from the application to the network interface in use. A user is not limited to just one item but the maximum IO size is limited by several factors including the allowable packet size on a network. Therefore the overall IO data size has a maximum of 1440 bytes. • Baskets – Baskets are a higher-level mechanism used to organize items and devices into consistent groups. A basket will contain exactly one device and any number of items so long as the maximum IO data size is not exceeded.
The sample configuration that is pre-distributed with the Connected Motion Reference Design is as follows:
• Device 400
o Has parameters specific to the protocol in use.
• Item 500 (Digital Inputs and Outputs)
o Input size: 2 bytes o Subindex 1 (2 bytes) o Output size: 2 bytes o Subindex 1 (2 bytes) o Other protocol specific information.
• Item 501 (Analog Inputs and Outputs)
o Input size: 4 bytes o Subindex 1 (2 bytes) o Output size: 4 bytes o Subindex 1 (2 bytes) o Other protocol specific information
• Item 502 (Control Register)
o Input size: 0 bytes o Output size: 2 bytes o Subindex 1 (2 bytes Control Data) o Other protocol specific information.
• Basket 1000 – Contains the following Devices and Items
o Device 400 o Item 500 o Item 501 o Item 502
A Device, in terms of the Common Interface, is a single element that defines a set of protocol- specific parameters used to identify the overall device to the industrial network. The developer assigns a number (16-bits) to each device-type that the application is intended to support (regardless of protocol). The configuration data then defines all information needed to adapt that device to a particular protocol. See Figure 3 below.
The API includes routines to set the current device (set once at initialization), as well as read and write some of the “fields” of the device.
INSERT FIGURE HERE Figure 2 - Common Interface Devices
An item identifies something that can be read or written. This can be a block of cyclic I/O data, a parameterization value (e.g. scale factor), or any number of other purposes. I/O data items will be mapped similarly for the various network protocols, other items can behave differently depending on the protocol. The API includes functions to add items to the device, read and write the data of items, and set and read parameters related to the items.
INSERT FIGURE HERE
Figure 3 - Common Interface Items
Baskets are the simplest element of the Common Interface. They are simply a collection of a Device and one or more Items. They are also not protocol-specific. The API includes a routine to retrieve the contents of a basket. See Figure 5 below.
INSERT FIGURE HERE
Figure 4 - Common Interface Baskets
The user’s application is developed beginning from the thread of IO_IoApplicationThread(), which is created in main() at ..io-example-app\src\IO_main.c as follows:
xTaskCreate(IO_IoApplicationThread, "IO Thread", 2*configMINIMAL_STACK_SIZE, NULL, IO_APP_BASE_PRIORITY, NULL)
This thread will then call an example of the user’s application in io-examlpe—srv\src\io-example.c:
extern int io_example_app() { #ifdef USE_BASKET_CONFIGURATION int i; CI_basket_t *basket_p; #endif int protocolType; int result; unsigned short shortData; static unsigned char largeData[1502]; unsigned int longData; CI_IoStatus_t outputStatus; /* Initialize the Common Interface */ CI_DEBUG("Beginning initialization of the Common Interface...\n"); protocolType = CI_Init(); if (protocolType < 0) { CI_FATAL_ERROR("Error %d initializing Common Interface\n", result); } else { CI_DEBUG("Detected %s Network Protocol\n", GetProtocolString(protocolType)); SetEndianFlag((CI_mode_t)protocolType); } /*********************************************************************/ /************* Configuration using the "basket" method ***************/ CI_DEBUG("Using \"basket\" configuration method\n"); /* Get basket description from demo configuration data */ basket_p = CI_GetBasket(BASE_DEMO_BASKET); /* Set device type from device ID in Basket configuration */ result = CI_SetDeviceType(basket_p->deviceID); if (result != CI_OK) { CI_FATAL_ERROR("Error %d setting device type\n", result); } else { CI_DEBUG("Successfully configured device ID %d\n", basket_p->deviceID); } /* Add each I/O item found in the Basket to the Common Interface run * time configuration, save the "handle" returned by the Common Interface. */ for (i = 0; i < basket_p->itemCount; i++) { itemHandle[i] = CI_AddItem(basket_p->ItemInfo[i].itemID, basket_p->ItemInfo[i].itemLocation, i); if (itemHandle[i] < 0) { CI_FATAL_ERROR("Error %d adding item\n", itemHandle[i]); } else { CI_DEBUG("Successfully configured item ID %d\n", basket_p->ItemInfo[i].itemID); } } /*********************************************************************/ /* Tell the Network Application the configuration is complete */ result = CI_ConfigComplete(100000); if (result != CI_OK) { CI_FATAL_ERROR("Error %d on CI config complete\n", result); } /* Create an event handler thread */ //CI_taskCreateLowPriority(handleEvents, "Event Handler", 4096); if (ospl_TaskCreate((void *)handleEvents, NULL, "IO Event Handler", 2*configMINIMAL_STACK_SIZE, EVENT_HANDLER_BASE_PRIORITY, NULL) != ospl_Success) { CI_FATAL_ERROR("Unable to launch IO event handler\n"); } /* Start the module */ CI_SetSystemStatus(CI_System_OK); /* Print a message on the debug console */ CI_DEBUG("Initialization complete\n\n"); while (1) { #ifdef USING_STANDARD_CONFIG_DATA // test with standard configuration data /*************************************************************************/ /* Read the digital data item */ outputStatus = CI_ReadItem(itemHandle[0], CI_IO_valid, &largeData); if (outputStatus < 0) { CI_FATAL_ERROR("Error %d on call to CI_ReadItem\n", outputStatus); } /* Then, if the data is valid, echo, save, convert and display it */ if (outputStatus == CI_IO_valid) { /* Write (echo) it back to the Controller (exactly as received) */ result = CI_WriteItem(itemHandle[0], CI_IO_valid, &largeData); if (result != CI_OK) { CI_FATAL_ERROR("Error %d on call to CI_WriteItem\n", result); } /* Save the data */ shortData = (unsigned short)(largeData[0] | (largeData[1] << 8)); digitalData = shortData; /* If necessary convert the data */ if (g_endianMode == LITTLE_ENDIAN) { /* fido is big endian so only need to do this for little endian data */ EndianConvertWord(digitalData); } /* Display the data */ // CI_DEBUG("New Digital I/O Data received: 0x%04x\n", digitalData); } #endif …… /*************************************************************************/ /* Read the analog data item */ outputStatus = CI_ReadItem(itemHandle[1], CI_IO_valid, &largeData); if (outputStatus < 0) { CI_FATAL_ERROR("Error %d on call to CI_ReadItem\n", outputStatus); } /* Then, if the data is valid, echo, save, convert and display it */ if (outputStatus == CI_IO_valid) { /* Write (echo) it back to the Controller (exactly as received) */ result = CI_WriteItem(itemHandle[1], CI_IO_valid, &largeData); if (result != CI_OK) { CI_FATAL_ERROR("Error %d on call to CI_WriteItem\n", result); } /* Save the data */ longData = (unsigned int)(largeData[0] | (largeData[1] << 8) | (largeData[2] << 16) | (largeData[3] << 24)); analogData = longData; /* If necessary convert the data */ if (g_endianMode == LITTLE_ENDIAN) { /* fido is big endian so only need to do this for little endian data */ EndianConvertLongWord(analogData); } /* Display the data */ // CI_DEBUG("New Analog I/O Data received: 0x%08x\n", analogData); } /*************************************************************************/ /* Read the control register data item */ outputStatus = CI_ReadItem(itemHandle[2], CI_IO_valid, &largeData); if (outputStatus < 0) { CI_FATAL_ERROR("Error %d on call to CI_ReadItem\n", outputStatus); } /* If the data is valid, save, convert and display it */ if (outputStatus == CI_IO_valid) { /* Save the data */ shortData = (unsigned short)(largeData[0] | (largeData[1] << 8)); controlReg = shortData; /* If necessary convert the data */ if (g_endianMode == LITTLE_ENDIAN) { /* fido is big endian so only need to do this for little endian data */ EndianConvertWord(controlReg); } /* Display the data */ CI_DEBUG("New Control Register Data received: 0x%04x\n", controlReg); } /* Tell the Network Application we have completed one I/O cycle */ CI_IoComplete(); /* Wait for the Network Application to begin a new I/O cycle */ CI_WaitIO(); } /* The application should never get here */ return 0; }
This is a complete Common Interface application. Real I/O processing will have to occur to make a useful device, but most applications will have this basic form:
• Initialization
o Includes lowering of interrupt mask (necessary for proper operation of CI_Init()). o Includes call to CI_Init(). o Call CI_SetDeviceType(). This will result in loading of various protocol-specific information from the configuration loaded into the network application (e.g. EtherCAT vendor ID, device type, etc.). o Call CI_AddItem(). This will be called for each distinct set of I/O in the device.For example, in a modular system each module plugged into the backplane would typically generate a separate call to CI_AddItem() as they are detected. The example above has a simple, fixed set of I/O. This call also results in the discovery of information in the configuration loaded into the network application including size, direction, etc. Additionally, protocol-specific information is used to properly configure the device on the network. o Call CI_ConfigComplete() to indicate that all items have been added. At this point the network application has all the information it needs to start up the network side and begin communications. The argument to this call is the maximum delay, in microseconds, that the application can wait during a call to CI_WaitIO().
• Operating Loop
o Includes a call to CI_IoComplete(). In some protocols this function operates to update data to and from the network, in others this update occurs immediately on each call to CI_ReadItem()/CI_WriteItem(). o Includes a blocking call (e.g. to CI_WaitIO() or to a CI timer function). This is critical - the user application runs at a higher priority than much of the network application and it must block to allow the lower priority contexts to execute.
For a basic Common Interface application, the only dependencies are on the library project. This project generates static libraries that are linked into the Project executable.
To debug a Common Interface application, the Network Application binary and a Common Interface Configuration must be present on the module being used for debug.
Once the Network Application and configuration data are installed on the module, you can begin developing your own application using the IAR ARM environment.
It is simplest to start with one of the provided the sample project (IO-example-app.eww) and its associated configuration data. As you begin to modify the application you can also modify the configuration data to match and load the updated configuration using the Configuration Tool.
When using the debug version of the network application, you will notice that a number of messages are printed to the debugger console between the time that the application is loaded and when it breaks at the beginning of main(). This is the early initialization and setup of the freeRTOS. From this point on, the operating system (as opposed to your application) will only display on the console when an error is detected.
The display of these messages is a time-consuming process and the startup will take several seconds. When executing with the release version (which prints nothing to the console), startup will only require a fraction of a second. A user application can be executed with either a debug or release version of the network binary, regardless whether debugging is enabled in the user applications.
This tool allows the device developer to define the device-specific parameters for each protocol (multiple devices can be defined in a single configuration). Also, items are defined to map data I/O from the application to the specific protocol.
There are three basic elements available to use for a configuration: • Devices • Items • Baskets
A device represents a product from the network perspective. It contains information like the device ID, manufacturer ID, ordering information, and some default behaviors (with the specifics varying depending on the protocol for which it is defined). While many devices can be defined in a single configuration, only a single device can be set during initialization of the Common Interface. This allows the user to use a common set of software across a range of products, by detecting what the hardware configuration is and selecting the appropriate device.
With some protocols, there is a relationship between a Common Interface Device and the configuration file used by the protocol. For example, a PROFINET device would have all the information necessary to indicate to a PROFINET configuration utility or controller what GSDML file to associate with the device. Similarly, an EtherNet/IP CI Device would be associated with an EDS file. However, the developer is free to differentiate among the protocols: a PROFINET GSDML file may be associated with several different devices (or an entire product line).
An item is used to define data-flow between the user’s application and the Common Interface. The most straight-forward items define cyclic I/O data. Other items may be used to define acyclic I/O, initialization parameters, alarms, diagnostic data, etc.
The ways of accessing data over a network vary substantially for the various protocols. Therefore, with no difference in the user’s application code, a parameter for an I/O device (e.g. a scale factor for an analog input) can be mapped to an Acyclic read/write interface in PROFINET.
Finally, baskets are collections of the other configuration elements. A basket typically contains a single CI Device and one or more CI items. This mechanism can be used to write a generic application that can support sets of items (e.g. I/O modules) that have not been developed at the time of application development. A configuration change will provide support.
Further examples of the usage of these elements are provided later in this document as well as in the protocol-specific chapters of the design integration guide.
This document contains general descriptions of the Common Interface Application programming Interface (API). The more commonly used functions are discussed below. For more details on the data types, function parameters and function return values, see the header files referenced.
This function returns a pointer to a basket. This includes a Device ID and some number of Item IDs. Typically, it would be used to define a device and associated I/O in the configuration data, while supporting several such devices in generic code. The code will request the basket and use the device and items that are returned.
Called once during initialization, this function indicates to the Common Interface what device definition to look up. The configured definition includes protocol-specific information necessary to establish communications on the network. This allows a single configuration database to support multiple device types (and multiple I/O applications).
Called one or more times during initialization, this function installs an item in the network application. An item represents data transferred between the user application and the network application. The item ID matches a protocol-specific description of the item in the network application’s configuration database. The location parameter can mean various things for different types of items, but is typically used to indicate where a module/etc. is plugged into a configurable device (it also allows the installation of multiple copies of a device type).
The last parameter, userID is for the convenience of the programmer. When an event is received for an item (e.g. a read request for an acyclic I/O item), the userID provided in this call is provided to the user’s application to ease identification of the item in question.
Note that for items representing cyclic or acyclic I/O, in protocols that use such information (e.g. PROFINET), the location will be directly translated to a slot/subslot number in the protocol.
Called once during initialization after the device has been set and all items have been added, this function indicates to the network application that it has a complete configuration and can begin network communications. The parameter (maxPeriod) is used to indicate the longest delay that the user’s application can tolerate during a subsequent call to CI_WaitIO().
Called during normal operation, this function indicates to the network application that an item has been removed from service (e.g. a module has been unplugged).
If CI_RemoveItem() has been called for a particular item, the application can return it to normal operation with a call to CI_ReturnItem().
This function writes data for an item to the Network Application. The meaning of this depends on the nature of the item involved.
For an item representing cyclic input data, this function will provide the data to be output to the network. The status parameter indicates the health of the input path (bad status indicates that a problem has been detected in the hardware). For this type of I/O, CI_WriteItem() will typically be called periodically for each set of inputs (e.g. for each input module in a modular system).
Another example is acyclic I/O. This type of I/O is typically only written in response to a request from the protocol master (controller or scanner). In terms of the Common interface, this would be in response to an event received by the user application.
Item writes can also be used to set or to clear alarms or diagnostic information, if supported by the underlying protocol.
This function retrieves output data from the network application. In this case the status parameter indicates the health of the output circuitry. The return value indicates the quality/validity of the returned data.
Similar to CI_WriteItem(), this routine would be called periodically for cyclic output data, and based on events received from the Common Interface for acyclic items, alarms, etc.
This interface supports the setting of several device-wide parameters. This can be used to override some settings in the configuration data or default behaviors (e.g. set MAC Address or IP address).
This interface provides access to device-wide parameters like MAC address or serial number, etc.
This interface supports the setting of several item-specific parameters. The specific elements that can be changed depend on the type of item involved. Some parameters are protocol-specific.
=== 5.1.12 int CI_GetItemParam(CI_itemHandle_t handle, CI_Item_Param_ID_e paramID, void *paramData, int paramSize); ===
This interface provides access to item-specific parameters. The parameters available depend on the item type and protocol in use.
This interface indicates to the network application that the current I/O cycle is complete.
This function implements an event interface for the user application. It can be called in a polling fashion (if the ‘block’ parameter is zero), or, if used in a dedicated thread, it can be called with the ‘block’ parameter set to 1 and will pend until an event is available.
If an event is returned, it includes the handle of the item that that event concerns, the userID associated with that item, and the type of action indicated by the event. This generic interface can then be used to indicate that an acyclic write has been requested by the controller, for example.
This interface sets the overall system status for the network application. This will be reflected in LEDs and/or network communications (depending on the protocol).
This function retrieves the status of the network application and network connection.
This interface allows the programmer to spawn additional threads. These threads will operate at a lower priority than the user’s main program. It is intended that cyclic I/O processing should operate at a high priority, so it should be done in the context of the main program. These threads are intended for such things as event handling, socket management, handling of other interfaces, etc.
Note that these threads, while at a lower priority, still need to take some blocking action regularly so that other low priority processing can execute.
This function returns the frequency of the system tick in the network application. It can be used in conjunction with the provided time and timer functions.
This function returns the period that the system has been operating in system ticks (typically 1 ms per tick). Note that this is a 64-bit value.
This function returns the period in system ticks of the current cyclic I/O connection. This function is not supported in all protocols, if not supported it returns an error indicating that the value is unknown.
This function creates a timer with the given period for use by the application.
This function blocks operation of the user application until a timer created by a call to CI_CreateTimer() triggers.
This function blocks operation of the user application until data has been exchanged with the network. A timeout on this delay is set in the call to CI_ConfigComplete() (for example; so the application will continue to execute on the loss of a connection).
This function causes a hard reset of the microprocessor, which will in turn reset the entire device.
The CI_Codes.h are in place to support specific Common Interface codes. The codes can be defined as seen below.
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_CODES_H_ #define _CI_CODES_H_ // Includes ******************************************************************* // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** /* Success/error codes */ #define CI_OK 0 #define CI_ERROR -1 #define CI_INVALID_PARAM -2 #define CI_MEMORY_ERROR -3 #define CI_VERSION_ERROR -4 #define CI_TIMEOUT -5 #define CI_UNKNOWN -6 #define CI_EMPTY -100 #define CI_NOT_SUPPORTED -101 #define CI_NO_ENTRY -102 #define CI_READ_ONLY -103 #define CI_TIME_NOT_SYNCED -104 /* CI_MAX_SOCKETS sets the number of sockets to be supported by the application. * This macro is further used in CI_socket_defines.h to calculate the size of * fd_set member variable (fd). */ #define CI_MAX_SOCKETS 50 // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** // End Functions ************************************************************** #endif /* _CI_CODES_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ #ifndef H_CI_CFG_CONFIG_API #define H_CI_CFG_CONFIG_API #include "CI_config_types.h" /* * Open a database connection. Selects the data domain, the store and if write * permission is required. Returns a context handle that is used to access the * database. * * This is the first function a user must call to be able to access any of the * other functionality * in this API. * * Database connections are bound to a thread/task and ensure consistent * manipulation of data. * A connection is bound to a specific domain and store. Write access is * required for writing, committing, revoking and discarding a candidate. Write * access is ignored for other stores than candidate. * * [in] domain_p, default is "net" is domain is NULL. Enables to use this * database for more than network config only. Example would be * "ci-io" for io configuration of common interface devices/items. * [in] store, selects the store to be accessed (candidate,running, * status, ...) * [in] wraccess: requesting write permission. If true the caller has * write permission * [out] dhch_p, the database handle, is the identifier returned by this call * and is used to identify this db connection in subsequent calls to * access the database * * return CI_OK * CI_INVALID_PARAM * CI_ERROR if maximum number of data base connections is exceeded * CI_READ_ONLY if there is another process already connected to * the same domain/store with write permission. * */ CI_openCfg_t CI_OpenCfg; /* * Close a connection. After closing the connection, the dbch can no * longer be used to access the database * * [in] dbch, database connection handle * * return CI_OK * CI_ERROR if there is no open connection * */ CI_closeCfg_t CI_CloseCfg; /* * Register a notification callback (one for each connection) * * [in] domain * [in] cb_p Notification callback function * * return CI_OK * CI_ERROR * CI_INVALID_PARAM */ CI_regConfigEvt CI_RegConfigEvt; /* * Read an object from the database. The return values are in text form. * * [in] dbch, database connection handle * [in] path_p to the object * [in] value_p, a buffer to receive the \0 terminated string * [in] size of the value buffer * * return CI_OK * CI_NO_ENTRY if object does not exist * CI_ERROR if value is not properly formated or the receiving * buffer (value_p) is too small to hold the value * */ CI_readCfg_t CI_ReadCfg; /* * Write an object to the database. The values are in text form. * * [in] dbch, database connection handle * [in] path_p to the object * [in] value_p, a buffer to receive the \0 terminated string * * return CI_OK * CI_READ_ONLY or * CI_NO_ENTRY if object does not exist * CI_ERROR if value is not properly formated * * Note Only possible if data store is CI_storeCandidate and database * connection got write permission */ CI_writeCfg_t CI_WriteCfg; /* * Each node in the database tree can have attribute. This function is designed * to retrieve the attribute for the node designated by path_p. This may be an * object, but also a node item or anything else. * * Attributes can be everything from an uri, a node type ("ntype"), object size, * elements in an list ("len") * * [in] dbch, database connection handle * [in] path_p into database * [in] attr_p string, name of the attribute to read * [out] value_p, a buffer to receive the \0 terminated string * [in] size of the value buffer * * return CI_OK * CI_NO_ENTRY if object does not exist * CI_ERROR if value is not properly formated */ CI_readAttr_t CI_ReadAttr; /* * Initialize a enumeration. A start path defines the starting point for the * enumeration within data tree. * * [in] dbch, database connection handle * [in] The start_p path. If NULL, "", or "/" the starting point is the * root of the domain/data store given by dbch * [in] nodes, if 0 only data object nodes are iterated. If not 0, all * nodes are iterated * * return CI_OK */ CI_newEnum_t CI_NewEnum; /* * Travers the database starting at the root set by CI_NewEnum * * [in] dbch, database connection handle * [out] name_p returns the name of current object. Can be zero is not * needed * [out] value_p returns the value of current object. Can be zero is not * needed * [in/out] psize holds the size available to store the path and receives the * actual size of the path (including trailing zero) on return * [in/out] vsize holds the size available to store the value and receives the * actual size of the value (including trailing zero) on return * [out] node If true, the retrieved values refer to a non-value element * in the path * * return CI_OK if path and/or value have been retrieved as requested * CI_INVALID_PARAM * CI_ERROR if maximum number of data base connections is exceeded * CI_NO_ENTRY enumeration complete, no more data in tree */ CI_enumerate_t CI_Enumerate; /* data store management * * - we do not support editing of the running configuration store. * - or better said, we support write to candidate store only * */ /* * Commit a candidate to running. * * This call require that the database connection (dbch) got write permission. * * Running store becomes the backup store, Candidate store becomes running store * If a timeout is set, no further edits to candidate are allowed until the * timeout is expired. * If another commit is executed while a timeout is still pending, the new * timeout overrides the previous value. This can be used to prolong the commit * timeout or to make a commit permanent. * * [in] dbch, database connection handle * [in] tout_in_sec, 0 means NO TIMEOUT (commit for ever) * max value for tout_in_sec is 3600. If its higher, it * will be limited to 3600 * * return CI_OK * CI_READ_ONLY or * CI_NO_ENTRY * * Note Requires write access */ CI_commit_t CI_Commit; /* * Revoke a running candidate. * * This call require that the database connection (dbch) got write permission. * * Backup store becomes the running store, running store becomes candidate * store. * Edits made in candidate since last commit are lost if not saved to file * before revoke. * Revoke can only be executed after a previously executed Commit * * [in] dbch, database connection handle * * return CI_OK * CI_READ_ONLY or * CI_NO_ENTRY * * Note Requires write access */ CI_revoke_t CI_Revoke; /* * Discard a candidate. * * This call require that the database connection (dbch) got write permission. * * Override pending edits of the candidate with the current values from the * running store. * Used to get rid of bad edits. * * [in] dbch, database connection handle + * return CI_OK * CI_READ_ONLY or * CI_NO_ENTRY * * Note Requires write access */ CI_discard_t CI_Discard; /* save/load files */ /* * Save (serialize) a Store to a file. * * If default startup file is addressed, this call require that the database * connection (dbch) got write permission. * * [in] dbch, database connection handle * [in] file_p The file. If NULL or "", the default startup file is used * * return CI_OK * CI_READ_ONLY or * CI_ERROR */ CI_saveCfg_t CI_SaveCfg; /* * Load (de-serialize) a Store from file. * * [in] dbch, database connection handle * [in] file_p The file. If NULL or "", the default startup file is used * * return CI_OK * CI_INVALID_PARAM * CI_ERROR * * Note Does require write access */ CI_loadCfg_t CI_LoadCfg; #endif
* Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ #ifndef H_CI_CFG_CONFIG_TYPES #define H_CI_CFG_CONFIG_TYPES #include "CI_config.h" #define CI_CFG_VER_MAJ 0x01 #define CI_CFG_VER_MIN 0x00 #define CI_CFG_VER ((CI_CFG_VER_MAJ << 16) | CI_CFG_VER_MIN) #define CI_CFG_NAME ("CI_config") /* API Function Name List */ #define CI_CFG_NAME_VERSION ("Version") /* 1st in list */ #define CI_CFG_NAME_OPEN_DB ("open") #define CI_CFG_NAME_CLOSE_DB ("close") #define CI_CFG_NAME_REG_NOTIF ("registerNoti") #define CI_CFG_NAME_READ_OBJ ("readObj") #define CI_CFG_NAME_WRITE_OBJ ("writeObj") #define CI_CFG_NAME_READ_ATTR ("readAttr") #define CI_CFG_NAME_INIT_ENUM ("initEnum") #define CI_CFG_NAME_ENUMERATE ("enumerate") #define CI_CFG_NAME_COMMIT ("commitConfig") #define CI_CFG_NAME_REVOKE ("revokeCommit") #define CI_CFG_NAME_DISCARD ("discardCand") #define CI_CFG_NAME_SAVE ("saveConf") #define CI_CFG_NAME_LOAD ("loadConf") /* * Open a database connection. Selects the data domain, the store and if write * permission is required. Returns a context handle that is used to access the * database. */ typedef int32_t (CI_openCfg_t)(char *domain_p, CI_store_t store, int32_t wraccess, int32_t *dbch_p); typedef CI_openCfg_t (*CI_openCfg_tp); /* * Close a connection. After closing the connection, the dbch can no * longer be used to access the database * * [in] dbch, database connection handle * * return TSNA_OK */ typedef int32_t (CI_closeCfg_t)(int32_t dbch); typedef CI_closeCfg_t (*CI_closeCfg_tp); /* * Notification Callback. A driver or stack can issue a notification, that is an * event that is codified in a modules definition (YANG), to the database using * TSNA_eventType_t (see TSNA_CTR api). The database will translate the * notification from the driver/stack * into a ascii (ascii subset of uft8) * formated notification that in turn is pushed to any application * with an open connection to the status store of the affected module. */ typedef int32_t (CI_CFG_notificationCB_t)(char *path_p, uint16_t nargs, CI_keyValuePair_t *argv_p); typedef CI_CFG_notificationCB_t (*CI_CFG_notificationCB_tp); /* * Register a notification callback (one for each connection) */ typedef int32_t (CI_regConfigEvt)(int32_t dbch, CI_CFG_notificationCB_tp cb_p); typedef CI_regConfigEvt (*CI_regConfigEvtp); /* * Read an object from the database. The return values are in text form. */ typedef int32_t (CI_readCfg_t)(int32_t dbch, char *path_p, char *value_p, uint16_t size); typedef CI_readCfg_t (*CI_readCfg_tp); /* * Write an object to the database. The values are in text form. */ typedef int32_t (CI_writeCfg_t)(int32_t dbch, char *path_p, char *value_p); typedef CI_writeCfg_t (*CI_writeCfg_tp); /* * Each node in the database tree can have attribute. This function is designed * to retrieve the attribute for the node designated by path_p. This may be an * object, but also a node item or anything else. */ typedef int32_t (CI_readAttr_t)(int32_t dbch, char *path_p, char *attr_p, char *value_p, uint16_t size); typedef CI_readAttr_t (*CI_readAttr_tp); /* * Initialize a enumeration. A start path defines the starting point for the * enumeration within data tree. * */ typedef int32_t (CI_newEnum_t)(int32_t dbch, char *start_p, CI_nodeType_t select); typedef CI_newEnum_t (*CI_newEnum_tp); /* * Travers the database starting at the root set by CI_NewEnum * */ typedef int32_t (CI_enumerate_t)(int32_t dbch, char *name_p, char *value_p, uint16_t *nsize_p, uint16_t *vsize_p, CI_nodeType_t *ntype_p); typedef CI_enumerate_t (*CI_enumerate_tp); /* * Commit a candidate to running. * */ typedef int32_t (CI_commit_t)(int32_t dbch, char *path_p, uint16_t tout_in_sec); typedef CI_commit_t (*CI_commit_tp); /* * Revoke a running candidate. * */ typedef int32_t (CI_revoke_t)(int32_t dbch, char *path_p); typedef CI_revoke_t (*CI_revoke_tp); /* * Discard a candidate. */ typedef int32_t (CI_discard_t)(int32_t dbch, char *path_p); typedef CI_discard_t (*CI_discard_tp); /* save/load files */ /* * Save (serialize) a Store to a file. */ typedef int32_t (CI_saveCfg_t)(int32_t dbch, char *file_p); typedef CI_saveCfg_t (*CI_saveCfg_tp); /* * Load (de-serialize) a Store from file. */ typedef int32_t (CI_loadCfg_t)(int32_t dbch, char *file_p); typedef CI_loadCfg_t (*CI_loadCfg_tp); #endif
/* /* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ #ifndef H_CI_CONFIG_AND_CONTROL_API_INC #define H_CI_CONFIG_AND_CONTROL_API_INC #include <stdint.h> #include <limits.h> #include "CI_codes.h" typedef enum { CI_storeCandidate, CI_storeRunning, CI_storeBackup, CI_storeStartup, CI_storeStatus, // formally not a store, it easier to // handle it like one CI_illegal=INT16_MIN, CI_storeLast=INT16_MAX } CI_store_t; typedef enum { CI_isValue=0x01, CI_isNode=0x02, CI_isAttribute=0x03, CI_isNIL=0, CI_isLast=INT8_MAX } CI_nodeType_t; typedef struct { char *key_p; char *value_p; } CI_keyValuePair_t; /* * event types of the callback routine */ typedef enum { CI_evtStop, CI_evtStart, CI_evtReqStatus, CI_evtNewConfig, CI_evtRPC, CI_evtReset, CI_evtSIZE=INT16_MAX } CI_eventType_t; #endif
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ #ifndef H_CI_CONTROL_API #define H_CI_CONTROL_API #include "CI_control_types.h" /* * Register a driver with the database * * [in] name of this driver instance (debug) * [out] thisDriverID_p, a handle to identify this driver instance * [in] cb_p, the callback function for this driver * * return error code */ CI_regDriver_t CI_RegDriver; /* * Instantiate a YANG module for this driver or stack * * [in] path_p, identifies the module (Example "net/ieee802-dot1q-sched") * [in] name_p, name under which the module get registered. Examples "P0", * "ETH0" * note: different module types can be registered under same name! * [in] instanceID to identify the instance with any callbacks * * return CI_OK * CI_INVALID_PARAM * CI_ERROR */ CI_addModule_t CI_AddModule; /* * Fire a notification. YANG allows to define notifications that * are pushed upstream. This function is designed to support this mechanism * * [in] path identifying the notification * [in] ndata_p points to a structure that holds the parameters that * are required for this notification * [in] nsize the size of the argument structure. Needed for error * checking only * * return CI_OK * CI_INVALID_PARAM */ CI_fireEvent_t CI_FireEvent; CI_enableGateway_t CI_EnableGateway; #endif
*/ typedef int32_t (CI_eventCB_t)(CI_eventType_t event, uint16_t instanceID, void *arg_p); typedef CI_eventCB_t (*CI_eventCB_tp); /* * Register a driver with the database */ typedef int32_t (CI_regDriver_t)(char *name_p, uint16_t *thisDriverID_p, CI_eventCB_tp cb_p); typedef CI_regDriver_t (*CI_regDriver_tp); /* * Instantiate a YANG module for this driver or stack */ typedef int32_t (CI_addModule_t)(uint16_t drv, char *path_p, char *name_p, uint16_t instanceID); typedef CI_addModule_t (*CI_addModule_tp); /* * Fire a notification. */ typedef int32_t (CI_fireEvent_t)(char *path_p, void *ndata_p, uint16_t nsize); typedef CI_fireEvent_t (*CI_fireEvent_tp); /* * Enable TSN gateway functionality */ typedef int32_t (CI_enableGateway_t)(void); typedef CI_enableGateway_t (*CI_enableGateway_tp); #endif
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ #ifndef DEBUG_H #define DEBUG_H #include <stdio.h> #define DBG_SHOW_ERROR 0 #define DBG_SHOW_INFO 0 #ifdef NDEBUG #define DBG_PRINT(...) #else #include <stdio.h> #define DBG_STRINGIFY(x) #x #define DBG_TO_STRING(x) DBG_STRINGIFY(x) #define DBG_AT "[" __FILE__ ":" DBG_TO_STRING(__LINE__) "]" #define DBG_PRINT(...) printf(DBG_AT " " __VA_ARGS__) #endif #if DBG_SHOW_ERROR == 1 #define DBG_ERROR(...) DBG_PRINT("ERROR: " __VA_ARGS__) #else #define DBG_ERROR(...) #endif #if DBG_SHOW_INFO == 1 #define DBG_INFO(...) DBG_PRINT("INFO: " __VA_ARGS__) #else #define DBG_INFO(...) #endif /* Note do-while is to guard the if statement */ #define DBG_ASSERT(x) \ do { \ if (!x) { \ DBG_PRINT(" ASSERT\n"); \ while(1); \ } \ } while(0) #endif /* DEBUG_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ #ifndef H_CI_CONTROL_TYPES #define H_CI_CONTROL_TYPES #include "CI_config.h" #define CI_VER_MAJ 0x01 #define CI_VER_MIN 0x00 #define CI_VER ((CI_VER_MAJ << 16) | CI_VER_MIN) #define CI_NAME ("CI_control") /* API Function Name List */ #define CI_NAME_VERSION ("Version") /* 1st in list */ #define CI_NAME_REG_DRIVER ("regDriver") #define CI_NAME_ADD_MODULE ("addModule") #define CI_NAME_FIRE_NOTI ("fireNoti") #define CI_NAME_ENABLE_GATEWAY ("enGateway") /* * the control api has to deal with two data stores only: * - STATUS: data from the driver/stack towards the database * - RUNNING: current config data towards the driver/stack */ /* * Callback function receive updates from the configuration database /* * Copyright (c) 2018 - 2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_DEVICES_H_ #define _CI_DEVICES_H_ /***************************************************************************** * * This file contains device structures to be used with the * CI_SetDeviceCustom() function * ****************************************************************************/ // Includes ******************************************************************* #include <stdint.h> // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** /* PROFINET macros */ #define CI_PNET_DEVICE_TYPE_LENGTH 240 #define CI_PNET_DEVICE_ORDER_ID_LENGTH 20 #define CI_PNET_DEVICE_SNMP_BUFFER_LENGTH 256 #define CI_PNET_MAX_STATION_NAME_LENGTH 240 #define CI_PNET_DEVICE_VERSION 0 // EtherNet/IP macros #define CI_EIP_NUM_ETH_PORTS 2 #define CI_EIP_MAX_PRODUCT_NAME_SIZE 33 #define CI_EIP_DOMAIN_NAME_LENGTH 49 #define CI_EIP_HOST_NAME_LENGTH 65 #define CI_EIP_DEVICE_VERSION 2 // EtherCAT macros #define MAX_DEVICE_NAME_STR_LEN 32 // Including NULL terminator #define MAX_HW_VERSION_STR_LEN 8 // Including NULL terminator #define MAX_SW_VERSION_STR_LEN 8 // Including NULL terminator #define CI_ECAT_DEVICE_VERSION 0 // ---------------------------------------------------------------------------- /* PROFINET device structure */ typedef struct { uint16_t vendorID; uint16_t deviceID; uint16_t profileID; uint16_t profileType; uint32_t moduleID; uint32_t subModuleID; uint8_t majorRevision; /* Functional enhancement */ uint8_t minorRevision; /* Bug fix */ uint8_t internalRevision; /* internal change */ uint8_t revisionCounter; int8_t deviceType[CI_PNET_DEVICE_TYPE_LENGTH]; int8_t orderID[CI_PNET_DEVICE_ORDER_ID_LENGTH]; /* SNMP data */ uint32_t enterpriseID; /* Private SNMP OID */ /* SNMP sys desc Mib2 */ int8_t systemDescription[CI_PNET_DEVICE_SNMP_BUFFER_LENGTH]; /* InternalIf desc Mib2*/ int8_t internalInterface[CI_PNET_DEVICE_SNMP_BUFFER_LENGTH]; /* Port IF desc Mib2 */ int8_t port1Interface[CI_PNET_DEVICE_SNMP_BUFFER_LENGTH]; /* Port IF desc Mib2 */ int8_t port2Interface[CI_PNET_DEVICE_SNMP_BUFFER_LENGTH]; } __attribute__ ((packed)) CI_profinetDevice_t; /* EtherNet/IP device structure */ typedef struct { uint8_t type; /* Always 3 */ int8_t pad1; /* Always 0 */ uint16_t vendorID; /* Valid range 0-65535 */ uint16_t productType; /* Valid range 0-65535 */ uint16_t productCode; /* Valid range 0-65535 */ uint16_t majorRevision; /* Valid range 0-255 */ uint16_t minorRevision; /* Valid range 0-255 */ /* The following portion of this structure contains the data that is used * as the "out of the box" defaults */ uint8_t use_dhcp; /* 0 = static IP, non-zero = use DHCP */ int8_t pad2; /* Always 0 */ uint32_t ipaddr; /* Local IP address (if DHCP disabled) * e.g. 192.168.21.26 is 0xc0a8151a */ uint32_t subnetMask; /* Local subnet mask (if DHCP disabled) * e.g. 255.255.255.0 is 0xffffff00 */ uint32_t defaultGateway; /* Local gateway IP address (if DHCP disabled), * formatted as above */ uint32_t dns[2]; /* DNS server IP addresses (if DHCP disabled) * [0] for primary, [1] for secondary, formatted * as above */ uint8_t ifc_speed[CI_EIP_NUM_ETH_PORTS]; /* 0 = 10 Mbps, 1 = 100 Mbps */ uint8_t ifc_duplex[CI_EIP_NUM_ETH_PORTS]; /* 0 = half, 1 = full */ uint8_t ifc_use_autonegotiation[CI_EIP_NUM_ETH_PORTS]; /* 0 = force * 1 = auto */ uint8_t byTTLValue; /* Used by EtherNet/IP stack, see EIP Spec */ uint8_t byAllocControl; /* Used by EtherNet/IP stack, see EIP Spec */ uint16_t iNumMulticast; /* Used by EtherNet/IP stack, see EIP Spec */ uint8_t use_ACD; /* 0=don't, 1=do use Address Conflict Detection */ int8_t pad3; /* always 0 */ /* EtherNet/IP Ethernet Link Object settings */ uint8_t byAdminState[CI_EIP_NUM_ETH_PORTS]; /* 1=enable port * 2=disable port */ uint32_t lMCastStartAddr; /* Used by EtherNet/IP stack, see EIP Spec */ int8_t productName[CI_EIP_MAX_PRODUCT_NAME_SIZE]; /* Local product name */ int8_t domain_name[CI_EIP_DOMAIN_NAME_LENGTH]; /* Local domain name (if * DHCP disabled) */ int8_t host_name[CI_EIP_HOST_NAME_LENGTH]; /* Local host name */ int8_t pad4; /* always 0 */ uint8_t dlrEnable; /* 0 = disable DLR, */ /* 1 = enable DLR */ int8_t pad5; /* Always 0 */ uint16_t CI_deviceExtID; // Object number containing Extension Object info } __attribute__ ((packed)) CI_etherNetIpDevice_t; /* EtherCAT device structure*/ typedef struct { uint32_t vendorId; // Vendor ID (from MDP object 0x1018) uint32_t productCode; // Product Code (from MDP object 0x1018) uint8_t deviceName[MAX_DEVICE_NAME_STR_LEN]; // Device name (MDP object 0x1008) uint8_t hwVersion[MAX_HW_VERSION_STR_LEN]; // Hardware version (MDP object 0x1009) uint8_t swVersion[MAX_SW_VERSION_STR_LEN]; // Software version (MDP object 0x100A) uint16_t majorRevNum; // Major revision number (from MDP object 0x1018) uint16_t minorRevNum; // Minor revision number (from MDP object 0x1018) } __attribute__ ((packed)) CI_ethercatDevice_t; // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** // End Functions ************************************************************** #endif /* _CI_DEVICES_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_EXTENSIONS_H_ #define _CI_EXTENSIONS_H_ /*--------------------------------------------------------------------------*/ /*------------ EtherNet/IP Stack Common Interface Extension Sectionn -------*/ /* Note Update this version number in case of ANY change to the EIP LED interface * extension (enums and function calls) */ /* EIP led interface extension version */ #define CI_LED_IF_EXT_VER 1 /* Enumerations for CI_ifExtLedApi CI interface extension */ typedef enum { CI_ledMod, CI_ledNet, } CI_ledStatus_t; typedef enum { CI_ledOff, CI_ledRedOn, CI_ledRedFlashing, CI_ledGreenOn, CI_ledGreenFlashing, } CI_ledStatusState_t; /* Functions for CI_ifExtLedApi interface extension */ typedef int32_t CI_LedGetStatusStateFunct_t(CI_ledStatus_t led, CI_ledStatusState_t *state_p); CI_LedGetStatusStateFunct_t CI_LedGetStatusState; typedef int32_t CI_LedSetStatusStateFunct_t(CI_ledStatus_t led, CI_ledStatusState_t state); CI_LedSetStatusStateFunct_t CI_LedSetStatusState; /* Structure holding function pointer to callbacks to be passed to interface * exension function */ typedef struct { CI_LedGetStatusStateFunct_t *CI_LedGetStatusStateFunct_p; CI_LedSetStatusStateFunct_t *CI_LedSetStatusStateFunct_p; } CI_LedStatusIfExt_t; /*--------------------------------------------------------------------------*/ /*------------ PROFINET Stack Common Interface Extension Section ------------*/ #define CI_PNET_STACK_VERSION 4 typedef enum { alarmPriorityUnknown, alarmPriorityLow = 5, alarmPriorityHigh = 6 } alarmPriority_t; typedef enum { alarmDiagnosis = 0x01, alarmProcess = 0x02 } alarmType_t; typedef enum { Unknown_error = 0, /* Reserved */ Short_circuit, Undervoltage, Overvoltage, Overload, Overtemperature, Line_break, Upper_limit_exceeded, Lower_limit_exceeded, Error, Simulation_active, Parameter_missing = 0x000f, Parameter_fault, Power_fault, Fuse_blown, Comm_fault, Ground_fault, Reference_lost, Process_lost, Threshold_warning, Output_disabled, External_fault = 0x001a, ManufactureSpecific, Temporary_fault = 0x001f, } diagChannelError_t; typedef enum { Input = 1, Output, In_out, } diagChannelDir_t; typedef int32_t CI_PnetSendAlarm_t(alarmPriority_t alarmPriority, alarmType_t alarmType, uint16_t slot, uint16_t subslot, uint16_t alarmSpecifier, uint8_t *alarmData_p, uint16_t alarmDataLength, uint16_t usrStructureIdentifier); CI_PnetSendAlarm_t CI_PNET_Ext_SendAlarm_Func; typedef int32_t CI_PnetSendDiag_t(uint16_t slot, uint16_t subslot, uint16_t diagType, uint16_t channelNumber, uint16_t channelType, diagChannelDir_t direction, uint8_t *manSpecificData_p, uint16_t dataLen); CI_PnetSendDiag_t CI_PNET_Ext_SendDiag_Func; typedef int32_t CI_PnetClearDiag_t(uint16_t slot, uint16_t subslot, uint16_t diagType, uint16_t channelNumber, uint16_t channelType, diagChannelDir_t direction); CI_PnetClearDiag_t CI_PNET_Ext_ClearDiag_Func; typedef int32_t (CI_PnetAddItem_t)(uint16_t id, void *data_p, uint32_t bufSize, uint16_t slot, uint16_t subslot); CI_PnetAddItem_t CI_PNET_Ext_AddItem_Func; typedef int32_t CI_PnetModuleDiffFunct_t (uint16_t ARindix, uint32_t API, uint16_t slot, uint16_t subslot, uint32_t realModuleID, uint32_t expectedModuleID, uint32_t realsubmoduleID, uint32_t expectedSubmoduleID); CI_PnetModuleDiffFunct_t CI_PNET_Ext_ModuleDiff_CB; typedef int32_t CI_PnetParameterEnd_t (uint16_t ARindix); CI_PnetParameterEnd_t CI_PNET_Ext_ParamEnd_CB; /* Structure holding function pointer to callbacks to be passed to interface * exension function */ typedef struct { CI_PnetModuleDiffFunct_t* CI_PNET_Ext_ModuleDiff_p; CI_PnetParameterEnd_t* CI_PNET_Ext_ParamEnd_p; } CI_PnetCallbackFunctionTable_t; /* Structure holding function pointer to callbacks to be passed to interface * exension function */ typedef struct { CI_PnetSendAlarm_t* CI_PNET_Ext_SendAlarm_Func_p; CI_PnetSendDiag_t* CI_PNET_Ext_SendDiag_Func_p; CI_PnetClearDiag_t* CI_PNET_Ext_ClearDiag_Func_p; CI_PnetAddItem_t* CI_PNET_Ext_AddItem_Func_p; } CI_PnetInterfaceFunctionTable_t; /*---------------------------------------------------------------------------*/ /*--------------- Place Other Protocol Extension Sections Below Here --------*/ #endif /* _CI_EXTENSIONS_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_HARDWARE_API_H_ #define _CI_HARDWARE_API_H_ // Includes ******************************************************************* #include "CI_hardware_types.h" // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** CI_getAvailableTimerCount_t CI_GetAvailableTimerCount; CI_timerSetSignal_t CI_ConfigureTimerSignal; // End Functions ************************************************************** #endif /* _CI_HARDWARE_API_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_HARDWARE_TYPES_H_ #define _CI_HARDWARE_TYPES_H_ // Includes ******************************************************************* #include <stdint.h> // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** /*************************************************************************** * IMPORTANT: The interface version below is used to detect CHANGES the to * functions in the interface and SHALL be updated any time there is a change * to ANY function in this header that is part of a registered (i.e. used with * the registrar) interface. "Change" in this case only means a change to the * SIGNATURE of a function. The interface version need not be updated if the * number of functions in the interface changes (i.e. a function is added or * removed). ***************************************************************************/ #define CI_HW_VER_MAJ 0x01 #define CI_HW_VER_MIN 0x02 #define CI_HW_VER ((CI_HW_VER_MAJ << 16) | CI_HW_VER_MIN) #define CI_HW_NAME ("CI_hwIf") /* API Function Name List */ #define CI_HW_NAME_VERSION ("Version") /* 1st in list */ #define CI_HW_NAME_GET_AVAIL_COUNT ("GetAvailCount") #define CI_HW_NAME_CONFIG_TIMER_SIGNAL ("ConfTimerSig") // ---------------------------------------------------------------------------- /* ------------------------------------------------------------------------ */ /* ------------------ Data/enum types for this interface ------------------ */ /* ------------------------------------------------------------------------ */ /* Hardware timer signal active state */ typedef enum { CI_signalActiveLow, CI_signalActiveHigh } CI_signalActiveState_t; /* ------------------------------------------------------------------------- */ /* ------------------- Function types for this interface ------------------- */ /* ------ See the corresponding API header for function declarations ------ */ /* ------------------------------------------------------------------------- */ typedef int32_t (CI_getAvailableTimerCount_t)(void); typedef CI_getAvailableTimerCount_t (*CI_getAvailableTimerCount_tp); typedef int32_t (CI_timerSetSignal_t)(uint32_t timer, uint32_t pulsePeriod, uint32_t pulseOffset, uint32_t pulseWidth, CI_signalActiveState_t activeLevel); typedef CI_timerSetSignal_t (*CI_timerSetSignal_tp); // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** // End Functions ************************************************************** #endif /* _CI_HARDWARE_TYPES_H_ */
/* * Copyright (c) 2019-2020 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_IO_API_H_ #define _CI_IO_API_H_ // Includes ******************************************************************* #include "CI_io_types.h" // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** /** * Set the device for the system * * Use this function to set a "canned" device from the IO configuration file by * device ID number. Using this function will effectively override the network * application's working copy of the device structure with the data from the IO * configuration file. Once CI_ConfigComplete() is called, the working copy * will be latched and may not be modified from that point forward. * * Parameters * Dir Type Name Description * [in] uint16_t deviceId ID number (from IO config file) of the device * to set for the system * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR if device not found in IO config data * CI_ERROR if called after CI_ConfigComplete() */ CI_setDevice_t CI_SetDevice; /** * Set a custom device, bypassing the config data * * Use this function to set a custom device programatically rather than using a * "canned" device from the IO configuration file (using CI_SetDevice()). Using * this function will effectively override the network application's working * copy of the device structure with the data in the indicated buffer. Once * CI_ConfigComplete() is called, the working copy will be latched and may not * be modified from that point forward. * * This function has the same functionality as CI_SetDevice() except that the * device data comes from the IO application rather than the IO configuration * data file. * * Parameters * Dir Type Name Description * [in] void * device_p Pointer to a filled-in CI device structure in * the format expected by the protocol in use * [in] uint32_t bufSize Size (in bytes) of the structure pointed to by * data_p * * Refer to the file CI_device_structs.h for the data structure this function * expects. Each protocol has a distinct device structure: * (e.g. EtherNet/IP -----> CI_etherNetIpDevice_t) * * It is up to the IO application to know what the underlying protocol is and * supply a correctly-formated, corresponding device structure. (The underlying * protocol is returned by CI_GetProtocol().) * * Return * Type: int32_t * Values: CI_OK on success * CI_INVALID_PARAM on error processing device information * CI_INVALID_PARAM if device data buffer size not equal to expected * structure size * CI_ERROR if called after CI_ConfigComplete() * CI_ERROR on error */ CI_setDeviceCustom_t CI_SetDeviceCustom; /** * Get a copy of the device structure working copy * * Use this function to have the network application copy the working copy of * the device structure into the indicated buffer. This will enable the IO * application to read device parameters or optionally, read, modify and then * write them back to the network application using CI_SetDeviceCustom(). * * Parameters * Dir Type Name Description * [out] void * device_p Pointer to buffer to be filled in with working * copy of device structure * [in] uint16_t maxSize Maximum number of bytes that can be copied to * caller's buffer when filling in device structure * * The working copy of the device structure must be initialized (using * CI_SetDeviceCustom() or CI_SetDevice()) prior to calling this function. * Otherwise, an an error will be returned. * * Return * Type: int32_t * Values: number of bytes copied to caller's buffer * CI_INVALID_PARAM if device_p == NULL * CI_INVALID_PARAM if maxSize < size of device structure (i.e. buffer * too small for device structure) * CI_ERROR if working copy of device structure not initialized * CI_ERROR on error */ CI_getDevice_t CI_GetDevice; /** * Add an item to the system * * Parameters * Dir Type Name Description * [in] uint16_t id Item ID number (from IO config file) * [in] uint32_t location 1-based location (i.e. slot) into which the * item should be installed * Return * Type: int32_t * Values: >= 0: item handle (positive integer used in other calls) * <0: CI_INVALID_PARAM if location out of range (must be >0) * CI_ERROR if item not found by ID * CI_ERROR if items not currently permitted to be added */ CI_addItem_t CI_AddItem; /** * Create and add a custom item, bypassing the config data * * This is not the traditional way to set add an item. Normally, you would * simply add an item using CI_AddItem(). * * This function has the same functionality as CI_AddItem() except that the * item data comes from the IO application rather than the IO configuration * data file. * * Parameters * Dir Type Name Description * [in] uint16_t id Item ID number (as if it from IO config file) * [in] void * data_p Pointer to a filled-in CI item structure in the * format expected by the protocol in use * [in] uint32_t bufSize Size (in bytes) of the structure pointed to by * data_p * [in] uint32_t location 1-based location (i.e. slot) into which the * item should be installed * * Refer to the file CI_item_structs.h for the data structure this function * expects. Each protocol has a distinct item structure: * (e.g. EtherNet/IP ---- CI_etherNetIpItem_t) * * It is up to the IO application to know what the underlying protocol is and * supply the correctly-formatted, corresponding item structure. (The * underlying protocol is returned by CI_GetProtocol().) * * Return * Type: int32_t * Values: >= 0: item handle (positive integer used with other CI calls) * <0: CI_INVALID_PARAM if item data pointer == NULL * CI_INVALID_PARAM if item data buffer size not equal to * expected structure size * CI_INVALID_PARAM if location out of range (must be >0) * CI_INVALID_PARAM if error processing item data */ CI_addItemCustom_t CI_AddItemCustom; /** * Set the value of an item parameter * * Parameters * Dir Type Name Description * [in] int32_t handle Handle to item for which parameter * should be set (returned * from CI_AddItem()) * [in] CI_itemParamId_t param Item parameter to set (see * CI_itemParamId_t for examples and * descriptions of item parameters) * [in] void * paramData_p Pointer to buffer in which the * desired item parameter data currently * resides * [in] uint32_t paramSize The number of bytes in the buffer * pointed to by paramData_p * * Return * Type: int32_t * Values: CI_OK on success * CI_INVALID_PARAM if invalid item handle * CI_NOT_SUPPORTED if invalid item parameter * CI_INVALID_PARAM if parameter data pointer == NULL * CI_INVALID_PARAM if invalid item parameter size * CI_ERROR on error */ CI_setItemParam_t CI_SetItemParam; /** * Get the value of an item parameter * * Parameters * Dir Type Name Description * [in] int32_t handle Handle to item for which parameter * should be retrieved (returned from * CI_AddItem()) * [in] CI_itemParamId_t param Item parameter to get * (see CI_itemParamId_t for examples * and descriptions of item parameters) * [in] void * paramData_p Pointer to buffer into which the * desired item parameter data should be * placed * [in] uint32_t paramSize Size (in bytes) of the requested item * parameter data * * Return * Type: int32_t * Values: CI_OK on success * CI_INVALID_PARAM if invalid item handle * CI_INVALID_PARAM if invalid item parameter * CI_INVALID_PARAM if parameter data pointer == NULL * CI_INVALID_PARAM if invalid paramSize value * CI_ERROR on error */ CI_getItemParam_t CI_GetItemParam; /** * Install direct IO functions * * Use this function to install direct input/output functions. These functions * will be called directly by the network application to precisely synchronize * the IO application's input and/or output data processing with each network * cycle. * * NOTE: These functions may be called from an interrupt context. Only take * actions in these functions that are appropriate inside an interrupt service * routine. * * Parameters * Dir Type Name Description * [in] CI_dirIoFunc_t dirInFunc_p Pointer to direct input data handler * function * [in] CI_dirIoFunc_t dirOutFunc_p Pointer to direct output data handler * function * * NOTE: NULL may be passed in for either parameter to disable installation of * a handler for the corresponding data direction. * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR if called after CI_ConfigComplete() * CI_NOT_SUPPORTED if direct IO not supported by network application */ CI_installDirectIo_t CI_InstallDirectIo; /** * Remove a previously-added item * * Parameters * Dir Type Name Description * [in] int32_t handle Handle of the item to be removed (returned by * CI_itemAddItem() or CI_AddItemCustom()) * * Return * Type: int32_t * Values: CI_OK on successful removal * CI_INVALID_PARAM if handle is invalid * CI_NOT_SUPPORTED if function not supported */ CI_removeItem_t CI_RemoveItem; /** * Return a previously-removed item * * Parameters * Dir Type Name Description * [in] int32_t handle Handle of the item to be returned (returned by * CI_itemAddItem() or CI_AddItemCustom()) * * Return * Type: int32_t * Values: CI_OK on successful replacement * CI_INVALID_PARAM if handle is invalid * CI_NOT_SUPPORTED if function not supported */ CI_returnItem_t CI_ReturnItem; /** * Write item data * * Parameters * Dir Type Name Description * [in] int32_t handle Handle of item for which data should be written * (returned by CI_AddItem() or CI_AddItemCustom()) * [in] void * data_p Pointer to buffer containing the data to be written * to the item * * Return * Type: int32_t * Values: CI_OK on success * CI_INVALID_PARAM if invalid handle or data pointer is NULL * CI_ERROR if item is written before CI_ConfigComplete() * CI_ERROR on error */ CI_writeItem_t CI_WriteItem; /** * Read item data * * Parameters * Dir Type Name Description * [in] int32_t handle Handle of item for which data should be read * (returned by CI_AddItem() or CI_AddItemCustom()) * [out] void * data_p Pointer to buffer into which item data should be * * Return * Type: int32_t * Values: >=0: IO Status status of data from network (see CI_ioStatus_t) * CI_INVALID_PARAM if invalid handle or data pointer is NULL * CI_ERROR if item is read before CI_ConfigComplete() * CI_ERROR on error */ CI_readItem_t CI_ReadItem; /** * Set the input or output path status of an item * * Use this function to indicate the status of the input and/or output path to * the network application. Depending on the industrial protocol implemented by * the network application, this information may be to the PLC as "IO module * health" information. * * Parameters * Dir Type Name Description * [in] int32_t handle Handle of item for which the * status should be set * [in] CI_itemDataDir_t direction Data direction (input or output) * for which the status should be * set * [in] CI_itemDataPathStatus_t status Status of the indicated input * or output path for the indicated * item * * Return * Type: int32_t * Values: CI_OK on success * CI_INVALID_PARAM on invalid item handle * CI_INVALID_PARAM on invalid data direction * CI_INVALID_PARAM on invalid status * CI_ERROR on error */ CI_setItemStatus_t CI_SetItemStatus; /** * Get the period of cyclic I/O connection * * Parameters * NONE * * Return * Type: int32_t * Values: cyclic I/O period in microseconds * CI_UNKNOWN if protocol in use doesn't have a cyclic period */ CI_getCyclicPeriod_t CI_GetCyclicPeriod; /** * Tell the network application that an I/O cycle is complete * * Parameters * NONE * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR if called prior to CI_ConfigComplete() */ CI_ioComplete_t CI_IoComplete; // End Functions ************************************************************** #endif /* _CI_IO_API_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_IO_TYPES_H_ #define _CI_IO_TYPES_H_ // Includes ******************************************************************* #include <stdint.h> // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** /*************************************************************************** * IMPORTANT: The interface version below is used to detect CHANGES the to * functions in the interface and SHALL be updated any time there is a change * to ANY function in this header that is part of a registered (i.e. used with * the registrar) interface. "Change" in this case only means a change to the * SIGNATURE of a function. The interface version need not be updated if the * number of functions in the interface changes (i.e. a function is added or * removed). ***************************************************************************/ #define CI_IO_VER_MAJ 0x01 #define CI_IO_VER_MIN 0x00 #define CI_IO_VER ((CI_IO_VER_MAJ << 16) | CI_IO_VER_MIN) #define CI_IO_NAME ("CI_ioIf") /* API Function Name List */ #define CI_IO_NAME_VERSION ("Version") /* 1st in list, required */ #define CI_IO_NAME_SET_DEVICE ("SetDevice") #define CI_IO_NAME_SET_DEVICE_CUST ("SetDeviceCust") #define CI_IO_NAME_GET_DEVICE ("GetDevice") #define CI_IO_NAME_ADD_ITEM ("AddItem") #define CI_IO_NAME_ADD_ITEM_CUST ("AddItemCust") #define CI_IO_NAME_SET_ITEM_PARAM ("SetItemParam") #define CI_IO_NAME_GET_ITEM_PARAM ("GetItemParam") #define CI_IO_NAME_INSTALL_DIR_IO ("InstDirIo") #define CI_IO_NAME_REMOVE_ITEM ("RemoveItem") #define CI_IO_NAME_RETURN_ITEM ("ReturnItem") #define CI_IO_NAME_WRITE_ITEM ("WriteItem") #define CI_IO_NAME_READ_ITEM ("ReadItem") #define CI_IO_NAME_SET_ITEM_STATUS ("SetItemStatus") #define CI_IO_NAME_GET_CYCLIC_PERIOD ("GetCyclicPeriod") #define CI_IO_NAME_IO_COMPLETE ("IoComplete") // ---------------------------------------------------------------------------- /* ------------------------------------------------------------------------ */ /* ------------------ Data/enum types for this interface ------------------ */ /* ------------------------------------------------------------------------ */ /* * Item parameters (as used by CI_SetItemParam() and CI_GetItemParam()) * and their data types/structures are documented below */ typedef enum { CI_itemParamInputSize, /* Desc: Total size of input data for the indicated item * Type: uint16_t */ CI_itemParamOutputSize, /* Desc: Total size of output data for the indicated item * Type: uint16_t */ CI_itemParamCyclicness, /* Desc: Indicates whether the data for the indicated item is transferred on * the network each cycle (cyclic) or not (acyclic). * Type: CI_itemCyclicness_t */ /* place more item parameter ID codes here... */ CI_itemParamLast = 0xFFFF /* To force enumeration width */ } CI_itemParamId_t; /* Item data direction */ typedef enum { CI_itemDataDirInput, CI_itemDataDirOutput, CI_itemDataDirLast = 0xFFFF /* To force enumeration width */ } CI_itemDataDir_t; /* Item data path status */ typedef enum { CI_itemDataPathBad, CI_itemDataPathOk, CI_itemDataPathLast = 0xFFFF /* To force enumeration width */ } CI_itemDataPathStatus_t; /* Item cyclicness (i.e. whether or not item data is transferred every * network cycle or not) */ typedef enum { CI_itemCyclicnessAcyclic, CI_itemCyclicnessCyclic, CI_itemCyclicnessLast = 0xFFFF /* To force enumeration width */ } CI_itemCyclicness_t; /* IO status type (as returned by CI_ReadItem()) */ typedef enum { /* Data valid? New? Copied to caller's buffer? */ CI_ioStatusInvalid, /* No N/A No */ CI_ioStatusValid, /* Yes Yes Yes */ CI_ioStatusValidNotNew, /* Yes No Yes */ CI_ioStatusLast = 0xFFFFFFFF /* To force enumeration width */ } CI_ioStatus_t; /* Direct input/output data handler function prototype */ typedef void (CI_dirIoFunc_t)(); /* ------------------------------------------------------------------------- */ /* ------------------- Function types for this interface ------------------- */ /* ------ See the corresponding API header for function declarations ------ */ /* ------------------------------------------------------------------------- */ typedef int32_t (CI_setDevice_t)(uint16_t deviceId); typedef CI_setDevice_t (*CI_setDevice_tp); typedef int32_t (CI_setDeviceCustom_t)(void* device_p, uint32_t bufSize); typedef CI_setDeviceCustom_t (*CI_setDeviceCustom_tp); typedef int32_t (CI_getDevice_t)(void *device_p, uint16_t maxSize); typedef CI_getDevice_t (*CI_getDevice_tp); typedef int32_t (CI_addItem_t)(uint16_t id, uint32_t location); typedef CI_addItem_t (*CI_addItem_tp); typedef int32_t (CI_addItemCustom_t)(uint16_t id, void *data_p, uint32_t bufSize, uint32_t location); typedef CI_addItemCustom_t (*CI_addItemCustom_tp); typedef int32_t (CI_setItemParam_t)(int32_t handle, CI_itemParamId_t param, void *paramData_p, uint32_t paramSize); typedef CI_setItemParam_t (*CI_setItemParam_tp); typedef int32_t (CI_getItemParam_t)(int32_t handle, CI_itemParamId_t param, void *paramData_p, uint32_t paramSize); typedef CI_getItemParam_t (*CI_getItemParam_tp); typedef int32_t (CI_installDirectIo_t)(CI_dirIoFunc_t *dirInFunc_p, CI_dirIoFunc_t *dirOutFunc_p); typedef CI_installDirectIo_t (*CI_installDirectIo_tp); typedef int32_t (CI_removeItem_t)(int32_t handle); typedef CI_removeItem_t (*CI_removeItem_tp); typedef int32_t (CI_returnItem_t)(int32_t handle); typedef CI_returnItem_t (*CI_returnItem_tp); typedef int32_t (CI_writeItem_t)(int32_t handle, void *data_p); typedef CI_writeItem_t (*CI_writeItem_tp); typedef int32_t (CI_readItem_t)(int32_t handle, void *data_p); typedef CI_readItem_t (*CI_readItem_tp); typedef int32_t (CI_setItemStatus_t)(int32_t handle, CI_itemDataDir_t direction, CI_itemDataPathStatus_t status); typedef CI_setItemStatus_t (*CI_setItemStatus_tp); typedef int32_t (CI_getCyclicPeriod_t)(void); typedef CI_getCyclicPeriod_t (*CI_getCyclicPeriod_tp); typedef int32_t (CI_ioComplete_t)(void); typedef CI_ioComplete_t (*CI_ioComplete_tp); // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** // End Functions ************************************************************** #endif /* _CI_IO_TYPES_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_ITEMS_H_ #define _CI_ITEMS_H_ /***************************************************************************** * * This file contains structures to be used with the CI_AddItemCustom() * function * ****************************************************************************/ // Includes ******************************************************************* #include <stdint.h> // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** // ---------------------------------------------------------------------------- /* PROFINET item section =================================================== */ typedef enum { CI_pnetItemTypeCyclic, CI_pnetItemTypeAcyclic } CI_profinetItemType_t; #define CI_PNET_ITEM_VERSION 0 typedef struct { uint8_t type; // See CI_profinetItemType_t uint8_t pad1; uint8_t pad2; uint8_t pad3; uint32_t moduleID; uint32_t subModuleID; uint16_t outputBytes; uint16_t inputBytes; } CI_profinetItemCyclic_t; typedef struct { uint8_t type; // See CI_profinetItemType_t uint8_t pad; uint16_t index; uint16_t inputBytes; uint16_t outputBytes; } CI_profinetItemAcyclic_t; /* ========================================================================= */ /* EtherNet/IP item section ================================================ */ #define CI_EIP_ITEM_VERSION 0 typedef struct { uint8_t type; /* accumulating = 0 * incrementing = 1 * unique = 2 * configuration = 3 * diagnostic = 4 */ uint8_t pad; /* Always 0 */ uint16_t consumeInstanceID; /* Always 0 for diagnostic type */ uint16_t consumeSize; /* Consume size in bytes, always 0 for * diagnostic type */ uint16_t produceInstanceID; /* Always 0 for config type */ uint16_t produceSize; /* Produce size in bytes, always 0 for * configuration type */ } CI_etherNetIpItem_t; /* ========================================================================= */ /* EtherCAT item section ================================================ */ #define OBJECT_NAME_STR_LEN 16 // Arbitrary #define SUBINDEX_NAME_STR_LEN 16 // Arbitrary /* NOTE: The maximum number of data subindices dictates the length of the RxPDO * and TxPDO objects (and many others). This affects the corresponding data * type in the ESI file. If the maximum number of data subindices is changed, * the "Descriptions:Devices:Device:Profile:Dictionary:DataTypes:DataType" * for all application structs typed out (i.e. described) in the ESI file will * need to be updated. This definition could exist in multiple device * dictionaries. Every dictionary will need to be updated. */ #define MAX_DATA_SUBINDICES 16 /* EtherCAT item type (see type field in CI_ethercatItem_t) */ typedef enum { itemType_Data = 0, itemType_Configuration, itemType_Diagnostic } CI_ethercatItemType_t; /* EtherCAT object subindex */ typedef struct { uint16_t dataType; // Data type of this subindex (see EcatDataType_t) uint16_t arrLen; // Array length (only if array data type) char name[SUBINDEX_NAME_STR_LEN]; // Name of this subindex } CI_ethercatSubindexDesc_t; #define CI_ECAT_ITEM_VERSION 1 typedef struct { uint8_t type; // Item type (see CI_ethercatItemType_t) uint8_t pad; // Pad 0 char inputObjName[OBJECT_NAME_STR_LEN]; // Name of the input object char outputObjName[OBJECT_NAME_STR_LEN]; // Name of the output object CI_ethercatSubindexDesc_t inputSubindices[MAX_DATA_SUBINDICES]; // Data entries for each input subindex CI_ethercatSubindexDesc_t outputSubindices[MAX_DATA_SUBINDICES]; // Data entries for each output subindex } CI_ethercatItem_t; /* ========================================================================= */ // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** // End Functions ************************************************************** #endif /* _CI_ITEMS_H_ */
/* * Copyright (c) 2019-2020 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_SOCKET_API_H_ #define _CI_SOCKET_API_H_ // Includes ******************************************************************* #include "CI_socket_types.h" // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** /** * Set a socket to non-blocking IO * * Use CI_FIONBIO command to set socket to non-blocking mode. Other commands * CI_FIONREAD and CI_FIONWRITE not supported return error. * * Parameters * Dir Type Name Description * [in] int32_t socket Socket handle returned from the socket call * [in] int32_t cmd Command (CI_SOCK_FIONBIO, CI_SOCK_FIONREAD, or * CI_SOCK_FIONWRITE) * [in] uint32_t * arg_p Pointer to socket option data * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_IoctlSocketProto_t CI_IoctlSocket; /** * For SOCK_STREAM type sockets, respond to incomming connection requests * * Use one of the connection slots established by "listen" to create a new * socket and begin communications. * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the * socket call * [in] struct sockaddr * addr_p Pointer to an address structure * [in] socklen_t * addrlen_p Pointer to the size of the address * structure * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_acceptProto_t CI_Accept; /** * Bind an address (i.e. an interface) to a socket * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from * the socket call * [in] const struct sockaddr * addr_p Pointer to an address structure * [in] socklen_t addrlen Size of the address structure * * * This function assigns the address specified by addr_p to the socket. This * address references one of our interfaces. * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_bindProto_t CI_Bind; /** * Terminate communications and close a socket * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the socket call * [in] int32_t * err_p Pointer to an integer used to return the * stack's error code * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_closeSocketProto_t CI_CloseSocket; /** * Connect the socket to the address * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the * socket call * [in] struct sockaddr * addr_p Pointer to an address structure * [in] socklen_t addrlen The size of the address structure * * For SOCK_STREAM sockets this function will attempt to establish a connection * to the specified address * * Return * Type: int32_t * Values: CI_OK On success * CI_ERROR On failure * CI_SOCK_SOCKET_EISCONN Socket connection already established * CI_SOCK_SOCKET_EALREADY Connect already called by socket not connected * yet (non-blocking mode only) */ CI_connectProto_t CI_Connect; /** * Release the memory used by the addrinfo linked list * * Parameters * Dir Type Name Description * [in] struct addrinfo * res_p Pointer to a linked list of addrinfo * structs * Return nothing */ CI_freeAddrInfoProto_t CI_FreeAddrInfo; /** * Return the address of the specified host and/or service * * Parameters * Dir Type Name Description * [in] const char * node_p Host name or dotted string * address * [in] const char * service_p Service or port name * [in] const struct addrinfo * hints_p Pointer to addrinfo struct * [out] struct addrinfo ** res_p Pointer to a linked list of * addrinfo structs * * This function directly returns a translated version of whatever the IP stack * returns. This is either zero for success or a non-zero error code. * * To avoid memory leaks, call CI_FreeAddrInfo to release the memory used by * res_p. * * Return * Type: int32_t * Values: 0 on success * <0 on failure * (see http://man7.org/linux/man-pages/man3/getaddrinfo.3.html) */ CI_getAddrInfoProto_t CI_GetAddrInfo; /** * Return the last socket error code * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the socket call * [out] int32_t * err_p Pointer to an integer to receive the last error * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_getLastSocketErrorProto_t CI_GetLastSocketError; /** * Convert a socket address to a corresponding host and service * * Parameters * Dir Type Name Description * [in] const struct sockaddr * addr_p Pointer to a socket address to * be translated * [in] socklen_t addrlen Size of the socket address * [out] char * host_p Pointer to a buffer the * function will use to return the * host name * [in] int32_t hostlen Length of the buffer * [out] char * serv_p Pointer to a buffer the * function will use to return the * service name * [in] int32_t servlen Length of the buffer * [in] int32_t flags Flags used to alter the * behavior of GetNameInfo * * This function directly returns a translated version of whatever the IP stack * returns. This is either zero for success or a non-zero error code. * * Return * Type: int32_t * Values: 0 on success * <0 on failure * (see http://man7.org/linux/man-pages/man3/getnameinfo.3.html */ CI_getNameInfoProto_t CI_GetNameInfo; /** * Returns the address of the peer connected to the socket * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the * socket call * [in] struct sockaddr * addr_p Pointer to an address structure * [in] socklen_t * addrlen_p The size of the address structure * * See http://man7.org/linux/man-pages/man2/getpeername.2.html * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_getPeerNameProto_t CI_GetPeerName; /** * Return the address to which the socket is bound * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the * socket call * [out] struct sockaddr * addr_p Pointer to an address structure * [out] socklen_t * addrlen_p Pointer to the size of the address * structure * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_getSockNameProto_t CI_GetSockName; /** * Return the specified option state/data from a specified socket * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the socket * call * [in] int32_t level The protocol level at which the option * resides * [in] int32_t optname The single option to set/get * [out] void * optval_p Pointer to buffer to receive the data * specific to this option * [out] socklen_t * optlen Pointer to the option data length * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_getSockOptProto_t CI_GetSockOpt; /** * Begin waiting for a connection * * Set the socket up to be used to allow incoming connection requests using * accept * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the socket call * [in] int32_t backlog the max number of allowed connections * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_listenProto_t CI_Listen; /** * Receive a message from another socket * * Once the socket is in the connected state recv is used to communicate with * the remote connection. * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the socket * call * [out] const void * buf_p Pointer to a buffer to receive the data * [in] int32_t length The length (in bytes) of the buffer * [in] int32_t flags Not supported, use 0 * * Return * Type: int32_t * Values: On success, the number of bytes received * CI_ERROR on failure */ CI_recvProto_t CI_Recv; /** * Receive a message from another socket * * When a message is recieved from a remote peer the data is placed into the * provided buffer and the peer's address is placed into the supplied address * structure. * * Parameters * Dir Type Name Description * [in] int32_t socket the socket handle returned from the * socket call * [out] const void * buf_p pointer to a buffer to receive the * data * [in] int32_t length The length (in bytes) of the buffer * [in] int32_t flags Not supported, use 0 * [in] struct sockaddr * addr_p Pointer to an address structure * [in] socklen_t * addrlen_p Pointer to the size of the address * structure * * Return * Type: int32_t * Values: On success, the number of bytes received * CI_ERROR on failure */ CI_recvFromProto_t CI_RecvFrom; /** * Wait for a file descriptor * * When a socket operation is ready the file descriptor will indicate this * * Parameters * Dir Type Name Description * [in] int32_t nfds Number of file descriptors to wait on * [in] fd_set * readset_p The set of read descriptors * [in] fd_set * writeset_p The set of write descriptors * [in] fd_set * exceptset_p The set of exception descriptors * [in] int32_t timeoutMicroSec the max time (in uSec) to wait before * returning, use -1 to wait forever * * Return * Type: int32_t * Values: On success, the number of set bits in the file descriptors * CI_ERROR on failure */ CI_selectProto_t CI_Select; /** * File descriptor "macro" functions to accompany select * * Since the file descriptors and FD set data structures are particular to each * TCP/IP stack implementation, we need to add porting layer functions to * provide access to these. * * CI_GetFdSet() -------------------------------------------------------------- * Parameters * None * * Return * Nothing * * CI_ReturnFdSet() ----------------------------------------------------------- * Parameters * Dir Type Name Description * void * set_p Pointer to a set of descriptors * * Return * Nothing * * CI_FdClr() ----------------------------------------------------------------- * Parameters * Dir Type Name Description * int32_t fd A particular file descriptor (socket handle) * void * set_p Pointer to a set of descriptors * * Return * Nothing * * CI_FdIsSet() --------------------------------------------------------------- * Parameters * Dir Type Name Description * int32_t fd A particular file descriptor (socket handle) * void * set_p Pointer to a set of descriptors * * Return * Type: int32_t * Values: 0 if specified fd is not a part of the set * 1 if specified fd is a part of the set * * CI_FdSet() ----------------------------------------------------------------- * Parameters * Dir Type Name Description * int32_t fd A particular file descriptor (socket handle) * void * set_p Pointer to a set of descriptors * * Return * Nothing * * CI_FdZero() ---------------------------------------------------------------- * Parameters * Dir Type Name Description * void * set_p Pointer to a set of descriptors * * Return * Nothing * * The IP stack definitions of things like file descriptors and the associated * macros are very specific to that IP stack. The following group of functions * provide that interface here. */ CI_getFdSetProto_t CI_GetFdSet; CI_returnFdSetProto_t CI_ReturnFdSet; CI_fdClrProto_t CI_FdClr; CI_fdIsSetProto_t CI_FdIsSet; CI_fdSetProto_t CI_FdSet; CI_fdZeroProto_t CI_FdZero; /** * Transmit a message to another socket * * Once the socket is in the connected state send is used to communicate with * the remote connection * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the socket * call * [out] const void * buf_p Pointer to the payload data to send * [in] int32_t length Length (in bytes) of the payload data * [in] int32_t flags Not supported, use 0 * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_sendProto_t CI_Send; /** * Transmit a message to another socket * * Send a message to the remote peer at the specified address * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the * socket call * [in] const void * buf_p Pointer to the payload data to send * [in] int32_t length The length (in bytes) of the payload * data * [in] int32_t flags Not supported, use 0 here * [in] struct sockaddr * addr_p Pointer to an address structure * [in] socklen_t addrlen The size of the address structure * * Return * Type: int32_t * Values: On success, the number of bytes sent * CI_ERROR on failure */ CI_sendToProto_t CI_SendTo; /** * Invoke a specified option on a specified socket * * Parameters * Dir Type Name Description * [in] int32_t socket The socket handle returned from the socket * call * [in] int32_t level The protocol level at which the option * resides * [in] int32_t optname The single option to set/get * [in] const void * optval_p The data specific to this option * [in] socklen_t optlen The data length * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_setSockOptProto_t CI_SetSockOpt; /** * Create an endpoint for communication * * Create and initialize a socket within the TCP/IP stack * * Parameters * Dir Type Name Description * [in] int32_t domain Communications domain, use AF_INET or * AF_PACKET * [in] int32_t type Socket type, use one of SOCK_STREAM, SOCK_DGRAM or SOCK_RAW * [in] int32_t protocol Socket protocol, use one of IPPROTO_IP or IPPROTO_UDP or 0 * [out] int32_t * err_p Pointer to an integer used to return the * stack's error code * * Return * Type: int32_t * Values: On success, a socket handle is returned (this could be zero) * On error, CI_ERROR */ CI_socketProto_t CI_Socket; /** * Shut down a socket in the direction(s) indicated * * Parameters * Dir Type Name Description * [in] int32_t fd Socket descriptor * [in] int32_t direction Direction to shut down, use CI_SHUT_RD or * CI_SHUT_WR or * CI_SHUT_RDWR) * [out] int32_t * err_p Pointer to location in which to place any * error codes * * Return * Type: int32_t * Values: IPM_OK on success * IPM_ERROR on failure */ CI_shutdown_t CI_Shutdown; /** * Convert from ASCII internet address to network ordered address * * Converts a ASCII internet address (e.g. "192.168.1.1") to a network ordered * address of an integer type * * Parameters * Dir Type Name Description * [in] const char * c_p Pointer to ASCII string to be converted * * Return * Type: uint32_t * Values: On success, a network ordered IP address (uint32_t) * On error, 0 */ CI_inetAddr_t CI_InetAddr; /** * Network ordered address to ASCII internet address * * Converts a network ordered unsigned integer address to a ASCII internet * address (e.g. "192.168.1.1") * * Parameters * Dir Type Name Description * [in] struct in_addr in Network ordered address * * Return * Type: char * * Values: pointer to ASCII internet address string */ CI_inetNtoA_t CI_InetNtoA; // End Functions ************************************************************** #endif /* _CI_SOCKET_API_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_SOCKET_DEFINES_H_ #define _CI_SOCKET_DEFINES_H_ #pragma pack(push, 1) // Includes ******************************************************************* #ifdef WIN32 #include <winsock2.h> #endif #include "CI_codes.h" // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** #define CI_FDSET_SIZE (CI_MAX_SOCKETS + 1) #define CI_FDSET_FD_NBITS 32 /* * Define the following macro if this library is to be executed on a * little-endian processor. Comment it out if it is to be run on a big-endian * processor. */ #define CI_LITTLE_ENDIAN #ifdef CI_LITTLE_ENDIAN /* Little endian swapping macros */ #define CI_NTOHS(x) (uint16_t)( \ (((uint16_t)x << 8) & 0xFF00) | \ (((uint16_t)x >> 8) & 0x00FF)) #define CI_NTOHL(x) (uint32_t)( \ (((uint32_t)x << 24) & 0xFF000000) | \ (((uint32_t)x << 8) & 0x00FF0000) | \ (((uint32_t)x >> 8) & 0x0000FF00) | \ (((uint32_t)x >> 24) & 0x000000FF)) #define CI_NTOHLL(x) (uint64_t)( \ (((uint64_t)x << 56) & 0xFF00000000000000ULL) | \ (((uint64_t)x << 40) & 0x00FF000000000000ULL) | \ (((uint64_t)x << 24) & 0x0000FF0000000000ULL) | \ (((uint64_t)x << 8) & 0x000000FF00000000ULL) | \ (((uint64_t)x >> 8) & 0x00000000FF000000ULL) | \ (((uint64_t)x >> 24) & 0x0000000000FF0000ULL) | \ (((uint64_t)x >> 40) & 0x000000000000FF00ULL) | \ (((uint64_t)x >> 56) & 0x00000000000000FFULL)) #define CI_HTONS CI_NTOHS #define CI_HTONL CI_NTOHL #define CI_HTONLL CI_NTOHLL #else /* Big endian swapping macros */ #define CI_NTOHS(x) (uint16_t)(x) #define CI_NTOHL(x) (uint32_t)(x) #define CI_NTOHLL(x) (uint64_t)(x) #define CI_HTONS CI_NTOHS #define CI_HTONL CI_NTOHL #define CI_HTONLL CI_NTOHLL #endif // Common socket success/error codes: #define CI_SOCK_UNKNOWN_OPTION (int32_t) -100 #define CI_SOCK_SOCKET_EISCONN (int32_t) -101 #define CI_SOCK_SOCKET_EALREADY (int32_t) -102 #define CI_SOCK_DIGEST_AUTH_NONCE_EXPIRE_ERR (int32_t) -103 #define CI_SOCK_DIGEST_AUTH_NONCE_STALE_ERR (int32_t) -104 /* socket shutdown codes */ #define CI_SHUT_RD 0 #define CI_SHUT_WR 1 #define CI_SHUT_RDWR 2 /* Translated network/socket error codes: */ #define CI_EPERM 1 #define CI_ENOENT 2 #define CI_ESRCH 3 #define CI_EINTR 4 #define CI_EIO 5 #define CI_ENXIO 6 #define CI_E2BIG 7 #define CI_ENOEXEC 8 #define CI_EBADF 9 #define CI_ECHILD 10 #define CI_EAGAIN 11 #define CI_ENOMEM 12 #define CI_EACCES 13 #define CI_EFAULT 14 #define CI_ENOTBLK 15 #define CI_EBUSY 16 #define CI_EEXIST 17 #define CI_EXDEV 18 #define CI_ENODEV 19 #define CI_ENOTDIR 20 #define CI_EISDIR 21 #define CI_EINVAL 22 #define CI_ENFILE 23 #define CI_EMFILE 24 #define CI_ENOTTY 25 #define CI_ETXTBSY 26 #define CI_EFBIG 27 #define CI_ENOSPC 28 #define CI_ESPIPE 29 #define CI_EMLINK 30 #define CI_EPIPE 31 #define CI_EDOM 32 #define CI_ERANGE 33 #define CI_ENOMSG 34 #define CI_EIDRM 35 #define CI_EDEADLOCK 36 #define CI_EWOULDBLOCK 37 #define CI_EINPROGRESS 38 #define CI_EALREADY 39 #define CI_ENOTSOCK 40 #define CI_EDESTADDRREQ 41 #define CI_EMSGSIZE 42 #define CI_EPROTOTYPE 43 #define CI_ENOPROTOOPT 44 #define CI_EPROTONOSUPPORT 45 #define CI_ESOCKTNOSUPPORT 46 #define CI_EOPNOTSUPP 47 #define CI_EAFNOSUPPORT 48 #define CI_EADDRINUSE 49 #define CI_EADDRNOTAVAIL 50 #define CI_ENETDOWN 51 #define CI_ENETUNREACH 52 #define CI_ENETRESET 53 #define CI_ECONNABORTED 54 #define CI_ECONNRESET 55 #define CI_ENOBUFS 56 #define CI_EISCONN 57 #define CI_ENOTCONN 58 #define CI_ESHUTDOWN 59 #define CI_ETIMEDOUT 60 #define CI_ECONNREFUSED 61 #define CI_EPFNOSUPPORT 62 #define CI_EHOSTDOWN 63 #define CI_EHOSTUNREACH 64 #define CI_ENOURGENTDATA 65 #define CI_ENOOOBDATA 66 #define CI_ETOOMANYREFS 67 #define CI_EUNATCH 68 #define CI_ELNRNG 69 #define CI_ENETUNKNOWN 70 /* Locally defined Socket option levels and Socket protocol codes: */ #define CI_SOL_SOCKET 1 #define CI_IPPROTO_IP 2 #define CI_IPPROTO_IPV6 3 #define CI_IPPROTO_TCP 4 #define CI_IPPROTO_UDP 5 /* Locally defined Socket option names: */ #define CI_SO_DEBUG 1 #define CI_SO_ACCEPTCONN 2 #define CI_SO_REUSEADDR 3 #define CI_SO_KEEPALIVE 4 #define CI_SO_DONTROUTE 5 #define CI_SO_LINGER 6 #define CI_SO_THROUGHPUT 7 #define CI_SO_EXPEDITE 8 #define CI_SO_BROADCAST 9 #define CI_SO_REUSEPORT 10 #define CI_SO_NOCHKSUM 11 #define CI_SO_NO_WAKEUP 12 #define CI_SO_NO_WAKEUP_INHERIT 13 #define CI_SO_ERROR 14 #define CI_SO_MAXMSG 15 #define CI_SO_MYADDR 16 #define CI_SO_NONBLOCK 17 #define CI_SO_OOBINLINE 18 #define CI_SO_RCVBUF 19 #define CI_SO_RXDATA 20 #define CI_SO_SNDBUF 21 #define CI_SO_TYPE 22 #define CI_SO_BIO 23 #define CI_SO_NBIO 24 #define CI_SO_MSG_PRIORITY 25 #define CI_SO_VLAN_MSG_PRIORITY 26 #define CI_SO_BINDTODEVICE 27 #define CI_IP_O_TOS 28 #define CI_IP_O_FRAG 29 #define CI_IP_O_SECURE 30 #define CI_IP_O_LSRR 31 #define CI_IP_O_SSRR 32 #define CI_IP_O_RR 33 #define CI_IP_O_STREAM 34 #define CI_IP_O_TIME 35 #define CI_IP_ADD_MEMBERSHIP 36 #define CI_IP_DROP_MEMBERSHIP 37 #define CI_IP_MULTICAST_IF 38 #define CI_IP_MULTICAST_LOOP 39 #define CI_IP_MULTICAST_TTL 40 #define CI_IP_TTL 41 #define CI_IP_BLOCK_SOURCE 42 #define CI_IP_UNBLOCK_SOURCE 43 #define CI_IP_ADD_SOURCE_MEMBERSHIP 44 #define CI_IP_DROP_SOURCE_MEMBERSHIP 45 #define CI_MCAST_JOIN_GROUP 46 #define CI_MCAST_LEAVE_GROUP 47 #define CI_MCAST_BLOCK_SOURCE 48 #define CI_MCAST_UNBLOCK_SOURCE 49 #define CI_MCAST_JOIN_SOURCE_GROUP 50 #define CI_MCAST_LEAVE_SOURCE_GROUP 51 #define CI_IPV6_MULTICAST_IF 52 #define CI_IPV6_MULTICAST_HOPS 53 #define CI_IPV6_MULTICAST_LOOP 54 #define CI_IPV6_JOIN_GROUP 55 #define CI_IPV6_LEAVE_GROUP 56 #define CI_IPV6_V6ONLY 57 #define CI_IPV6_PREFER_TEMP_ADDRS 58 #define CI_IPV6_TCLASS 59 #define CI_TCP_ACKDELAYTIME 60 #define CI_TCP_ACKNSEG 61 #define CI_TCP_ADAPT_ACKNSEG 62 #define CI_TCP_PERMIT_SACKS 63 #define CI_TCP_SEND_SACKS 64 #define CI_TCP_FAST_RETR_RECOV 65 #define CI_TCP_SLOW_START_CA 66 #define CI_TCP_MAX_TTL 67 #define CI_TCP_KEEPALIVE_CNT 68 #define CI_TCP_KEEPALIVE_IDLE 69 #define CI_TCP_KEEPALIVE_INTVL 70 #define CI_TCP_ENABLE_PAWS 71 #define CI_TCP_MAXSEG 72 #define CI_TCP_NODELAY 73 #define CI_TCP_O_SEQNO 74 #define CI_TCP_PROVIDE_TIMESTAMPS 75 #define CI_TCP_REX_MAX 76 #define CI_TCP_REX_MIN 77 #define CI_TCP_REX_INIT 78 #define CI_TCP_RTT_ALGORITHM 79 #define CI_TCP_SET_RCV_MSS 80 #define CI_TCP_USE_PEER_MSS_OPTION 81 #define CI_TCP_WINDOW_SCALE 82 /* Socket "type" codes */ #define CI_SOCK_STREAM 1 #define CI_SOCK_DGRAM 2 #define CI_SOCK_RAW 3 /* Defines for CI_IoctlSocket commands. Values are arbitrary. */ #define CI_FIONBIO 0 #define CI_FIONREAD 1 #define CI_FIONWRITE 2 /* AF/PF Defines */ #ifndef AF_INET #define AF_INET 1 #endif #ifndef AF_PACKET #define AF_PACKET 1 #endif #ifndef PF_INET #define PF_INET AF_INET #endif #ifndef PF_PACKET #define PF_PACKET AF_PACKET #endif #ifndef INADDR_ANY #define INADDR_ANY 0x00000000L #endif // ---------------------------------------------------------------------------- #ifndef sa_family_t typedef uint16_t sa_family_t; #endif #ifndef IP_SERVICE struct sockaddr { sa_family_t sa_family; int8_t sa_data[28]; }; struct in_addr { uint32_t s_addr; }; struct sockaddr_in { int16_t sin_family; uint16_t sin_port; struct in_addr sin_addr; char sin_zero[8]; }; struct ip_mreq { struct in_addr imr_multiaddr; struct in_addr imr_interface; }; struct ip_mreq_source { struct in_addr imr_multiaddr; struct in_addr imr_sourceaddr; struct in_addr imr_interface; }; struct linger { int32_t l_onoff; int32_t l_linger; }; struct ipot_t { uint8_t pointer; uint8_t oflw_flg; uint32_t ipt_addr[9]; }; typedef struct { uint32_t fd[(CI_FDSET_SIZE/CI_FDSET_FD_NBITS)+1]; } fd_set; #endif /* BSD Socket structs */ #ifndef socklen_t typedef int32_t socklen_t; #endif #ifndef WIN32 struct addrinfo { int32_t ai_flags; int32_t ai_family; int32_t ai_socktype; int32_t ai_protocol; socklen_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }; #endif // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** // End Functions ************************************************************** // Unset the packing setting used for this file to the previous one #pragma pack(pop) #endif /* _CI_SOCKET_DEFINES_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_SOCKET_TYPES_H_ #define _CI_SOCKET_TYPES_H_ // Includes ******************************************************************* #include <stdint.h> #include "CI_socket_defines.h" // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** /*************************************************************************** * IMPORTANT: The interface version below is used to detect CHANGES the to * functions in the interface and SHALL be updated any time there is a change * to ANY function in this header that is part of a registered (i.e. used with * the registrar) interface. "Change" in this case only means a change to the * SIGNATURE of a function. The interface version need not be updated if the * number of functions in the interface changes (i.e. a function is added or * removed). ***************************************************************************/ #define CI_SOCKET_VER_MAJ 0x01 #define CI_SOCKET_VER_MIN 0x02 #define CI_SOCKET_VER ((CI_SOCKET_VER_MAJ << 16) | CI_SOCKET_VER_MIN) #define CI_SOCKET_NAME ("CI_socketIf") /* API Function Name List */ #define CI_SOCKET_NAME_VERSION ("Version") /* 1st in list */ #define CI_SOCKET_NAME_IOCTLSOCKET ("IoctlSocket") #define CI_SOCKET_NAME_ACCEPT ("Accept") #define CI_SOCKET_NAME_BIND ("Bind") #define CI_SOCKET_NAME_CLOSESOCKET ("CloseSocket") #define CI_SOCKET_NAME_CONNECT ("Connect") #define CI_SOCKET_NAME_FREEADDRINFO ("FreeAddrInfo") #define CI_SOCKET_NAME_GETADDRINFO ("GetAddrInfo") #define CI_SOCKET_NAME_GETLASTSOCKETERROR ("GetLastSockErr") #define CI_SOCKET_NAME_GETNAMEINFO ("GetNameInfo") #define CI_SOCKET_NAME_GETPEERNAME ("GetPeerName") #define CI_SOCKET_NAME_GETSOCKNAME ("GetSockName") #define CI_SOCKET_NAME_GETSOCKOPT ("GetSockOpt") #define CI_SOCKET_NAME_LISTEN ("Listen") #define CI_SOCKET_NAME_RECV ("Recv") #define CI_SOCKET_NAME_RECVFROM ("RecvFrom") #define CI_SOCKET_NAME_SELECT ("Select") #define CI_SOCKET_NAME_GETFDSET ("GetFdSet") #define CI_SOCKET_NAME_RETURNFDSET ("ReturnFdSet") #define CI_SOCKET_NAME_FDCLR ("FD_CLR") #define CI_SOCKET_NAME_FDISSET ("FD_ISSET") #define CI_SOCKET_NAME_FDSET ("FD_SET") #define CI_SOCKET_NAME_FDZERO ("FD_ZERO") #define CI_SOCKET_NAME_SEND ("Send") #define CI_SOCKET_NAME_SENDTO ("SendTo") #define CI_SOCKET_NAME_SETSOCKOPT ("SetSockOpt") #define CI_SOCKET_NAME_SOCKET ("Socket") #define CI_SOCKET_NAME_SHUTDOWN ("Shutdown") #define CI_SOCKET_NAME_INET_ADDR ("InetAddr") #define CI_SOCKET_NAME_INET_NTOA ("InetNtoA") // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ /* indexes must match order of CI_socketIf_g array */ typedef enum { CI_SOCKETS_UTILS_VERSION_INDEX, CI_SOCKETS_IOCTLSOCKET_INDEX, CI_SOCKETS_ACCEPT_INDEX, CI_SOCKETS_BIND_INDEX, CI_SOCKETS_CLOSESOCKET_INDEX, CI_SOCKETS_CONNECT_INDEX, CI_SOCKETS_FREEADDRINFO_INDEX, CI_SOCKETS_GETADDRINFO_INDEX, CI_SOCKETS_GETLASTSOCKERR_INDEX, CI_SOCKETS_GETNAMEINFO_INDEX, CI_SOCKETS_GETPEERNAME_INDEX, CI_SOCKETS_GETSOCKNAME_INDEX, CI_SOCKETS_GETSOCKOPT_INDEX, CI_SOCKETS_LISTEN_INDEX, CI_SOCKETS_RECV_INDEX, CI_SOCKETS_RECVFROM_INDEX, CI_SOCKETS_SELECT_INDEX, CI_SOCKETS_GETFDSET_INDEX, CI_SOCKETS_RETURNFDSET_INDEX, CI_SOCKETS_FD_CLR_INDEX, CI_SOCKETS_FD_ISSET_INDEX, CI_SOCKETS_FD_SET_INDEX, CI_SOCKETS_FD_ZERO_INDEX, CI_SOCKETS_SEND_INDEX, CI_SOCKETS_SENDTO_INDEX, CI_SOCKETS_SETSOCKOPT_INDEX, CI_SOCKETS_SOCKET_INDEX, CI_SOCKETS_SHUTDOWN_INDEX, CI_SOCKETS_INET_ADDR_INDEX, CI_SOCKETS_INET_NTOA_INDEX, CI_SOCKETS_NUM_FUNC_INDEXES /* this value always last */ } CI_socketsIndex_t; // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** /* ------------------------------------------------------------------------- */ /* ------------------- Function types for this interface ------------------- */ /* ------ See the corresponding API header for function declarations ------ */ /* ------------------------------------------------------------------------- */ typedef int32_t (CI_IoctlSocketProto_t)(int32_t socket, int32_t cmd, uint32_t *argp); typedef CI_IoctlSocketProto_t (*CI_IoctlSocket_tp); typedef int32_t (CI_acceptProto_t)(int32_t socket, struct sockaddr *addr_p, socklen_t *addrlen_p); typedef CI_acceptProto_t (*CI_accept_tp); typedef int32_t (CI_bindProto_t)(int32_t socket, const struct sockaddr *addr_p, socklen_t addrlen); typedef CI_bindProto_t (*CI_bind_tp); typedef int32_t (CI_closeSocketProto_t)(int32_t socket, int32_t *err_p); typedef CI_closeSocketProto_t (*CI_closeSocket_tp); typedef int32_t (CI_connectProto_t)(int32_t socket, struct sockaddr *addr_p, socklen_t addrlen); typedef CI_connectProto_t (*CI_connect_tp); typedef void (CI_freeAddrInfoProto_t)(struct addrinfo *res_p); typedef CI_freeAddrInfoProto_t (*CI_freeAddrInfo_tp); typedef int32_t (CI_getAddrInfoProto_t)(const char *node_p, const char *service_p, const struct addrinfo *hints_p, struct addrinfo **res_p); typedef CI_getAddrInfoProto_t (*CI_getAddrInfo_tp); typedef int32_t (CI_getLastSocketErrorProto_t)(int32_t socket, int32_t *err_p); typedef CI_getLastSocketErrorProto_t (*CI_getLastSocketError_tp); typedef int32_t (CI_getNameInfoProto_t)(const struct sockaddr *addr_p, socklen_t addrlen, char *host_p, int32_t hostlen, char *serv_p, int32_t servlen, int32_t flags); typedef CI_getNameInfoProto_t (*CI_getNameInfo_tp); typedef int32_t (CI_getPeerNameProto_t)(int32_t socket, struct sockaddr *addr_p, socklen_t *addrlen_p); typedef CI_getPeerNameProto_t (*CI_getPeerName_tp); typedef int32_t (CI_getSockNameProto_t)(int32_t socket, struct sockaddr *addr_p, socklen_t *addrlen_p); typedef CI_getSockNameProto_t (*CI_getSockName_tp); typedef int32_t (CI_getSockOptProto_t)(int32_t socket, int32_t level, int32_t optname, void *optval_p, socklen_t *optlen); typedef CI_getSockOptProto_t (*CI_getSockOpt_tp); typedef int32_t (CI_listenProto_t)(int32_t socket, int32_t backlog); typedef CI_listenProto_t (*CI_listen_tp); typedef int32_t (CI_recvProto_t)(int32_t socket, void *buf_p, int32_t length, int32_t flags); typedef CI_recvProto_t (*CI_recv_tp); typedef int32_t (CI_recvFromProto_t)(int32_t socket, void *buf_p, int32_t length, int32_t flags, struct sockaddr *addr_p, socklen_t *addrlen_p); typedef CI_recvFromProto_t (*CI_recvFrom_tp); typedef int32_t (CI_selectProto_t)(int32_t nfds, fd_set *readset_p, fd_set *writeset_p, fd_set *exceptset_p, int32_t timeoutMicroSec); typedef CI_selectProto_t (*CI_select_tp); typedef void *(CI_getFdSetProto_t)(); typedef CI_getFdSetProto_t (*CI_getFdSet_tp); typedef void (CI_returnFdSetProto_t)(void *set_p); typedef CI_returnFdSetProto_t (*CI_returnFdSet_tp); typedef void (CI_fdClrProto_t)(int32_t fd, void *set_p); typedef CI_fdClrProto_t (*CI_fdClr_tp); typedef int32_t (CI_fdIsSetProto_t)(int32_t fd, void *set_p); typedef CI_fdIsSetProto_t (*CI_fdIsSet_tp); typedef void (CI_fdSetProto_t)(int32_t fd, void *set_p); typedef CI_fdSetProto_t (*CI_fdSet_tp); typedef void (CI_fdZeroProto_t)(void *set_p); typedef CI_fdZeroProto_t (*CI_fdZero_tp); typedef int32_t (CI_sendProto_t)(int32_t socket, const void *buf_p, int32_t length, int32_t flags); typedef CI_sendProto_t (*CI_send_tp); typedef int32_t (CI_sendToProto_t)(int32_t socket, const void *buf_p, int32_t length, int32_t flags, struct sockaddr *addr_p, socklen_t addrlen); typedef CI_sendToProto_t (*CI_sendTo_tp); typedef int32_t (CI_setSockOptProto_t)(int32_t socket, int32_t level, int32_t optname, const void *optval_p, socklen_t optlen); typedef CI_setSockOptProto_t (*CI_setSockOpt_tp); typedef int32_t (CI_socketProto_t)(int32_t domain, int32_t type, int32_t protocol, int32_t *err_p); typedef CI_socketProto_t (*CI_socket_tp); typedef int32_t (CI_shutdown_t)(int32_t fd, int32_t direction, int32_t *err_p); typedef CI_shutdown_t (*CI_shutdown_tp); typedef uint32_t (CI_inetAddr_t)(const char *c_p); typedef CI_inetAddr_t (*CI_inetAddr_tp); typedef char * (CI_inetNtoA_t)(struct in_addr in); typedef CI_inetNtoA_t (*CI_inetNtoA_tp); // End Functions ************************************************************** #endif /* _CI_SOCKET_TYPES_H_ */
/* * Copyright (c) 2019-2020 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_SYSTEM_API_H_ #define _CI_SYSTEM_API_H_ // Includes ******************************************************************* #include "CI_system_types.h" // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** /** * Get a basket from the IO configuration file * * Parameters * Dir Type Name Description * [in] uint16_t basketID Basket ID number (from IO config file) * * Return * Type: CI_basket_t * * Values: pointer to CI_basket_t structure containing the contents of the * specified basket or NULL if the basket doesn't exist */ CI_getBasket_t CI_GetBasket; /** * Get the protocol implemented by the underlying network application * * Parameters * NONE * * Return * Type: CI_protocol_t * Values: protocol implemented by the network application (see CI_protocol_t) * CI_protocolError if retrieval failed */ CI_getProtocol_t CI_GetProtocol; /** * Set a system parameter * * Parameters * Dir Type Name Description * [in] CI_systemParam_t param The system parameter to set * [in] void * paramData_p Pointer to buffer in which the * desired system parameter data * currently resides * [in] uint16_t paramSize The number of bytes in the buffer * pointed to by paramData_p * * The number of bytes in a given system parameter varies from parameter to * parameter. See the definition of CI_systemParam_t for the sizes and * structures of each parameter. * * For string parameters the value of paramSize must be less than or equal to * the value shown in CI_systemParam_t. Otherwise, an error will be returned if * the caller provides fewer bytes than the size of the indicated parameter as * indicated by the paramSize argument. * * Return * Type: int32_t * Values: CI_OK on success * CI_INVALID_PARAM if parameter not a writeable parameter * CI_INVALID_PARAM on unrecognized system parameter * CI_INVALID_PARAM on NULL parameter data pointer * CI_INVALID_PARAM if paramSize argument < size of indicated parameter * CI_ERROR if called after CI_ConfigComplete() */ CI_setSystemParam_t CI_SetSystemParam; /** * Get a system parameter * * Parameters * Dir Type Name Description * [in] CI_systemParam_t param The system parameter of interest (see * CI_systemParam_t for examples and * descriptions of system parameters) * [out] void * paramData_p Pointer to buffer into which the system * parameter data should be copied * [in] int32_t paramLen_p The number of bytes available in the * buffer pointed to by paramData_p * * The number of bytes in a given system parameter varies from parameter to * parameter. See the definition of CI_systemParam_t for the sizes and * structures of each parameter. * * Return * Type: int32_t * Values: number of bytes copied to caller's buffer (i.e. the parameter size) * CI_INVALID_PARAM if parameter not a readable parameter * CI_INVALID_PARAM on unrecognized system parameter * CI_INVALID_PARAM on NULL parameter data pointer */ CI_getSystemParam_t CI_GetSystemParam; /** * Apply and/or store the system IP settings. * * Parameters * Dir Type Name Description * [in] bool store set to true to override stored settings * * Return * Type: int32_t * Values: CI_OK on success * CI_INVALID_PARAM if IP settings conflict * CI_ERROR if error in applying IP settings. */ CI_applySystemIpParam_t CI_ApplySystemIpParam; /** * Store the ethernet settings in non-volatile memory. * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR if error storing settings in NVM */ CI_storeSystemEthParam_t CI_StoreSystemEthParam; /** * Set the value of an industrial Ethernet protocol parameter * * Parameters * Dir Type Name Description * [in] CI_protocolParam_t param The protocol parameter to set (see * CI_protocolParam_t) * [in] void * paramData_p Pointer to buffer in which the * desired parameter data currently * resides * [in] uint32_t paramSize The number of bytes in the buffer * pointed to by paramData_p * * The number of bytes in a given protocol parameter varies from parameter to * parameter. See the definition of CI_protocolParam_t for the sizes and * structures of each parameter. * * Return * Type: int32_t * Values: CI_OK on success * CI_INVALID_PARAM if protocol parameter unsupported * CI_INVALID_PARAM if protocol parameter data pointer == NULL * CI_INVALID_PARAM if protocol parameter size incorrect * CI_ERROR on error */ CI_setProtocolParam_t CI_SetProtocolParam; /** * Get the value of an industrial Ethernet protocol parameter * * Parameters * Dir Type Name Description * [in] CI_protocolParam_t param The protocol parameter of interest * (see CI_protocolParam_t) * [out] void * paramData_p Pointer to buffer into which the * protocol parameter data should be * copied * [in] uint32_t paramSize Size (in bytes) of the requested * parameter data * * Return * Type: int32_t * Values: CI_OK on success * CI_INVALID_PARAM if protocol parameter unsupported * CI_INVALID_PARAM if protocol parameter data pointer == NULL * CI_INVALID_PARAM if protocol parameter size incorrect * CI_ERROR on error */ CI_getProtocolParam_t CI_GetProtocolParam; /** * Indicate that configuration is complete (device set, all items added, system * parameters set, etc.). * * This is the last function called during configuration time. No further calls * should be made to CI_AddItem(), etc. No calls to standard operation * functions (e.g. CI_WriteItem(), CI_ReadItem()) should be made before this * function is called. * * Parameters * NONE * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR if there is a problem with the system */ CI_configComplete_t CI_ConfigComplete; /** * Set the status for the IO app side of the system * * Parameters * Dir Type Name Description * [in] CI_systemStatus_t status New IO app status to report to * network app * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR if system not configured */ CI_setSysStatus_t CI_SetSystemStatus; /** * Get the status of the network application side of the system * * Return * Type: int32_t * Values: CI_systemStatus_t on success * CI_ERROR if system not configured */ CI_getSysStatus_t CI_GetSystemStatus; /** * Block until the next network I/O cycle * * Use this routine to synchronize the IO application's I/O processing with * network IO cycle * * Parameters * [in] uint32_t maxWait Maximum number of microseconds the call to this * function will take (subject to rounding to the * system clock tick). Use CI_WAIT_FOREVER to wait * indefinitely. * * Return * Type: int32_t * Values: CI_OK after wait on complete * CI_ERROR if blocking feature not available yet */ CI_waitIo_t CI_WaitIO; /** * Get a Common Interface event * * Parameters * Dir Type Name Description * [out] CI_eventInfo_t * event_p Pointer to event information structure to * be filled in * [in] int16_t block ==0: return immediately whether or not an * event has been retrieved * !=0: return only after (i.e. block until) * an event has been retrieved * * Return * Type: int32_t * Values: CI_OK event structure successfully retrieved * CI_EMPTY if the event queue is empty * CI_ERROR if there is an error within the queue * CI_INVALID_PARAM if event invalid or system not in proper state */ CI_getEvent_t CI_GetEvent; /** * Add an extension to the Common Interface * * Parameters * * Dir: [in] * Type: CI_interfaceExtension_t * Name: extension * Description: Requested interface extension * * Dir: [in] * Type: int32_t * Name: version * Description: Version for the requested interface extension * * Dir: [in] * Type: void* * Name: callbackTable_p * Description: Pointer to IO application-side callback function pointer * table structure e.g. CI_EipStatusLedIfExt_t (provided by IO app to network * app). Callback functions are defined and pointers to them are placed into * the callback table structure. The pointer to the table is passed to the * interface extension function to allow the network app to invoke the * callbacks using the function pointers stored in the table structure. * * Dir: [out] * Type: void** * Name: ifExtensionTable_p * Reference to a pointer to a function pointer table structure defined on the * network application side. This table structure contains pointers to * functions that extend the interface referred to by the extension variable. * The IO application, prior to attempting to use any these functions needs to * test that the table pointer is non-null, and that any given function pointer in * the table is non-null. Once these checks are completed, the application may * use the function pointer to invoke the desired network-app-side function. * * Return * Type: int32_t * Values: CI_OK for success * CI_INVALID_PARAM if callback table pointer is null, unsupported * extension, or protocol implementation of * interface extension function is not registered * CI_ERROR if extension cannot be added or other error */ CI_addInterfaceExtension_t CI_AddInterfaceExtension; /** * Get system time * * Parameters * Dir Type Name Description * [out] CI_time_t * time_p Pointer to time information structure to * be filled in * * Return * Type: int32_t * Values: CI_OK system time successfully retrieved * CI_ERROR never got response from SNTP server * CI_TIME_NOT_SYNCED last sync was more than one minute ago * CI_PARAM_ERROR argument is invalid */ CI_getSystemTime_t CI_GetSystemTime; /** * Configure time zone * * Parameters * Dir Type Name Description * [in] int32_t timeCorrection time correction in minutes with * respect to UTC * * Type: int32_t * Values: CI_OK timezone configuration successful * CI_ERROR if there is an error while configuring timezone */ CI_configureTimezone_t CI_ConfigureTimezone; /** * Open network ports * * Parameters * Dir Type Name Description * [in] CI_portsSubsystem_t subSystem Open all ports associated with * requested subsystem * * Return * Type: int32_t * Values: CI_OK Open ports was successful * CI_ERROR Error while opening ports */ CI_openPorts_t CI_OpenPorts; /** * Close network ports * * Parameters * Dir Type Name Description * [in] CI_portsSubsystem_t subSystem Close all ports associated with * requested subsystem * * Return * Type: int32_t * Values: CI_OK Close ports was successful * CI_ERROR Error while closing ports */ CI_closePorts_t CI_ClosePorts; // End Functions ************************************************************** #endif /* _CI_SYSTEM_API_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /* Exclusionary ifdef */ #ifndef _CI_SYSTEM_TYPES_H_ #define _CI_SYSTEM_TYPES_H_ // Includes ******************************************************************* #include <stdint.h> #include <stdbool.h> // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** /*************************************************************************** * IMPORTANT: The interface versions below is used to detect CHANGES the to * functions in the interfaces and SHALL be updated any time there is a change * to ANY function in this header that is part of a registered (i.e. used with * the registrar) interface. "Change" in this case only means a change to the * SIGNATURE of a function. The interface version need not be updated if the * number of functions in the interface changes (i.e. a function is added or * removed). ***************************************************************************/ #define CI_SYS_VER_MAJ 0x01 #define CI_SYS_VER_MIN 0x02 #define CI_SYS_VER ((CI_SYS_VER_MAJ << 16) | CI_SYS_VER_MIN) #define CI_SYS_NAME ("CI_systemIf\0") #define CI_SYS_PROTO_VER_MAJ 0x01 #define CI_SYS_PROTO_VER_MIN 0x00 #define CI_SYS_PROTO_VER ((CI_SYS_PROTO_VER_MAJ << 16) | \ CI_SYS_PROTO_VER_MIN) #define CI_SYS_PROTO_NAME ("CIsystemProtoIf") /* System API Function Name List */ #define CI_SYS_NAME_VERSION ("Version") /* must be first */ #define CI_SYS_NAME_GET_PROTOCOL ("GetProtocol") #define CI_SYS_NAME_GET_BASKET ("GetBasket") #define CI_SYS_NAME_SET_SYSTEM_PARAM ("SetSystemParam") #define CI_SYS_NAME_GET_SYSTEM_PARAM ("GetSystemParam") #define CI_SYS_NAME_STORE_SYSTEM_PARAM ("StoreSysIpParam") #define CI_SYS_NAME_APPLY_SYSTEM_IP_PARAM ("ApplySysIpParam") #define CI_SYS_NAME_STORE_SYSTEM_ETH_PARAM ("StoreEthParam") #define CI_SYS_NAME_CONFIG_COMPLETE ("ConfigComplete") #define CI_SYS_NAME_WAIT_IO ("WaitIo") #define CI_SYS_NAME_GET_EVENT ("GetEvent") #define CI_SYS_NAME_GET_SYSTEM_STATUS ("GetSysStatus") #define CI_SYS_NAME_GET_SYSTEM_TIME ("GetSystemTime") #define CI_SYS_NAME_CONFIG_TIME_ZONE ("ConfigTimeZone") #define CI_SYS_NAME_OPEN_PORTS ("OpenPorts") #define CI_SYS_NAME_CLOSE_PORTS ("ClosePorts") /* System Protocol API Function Name List */ #define CI_SYS_PROTO_NAME_VERSION ("Version") /* must be first */ #define CI_SYS_PROTO_NAME_SET_PROTO_PARAM ("SetProtoParam") #define CI_SYS_PROTO_NAME_GET_PROTO_PARAM ("GetProtoParam") #define CI_SYS_PROTO_NAME_SET_SYS_STATUS ("SetSysStatus") #define CI_SYS_PROTO_NAME_ADD_IF_EXTENSION ("AddIfExtension") // Wait forever for a network output data cycle to complete #define CI_WAIT_FOREVER 0xFFFFFFFF // ---------------------------------------------------------------------------- /* ------------------------------------------------------------------------ */ /* ------------------ Data/enum types for this interface ------------------ */ /* ------------------------------------------------------------------------ */ /* Supported Common Interface protocols */ typedef enum { CI_protocolError = -1, CI_protocolProfinet = 2, CI_protocolEtherNetIP = 3, CI_protocolModbusTCP = 4, CI_protocolEtherCAT = 7, CI_protocolPowerlink = 8, CI_protocolIP = 9, CI_protocolLast = 0xFFFFFFFF /* To force enumeration width */ } CI_protocol_t; typedef enum { CI_phyDuplexModeHalf, CI_phyDuplexModeFull, CI_phyDuplexUnknown, } CI_phyDuplexMode_t; /* The item description data contained in a basket */ typedef struct { uint16_t itemID; uint16_t itemLocation; uint32_t infoA; /* developer-specified data A */ uint32_t infoB; /* developer-specified data B */ } CI_basketCase_t; /* The basket structure, used to contain groups of items */ #define CI_BASKET_VERSION 1 /* Increment for any change to basket structure */ typedef struct { uint16_t deviceID; uint16_t itemCount; CI_basketCase_t *itemInfo_p; /* pointer to array of CI_basketCase_t structs */ } CI_basket_t; /* Supported interface extensions of the Common Interface */ typedef enum { CI_ifExtProfinetStackApi, CI_ifExtLedApi, /* Future extensions go here */ CI_ifExtLast = 0xFFFF /* To force enumeration width */ } CI_interfaceExtension_t; /* Define the IP stats structure */ /* Note the following counters are defined in the RFC 1213 MIB-II with the * exception of openSockets and maxSockets which were added for use by the * user application */ typedef struct { /*TCP and UDP */ uint32_t maxSockets; /* Total number of sockets of any type currently open */ uint32_t openSockets; /* IP */ uint32_t ipInDelivers; uint32_t ipReasmTimeout; uint32_t ipReasmReqds; uint32_t ipReasmOKs; uint32_t ipReasmFails; uint32_t ipInUnknownProtos; uint32_t ipInDiscards; uint32_t ipInReceives; uint32_t ipInHdrErrors; uint32_t ipForwDatagrams; uint32_t ipInAddrErrors; uint32_t ipInTruncPkts; uint32_t ipInMcastPkts; uint32_t ipInBcastPkts; uint32_t ipOutRequests; uint32_t ipFragOKs; uint32_t ipFragFails; uint32_t ipFragCreates; uint32_t ipOutDiscards; uint32_t ipOutNoRoutes; uint32_t ipRoutingDiscards; uint32_t ipOutMcastPkts; uint32_t ipOutBcastPkts; uint32_t ipOutTransmPkts; uint32_t ipOutMcastOctets; uint32_t ipOutOctets; uint32_t ipInOctets; uint32_t ipInMcastOctets; uint32_t ipForwarding; uint32_t ipDefTTL; uint64_t ipInHCReceives; uint64_t ipInHCOctets; uint64_t ipHCForwDatagrams; uint64_t ipInHCDelivers; uint64_t ipOutHCRequests; uint64_t ipOutHCTransmPkts; uint64_t ipOutHCOctets; uint64_t ipInHCMcastPkts; uint64_t ipInHCMcastOctets; uint64_t ipOutHCMcastPkts; uint64_t ipOutHCMcastOctets; uint64_t ipInHCBcastPkts; uint64_t ipOutHCBcastPkts; /* ICMP */ uint32_t icmpInMsgs; uint32_t icmpInErrors; uint32_t icmpOutMsgs; uint32_t icmpOutErrors; uint32_t icmpInDestUnreachs; uint32_t icmpInPktTooBig; uint32_t icmpInTimeExcds; uint32_t icmpInParmProbs; uint32_t icmpInEchos; uint32_t icmpInEchoReps; uint32_t icmpInMcastLstQ; uint32_t icmpInMcastLstR; uint32_t icmpInMcastLstD; uint32_t icmpInRedirects; uint32_t icmpInSrcQuenchs; uint32_t icmpInAddrMaskReps; uint32_t icmpInAddrMasks; uint32_t icmpInTimestampReps; uint32_t icmpInTimestamps; uint32_t icmpOutDestUnreachs; uint32_t icmpOutPktTooBig; uint32_t icmpOutTimeExcds; uint32_t icmpOutParmProbs; uint32_t icmpOutEchos; uint32_t icmpOutEchoReps; uint32_t icmpOutMcastLstQ; uint32_t icmpOutMcastLstR; uint32_t icmpOutMcastLstD; uint32_t icmpOutRedirects; uint32_t icmpOutSrcQuenchs; uint32_t icmpOutAddrMaskReps; uint32_t icmpOutAddrMasks; uint32_t icmpOutTimestampReps; uint32_t icmpOutTimestamps; /* TCP */ uint32_t tcpActiveOpens; uint32_t tcpPassiveOpens; uint32_t tcpAttemptFails; uint32_t tcpEstabResets; uint32_t tcpInSegs; uint32_t tcpOutSegs; uint32_t tcpRetransSegs; uint32_t tcpInErrs; uint32_t tcpOutRsts; uint64_t tcpHCOutSegs; uint64_t tcpHCInSegs; /* TCP Connections */ uint32_t tcpEstablished; /* UDP */ uint32_t udpInErrors; uint32_t udpInDatagrams; uint32_t udpNoPorts; uint32_t udpOutDatagrams; uint64_t udpHCInDatagrams; uint64_t udpHCOutDatagrams; } CI_statistic_t; /* * System parameters (as used by CI_SetSystemParam() and CI_GetSystemParam()) * and their data types/structures are documented below */ typedef enum { CI_sysParamIoAppVersion, /* Desc: Pointer to IO application version information structure * Type: IO_appInfo_t* */ CI_sysParamNetworkAppVersion, /* Desc: Pointer to network application version information structure * Type: IO_appInfo_t* */ CI_sysParamNumPorts, /* Desc: Number of attached ports * Type: uint16_t */ CI_sysParamPortLinkState, /* Desc: Link state (up/down) for all attached ports * Type: uint32_t[] Each element of the array is the link state for the * corresponding port - use CI_sysParamNumPorts to * get the number of attached ports * ==0: no link on corresponding port * !=0: link on corresponding port */ CI_sysParamPortPhyState, /* Desc: PHY configuration for all attached ports from current settings * Type: uint32_t[][3] (2-D array of uint32_t) * Number of attached ports by uint32_t[3] per port - use * CI_sysParamNumPorts to get the number of attached ports) * * Per-port configuration array format * Index 0: Auto-negotiation enabled * Index 1: Link speed (in Mbps - 0: indicates speed is unknown) * Index 2: Duplex mode see CI_phyDuplexMode_t */ CI_sysParamPortPhyStateNvm, /* Desc: PHY configuration for all attached ports from NV memory * Can be used by CI_GetSystemParam() * Type: uint32_t[][3] (2-D array of uint32_t) * Number of attached ports by uint32_t[3] per port - use * CI_sysParamNumPorts to get the number of attached ports) * * Per-port configuration array format * Index 0: Auto-negotiation enabled * Index 1: Link speed (in Mbps - 0: indicates speed is unknown) * Index 2: Duplex mode see CI_phyDuplexMode_t */ CI_sysParamPortEthStats, /* Desc: Simplified Ethernet statistics for all attached ports * Type: uint32_t[][18] (2-D array of uint32_t) * Number of attached ports by uint32_t[18] per port - use * CI_sysParamNumPorts to get the number of attached ports) * * Per-port statistics array format * Index 0: Bytes received * Index 1: Unicast packets received * Index 2: Broadcast packets received * Index 3: Multicast packets received * Index 4: Frames received with alignment error * Index 5: Frames received with CRC/FCS error * Index 6: Frames received with large frame error * Index 7: Frames with RX MAC errors * -------------------- * Index 8: Bytes transmitted * Index 9: Unicast packets transmitted * Index 10: Broadcast packets transmitted * Index 11: Multicast packets transmitted * Index 12: Frames transmitted after single collision * Index 13: Frames transmitted after multiple collisions * Index 14: Frames dropped after excessive collisions * Index 15: Frames with a collision after 512 bits * Index 16: Frames delayed by traffic * Index 17: Frames with TX MAC errors */ CI_sysParamMacAddresses, /* Desc: Local MAC addresses * Type: uint8_t[][6] 2-D array of uint8_t * (Number of attached ports PLUS ONE for the system MAC by uint8_t[6] * per MAC address - use CI_sysParamNumPorts to get the number of * attached ports) */ CI_sysParamDhcpEnable, /* Desc: DHCP enable flag * Type: uint8_t * ==0: disable DHCP (use static IP address) * !=0: enable DHCP */ CI_sysParamIpAddress, /* Desc: System IP address * Type: uint32_t */ CI_sysParamSubnetMask, /* Desc: Subnet mask * Type: uint32_t */ CI_sysParamDefaultGateway, /* Desc: Default gateway IP address * Type: uint32_t */ CI_sysParamPrimaryDns, /* Desc: Primary DNS server's IP address * Type: uint32_t */ CI_sysParamSecondaryDns, /* Desc: Secondary DNS server's IP address * Type: uint32_t */ CI_sysParamDomainName, /* Desc: Domain name * Type char[64] */ CI_sysParamHostname, /* Desc: Local hostname * Type char[64] */ CI_sysParamSerialNumber, /* Desc: Serial Number * Type: uint32_t */ CI_sysParamIpStats, /* Desc: Simplified IP statistics for TCP/IP stack * Type: CI_statistic_t */ CI_sysParamWebServerEnable, /* Desc: Web server enable flag * Type: uint8_t * ==0: disable web server (use static IP address) * !=0: enable web server */ CI_sysParamSntpEnable, /* Desc: Sntp enable flag * Type: uint8_t * ==0: disable sntp * !=0: enable sntp */ CI_sysParamPrimarySntp, /* Desc: Sntp primary server IP address * Type: uint32_t */ CI_sysParamSecondarySntp, /* Desc: Sntp secondary server IP address * Type: uint32_t */ /* Future system parameters go here... */ CI_sysParamLast = 0xFFFFFFFF /* To force enumeration width */ } CI_systemParam_t; /* * Protocol parameters (as used by CI_SetProtocolParam() and * CI_GetProtocolParam()) and their data types/structures are documented below */ typedef enum { /* PROFINET-specific parameters */ CI_protoParamProfinetStationName = (CI_protocolProfinet * 1000), /* Desc: PROFINET station name (as assigned by the PLC) * Type: char[] (max length: 240 characters) */ /* EtherNet/IP-specific parameters */ /* Modbus/TCP-specific parameters */ /* EtherCAT-specific parameters */ /* POWERLINK-specific parameters */ CI_protoParamLast = 0xFFFFFFFF /* To force enumeration width */ } CI_protocolParam_t; /* Status for IO application in general */ typedef enum { CI_systemStatusFail, CI_systemStatusOk, CI_systemStatusLast = 0xFFFF /* To force enumeration width */ } CI_systemStatus_t; /* Overall link state */ typedef enum { CI_ethLinkStateUnknown, /* Link state not known or knowable */ CI_ethLinkStateDown, /* No ports have link */ CI_ethLinkStateUp, /* At least one port has link */ CI_ethLinkStateLast = 0xFFFF /* To force enumeration width */ } CI_ethLinkState_t; /* PLC connection status */ typedef enum { CI_plcConnectionStatusUnknown, /* PLC connection status not known or * knowable */ CI_plcConnectionStatusDown, /* No PLC currently connected */ CI_plcConnectionStatusUp, /* At least one PLC connected */ CI_plcConnectionStatusTimedOut, /* IO transfer with PLC timed out */ CI_plConnectionStatusLast = 0xFFFF /* To force enumeration width */ } CI_plcConnectionStatus_t; /* Common Interface events */ typedef enum { CI_eventLinkChange, /* Description: The link state of the indicated port has changed. * info: The new port link state (see CI_ethLinkState_t) * detail: Upper 16 bits: interface number on which the port is located, * Lower 16 bits: port number on the indicated interface on * which the link state changed */ CI_eventIpConfigChange, /* Description: The system's IP configuration (e.g. IP address, subnet mask, * default gateway address, etc.) has been changed via the * underlying industrial protocol or configuration mechanism * (e.g. DHCP). This event signals a IP configuration change * caused by either the PLC or DHCP. * info: == 0 if IP configuration just went invalid (IP address * received via DHCP or from PLC, etc. and deemed * invalid/unusable) * != 0 if IP configuration just went valid (IP address received * via DHCP or from PLC, etc. and deemed valid) * detail: Not used */ CI_eventIpConflict, /* Description: EtherNet/IP only: The local system detected an IP address * conflict with another device on the network. * info: Not used * detail: Not used */ CI_eventPlcConnectionChange, /* Description: The state of the PLC connection has changed. A PLC has * connected or disconnected from the local device or the * connection has timed out. * info: The new state of the PLC connection * (see CI_plcConnectionStatus_t) * detail: Not used */ CI_eventReadItem, /* Description: New item data has arrived from the network, the IO * application can read the indicated item to get the new data * before the next network cycle takes place. * info: Handle of the item for which data has arrived * detail: ID of the item (used when the item was added to the system) */ CI_eventWriteItem, /* Description: Item data was just retrieved by the network, the IO * application can write the indicated item to set new data for * the next network cycle. * info: Handle of the item for which data has arrived * detail: ID of the item (used when the item was added to the system) */ CI_eventRiFlagChange, /* Description: EtherNet/IP only: The Run/Idle flag just changed. * info: The new state of the Run/Idle flag * detail: Not used */ CI_eventDeviceBlinkInd, /* Description: PROFINET only: the PLC has requested that the local device * blink (via its LEDs, display, etc.) * info: Number of times to blink * detail: Upper 16 bits: time for LED on, Lower 16 bits: time for LED off */ CI_eventNetworkResetRequest, /* Description: The PLC (or other networked control device) has requested a * local reset. * info: For EtherNet/IP: the type of reset that was requested * For all others: always 0 * detail: Not used */ CI_eventWebServerStatus, /* Description: Status of the web server. * info: Web Server specific sub-event * detail: Status code of the sub-event */ CI_eventLast = 0xFFFFFFFF /* To force enumeration width */ } CI_event_t; /* Event information */ typedef struct { CI_event_t event; // What happened and/or what the IO app should do int32_t info; // Information about the event (see event descriptions) int32_t detail; // Detail about the event (see event descriptions) } CI_eventInfo_t; /* SNTP time */ typedef struct { int32_t hour; int32_t minute; int32_t second; int32_t month; int32_t day; int32_t year; } CI_time_t; /* Subsystem ports */ typedef enum { CI_portsIeProtocol, CI_portsWebServer, CI_portsSntp, }CI_portsSubsystem_t; /* ------------------------------------------------------------------------- */ /* ------------------- Function types for this interface ------------------- */ /* ------ See the corresponding API header for function declarations ------ */ /* ------------------------------------------------------------------------- */ // =========================================================================== // ===================== System Interface function types ===================== // =========================================================================== typedef CI_protocol_t (CI_getProtocol_t)(void); typedef CI_getProtocol_t (*CI_getProtocol_tp); typedef CI_basket_t *(CI_getBasket_t)(uint16_t id); typedef CI_getBasket_t (*CI_getBasket_tp); typedef int32_t (CI_setSystemParam_t)(CI_systemParam_t param, void *paramData_p, uint16_t paramSize); typedef CI_setSystemParam_t (*CI_setSystemParam_tp); typedef int32_t (CI_getSystemParam_t)(CI_systemParam_t param, void *paramData_p, int32_t *paramLen); typedef CI_getSystemParam_t (*CI_getSystemParam_tp); typedef int32_t (CI_waitIo_t)(uint32_t maxWait); typedef CI_waitIo_t (*CI_waitIo_tp); typedef int32_t (CI_getEvent_t)(CI_eventInfo_t *event_p, int16_t block); typedef CI_getEvent_t (*CI_getEvent_tp); typedef int32_t (CI_addInterfaceExtension_t)(CI_interfaceExtension_t extension, int32_t version, void* callbackTable_p, void** ifExtensionTable_p); typedef CI_addInterfaceExtension_t (*CI_addInterfaceExtension_tp); typedef int32_t (CI_applySystemIpParam_t)(bool store); typedef CI_applySystemIpParam_t (*CI_applySysemIpParam_tp); typedef int32_t (CI_storeSystemEthParam_t)(void); typedef CI_storeSystemEthParam_t (*CI_storeSystemEthParam_tp); typedef int32_t (CI_getSystemTime_t)(CI_time_t *time_p); typedef CI_getSystemTime_t (*CI_getSystemTime_tp); typedef int32_t (CI_configureTimezone_t)(int32_t timeCorrection); typedef CI_configureTimezone_t (*CI_configureTimezone_tp); // =========================================================================== // ================= System Protocol Interface function types ================ // =========================================================================== typedef int32_t (CI_setProtocolParam_t)(CI_protocolParam_t param, void *paramData_p, uint32_t paramSize); typedef CI_setProtocolParam_t (*CI_setProtocolParam_tp); typedef int32_t (CI_getProtocolParam_t)(CI_protocolParam_t param, void *paramData_p, uint32_t paramSize); typedef CI_getProtocolParam_t (*CI_getProtocolParam_tp); typedef int32_t (CI_configComplete_t)(void); typedef CI_configComplete_t (*CI_configComplete_tp); typedef int32_t (CI_setSysStatus_t)(CI_systemStatus_t status); typedef CI_setSysStatus_t (*CI_setSysStatus_tp); typedef CI_systemStatus_t (CI_getSysStatus_t)(void); typedef CI_getSysStatus_t (*CI_getSysStatus_tp); typedef int32_t (CI_openPorts_t)(CI_portsSubsystem_t subSystem); typedef CI_openPorts_t(*CI_openPorts_tp); typedef int32_t (CI_closePorts_t)(CI_portsSubsystem_t subSystem); typedef CI_closePorts_t(*CI_closePorts_tp); // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** // End Functions ************************************************************** #endif /* _CI_SYSTEM_TYPES_H_ */
/* * Copyright (c) 2019-2020 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /**************************************************************************** ** This header defines the CI webserver API. */ #ifndef _CI_WEBSERVER_API_H_ #define _CI_WEBSERVER_API_H_ // Includes ******************************************************************* #include "CI_webserver_types.h" // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** /** * Set http tunnel handler. * * Parameters * Dir Type Name Description * [in] CI_httpTunnelHandler_tp handler_p http tunnel handler to set * * The handler set using this function is called when tunnel request is * received from the web browser. * * An error will be returned if the caller provides invalid function pointer * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on NULL handler_p */ CI_setHttpTunnelHandler_t CI_SetHttpTunnelHandler; /** * Set http response not found handler. * * Parameters * Dir Type Name Description * [in] CI_httpResNotFoundHandler_tp handler_p http res not found * handler to set * * The handler set using this function is called when webserver could not find * response for the given http request. * * An error will be returned if the caller provides invalid function pointer * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on NULL handler_p */ CI_setHttpResNotFoundHandler_t CI_SetHttpResNotFoundHandler; /** * Write http response. * * Parameters * Dir Type Name Description * [in] const char * format_p pointer to the data to be formatted * [in] - - variable number of arguments. * * Formats and writes the http response directly to the transmit buffer. * Format of the arguments is similar to standard library printf function. * * An error will be returned if format_p is null or when there is webserver * session exists. * * Return * Type: int32_t * Values: > 0 Number of bytes written. * CI_ERROR on NULL format_p or there is no webserver connection. */ CI_writeHttpResponse_t CI_WriteHttpResponse; /** * Reloads certificate(/private/pki/server.crt) and key(/private/pki/server.key) * used by the web-server from the file system * * Parameters * None * * Return * Type: int32_t * Values: CI_OK on success * CI_ERROR on failure */ CI_webserverCertificateReload_t CI_WebserverCertificateReload; /** * Register url --> CGI handler mappings. * * Parameters * Dir Type Name Description * [in] CI_cgiEntry_t* entry_p Pointer to the cgi entries. * [in] uint32_t* numEntries Number of entries to register. * * Register url --> CGI handler with web server. * Registered CGI handler (entry_p->handler_p) will be called when * url (entry_p->url) is received by the web server * * Return * Type: int32_t * Values: CI_OK on success. * CI_ERROR on failure. */ CI_registerCgiEntry_t CI_RegisterCgiEntry; // End Functions ************************************************************** #endif /* _CI_WEBSERVER_API_H_ */
/* * Copyright (c) 2019-2021 Analog Devices, Inc. All Rights Reserved. * * This software is proprietary and confidential to Analog Devices, Inc. and * its licensors. */ /**************************************************************************** ** This header defines the CI web server API. */ #ifndef _CI_WEBSERVER_TYPES_H_ #define _CI_WEBSERVER_TYPES_H_ // Includes ******************************************************************* #include <stdint.h> #include <stdarg.h> // End Includes *************************************************************** // Macros, typedefs, enums **************************************************** /*************************************************************************** * IMPORTANT: The interface version below is used to detect CHANGES the to * functions in the interface and SHALL be updated any time there is a change * to ANY function in this header that is part of a registered (i.e. used with * the registrar) interface. "Change" in this case only means a change to the * SIGNATURE of a function. The interface version need not be updated if the * number of functions in the interface changes (i.e. a function is added or * removed). ***************************************************************************/ #define CI_WEBS_VER_MAJ 0x01 #define CI_WEBS_VER_MIN 0x01 #define CI_WEBS_VER ((CI_WEBS_VER_MAJ << 16) | CI_WEBS_VER_MIN) #define CI_WEBS_NAME ("CI_websIf") /* API Function List */ #define CI_WEBS_NAME_VERSION ("Version") #define CI_NAME_SET_HTTP_TUNNEL_HANDLER ("HttpTunlHandler") #define CI_NAME_SET_HTTP_RES_NOT_FOUND_HANDLER ("HttpResNotFound") #define CI_NAME_WRITE_HTTP_RESPONSE ("WriteHttpRes") #define CI_NAME_WEBS_CERTIFICATE_RELOAD ("WebsCertReload") #define CI_NAME_WEBS_PASSWORD_RESET ("WebsPassReset") #define CI_NAME_REGISTER_CGI ("RegisterCgi") #define CI_MAX_CGI_ENTRIES 256 // ---------------------------------------------------------------------------- /* ------------------------------------------------------------------------ */ /* ------------------ Data/enum types for this interface ------------------ */ /* ------------------------------------------------------------------------ */ /* Tunnel request structure */ typedef struct { char *requestData_p; int requestDataLen; char *requestUrl_p; int requestUrlLen; } CI_httpTunnelRequest_t; /* Tunnel response structure */ typedef struct { char *responseData_p; int responseDataLen; } CI_httpTunnelResponse_t; /* Http error codes */ typedef enum { CI_httpContinue = 0, /* 100 */ CI_httpSwitching, /* 101 */ CI_httpOk, /* 200 */ CI_httpCreated, /* 201 */ CI_httpAccepted, /* 202 */ CI_httpNonAuthoritative, /* 203 */ CI_httpNoContent, /* 204 */ CI_httpReset, /* 205 */ CI_httpPartial, /* 206 */ CI_httpPartialOk, /* 207 */ CI_httpMultiple, /* 300 */ CI_httpMoved, /* 301 */ CI_httpFound, /* 302 */ CI_httpMethod, /* 303 */ CI_httpNotModified, /* 304 */ CI_httpUseProxy, /* 305 */ CI_httpProxyRedirect, /* 306 */ CI_httpTempRedirect, /* 307 */ CI_httpBadRequest, /* 400 */ CI_httpUnAuthorized, /* 401 */ CI_httpPaymentRequired, /* 402 */ CI_httpForbidden, /* 403 */ CI_httpNotFound, /* 404 */ CI_httpNotAllowed, /* 405 */ CI_httpNoneAcceptable, /* 406 */ CI_httpProxyUnauthorized, /* 407 */ CI_httpTimeout, /* 408 */ CI_httpConflict, /* 409 */ CI_httpGone, /* 410 */ CI_httpLengthRequired, /* 411 */ CI_httpPreconFailed, /* 412 */ CI_httpTooBig, /* 413 */ CI_httpUriTooBig, /* 414 */ CI_httpUnsupported, /* 415 */ CI_httpBadRange, /* 416 */ CI_httpExpectationFailed, /* 417 */ CI_httpReauth, /* 418 */ CI_httpProxyReauth, /* 419 */ CI_httpInternal, /* 500 */ CI_httpNotImplemented, /* 501 */ CI_httpBadGate, /* 502 */ CI_httpDown, /* 503 */ CI_httpGateTimeout, /* 504 */ CI_httpBadVersion, /* 505 */ CI_httpNoPartialUpdate /* 506 */ } CI_httpStatus_t; /*CGI meta variables structure*/ typedef struct { int contentLength; int serverPort; int remotePort; const char *authType_p; const char *contentType_p; const char *documentArgs_p; const char *queryString_p; const char *remoteUser_p; const char *requestMethod_p; const char *scriptName_p; const char *remoteAddress_p; } CI_cgiMetaVariable_t; /* CGI request structure*/ typedef struct { CI_cgiMetaVariable_t metaVar; const char *msgBody_p; } CI_cgiRequest_t; /* CGI response structure.*/ typedef struct { char *msgBody_p; int msgBodyMaxLen; const char *contentType_p; int msgBodyLen; } CI_cgiResponse_t; /* Web Server Events */ typedef enum { CI_websStatusEventInit /* Description: Web Server Initialization Event status. * It is used to report the return value of * web server initialization. * detailStatusCode will have the return value as * CI_OK if Initialization is successful and * CI_ERROR if Initialization is failed. */ } CI_websStatusEvent_t; /* Web server event data */ typedef struct { CI_websStatusEvent_t statusEvent; int32_t detailStatusCode; } CI_websEventData_t; /* Forward declaration of CGI handler */ typedef void (*CI_cgiHandler_tp)(CI_cgiRequest_t, CI_cgiResponse_t *); /* CGI entry structure.*/ typedef struct { const char *url_p; CI_cgiHandler_tp handler_p; } CI_cgiEntry_t; /* ------------------------------------------------------------------------- */ /* ------------------- Function types for this interface ------------------- */ /* ------ See the corresponding API header for function declarations ------ */ /* ------------------------------------------------------------------------- */ typedef int32_t (*CI_httpTunnelHandler_tp)(CI_httpTunnelRequest_t *req_p, CI_httpTunnelResponse_t *resp_p); typedef int32_t (CI_setHttpTunnelHandler_t)(CI_httpTunnelHandler_tp handler_p); typedef CI_setHttpTunnelHandler_t (*CI_setHttpTunnelHandler_tp); typedef int32_t (*CI_httpResNotFoundHandler_tp)(int32_t socket, uint8_t* request_p, uint32_t reqLen); typedef int32_t (CI_setHttpResNotFoundHandler_t)( CI_httpResNotFoundHandler_tp handler_p); typedef CI_setHttpResNotFoundHandler_t (*CI_setHttpResNotFoundHandler_tp); typedef int32_t (CI_writeHttpResponse_t)(const char* format_p, ...); typedef CI_writeHttpResponse_t (*CI_writeHttpResponse_tp); typedef int32_t (CI_webserverCertificateReload_t)(void); typedef CI_webserverCertificateReload_t (*CI_webserverCertificateReload_tp); typedef int32_t (CI_WebserverPasswordReset_t)(void); typedef CI_WebserverPasswordReset_t (*CI_WebserverPasswordReset_tp); typedef void (CI_cgiHandler_t)(CI_cgiRequest_t req, CI_cgiResponse_t *resp_p); typedef int32_t (CI_registerCgiEntry_t)(CI_cgiEntry_t *entry_p, uint32_t numEntries); typedef CI_registerCgiEntry_t (*CI_registerCgiEntry_tp); // ---------------------------------------------------------------------------- // End Macros, typedefs, enums ************************************************ // Global Variables (externs, globals, static globals) ************************ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // End Global Variables ******************************************************* // Functions ****************************************************************** // End Functions ************************************************************** #endif /* _CI_WEBSERVER_TYPES_H_ */
The RapID _Common Interface API (CI)_ is designed to provide a uniform interface on top of very different Industrial Ethernet Protocols, including EtherNet/IP, EtherCAT and Profinet. This allows an application on top of the Common Interface to work across protocols. While this works fine for many, maybe even most applications, there are sometimes needs that require deeper integration with a specific protocol. To enable this type of protocol specific work, the protocol Extensions API was introduced. It extents the Common Interface with functionality specific to a certain Industrial Ethernet protocol. This document focuses on the Profinet Extension available thru CI_extensions.h.
A class of functions provided by the respective protocol stacks within the NetworkApp. Functions defined in this table can be called by the application. Typical example for these kind of functions is CI_PnetAddItem_t function. It is Profinet specific and called by the application to plug a specific sub-module into a slot/subslot with a given API type.
A class of function provided by the application and called by the NetworkApp. Typical example for these kind of functions is the CI_LedSetStatusStateFunct_p() function that provides the current system LED status to the application. It is important to understand that those calls are executed by the calling context (CPU stack and priority). Therefore the calls shall be short and crisp. • Furthermore Interrupts shall not be disabled, at least not permanently • IPC functions that send the calling thread into a wait state (e.g. wait on timer, wait on message, take semaphore) shall not be called from within a callback • Sharing non-atomic variables (e.g. structs, 64-Bit variables) with the application code must be implemented with care
Extensions can be installed any time before Config Complete is reached. After that point in time, calls to CI_AddInterfaceExtension() will be refused.
int32_t CI_AddInterfaceExtension(CI_interfaceExtension_t extension, int32_t version, void* callbackTable_p, void** ifExtensionTable_p);
This function provides a pointer to a structure that holds pointers to the extension functions - _ifExtensionTable_p_. before using one of the functions, the user shall check _ifExtensionTable_p_ as well as the specific function pointer in these structures being not _NULL_.
In Ci, one of the first things that need to be set up after system start is the device type. The device type defines many data important to a industrial ethernet device, such as vendorID and deviceID values. The device type information is protocol specific. The CI_SetDevice and CI_SetDeviceCustom functions are provided to set up the device. While CI_SetDevice will take the device information from the io-config database, CI_SetDevice allows the user to pass the device type information via a protocol specif data structure. However, the default data structure to set up a Profinet device lacks specific IDs for DAP and port submodules. This can lead to a conflict with some profiles, such as the PA profile. Using the function 'CI_PNET_Ext_SetDevice_Func' from the extension interface allows to pass a DAPSubID and an individual portSubID per port:
typedef int32_t (CI_PnetSetDevice_t)(CI_ProfinetDevice_t* device_p, uint32_t DAPSubID, uint16_t ports, uint32_t *portSubId_p); CI_PnetSetDevice_t CI_PNET_Ext_SetDevice_Func;
Please note that DAPSubID and the portSubIds need to match the related values in the GSDML file.
The CI_PNET_Ext_ModuleDiff_CB allows a customer to fix any deviations between the list of expected modules/submodules by the PLC and the modules/submodules actual plugged in the device. It grants the user an opportunity to fix miss mismatches before startup is completed. *Background:* For each entry in the diff block, the function is called to compare expected slot/sub-slot configuration (“what the PLC believe is installed”) with the installed (“what the device got actually installed”). This grants the application an opportunity to adjust the actual configuration to that expected by the PLC. This function does not directly influence how the stack handles any remaining differences between the PLC and device configuration. The return value just indicates whether the app was able to fix any mismatches or not. The function will get called for the expected submodules only (the configuration defined in the PLC program).
typedef int32_t CI_PnetModuleDiffFunct_t (uint16_t ARindix, uint32_t API, uint16_t slot, uint16_t subslot, uint32_t realModuleID, uint32_t expectedModuleID, uint32_t realsubmoduleID, uint32_t expectedSubmoduleID); CI_PnetModuleDiffFunct_t CI_PNET_Ext_ModuleDiff_CB;
The functions CI_addItem() and CI_removeItem() can be used to modify the configuration from within this callback. All memory associated with a CI_addItem() call is carefully removed in CI_removeItem() as needed. Once called for each expected module, a final call to this callback, called _finalization_ is executed with arNum and api both being 0xffff. This convenience call allows an application to clean up its configuration. It is still allowed to remove/add items at this point. If the call is used to change an existing configuration, the first call to that function or a “PLC down event” can be used to remove all slots/subslots of the current configuration. As an alternative, a list of modules no longer needed can be recorded and all module sin that list can be removed in the _finalization_ callback. Note on Adding Record Indices (Acyclics) It is recommended to add acyclic items only after the related submodule has been plugged.
This callback is designed to inform an application that an Application Relationship (AR) has been established and configured. No further startup parameters will be sent by the PLC. Can be used to lock certain functionality. The ARindex passed as a parameter can help to understand which AR has completed the configuration in case than more than one AR is established. Please note that adding and deleting items out of that callback will not work and will cause a deadlock of the Profinet stack.
typedef int32_t CI_PnetParameterEnd_t (uint16_t ARindix); CI_PnetParameterEnd_t CI_PNET_Ext_ParamEnd_CB;
The Profinet device model uses a module/sub-module concept. A module in the Profinet model is like an envelop or box for a set of one or more submodules. Data is provided and consumed by submodules only. While standard CI_AddItem() and CI_AddItemCustom() function allows to plug one module with one sub-module into a certain slot only. To allow more flexibility, the extension api adds the following function:
typedef int32_t (CI_PnetAddItem_t)(uint16_t id, void *data_p, uint32_t bufSize, uint16_t slot, uint16_t subslot, uint16_t api); CI_PnetAddItem_t CI_PNET_Ext_AddItem_Func;
Using CI_PNET_Ext_AddItem_Func allows an item to be plugged into a certain slot/subslot. In addition, a api number for the submodule can be set. • Modules with a predefined set of sub-modules • Modules with free sub-slots and the ability plug sub-modules into a module at runtime • Allows to add submodules with a distinct api number The ability to set an api value other than the default api=0 allows implementation of Profinet profiles. The first four parameters of this call are identical to CI_AddItemCustom(), just subslot and api are added to the parameter list.
In Profinet there are ALRAMS and DIAGNOSIS available. Whats the difference? Diagnosis provides status messages to the PLC. They are logged in the Engineering system and give the operator some inside on what's going on in the device. A diagnosis message can be activated and removed when no longer valid. Diagnosis messages are bound to a submodule and can be generated by the application and by the stack. The stack actually generates quite a few diagnosis messages. The user of the RapID platform has not to worry about maintaining those alarms and diagnosis messages. They are covered in the stack inside the NetworkApp. Alarms are disruptive events that are handled by the PLC and that may affect the plant operation. An alarm is sent upstream to the PLC and acknowledged by the PLC. Like with Diagnosis, source of an alarm may be the stack or the application. The user application shall not handle alarms that are dedicated to the stack. The details of the how alarms and diagnosis messages are formatted are documented in IEC CD 61158-5-10 “Diagnosis ASE”.
Please note that while QualifiedChannelDiagnosis is not supported yet, the function parameter _severity_ used in the diagnosis api in CI_extensions.h follows the required coding for QualifiedChannelQualifier for future compatibility.
Channel Diagnosis | Ext Channel Diagnosis | Qualified Channel Diagnosis |
---|---|---|
Slot Number | Slot Number | Slot Number |
SubSlot Number | SubSlot Number | SubSlot Number |
USI = 0x8000 | USI = 0x8002 | USI = 0x8003 |
Channel Number | Channel Number | Channel Number |
Channel Type | Channel Type | Channel Type |
Channel Error Type | Channel Error Type | Channel Error Type |
- | ExtChannelErrorType | ExtChannelErrorType |
- | ExtChannelAddValue | ExtChannelAddValue |
- | QualifiedChannelQualifer | - |
A diagnosis message is bound to an address based on api, slot, subslot and channel. While _api_, _slot_ and _subslot_ are common entities in Profinet, the _ChannelNumber_ is less prominent. The idea is that a submodule has one or more channels of a certain _ChannelType_. Examples: a digital input submodule with four inputs got four channels, one bit wide each. A analog output submodule with 8 channels uses a array of 8 16-bit words to represent its data.
Please note that ChannelType is a data width information only, not a datatype designation. A CI_pnetDiagChannelTypeDWord can be an 32-bit integer as well as an 32-bit float value.
The width of the channel is passed via the parameter ChannelType and defined as follows:
CI_pnetDiagChannelType_t | Channel Data Width in Bits |
---|---|
CI_pnetDiagChannelTypeOthers | Undefined |
CI_pnetDiagChannelType1Bit | Channel is a single bit wide |
CI_pnetDiagChannelType2Bit | Channel is two bits wide |
CI_pnetDiagChannelType4Bit | Channel is 4 bits wide |
CI_pnetDiagChannelTypeByte | Channel is 8 bits wide |
CI_pnetDiagChannelTypeWord | Channel is 16-bits wide |
CI_pnetDiagChannelTypeDWord | Channel is 32-bits wide |
CI_pnetDiagChannelTypeLWord | Channel is 64-bits wide |
Finally, a channel has a _direction_, its either input, output or both.
Direction | Comment |
---|---|
CI_pnetInput | input, data towards controller |
CI_pnetOutput | output, data from the controller |
CI_pnetIn_out | input and output |
The error code defined in _CI_pnetDiagChannelError_t_ can be used to signal standard error codes as defined in IEC CD 61158-5-10 “Diagnosis ASE”. The definition includes frequently used, self explanatory error codes, such as (list not complete):
CI_pnetShortCircuit CI_pnetUndervoltage CI_pnetOvervoltage CI_pnetOverload CI_pnetOvertemperature CI_pnetLineBreak CI_pnetUpperLimitExceeded CI_pnetLowerLimitExceeded CI_pnetPowerFault CI_pnetFuseBlown
All diagnosis calls in the extension api for Profinet support a parameter severity. The coding of this value follows the specification of QualifiedChannelQualifier. However, only 3 values can currently be used for severity:
Severity Code | Comment | |
---|---|---|
CI_PNET_S_LOW | Lowest Severity | Low |
CI_PNET_S_MAINTENANCEREQUIRED | Error signals that maintenance is required | Medium |
CI_PNET_S_MAINTENANCEDEMANDED | Error signals that maintenance is demanded | High |
The parameter lists of the diagnosis calls also refer to a parameter called _diagTag_. This tag is user supplied and shall be unique for each diagnosis sent. That said, the same value shall be used to send and to clear a diagnosis message, making diagTag an internal reference to a unique diagnosis transaction. It helps the stack to track diagnosis messages for the same api, slot, subslot and channel.
Channel specific process diagnosis message. Channel diagnosis is used to signal process/application errors related to individual IO channels. The channel is addressed by _api_, _slot_, _subslot_, _channelNumber_ and _channelType_. The _errorNumber_ is one of the predefined values in _CI_pnetDiagChannelType_t_. Please refer to the Profinet Diagnosis Guideline for the latest definitions. Channel type defines the width of the channel as per CI_pnetDiagChannelType_t. Typical examples are CI_pnetDiagChannelType1Bit for digital IO channels and CI_pnetDiagChannelTypeWord for analog input (16-Bit). The diagTag shall be unique to the message sent.
typedef int32_t CI_PnetSendChanDiag_t(uint16_t api, uint16_t slot, uint16_t subslot, uint16_t channelNumber, uint16_t channelType, uint16_t direction, uint16_t errorNum, uint16_t diagTag, uint32_t severity); CI_PnetSendChanDiag_t CI_PNET_Ext_SendChanDiag_Func;
Send an extended channel diagnosis message to the controller. Like channel diagnosis, extend channel diagnosis is used to signal process/application errors related to individual IO channels. The channel is addressed by _api_, _slot_, _subslot_, _channelNumber_ and _channelType_. The _errorNumber_ is one of the predefined values in _CI_pnetDiagChannelType_t_. Please refer to the Profinet Diagnosis Guideline for the latest definitions. Channel type defines the width of the channel as per CI_pnetDiagChannelType_t. Typical examples are CI_pnetDiagChannelType1Bit for digital IO channels and CI_pnetDiagChannelTypeWord for analog input (16-Bit). The extended information passed is used for specific use cases, where more error details are required. This includes nested errors, where an error is caused within an existing error.
typedef int32_t CI_PnetSendExtChanDiag_t(uint16_t api, uint16_t slot, uint16_t subslot, uint16_t channelNumber, uint16_t channelType, uint16_t direction, uint16_t errorNum, uint16_t diagTag, uint32_t severity, uint16_t extChannelErrType, uint32_t extChannelAddValue); CI_PnetSendExtChanDiag_t CI_PNET_Ext_SendExtChanDiag_Func;
Pls refer to Profinet Diagnosis Guideline for details.
Once the root cause for a channel diagnosis message or extended channel diagnosis message has vanished, use
uint16_t slot, uint16_t subslot, uint16_t channelNumber, uint16_t channelType, uint16_t direction, uint16_t errorNum, uint16_t diagTag); CI_PnetClearChanDiag_t CI_PNET_Ext_ClearChanDiag_Func;
to inactivate the diagnosis message. The same _CI_PNET_Ext_ClearChanDiag_Func()_ function is used to deactivate both, Channel Diagnosis and Extended Channel Diagnosis messages. Parameter diagTag must be identical to the related CI_PNET_Ext_SendChanDiag_Func or CI_PNET_Ext_SendExtChanDiag_Func call.
This type is currently not supported_.
Issue manufacturer specific diagnosis message. Like with channel diagnosis, the error is addressed by api, slot, subslot, channelNumber and channelType. The diagTag shall be unique to the message sent. As the name suggest, this diagnosis can be use to raise non standard, customized diagnosis messages. Please note that no error code is given, the message uses a single, predefined error code (CI_pnetManufactureSpecific). The parameter usrStructureIdentifier allows to create a set of manufacturer specific messages, it's valid range is 0-0x7fff. Please refer to Profinet Diagnosis Guideline for details.
typedef int32_t CI_PnetSendManDiag_t(uint16_t api, uint16_t slot, uint16_t subslot, uint16_t channelNumber, uint16_t channelType, uint16_t direction, uint16_t diagTag, uint16_t usrStructureIdentifier, uint32_t severity, uint8_t *manSpecificData_p, uint16_t dataLen); CI_PnetSendManDiag_t CI_PNET_Ext_SendManDiag_Func;
An alarm is a message that can trigger an interrupt on the controller. The behavior on the controller may be implementation depended. The classical way to handle interrupts is using OB40..48 blocks. Please refer op your PLC vendor documentation for implementing alarm driven interrupts. If an alarm is sent while a pending alarm has not been processed yet, the function returns CI_ERROR.
This value is for future compatibility and shall be set to zero for now.
Like with manufacturer specific diagnosis, usrStructureIdentifier shall be in range of 0..0x7FFF. This value identifies reasons for the alarm and identifies what type of data is passed via alarmData_p.
Data can be passed along with an alarm. AlarmData_p points to the data and alamaDataLength gives the length of the data in bytes.
typedef int32_t CI_PnetSendAlarm_t(uint16_t api, uint16_t slot, uint16_t subslot, uint16_t alarmSpecifier, uint16_t diagTag, uint16_t usrStructureIdentifier, uint8_t *alarmData_p, uint16_t alarmDataLength); CI_PnetSendAlarm_t CI_PNET_Ext_SendAlarm_Func;
In CI, a event is sent to the application in case a record-item has has been read or updated. However, that is seen as too late to validate the record data and to possibly answer with a Profinet specific error code. Both validate callbacks shall not cause a context switch by calling inter process communication functions nor other CommonInterface functions. Stack usage shall be conservative.
The CI_PnetReadItemValidate_t callback allows a application to inspect whether data in the addressed item is valid or not before it is actually read by the stack. It may use the callback to update an out-of-date item using CI_WriteItem(). If CI_ERROR is returned the read will be canceled and no data is read from the item. In this case, the application has to provide valid error information using the CI_PnetStatus_t structure. If the callback returns CI_OK, the data will be read from the respective item. _Note - it is allowed to pass NULL for this callback in CI_PnetCallbackFunctionTable_t if the use of this callback is not required_.
typedef int32_t (CI_PnetReadItemValidate_t)(int32_t handle, uint32_t *rdLen_p, CI_pnetStatus_t *pnioStatus_p);
The writeItemValidate_p callback allows a application to inspect the data provided by buffer_p/wrLen for validity. If CI_ERROR is returned the write will be canceled and no data is written to the associated item. The application may capture a copy of the data using memcpy. In case of a error, the application has to provide valid error information using the CI_PnetStatus_t structure. If the callback returns CI_OK, the data will be stored in the respective item. _Note - it is allowed to pass NULL for this callback in CI_PnetCallbackFunctionTable_t if the use of this callback is not required
typedef int32_t (CI_PnetWriteItemValidate_t)(int32_t handle, uint8_t *buffer_p, uint32_t *wrLen_p, CI_pnetStatus_t *pnioStatus_p);
The first four parameters represent the PNIO Status according to IEC61158-6 The “addValue” values shall contain additional user information within negative responses. The value zero indicates no further information. For positive read responses, the a 1 in addValue1 shall indicate that the Record Data Object contains more data than have been read.
typedef struct { uint8_t errorCode; uint8_t errorDecode; uint8_t errorCode1; uint8_t errorCode2; uint16_t addValue1; uint16_t addValue2; } CI_pnetStatus_t;
Profinet knows 5 I&M (Information and Maintenance) records. This implementation supports I&M 0 thru 4:
I&M Record | Content | |
---|---|---|
IM0 | Submodule manufacturer data, software and hardware version | Physical module properties |
I&M1 | Installation location and function tags | Plant information where and what a modules does |
I&M2 | Installation data | Date of installation |
I&M3 | User defined descriptor | A 54 byte visible string for holding additional information |
I&M4 | Reserved for use by PROFIsafe | PROFIsafe not supported currently |
I&M0 is special for the device module and DAP/Port modules. These carry the device I&M0 data and can not be overwritten. For more information see [Profinet University][https://profinetuniversity.com/profinet-features/profinet-im-how-to-use-im-records]
Using TIA Portal [Siemens Support][https://support.industry.siemens.com/cs/mdm/49948856?c=86913163787&lc=en-WW] or use [Proneta][https://new.siemens.com/global/en/products/automation/industrial-communication/profinet/proneta.html] instead of TIA Portal.
Read one of the 5 I&M data records from the Profinet stack. The function works pretty straight forward, using just the address information as an input (api, slot, subslot). The selectIM value can be in range 0..4 to select the desired I&M record. _Please note that the user is not informed whether the PLC updates IM 1..4_
typedef int32_t (CI_PnetReadIMData_t)(uint16_t selectIM, uint16_t api, uint16_t slot, uint16_t subslot, uint8_t *buffer_p, uint16_t bufLen); CI_PnetReadIMData_t CI_PNET_Ext_ReadIMData_Func;
Write one of the writeable I&M data records to the Profinet stack. The function works pretty straight forward, using just the address information as an input (api, slot, subslot). The selectIM value can be in range 0..4 to select the desired I&M record. Also note that IM0 is read only, with two exceptions: 1. Exception: The value revCount For some profiles, it is required to update revCount. RefCount is updated for the given module at api/slot/subslot if a IM0 record is supported by the module. To write revCount via this api function, use a CI_PnetIM0Record_t struct and set revCount to the desired value. All other values in that struct are ignored. _Note: To update the device I&M0 revCount, use api=0, slot=0 and subslot=1;_ 2. Exception: If a sub-module does not have a I&M set already If a I&M0 record per submodule is desired, it can be attached using this function. However, once it is set future updates will not be successful - except for updating the revCount. Or more generally said, a IM0 record can not be overwritten once set. _Note: Reset to factory or unplugging will clear the I&M0 records of any but device/DAP/PORT submodule in Slot 0!_ _Note: Reset to factory clears I&M records_
typedef int32_t (CI_PnetWriteIMData_t)(uint16_t selectIM, uint16_t api, uint16_t slot, uint16_t subslot, uint8_t *data_p, uint16_t dataLen); CI_PnetWriteIMData_t CI_PNET_Ext_WriteIMData_Func;