Chapter 187: PROFINET Protocol Basics
Chapter Objectives
By the end of this chapter, you will be able to:
- Understand the fundamentals of PROFINET as an Industrial Ethernet standard.
- Describe the roles of PROFINET Controllers, Devices, and Supervisors.
- Differentiate between PROFINET communication channels: Standard TCP/IP, Real-Time (RT), and Isochronous Real-Time (IRT).
- Explain the concept of PROFINET Conformance Classes (CC-A, CC-B, CC-C, CC-D).
- Recognize the structure and purpose of GSDML files in PROFINET.
- Outline the hardware requirements for connecting an ESP32 to a PROFINET network, focusing on Ethernet connectivity.
- Discuss conceptual software approaches for implementing a PROFINET device on an ESP32.
- Be aware of common challenges and considerations when working with PROFINET on embedded systems like the ESP32.
- Appreciate the differences among ESP32 variants concerning PROFINET implementation feasibility.
Introduction
Following our exploration of traditional fieldbuses like PROFIBUS-DP, we now turn our attention to Industrial Ethernet, a dominant force in modern automation. PROFINET (Process Field Network) is a leading Industrial Ethernet standard developed by PROFIBUS & PROFINET International (PI). It leverages standard Ethernet technologies to provide a high-performance, versatile communication solution for a wide range of industrial applications, from factory automation and process control to motion control.
PROFINET enables seamless integration of automation devices into enterprise networks and the Industrial Internet of Things (IIoT). Its ability to handle time-critical data alongside standard TCP/IP traffic on the same network makes it a powerful choice for contemporary industrial systems. For embedded developers using platforms like the ESP32, understanding PROFINET basics opens doors to creating intelligent devices that can participate in these sophisticated industrial networks, whether as simple I/O devices, gateways, or more complex control elements.
This chapter introduces the core concepts of PROFINET, its architecture, communication mechanisms, and the considerations for implementing PROFINET functionality, conceptually, on ESP32 devices using ESP-IDF v5.x. Given the complexity of PROFINET, particularly its real-time aspects, our focus will be on the foundational principles and the initial steps towards integration.
Theory
What is PROFINET?
PROFINET is an open Industrial Ethernet standard (IEC 61158 and IEC 61784) that uses TCP/IP and IT standards for non-time-critical communication (like configuration and diagnostics) and specialized real-time protocols for time-critical I/O data exchange. It is not simply “PROFIBUS over Ethernet” but rather a distinct protocol suite designed to take full advantage of Ethernet’s capabilities while addressing industrial requirements for speed, determinism, and robustness.
Key Characteristics:
- Ethernet-based: Utilizes standard Ethernet hardware (cables, switches, network interface cards).
- Scalability: Supports small to very large and complex automation systems.
- Speed: Offers high data rates (100 Mbit/s, 1 Gbit/s, and beyond).
- Real-time Capability: Provides mechanisms for deterministic data exchange.
- Coexistence: Allows standard TCP/IP traffic and real-time PROFINET traffic on the same network.
- Interoperability: Ensures devices from different manufacturers can communicate.
- Integration: Facilitates vertical integration from the field level to the enterprise level.
PROFINET Architecture: Roles and Components
A PROFINET network typically involves three main types of devices:
- PROFINET IO Controller (PLC, DCS, Industrial PC):
- This is the “master” device in the PROFINET IO system.
- It exchanges data with assigned PROFINET IO Devices.
- Manages the communication schedule for real-time data.
- Configures and parameterizes IO Devices.
- Example: A Siemens S7 PLC acting as a PROFINET IO Controller.
- PROFINET IO Device (Sensors, Actuators, Drives, I/O Modules):
- This is the “slave” or peripheral device.
- Provides I/O data to and receives output data from an IO Controller.
- Responds to requests from the IO Controller.
- Example: An ESP32 configured to act as a PROFINET IO Device, providing sensor readings or controlling outputs.
- PROFINET IO Supervisor (Engineering Tool, HMI):
- Used for commissioning, configuration, diagnostics, and monitoring of IO Devices and Controllers.
- Typically a PC running engineering software.
- Communicates using standard TCP/IP or UDP/IP for acyclic services.
graph TD %% Styling classDef controller fill:#EDE9FE,stroke:#5B21B6,stroke-width:2px,color:#5B21B6; classDef supervisor fill:#FEF3C7,stroke:#D97706,stroke-width:1px,color:#92400E; classDef device fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF; classDef switch fill:#F3F4F6,stroke:#6B7280,stroke-width:1.5px,color:#374151; %% Elements Controller["IO Controller<br>(e.g., PLC)"]:::controller Supervisor["IO Supervisor<br>(e.g., Engineering PC)"]:::supervisor Switch(Ethernet Switch):::switch subgraph IO Devices direction LR Device1[Drive]:::device Device2[I/O Block]:::device ESP32[<b>ESP32 Device</b>]:::device Device3[Robot]:::device end %% Connections Controller -- "PROFINET RT/IRT<br>(Cyclic Data)" --- Switch Supervisor -- "TCP/IP<br>(Acyclic Config/Diag)" --- Switch Switch --- Device1 Switch --- Device2 Switch --- ESP32 Switch --- Device3 linkStyle 0 stroke:#5B21B6,stroke-width:2px; linkStyle 1 stroke:#D97706,stroke-width:1.5px,stroke-dasharray: 5 5;
Communication Channels
PROFINET utilizes different communication channels optimized for various types of data:
- Standard TCP/IP (or UDP/IP):
- Used for non-time-critical communication.
- Examples: Device parameterization, configuration downloads, diagnostics, web server access on a device, communication with higher-level enterprise systems.
- This traffic goes through the full TCP/IP stack and is routed like standard Ethernet traffic.
- Real-Time (PROFINET RT – Class 1):
- Used for cyclic I/O data exchange between IO Controllers and IO Devices.
- Bypasses the TCP/IP layers and operates directly on Ethernet Layer 2 (using EtherType 0x8892).
- Data frames are given higher priority in switches that support IEEE 802.1p Quality of Service (QoS).
- Achieves typical cycle times from a few milliseconds down to 250 microseconds.
- Suitable for most factory automation tasks.
- Isochronous Real-Time (PROFINET IRT – Class 3):
- Used for high-precision, deterministic applications requiring minimal jitter, such as coordinated motion control.
- Requires specialized hardware in both devices and switches (IRT-capable switches).
- Utilizes a time-synchronized, scheduled communication approach where specific time slots are reserved for IRT traffic.
- Achieves cycle times down to 31.25 microseconds with jitter in the microsecond range.
- IRT communication also uses a specific EtherType and operates at Layer 2.
PROFINET Conformance Classes (CC)
To ensure interoperability and define a clear set of features for devices, PROFINET specifies Conformance Classes:
Class | Key Features | Hardware & Use Case |
---|---|---|
CC-A (Basic) |
– Standard PROFINET IO communication. – Cyclic data exchange using RT (Real-Time Class 1). – Basic diagnostics. |
Hardware: Standard Ethernet switches. Use Case: General factory automation, simple I/O devices. (Typical target for an ESP32 device). |
CC-B (Diagnostics) |
– All CC-A features. – Network diagnostics via SNMP. – Topology detection via LLDP. – System redundancy options. |
Hardware: PROFINET-aware switches required for full topology. Use Case: Process automation, systems requiring advanced diagnostics and network management. |
CC-C (Isochronous) |
– All CC-B features. – IRT (Isochronous Real-Time) communication. – High-precision synchronization and minimal jitter. |
Hardware: Requires specialized ASICs and IRT-capable switches. Use Case: High-speed, coordinated motion control (e.g., robotics, packaging machines). |
CC-D (TSN) |
– All CC-B features. – Real-time communication using standard TSN (Time-Sensitive Networking) mechanisms. |
Hardware: Requires TSN-capable Ethernet devices and switches. Use Case: The future of high-performance automation, merging IT and OT networks. |
- CC-A (Basic Functionality):
- Mandatory: PROFINET IO communication using RT (Real-Time Class 1).
- Basic device functions, cyclic data exchange.
- Standard Ethernet infrastructure (switches do not need special PROFINET capabilities beyond basic QoS if available).
- This is the most common class for general I/O devices.
- CC-B (Network Diagnostics and Topology):
- Includes all CC-A features.
- Mandatory: Network diagnostics (e.g., SNMP for network management).
- Topology detection (e.g., LLDP – Link Layer Discovery Protocol) to identify how devices are interconnected.
- System redundancy features.
- Requires PROFINET-aware switches for full topology information.
- CC-C (Isochronous Real-Time):
- Includes all CC-B features (though some aspects like SNMP might be optional if IRT is the primary focus).
- Mandatory: IRT (Isochronous Real-Time) communication.
- Requires specialized hardware and IRT-capable switches.
- Used for demanding applications like multi-axis motion control.
- CC-D (Time-Sensitive Networking):
- The newest conformance class, leveraging standard IEEE Time-Sensitive Networking (TSN) mechanisms.
- Aims to provide IRT-like performance using standardized TSN features in Ethernet switches and devices.
- Represents the future direction for high-performance PROFINET.
An ESP32-based device would typically aim for CC-A, or potentially CC-B if a more sophisticated stack and network management features are implemented. CC-C and CC-D are generally beyond the capabilities of a standard ESP32 without significant hardware assistance or a very specialized stack.
Device Model and GSDML Files
- Device Model (Application Relation – AR):PROFINET devices are modeled with a hierarchical structure:
- Device: The physical PROFINET IO Device.
- API (Application Process Instance): A logical instance of the application within the device.
- Slot: A physical or logical placeholder in the device (e.g., for a plug-in module).
- Subslot: A further subdivision of a slot, representing an I/O point or a group of I/O points.
- Module / Submodule: The actual hardware or software component providing the I/O data, plugged into slots/subslots.
- GSDML (General Station Description Markup Language) Files:
- Similar to GSD files in PROFIBUS, GSDML files describe PROFINET IO Devices to the engineering system (IO Supervisor).
- XML-based format: More modern and flexible than the text-based GSD files.
- Content: Vendor information, device model name, supported communication parameters (e.g., RT, IRT), available modules and submodules, I/O data structure, diagnostic information, IP addressing parameters, etc.
- Naming Convention:
GSDML-Vx.y-VendorName-DeviceFamily-YYYYMMDD.xml
(e.g.,GSDML-V2.3-Espressif-ESP32Device-20250604.xml
). - The IO Controller’s engineering tool imports this file to configure the IO Device.
Addressing and Identification
PROFINET devices use several identifiers:
- MAC Address: The unique hardware address of the Ethernet interface.
- IP Address, Subnet Mask, Gateway: Standard IP parameters for TCP/IP communication. These can be set manually, via DHCP, or by a PROFINET IO Controller using DCP.
- Device Name (Station Name): A logical name assigned to the device (e.g., “sensor-bay-5”). This name is used by the IO Controller to identify and establish communication with the IO Device. The name must be unique within the PROFINET network.
- Device ID & Vendor ID: Unique numbers identifying the device type and manufacturer, specified in the GSDML file.
Key Protocols and Services
- DCP (Discovery and Configuration Protocol):
- A Layer 2 protocol used to discover devices on the network and configure basic parameters like IP address and Device Name, even before an IP address is assigned.
- Allows an engineering tool or IO Controller to “find” and “name” new devices.
- RPC (Remote Procedure Calls):
- Used for acyclic communication, such as reading/writing parameters, diagnostics, and connection establishment. Typically runs over UDP.
- LLDP (Link Layer Discovery Protocol):
- Used for topology detection (identifying which port of a device is connected to which port of another device). Mandatory for CC-B and higher.
- Alarm Handling:
- PROFINET defines mechanisms for devices to send alarms (e.g., diagnostic alarms, process alarms) to the IO Controller.
Implementing PROFINET on ESP32
Implementing a PROFINET IO Device stack on an ESP32 is a significant undertaking, more complex than a typical fieldbus like Modbus RTU or even PROFIBUS-DP due to the Ethernet and real-time requirements.
Hardware Requirements:
- ESP32 Microcontroller:
- Ethernet MAC: The ESP32 (original series) and some ESP32-S3 variants include a built-in 10/100 Mbps Ethernet MAC. This is crucial.
- Ethernet PHY: An external Ethernet Physical Layer (PHY) transceiver IC (e.g., Microchip LAN8720/LAN8710A, Kendin KSZ8081) is required to interface the ESP32’s MAC (via RMII – Reduced Media-Independent Interface) to the physical Ethernet cable (RJ45 connector, magnetics).
- Variants without an internal Ethernet MAC would need an SPI-to-Ethernet module (e.g., W5500, ENC28J60). However, achieving PROFINET RT performance through SPI can be challenging due to latency and throughput limitations, making this approach less suitable for compliant PROFINET IO devices. Direct MAC access is preferred.
- RJ45 Connector with Magnetics: Standard Ethernet connector.
- Clock Source for PHY: Often a 25MHz or 50MHz crystal or oscillator, depending on the PHY and RMII configuration.

