Industrial Networking Protocols Knowledge Base

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Industrial Networking Protocols Knowledge Base

Discussions

Sort by:
CTT Version 2.5.0 Testcase 49   The Test Case TF-1200[4][10] "#49 Op > SafeOp, WD expired“ gives a warning if the device uses GOAL and a multicore architecture over SPI. This is due to time consuming remote procedere calls (RPC) leading to delayed watchdog timeouts, which are not triggered within the defined timeout of WD-time + 10% WD-time. A warning does not result in a failed conformance test.
View full article
Problem: The EtherCAT stack aborts a state transition with one of the following AL Status Codes: Invalid Mailbox Configuration (0x0016) Invalid Outputs (0x001D) Invalid Inputs (0x001E) Cause: During state transition, the stack checks the Sync Manager settings received from the MainDevice. If the settings contain an invalid start address or invalid size of a Sync Manager, the stack will return an error. Also, if a Sync Manager interferes with the memory area of another Sync Manager, an error is raised. For Input and Output Sync Managers, the corresponding PDO Mapping is also checked. The mapped byte stream must fit into a Sync Manager’s memory area. Possible Solutions: Make sure the generated Files of the Industrial Communications Creator are always applied to all participants of the network Compile and flash the source code to the SubDevice Update the EEPROM image of the SubDevice Update the ESI File in the Engineering Tool of the MainDevice and make sure the updated version is used Update the configuration of the MainDevice Ensure start addresses of the Sync Manager memory area is greater than or equal 0x1000 Avoid interference of memory areas between Sync Managers A Mailbox Sync Manager’s memory area is defined by its start address and the size of the Sync Manager An Input or Output Sync Manager’s memory area is defined by its start address and three times the size of the Sync Manager (3-buffer mode) The size of the Input and Output Sync Managers is defined by the default PDO mapping The start addresses of all Sync Managers and the sizes of the Mailbox Sync Managers can be defined in the Industrial Communication Creator (they are found in the Subindices of object 0x1C00)
View full article
Introduction   NXP EtherCAT stack provides different sample applications for GOAL. These applications have been created with help of Industrial Communication Creator and show how to setup and use the stack. The next chapter lists all application examples, which are located at appl/goal_ecat/. Related projects are placed at projects/goal_ecat* next to edt sub-directory ICC projects, EEPROM binaries and XML-device description files used by EtherCAT software like TwinCAT or Ethernet Codesys Master PLC for interacting with the device. ECAT projects are organized into single-/ multi-core and full-source/ demo projects: projects/goal_ecat - full source projects projects/goal_ecat_lib - 1h demo library projects projects/goal_ecat_rpc - multi-core projects projects/goal_ecat_rpc_lib - 1h demo library projects for multi-core projects Application description   All listed applications can be used for single and multi-core platforms equally. Only exception is 00_rpc_cc, which is designed for the communication core of multi-core platforms. In goal_appl.c is the initialization of GOAL and the EtherCAT stack located. The behavior of the sample application is controlled by goal_app_ecat.c, while the object dictionary is created by goal_appl_ecat_objects.c. Some additional, application specific files may be placed in the directories. Please note the file description of the related file for further information. appl/goal_ecat/00_rpc_cc   This application must be run on the communication core of a device. It provides the functionality for all other examples to the application core. It is not restricted to the examples but also provides the full GOAL EtherCAT functionality to the user application. The EtherCAT demo projects/00_goal_rpc_demo/ is a 1h time limited, full feature protocol stack library. appl/goal_ecat/01_simple_io   This application is a simple example of handling IOs. It features FoE and CoE and is configured by an explicit device ID APPL_ECAT_EXPL_DEV_ID of 5. Following objects are mapped as I/O data and can be accessed from a PLC (e.g. TwinCAT or Ethercat Codesys Master PLC). Object ID Variable Name Description 0x6000:0x01 applU8ButtonInput 8 byte: button input 0x6120:0x01 applVarU32Input 32 byte: input mirror data 0x6200:0x01 applU8LedOutput 8 byte: LED output 0x6320:0x01 applVarU32Output 32 byte: output mirror data   appl/goal_ecat/02_eoe_http   This application is equal to appl/goal_ecat/01_simple_io expanded by EoE feature. The file goal_appl.c contains a simple webserver content, which can be accessed via EoE at port APPL_TCP_PORT (8081) of device’s IP. Up to APPL_HTTP_CHAN_CNT (4) HTTP channels are available.    
View full article
Note: This is only necessary if the EtherCAT Library is used without GOAL. If it is used with GOAL,  the EoE interface is automatically connected to the TCP/IP stack of GOAL and the normal GOAL NET API can be used. Configuring your project   Our deliveries of the EtherCAT library allready contain a driver that connects lwIP to the EoE API. You have to do the following steps: add include paths to your IDE or Build System: drivers/common/lwip ext/lwip/src/includ add EoE driver files: drivers/common/lwip/ec_eoe_lwip.c drivers/common/lwip/lwipopts.h drivers/common/lwip/arch/cc.h drivers/common/lwip/arch/perf.h drivers/common/lwip/arch/sys_arch.h add  lwIP Source code: ext/lwip/src/core/def.c ext/lwip/src/core/dns.c ext/lwip/src/core/inet_chksum.c ext/lwip/src/core/init.c ext/lwip/src/core/ip.c ext/lwip/src/core/ipv4/etharp.c ext/lwip/src/core/ipv4/icmp.c ext/lwip/src/core/ipv4/igmp.c ext/lwip/src/core/ipv4/ip4_addr.c ext/lwip/src/core/ipv4/ip4.c ext/lwip/src/core/ipv4/ip4_frag.c ext/lwip/src/core/mem.c ext/lwip/src/core/memp.c ext/lwip/src/core/netif.c ext/lwip/src/core/pbuf.c ext/lwip/src/core/tcp.c ext/lwip/src/core/tcp_in.c ext/lwip/src/core/tcp_out.c ext/lwip/src/core/timeouts.c ext/lwip/src/core/udp.c ext/lwip/src/netif/ethernet.c ext/lwip/src/include/lwip/altcp.h ext/lwip/src/include/lwip/api.h ext/lwip/src/include/lwip/arch.h ext/lwip/src/include/lwip/autoip.h ext/lwip/src/include/lwip/debug.h ext/lwip/src/include/lwip/def.h ext/lwip/src/include/lwip/dhcp.h ext/lwip/src/include/lwip/dns.h ext/lwip/src/include/lwip/err.h ext/lwip/src/include/lwip/etharp.h ext/lwip/src/include/lwip/icmp6.h ext/lwip/src/include/lwip/icmp.h ext/lwip/src/include/lwip/igmp.h ext/lwip/src/include/lwip/inet_chksum.h ext/lwip/src/include/lwip/init.h ext/lwip/src/include/lwip/ip4_addr.h ext/lwip/src/include/lwip/ip4_frag.h ext/lwip/src/include/lwip/ip4.h ext/lwip/src/include/lwip/ip6_addr.h ext/lwip/src/include/lwip/ip6_frag.h ext/lwip/src/include/lwip/ip6.h ext/lwip/src/include/lwip/ip_addr.h ext/lwip/src/include/lwip/ip.h ext/lwip/src/include/lwip/mem.h ext/lwip/src/include/lwip/memp.h ext/lwip/src/include/lwip/mld6.h ext/lwip/src/include/lwip/nd6.h ext/lwip/src/include/lwip/netbuf.h ext/lwip/src/include/lwip/netdb.h ext/lwip/src/include/lwip/netifapi.h ext/lwip/src/include/lwip/netif.h ext/lwip/src/include/netif/etharp.h ext/lwip/src/include/netif/ethernet.h ext/lwip/src/include/netif/ppp/ppp_impl.h ext/lwip/src/include/netif/ppp/ppp_opts.h ext/lwip/src/include/lwip/opt.h ext/lwip/src/include/lwip/pbuf.h ext/lwip/src/include/lwip/priv/api_msg.h ext/lwip/src/include/lwip/priv/memp_priv.h ext/lwip/src/include/lwip/priv/memp_std.h ext/lwip/src/include/lwip/priv/nd6_priv.h ext/lwip/src/include/lwip/priv/sockets_priv.h ext/lwip/src/include/lwip/priv/tcpip_priv.h ext/lwip/src/include/lwip/priv/tcp_priv.h ext/lwip/src/include/lwip/prot/dhcp.h ext/lwip/src/include/lwip/prot/dns.h ext/lwip/src/include/lwip/prot/etharp.h ext/lwip/src/include/lwip/prot/ethernet.h ext/lwip/src/include/lwip/prot/icmp6.h ext/lwip/src/include/lwip/prot/icmp.h ext/lwip/src/include/lwip/prot/igmp.h ext/lwip/src/include/lwip/prot/ip4.h ext/lwip/src/include/lwip/prot/ip.h ext/lwip/src/include/lwip/prot/tcp.h ext/lwip/src/include/lwip/prot/udp.h ext/lwip/src/include/lwip/raw.h ext/lwip/src/include/lwip/snmp.h ext/lwip/src/include/lwip/sockets.h ext/lwip/src/include/lwip/stats.h ext/lwip/src/include/lwip/sys.h ext/lwip/src/include/lwip/tcpbase.h ext/lwip/src/include/lwip/tcp.h ext/lwip/src/include/lwip/timeouts.h ext/lwip/src/include/lwip/udp.h remove dummy EoE implementation from the sample application (if not done already) examples/*/usr_eoe.c   Writing an lwIP Application   You can simply set up the EtherCAT Library as you usually do. You can use all API functions of the lwIP that are enabled with the current configuration. If you want to change the lwIP settings please have a look at the file drivers/common/lwip/lwipopts.h. The following source code demonstrates how to set up an UDP Echo server. /** @file * * @brief EtherCAT Demo Application for EoE * * Received UDP frames on port APPL_PORT will be reflected to sender. * * @copyright * Copyright 2009-2021 port GmbH Halle/Saale. * This software is protected Intellectual Property and may only be used * according to the license agreement. */ #include "ecat_conf.h" #include "ec_header.h" #include "usr_dynod.h" #include "lwip/opt.h" #include "lwip/init.h" #include "lwip/netif.h" #include "netif/etharp.h" #include "lwip/sys.h" #include "lwip/udp.h" #include "lwip/udp.h" #include "lwip/tcp.h" #include "lwip/dns.h" #include "lwip/igmp.h" #include "lwip/dns.h" /****************************************************************************/ /* Local Defines */ /****************************************************************************/ #define APPL_PORT 12345 /****************************************************************************/ /* Global Variables */ /****************************************************************************/ extern BOOL_T shutDownFlag; /**< shut down application */ BOOL_T shutDownFlag = LIB_FALSE; /**< shut down application */ EC_INSTANCE_T ecatData; /**< EterCAT instance data */ /****************************************************************************/ /* Local Variables */ /****************************************************************************/ struct udp_pcb *pUdpPcbDesc = NULL; /**< pointer to LwIP UDP PCB */ /****************************************************************************/ /* Local prototypes */ /****************************************************************************/ static err_t ec_eoeLwipUdpOpen( void ); static void ec_eoeLwipUdpRecvCb( void *pArg, /**< arg user supplied argument (udp_pcb.recv_arg) */ struct udp_pcb *pUdpPcbDesc, /**< pcb the udp_pcb which received data */ struct pbuf *pLwipBuffer, /**< pointer the packet buffer that was received */ const ip_addr_t *pAddrRemote, /**< addr of the remote IP address from which the packet was received */ u16_t remote_port /**< remote port which received the udp packet */ ); /****************************************************************************/ /** Set up the device and execute the EtherCAT Library * * This function is the application's entry point. It initializes the device and * the EtherCAT Library. After setup the function @em ec_flushMbox() is called * cyclically to execute the EtherCAT Library. */ int main( void ) { EC_RET_T commonRet; /* EtherCAT Lib return value */ UNSIGNED8 ret; /* common return value */ BOOL_T err = LIB_FALSE; /* error flag */ /* hardware initialization, e.g GPIO configuration */ ret = ec_initDevice(); ec_logInfo("ec_iniDevice: 0x%02x", ret); if (ret != 0) { err = LIB_TRUE; } /* set up the timer for the EtherCAT Library */ ret = ec_initTimer(); ec_logInfo("ec_initTimer: 0x%02x", ret); if (ret != 0) { err = LIB_TRUE; } /* initialize the EtherCAT Library */ commonRet = ec_init(&ecatData); ec_logInfo("ec_initEtherCAT: 0x%02x", commonRet); if (commonRet != RET_OK) { err = LIB_TRUE; } /* open application UDP channel */ if (ERR_OK != ec_eoeLwipUdpOpen()) { err = LIB_TRUE; } /* enter application loop */ ec_logInfo("port GmbH EtherCAT Library %s.%s",EC_LIBRARY_VERSION, EC_LIBRARY_PATCH); if(LIB_TRUE == err) { shutDownFlag = LIB_TRUE; } while (shutDownFlag == LIB_FALSE) { ec_loop(&ecatData); } return 0; } /****************************************************************************/ /** UDP Application Callback * * This function is called by the stack when an UDP datagram has been received. * * The incoming frame is reflected to sender. */ static void ec_eoeLwipUdpRecvCb( void *pArg, /**< arg user supplied argument (udp_pcb.recv_arg) */ struct udp_pcb *pUdpPcbDesc, /**< pcb the udp_pcb which received data */ struct pbuf *pLwipBuffer, /**< pointer the packet buffer that was received */ const ip_addr_t *pAddrRemote, /**< addr of the remote IP address from which the packet was received */ u16_t remote_port /**< remote port which received the udp packet */ ) { /* copy remote address and port */ memcpy(&pUdpPcbDesc->remote_ip, pAddrRemote, sizeof(ip_addr_t)); pUdpPcbDesc->remote_port = remote_port; /* send message */ udp_send(pUdpPcbDesc, pLwipBuffer); } /****************************************************************************/ /** Open a network channel * * The Channel is bound to the local interfaces and remote interfaces IP * address. The Channel is described by a udp_cp from lwIP which is stored * as local variable. * * @retval ERR_OK - success * @retval other - fail */ static err_t ec_eoeLwipUdpOpen( void ) { err_t retValLwip; /* error value for lwIP */ /* check if channel is allraedy open */ if (NULL != pUdpPcbDesc) { ec_logInfo("Couldn't create new UDP channel descriptor"); return ERR_OK; } /* Create a new UDP lwIP control block */ pUdpPcbDesc = udp_new(); if (NULL == pUdpPcbDesc) { ec_logInfo("Couldn't create new UDP channel descriptor"); return ERR_MEM; } /* make addresses reusable */ pUdpPcbDesc->so_options |= SOF_REUSEADDR; /* Open local port for any local IP address */ retValLwip = udp_bind(pUdpPcbDesc, IP_ADDR_ANY, APPL_PORT); /* Check if operation was successful */ if (ERR_OK != retValLwip) { ec_logInfo("Couldn't connect UDP channel"); return retValLwip; } /* Set UDP receive callback */ udp_recv(pUdpPcbDesc, ec_eoeLwipUdpRecvCb, NULL); return ERR_OK; }   Testing the Application   EoE Settings in TwinCAT   Select the EtherCAT SubDevice in the Solution Explorer and go to the Tab “EtherCAT.“ Press the button “Advanced Settings.“ A Pop-up will open. In the setting tree, choose Mailbox → EoE. Here, you can configure the EoE Mailbox of the SubDevice as an IP Port. You can assign an IP address to the SubDevice, e.g. 192.168.1.2.     Test Setup   In order to test the UDP connection you have to connect a Test PC to the EtherCAT SubDevice. However, you cannot connect it directly to an EtherCAT SubDevice Controller. You have to use a Mailbox Gateway, i.e. a device that splits Ethernet frames into EoE Datagrams and vice versa. The Mailbox Gateway could be the PLC itself or an additional EtherCAT SubDevice.         Test Program   The test program on the Test PC should be able to send and receive UDP datagrams. Please make sure the PC’s interface is in the same subnet as the EoE device, e.g. by using the IP address 192.168.1.1. The test program must send datagrams to the IP address of the EoE device (e.g. 192.168.1.2) and to the UDP port “APPL_PORT“ that was defined by the sample application above (e.g. 12345). If you have netcat on your system, you can use the following command:   nc -u 192.168.1.2 12345 Now, you can enter an arbitrary text. When pressing enter the test is sent as UDP data to the EoE device. The sample application should echo back the received text. Therefore the text should appear again on the console.
View full article
    The EtherCAT SubDevice Controller uses Sync Managers to establish a consistent exchange of acyclic and cyclic data. A Sync Manager guards a RAM area in the ESC. It can be configured in Mailbox Mode and in 3-buffer-mode. The Mailbox Mode is for acyclic data exchange between MainDevice and SubDevice. One side can read or write the RAM area and has to wait until the other side has written or read this area. Thus two Mailboxes are required for data exchange. Usually Sync Manager 0 and 1 are used for this. The 3-buffer mode is used for cyclic data exchange. One buffer can be written by one side while another buffer is read by the other side. The 3rd buffer is used as a spare buffer is one side is faster than the other one. Again two Mailboxes are required to allow process data transfer in both directions. Usually Sync Managers 2 and 3 are used for this. Sync Manager Name Direction MainDevice View SubDevice View ESC Registers PDO 0 Mailbox Write M → S Output Consumer 0x800 - 0x807   1 Mailbox Read S → M Input Producer 0x807 - 0x80F   2 Process Data Write M → S Output Consumer 0x810 - 0x817 RxPDO 3 Process Data Read S → M Input Producer 0x818 - 0x81F TxPDO   Cyclic data exchange between MainDevice and SubDevice   The ESC has Fieldbus Memory Management Units (FMMU) that allow mapping logical addresses into physical memory and vice versa. The FMMU allows bit wise mapping, i.e. it is not bound to byte borders. Also it can by configured to only map a certain number of bits of the last byte. This way the the EtherCAT MainDevice can map the cyclic data of all SubDevices into one continuous logical address space. Usually two FMMUs are used to map the Outputs and Inputs of a SubDevice. Additionally a third FMMU can be used to map the Status bit of the Mailbox read by the MainDevice into a logical address space. This way the MainDevice can collect the Mailbox Status of all SubDevices to check if new content is available. An example configuration is shown in the following table. FMMU Log. Start Address Phys. Start Address Size Access Description 0 0x01000000.0 0x1000.0 12 Byte wr write process data to RAM in ESC via SM2 1 0x09000000.1 0x080d.0 1 Byte rd read SM1 Status (is there data in the Read Mailbox) 2 0x01000000.0 0x1100.0 12 Byte rd read process data from RAM in ESC via SM3   As you can see in the table above two FMMUs map the same logical address to two different physical addresses and use different access directions. The physical addresses are guarded by the Output Sync Manager and the Input Sync Manager. The MainDevice can send an EtherCAT Datagram with a "Logical Read/Write" command to the SubDevice. This datagram has the start address and the cyclic data, i.e. the frame contains the logical memory. If this frame is received by a SubDevice, the FMMU will read the assigned logical memory area and map it to the RAM area of the Output Sync Manager. Then it will read the the memory area guarded by the Input Sync Manager and map it to the assigned logical memory, i.e. it will write it into the frame. Since the last SubDevice in an EtherCAT segment returns the frame received from the MainDevice, the MainDevice can use one single EtherCAT Datagram to write all Outputs of the SubDevices and read all Inputs of the SubDevices. On the Data Link Layer process data is handled as an octet stream. On the the Application Layer this octet stream is parsed to/from objects of the Object Dictionary. There are PDO Mapping Objects that define what objects create a PDO. The PDO Assignment Objects define which PDO belongs to what Sync Manager. Thus the combination of PDO Mapping Objects and PDO Assignment Objects define the layout of the process data and the size of the Input and Output Sync Managers. For more details please read the corresponding section in the EtherCAT User Manual.
View full article