Software Approach Considerations:
- Full Software Stack (Extremely Complex): Developing a PROFINET IO Device stack from scratch, including the RT protocol handling, state machines, object dictionary, and GSDML generation/parsing. This is a massive task requiring deep protocol knowledge and real-time programming expertise. Generally not feasible for most projects without a dedicated team and extensive development time.
- Using an Existing Open-Source Stack: There are a few open-source PROFINET stacks available (e.g.,
PROFINET Device Implemented in C
– p-net on SourceForge, or other community efforts). Their completeness, ESP-IDF compatibility, performance on ESP32, and Conformance Class support vary widely. They often require significant porting effort and may not be certified. - Using a Commercial Stack: Several companies offer commercial, certified PROFINET stacks for various microcontrollers. These provide a robust, compliant solution but come with licensing costs. Some may have ports available or guidance for ESP32. This is the recommended route for products requiring certification and reliability.
- Using an External PROFINET Controller IC/Module: Similar to PROFIBUS, dedicated ASICs or modules (e.g., from Hilscher, Siemens, Renesas) handle the entire PROFINET protocol. The ESP32 communicates with this module via SPI or parallel bus to exchange I/O data and control information. This offloads the protocol complexity from the ESP32 and ensures compliance. This is often the most practical approach for robust PROFINET integration.
Tip: For any serious PROFINET product development, targeting certification is crucial. This usually involves using a pre-certified stack or module, or undergoing rigorous testing with PI-accredited test labs.
Practical Examples
This section will focus on the foundational step of initializing the Ethernet interface on an ESP32 using ESP-IDF, which is a prerequisite for any PROFINET communication. We will then conceptually discuss where a PROFINET stack would integrate.
Hardware Setup
- ESP32 Development Board with Ethernet:
- An ESP32 board that includes an Ethernet PHY (e.g., Olimex ESP32-Gateway, Espressif ESP32-Ethernet-Kit) or an ESP32 core board connected to an external Ethernet PHY module (like a LAN8720 module).
- Ensure the PHY is correctly wired to the ESP32’s EMAC interface pins (RMII).
- Ethernet Cable: To connect the ESP32 to an Ethernet switch or directly to a PC (using a crossover cable if auto-MDIX is not supported, though most modern interfaces support it).
- PROFINET IO Controller/Supervisor: A PLC or PC with PROFINET master/engineering software for testing (conceptual at this stage).
Software: ESP32 Ethernet Initialization and Conceptual PROFINET Integration
Project Setup in VS Code
- Create a new ESP-IDF v5.x project (e.g.,
esp32_profinet_device_basics
). - Ensure Ethernet support is enabled in your project configuration.
GSDML File Creation (Conceptual Snippet)
A GSDML file is essential for the IO Controller to recognize and configure the ESP32 device. Below is a highly simplified snippet. Real GSDML files are extensive.
<?xml version="1.0" encoding="UTF-8"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile GSDML-DeviceProfile-V2.3.xsd">
<ProfileHeader>
<ProfileIdentification>PROFINET Device Profile</ProfileIdentification>
<ProfileRevision>1.00</ProfileRevision>
<ProfileName>Device Profile for PROFINET Devices</ProfileName>
<ProfileSource>PROFIBUS Nutzerorganisation e. V. (PNO)</ProfileSource>
<ProfileClassID>Device</ProfileClassID>
<ISO15745Reference>
<ISO15745Part>4</ISO15745Part>
<ISO15745Edition>1</ISO15745Edition>
<ProfileTechnology>PROFINET</ProfileTechnology>
</ISO15745Reference>
</ProfileHeader>
<ProfileBody>
<DeviceIdentity VendorID="0x010C" DeviceID="0x0010"> <!-- Example: Espressif VendorID, custom DeviceID -->
<VendorName Value="Espressif Systems EDU"/>
<ModelName Value="ESP32 PROFINET IO Device Demo"/>
<HardwareRelease Value="1.0.0"/>
<SoftwareRelease Value="V1.0.0"/>
</DeviceIdentity>
<DeviceFunction>
<Family MainFamily="General" ProductFamily="ESP32 Based IO Device"/>
</DeviceFunction>
<ApplicationProcess>
<DeviceAccessPointList>
<DeviceAccessPointItem ID="DAP_1" PhysicalSlots="0..3" AddressAssignment="DCP;IP"
PNIO_Version="V2.3" ConformanceClass="A"
RequiredSchemaVersion="V2.3">
<ModuleInfo>
<NameText TextId="T_Name_DAP_1"/>
<InfoText TextId="T_Info_DAP_1"/>
</ModuleInfo>
<SystemDefinedSubmoduleList>
<SubmoduleItem ID="DAP_SUBMOD_1" SubslotNumber="32768" FixedInSubslots="32768"
ModuleIdentNumber="0x00000001" SubmoduleIdentNumber="0x00000001">
<ModuleInfo>
<NameText TextId="T_DAP_Name"/>
<InfoText TextId="T_DAP_Info"/>
</ModuleInfo>
<SupportedRT_Classes RT_Class="RT_CLASS_1"/>
</SubmoduleItem>
</SystemDefinedSubmoduleList>
<!-- Define I/O Modules here -->
<ModuleList>
<ModuleItem ID="MOD_1BYTE_IN_1BYTE_OUT" ModuleIdentNumber="0x1001" FixedInSlots="1">
<ModuleInfo><NameText TextId="T_Module_1B_IN_1B_OUT"/></ModuleInfo>
<VirtualSubmoduleList>
<SubmoduleItem ID="SUB_MOD_1BYTE_IN" SubslotNumber="1" SubmoduleIdentNumber="0x00010001"
DataLength="1" IOPS_Length="1" IOCS_Length="0">
<IOData><Input Consistency="All items consistency"><DataItem DataType="Unsigned8" UseAsBits="false" TextId="T_InputByte"/></Input></IOData>
</SubmoduleItem>
<SubmoduleItem ID="SUB_MOD_1BYTE_OUT" SubslotNumber="2" SubmoduleIdentNumber="0x00020001"
DataLength="1" IOPS_Length="0" IOCS_Length="1">
<IOData><Output Consistency="All items consistency"><DataItem DataType="Unsigned8" UseAsBits="false" TextId="T_OutputByte"/></Output></IOData>
</SubmoduleItem>
</VirtualSubmoduleList>
</ModuleItem>
</ModuleList>
</DeviceAccessPointItem>
</DeviceAccessPointList>
<ExternalTextList>
<PrimaryLanguage Lang="en">
<Text TextId="T_Name_DAP_1" Value="ESP32 PROFINET Interface"/>
<!-- More text entries -->
</PrimaryLanguage>
</ExternalTextList>
</ApplicationProcess>
</ProfileBody>
</ISO15745Profile>
Warning: This GSDML snippet is highly simplified and for illustrative purposes only. Creating a valid GSDML file requires adherence to the GSDML specification (available from PI) and usually involves using a GSDML editor or tool.
Main Application Code (main/main.c
)
This code initializes the Ethernet interface. The PROFINET stack interaction is purely conceptual.
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_netif.h"
#include "esp_eth.h"
#include "esp_event.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "sdkconfig.h" // For KConfig options
// Hypothetical PROFINET device stack header - NOT a real file for this example
// #include "profinet_device_stack.h"
static const char *TAG = "PROFINET_APP";
// --- Ethernet PHY Configuration ---
// Common PHYs: LAN8720, KSZ8081. Check your hardware.
#if CONFIG_IDF_TARGET_ESP32
#if CONFIG_ETH_USE_ESP32_EMAC
#define ETH_PHY_ADDR CONFIG_ETH_PHY_ADDR // Typically 0 or 1
#define ETH_PHY_RST_GPIO CONFIG_ETH_PHY_RST_GPIO // Reset pin, -1 if not used
#define ETH_MDC_GPIO CONFIG_ETH_MDC_GPIO // MDC pin
#define ETH_MDIO_GPIO CONFIG_ETH_MDIO_GPIO // MDIO pin
// RMII Pins for ESP32 Internal MAC
// TX_EN, TXD0, TXD1, CRS_DV (RX_DV), RXD0, RXD1, REF_CLK
#endif
#elif CONFIG_IDF_TARGET_ESP32S3
// ESP32-S3 might use internal MAC or SPI Ethernet. This example assumes internal MAC if available.
// Pin configurations for ESP32-S3 internal MAC would be similar.
#endif
// Global buffers for PROFINET I/O data (conceptual)
#define PROFINET_INPUT_DATA_SIZE 1 // Example: 1 byte IN
#define PROFINET_OUTPUT_DATA_SIZE 1 // Example: 1 byte OUT
uint8_t g_profinet_input_data[PROFINET_INPUT_DATA_SIZE];
uint8_t g_profinet_output_data[PROFINET_OUTPUT_DATA_SIZE];
// --- Hypothetical Callback Functions (would be part of a real PROFINET stack API) ---
/**
* @brief Callback from PROFINET stack: new output data received from IO Controller.
*/
void app_pn_output_received_cb(const uint8_t *data, uint16_t len) {
if (data && len == PROFINET_OUTPUT_DATA_SIZE) {
memcpy(g_profinet_output_data, data, len);
ESP_LOGI(TAG, "PROFINET Output data received (len %d): 0x%02X", len, g_profinet_output_data[0]);
// TODO: Application logic to use this data
}
}
/**
* @brief Callback from PROFINET stack: prepare input data to send to IO Controller.
*/
uint16_t app_pn_prepare_input_data_cb(uint8_t *buffer, uint16_t max_len) {
if (buffer && max_len >= PROFINET_INPUT_DATA_SIZE) {
// TODO: Application logic to prepare input data (e.g., read sensors)
g_profinet_input_data[0]++; // Simple counter for demo
memcpy(buffer, g_profinet_input_data, PROFINET_INPUT_DATA_SIZE);
return PROFINET_INPUT_DATA_SIZE;
}
return 0;
}
/**
* @brief Callback from PROFINET stack: IO Controller connection status changed.
*/
// void app_pn_connection_status_cb(bool connected, const char* controller_name) {
// if (connected) {
// ESP_LOGI(TAG, "Connected to PROFINET IO Controller: %s", controller_name);
// } else {
// ESP_LOGW(TAG, "Disconnected from PROFINET IO Controller.");
// }
// }
// --- End of Hypothetical Callbacks ---
/**
* @brief Event handler for Ethernet events
*/
static void eth_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) {
uint8_t mac_addr[6] = {0};
esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
ESP_LOGI(TAG, "Ethernet Link Up");
ESP_LOGI(TAG, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
break;
case ETHERNET_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "Ethernet Link Down");
break;
case ETHERNET_EVENT_START:
ESP_LOGI(TAG, "Ethernet Started");
// Here, you might set the PROFINET device name if not done by stack
// esp_netif_set_hostname(esp_netif_get_handle_from_ifkey("ETH_DEF"), "my-esp32-pn-device");
break;
case ETHERNET_EVENT_STOP:
ESP_LOGI(TAG, "Ethernet Stopped");
break;
default:
break;
}
}
/**
* @brief Event handler for IP_EVENT_ETH_GOT_IP
*/
static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) {
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
const esp_netif_ip_info_t *ip_info = &event->ip_info;
ESP_LOGI(TAG, "Ethernet Got IP Address");
ESP_LOGI(TAG, "~~~~~~~~~~~");
ESP_LOGI(TAG, "ETHIP:" IPSTR, IP2STR(&ip_info->ip));
ESP_LOGI(TAG, "ETHMASK:" IPSTR, IP2STR(&ip_info->netmask));
ESP_LOGI(TAG, "ETHGW:" IPSTR, IP2STR(&ip_info->gw));
ESP_LOGI(TAG, "~~~~~~~~~~~");
// --- Conceptual PROFINET Stack Start ---
// Once IP is obtained (or even before for DCP), the PROFINET stack can be fully started.
// profinet_device_config_t pn_config = {
// .device_name = "my-esp32-pn-device", // Must match GSDML and controller config
// .vendor_id = 0x010C, // From GSDML
// .device_id = 0x0010, // From GSDML
// // Assign callbacks
// .output_received_cb = app_pn_output_received_cb,
// .prepare_input_data_cb = app_pn_prepare_input_data_cb,
// .connection_status_cb = app_pn_connection_status_cb,
// // Pointers to I/O data configuration based on GSDML
// };
// if (profinet_device_stack_init(&pn_config) == ESP_OK) {
// profinet_device_stack_start();
// ESP_LOGI(TAG, "Conceptual PROFINET Device Stack Initialized and Started.");
// } else {
// ESP_LOGE(TAG, "Failed to initialize conceptual PROFINET stack.");
// }
ESP_LOGW(TAG, "Conceptual PROFINET stack functions are commented out.");
// --- End of Conceptual Stack Start ---
}
static void initialize_ethernet(void) {
ESP_ERROR_CHECK(esp_netif_init()); // Initialize TCP/IP network interface (should be called only once)
ESP_ERROR_CHECK(esp_event_loop_create_default()); // Create default event loop
// Create new default instance of esp-netif for Ethernet
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *eth_netif = esp_netif_new(&cfg);
// Init MAC and PHY without Kconfig defaults
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
// Update PHY config based on Kconfig settings (IMPORTANT!)
// These pins are specific to your hardware setup and ESP32 variant
// Ensure these are correctly defined in sdkconfig or here
phy_config.phy_addr = ETH_PHY_ADDR;
phy_config.reset_gpio_num = ETH_PHY_RST_GPIO;
// For ESP32 internal EMAC
#if CONFIG_IDF_TARGET_ESP32 && CONFIG_ETH_USE_ESP32_EMAC
mac_config.smi_mdc_gpio_num = ETH_MDC_GPIO;
mac_config.smi_mdio_gpio_num = ETH_MDIO_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
// Select PHY: LAN8720 is common, check your board
#if CONFIG_ETH_PHY_IP101
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_ETH_PHY_RTL8201
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_ETH_PHY_LAN87XX
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
#elif CONFIG_ETH_PHY_DP83848
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_ETH_PHY_KSZ80XX // For KSZ8081/KSZ8041
esp_eth_phy_t *phy = esp_eth_phy_new_ksz80xx(&phy_config);
#else
#error "Unsupported PHY defined in Kconfig"
esp_eth_phy_t *phy = NULL;
#endif
#elif CONFIG_IDF_TARGET_ESP32S3 && CONFIG_ETH_USE_ESP32_EMAC // Example for S3, check specific S3 EMAC init
// ESP32-S3 specific EMAC and PHY initialization would go here
// It might be similar to ESP32 or have its own `esp_eth_mac_new_esp32s3`
ESP_LOGE(TAG, "ESP32-S3 EMAC initialization not fully detailed here. Refer to IDF examples.");
esp_eth_mac_t *mac = NULL; // Placeholder
esp_eth_phy_t *phy = NULL; // Placeholder
#else // For other chips or SPI-Ethernet (e.g. W5500)
ESP_LOGW(TAG, "Using SPI Ethernet or unsupported target for direct EMAC example.");
// Example for W5500 SPI Ethernet (requires different Kconfig and init)
// spi_bus_config_t buscfg = {...};
// spi_device_interface_config_t devcfg = {...};
// esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&spi_eth_module_config, &mac_config);
// esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config);
esp_eth_mac_t *mac = NULL;
esp_eth_phy_t *phy = NULL;
#endif
if (!mac || !phy) {
ESP_LOGE(TAG, "Failed to create MAC or PHY instance. Check Kconfig and hardware.");
return;
}
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
ESP_ERROR_CHECK(esp_eth_driver_install(ð_config, ð_handle));
/* attach Ethernet driver to TCP/IP stack */
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
// Register user defined event handers
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, ð_handle));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
ESP_ERROR_CHECK(esp_eth_start(eth_handle)); // Start Ethernet driver state machine
ESP_LOGI(TAG, "Ethernet Initialized.");
}
void app_main(void) {
// Initialize NVS flash
// esp_err_t ret = nvs_flash_init();
// if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// ESP_ERROR_CHECK(nvs_flash_erase());
// ret = nvs_flash_init();
// }
// ESP_ERROR_CHECK(ret);
initialize_ethernet();
// The PROFINET stack would typically run in its own high-priority task(s).
// Application logic interacts with it via callbacks and shared data.
// For this basic example, we are just initializing Ethernet.
// A `profinet_device_task` would be created if a stack was integrated.
ESP_LOGI(TAG, "app_main finished. Ethernet interface is initializing.");
ESP_LOGI(TAG, "A real PROFINET application would start its stack after Ethernet is up.");
}
main/CMakeLists.txt
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")
KConfig Settings (via sdkconfig
or menuconfig
)
Ensure your project’s sdkconfig
(accessible via idf.py menuconfig
or VS Code’s SDK Configuration Editor) has the Ethernet MAC and PHY correctly configured for your specific ESP32 board/module:
Component config -> Ethernet -> Support ESP32 internal Ethernet MAC
(enable for ESP32 with internal MAC)- Select the correct Ethernet PHY model (e.g.,
LAN87XX
,KSZ80XX
,IP101
). - Configure GPIO pins for MDC, MDIO, PHY Reset, and RMII interface according to your hardware schematic.
Build Instructions
- Save
main.c
andCMakeLists.txt
in themain
directory. - Configure your project for your specific ESP32 hardware with Ethernet using
ESP-IDF: SDK Configuration editor
. Pay close attention to Ethernet MAC, PHY type, and GPIO pin assignments. - Build the project:
ESP-IDF: Build your project
.
Run/Flash/Observe Steps
- Flash the firmware:
ESP-IDF: Flash your project
. - Connect an Ethernet cable from your ESP32’s RJ45 port to your network switch (or PC).
- Open the ESP-IDF Monitor:
ESP-IDF: Monitor your device
. - Observe the log messages. You should see Ethernet initialization, link-up events, and potentially an IP address being assigned (if DHCP is active on your network and the ESP32 is configured as a DHCP client).
- Conceptual PROFINET Testing:
- If a PROFINET stack were integrated, you would then use a PROFINET engineering tool (IO Supervisor) on a PC connected to the same Ethernet network.
- Import the GSDML file for your ESP32 device.
- Assign a Device Name and IP address to the ESP32 device (often via DCP from the tool).
- Configure the IO Controller to communicate with the ESP32 IO Device.
- Observe I/O data exchange and diagnostics.
Tip: Wireshark with a PROFINET dissector is an invaluable tool for observing PROFINET traffic (DCP, RPC, RT frames) on the network and troubleshooting communication issues.
Variant Notes
- ESP32 (Original):
- Features a built-in 10/100 Mbps Ethernet MAC. Requires an external PHY (e.g., LAN8720, KSZ8081) connected via RMII.
- Sufficient processing power for a basic PROFINET IO Device stack (CC-A), especially if the stack is optimized or offloads some tasks.
- ESP32-S2:
- Does not have a built-in Ethernet MAC. Would require an SPI-based Ethernet controller (e.g., W5500, KSZ8863).
- Achieving PROFINET RT performance over SPI is challenging due to latency and potential bottlenecks. Less suitable for direct PROFINET IO Device implementation requiring RT. Could potentially act as a supervisor or handle non-real-time aspects if paired with another PROFINET interface.
- ESP32-S3:
- Some ESP32-S3 variants include an Ethernet MAC similar to the original ESP32, supporting RMII. Check the specific S3 module/chip datasheet.
- More processing power than the original ESP32, potentially better for more complex stack features or application logic alongside PROFINET.
- ESP32-C3 / ESP32-C2 / ESP32-C6 / ESP32-H2 (RISC-V series):
- These generally do not have a built-in Ethernet MAC. Similar to ESP32-S2, they would rely on SPI-Ethernet modules.
- Their suitability for PROFINET IO Device roles (especially RT) is limited by the SPI interface performance for real-time data.
- Could be used in roles that don’t require direct, high-performance PROFINET IO RT communication, or as a host controller for an external PROFINET ASIC/module.
General Considerations:
- PROFINET RT Performance: PROFINET RT (Real-Time) communication bypasses the TCP/IP stack and operates at Layer 2. This requires fast processing of Ethernet frames and timely responses. The ESP32’s internal MAC, when available, provides the necessary hardware foundation.
- IRT (Isochronous Real-Time): Implementing PROFINET IRT (Conformance Class C/D) on an ESP32 is highly unlikely without specialized external hardware (IRT-capable MAC/switch functionality) due to its stringent timing and synchronization requirements.
- Stack Memory and CPU Load: A PROFINET stack can be memory-intensive and CPU-intensive, especially if it handles many connections, large I/O data, or complex diagnostics. Careful resource management is essential.
- Recommendation for Robust Solutions: For commercial or critical PROFINET devices, using a dedicated PROFINET ASIC or a pre-certified commercial stack is strongly recommended to ensure compliance, performance, and reliability. The ESP32 can then serve as the application processor.
Common Mistakes & Troubleshooting Tips
Mistake / Issue | Symptom(s) | Troubleshooting / Solution |
---|---|---|
Ethernet PHY Init Failure | – No Ethernet link light on RJ45 port. – ESP-IDF logs show “Failed to create MAC/PHY instance”. – Device is completely unresponsive on the network. |
1. Check KConfig: Verify that the Ethernet MAC, PHY type (e.g., LAN8720), and all GPIO pin assignments in menuconfig perfectly match your board’s hardware schematic.2. PHY Clock/Reset: Ensure the PHY has a valid clock source and that the reset pin (if used) is handled correctly. |
No Link or IP Address | – Link light is on, but device gets no IP address. – Device doesn’t appear in network scans. – PROFINET IO controller cannot find the device. |
1. Physical Layer: Check Ethernet cable and switch port. Try a different cable/port. 2. DHCP Server: Confirm a DHCP server is active on the network if you are not using a static IP. 3. Firewall: Temporarily disable PC/network firewalls to ensure they aren’t blocking DHCP or PROFINET discovery packets. |
Device Name (Station Name) Issue | – IO Controller sees the device’s MAC address but reports a “name mismatch” error. – Cannot establish an Application Relation (AR). |
1. Assign Name: Use the engineering tool (IO Supervisor) to discover the device (via DCP) and assign it the correct, unique station name. 2. Match Configuration: The name assigned to the device must exactly match the station name configured for it in the IO Controller’s project. |
GSDML File Error | – Engineering tool fails to import the GSDML file. – Device appears with a generic icon or “Unknown Device” error. – Mismatch in Vendor/Device ID reported by the controller. |
1. Validate XML: Use a GSDML checker tool or an XML validator to ensure the file is well-formed. 2. Match IDs & Modules: The VendorID , DeviceID , and all Module/Submodule definitions in the GSDML must precisely match the firmware’s configuration. |
RT Communication Timeout | – IO Controller cyclically connects and disconnects from the device. – “BF” (Bus Fault) or error light flashes on the controller/device. – Data exchange is intermittent or fails completely. |
1. Task Priority: Ensure the PROFINET stack’s real-time tasks run at a high FreeRTOS priority to avoid being delayed by other application logic. 2. Network Load: Use PROFINET-aware switches that can prioritize RT frames (EtherType 0x8892) over standard traffic. 3. Analyze with Wireshark: Capture network traffic to see if the ESP32 is failing to respond to cyclic data requests within the configured watchdog time. |
Exercises
- Exercise 1: Ethernet MAC Address Display
- Modify the
eth_event_handler
in the providedmain.c
example. When theETHERNET_EVENT_CONNECTED
event occurs, print the ESP32’s MAC address to the console in the standard hex format (e.g.,AA:BB:CC:DD:EE:FF
). - Build, flash, and run. Observe the MAC address. This is a fundamental piece of information for network identification.
- Modify the
- Exercise 2: GSDML Study and Conceptual I/O Mapping
- Task: Imagine your ESP32 PROFINET device needs to provide 2 bytes of input data (e.g., from sensors) and control 1 byte of output data (e.g., to LEDs).
- Research the structure of a PROFINET GSDML file (refer to online examples or PI documentation).
- Conceptually, how would you define a
ModuleItem
in the GSDML to represent this “2 Bytes IN, 1 Byte OUT” configuration? WhatSubmoduleItem
entries would be needed for the input and output data? You don’t need to write perfect XML, but describe the key attributes likeModuleIdentNumber
,SubmoduleIdentNumber
,DataLength
,IOPS_Length
,IOCS_Length
. - What
VendorID
andDeviceID
would you hypothetically assign in theDeviceIdentity
section?
- Task: Imagine your ESP32 PROFINET device needs to provide 2 bytes of input data (e.g., from sensors) and control 1 byte of output data (e.g., to LEDs).
- Exercise 3: PROFINET Naming and Addressing Research
- Task: Research and answer the following:
- What is the role of the DCP (Discovery and Configuration Protocol) in setting up a PROFINET device?
- How does an IO Controller typically find and identify an IO Device on the network before establishing an application relationship (AR)?
- Can a PROFINET device have its IP address assigned by DHCP? If so, how does the IO Controller then reliably find it if the IP changes? (Hint: Device Name is key).
- Task: Research and answer the following:
Summary
- PROFINET is a versatile Industrial Ethernet standard using standard Ethernet hardware but employing specialized protocols for real-time (RT) and isochronous real-time (IRT) communication.
- It defines roles like IO Controller, IO Device, and IO Supervisor, and uses GSDML (XML-based) files for device description.
- Communication occurs via standard TCP/IP for non-critical tasks and direct Layer 2 protocols (PROFINET RT/IRT) for cyclic I/O data.
- Conformance Classes (CC-A, CC-B, CC-C, CC-D) define device capabilities, with CC-A being the baseline for IO devices.
- Implementing PROFINET on an ESP32 requires an Ethernet MAC and PHY. Variants like the original ESP32 and some ESP32-S3s have an internal MAC. Others would need SPI-Ethernet, which is less ideal for RT performance.
- A full PROFINET device stack is complex. Solutions range from developing from scratch (very hard), using open-source stacks (variable quality/completeness), or employing commercial stacks/ASICs (recommended for robust, certified products).
- Correct Ethernet hardware setup, PHY initialization, proper GSDML files, unique device names, and careful network configuration are crucial for successful PROFINET integration.
Further Reading
- PROFIBUS & PROFINET International (PI): https://www.profibus.com/technology/profinet/ – Official source for PROFINET specifications, guidelines, and technical documentation.
- ESP-IDF Programming Guide – Ethernet: https://docs.espressif.com/projects/esp-idf/en/v5.4/esp32/api-reference/network/esp_eth.html (Select your specific ESP32 target if needed).
- GSDML Specification (e.g., “GSDML V2.x Specification”): Available from PI for members or often discoverable through web searches.
- PROFINET System Description: A comprehensive overview document available from PI.
- Wireshark & PROFINET Dissector: https://www.wireshark.org – Essential for network analysis.
- “Industrial Ethernet: A Pocket Guide” by Perry S. Marshall and John S. Rinaldi: Provides a good overview of Industrial Ethernet concepts.