Hello, @ESP_alisitsyn,
Thank you for your answer. I will explain a bit more about my setup. This is an ESP32 that is going to be working as a TCP Slave device so someone else can connect to it and get the data from the registers with an HMI. While configuring and checking IP Addresses, I noticed that I have two different addresses, one for the original netif handler, and a second one for the ethernet handler. I'm able to change the netif IP without any issue using the functions you have shown me here, but I'm not able to set the IP address and subnet mask of the ethernet interface, which, as far as I know, are the ones that the Master TCP will need to communicate with my slave.
What I need is to be able to change the IP and subnet mask of the ethernet interface since they appear to be random. I will send a snippet of my code.
Code: Untitled.c Select all
esp_netif_ip_info_t info_ip;
// Initialize TCP/IP network interface (should be called only once in application)
ESP_ERROR_CHECK(esp_netif_init());
// Create default event loop that running in background
ESP_ERROR_CHECK(esp_event_loop_create_default());
// Create instance(s) of esp-netif for SPI Ethernet(s)
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
esp_netif_config.if_desc = "eth0";
esp_netif_config_t cfg_spi = {
.base = &esp_netif_config,
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
};
esp_netif_t *eth_netif_spi = { NULL };
char if_key_str[10];
char if_desc_str[10];
char num_str[3];
itoa(0, num_str, 10);
strcat(strcpy(if_key_str, "ETH_SPI_"), num_str);
strcat(strcpy(if_desc_str, "eth"), num_str);
esp_netif_config.if_key = if_key_str;
esp_netif_config.if_desc = if_desc_str;
esp_netif_config.route_prio = 30;
eth_netif_spi = esp_netif_new(&cfg_spi);
ESP_ERROR_CHECK(esp_netif_dhcpc_stop(eth_netif_spi));
char* ip= "10.25.10.2";
char* gateway = "10.25.0.1";
char* netmask = "255.255.0.0";
esp_netif_ip_info_t info_t;
memset(&info_t, 0, sizeof(esp_netif_ip_info_t));
info_t.ip.addr = esp_ip4addr_aton((const char *)ip);
info_t.gw.addr = esp_ip4addr_aton((const char *)gateway);
info_t.netmask.addr = esp_ip4addr_aton((const char *)netmask);
esp_netif_set_ip_info(eth_netif_spi, &info_t);
// Init MAC and PHY configs to default
eth_mac_config_t mac_config_spi = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config_spi = ETH_PHY_DEFAULT_CONFIG();
// Init SPI bus
spi_device_handle_t spi_handle = { NULL };
spi_bus_config_t buscfg = {
.miso_io_num = GPIO_NUM_36,
.mosi_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
// Install GPIO ISR handler to be able to service SPI Eth modlues interrupts
gpio_install_isr_service(0);
ESP_ERROR_CHECK(spi_bus_initialize(SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
// Init specific SPI Ethernet module configuration from Kconfig (CS GPIO, Interrupt GPIO, etc.)
spi_eth_module_config_t spi_eth_module_config = {
.spi_cs_gpio = GPIO_NUM_5,
.phy_reset_gpio = GPIO_NUM_27,
.int_gpio = GPIO_NUM_4,
.phy_addr = 10
};
// Configure SPI interface and Ethernet driver for specific SPI module
esp_eth_mac_t *mac_spi;
esp_eth_phy_t *phy_spi;
esp_eth_handle_t eth_handle_spi = { NULL };
spi_device_interface_config_t devcfg = {
.command_bits = 16, // Actually it's the address phase in W5500 SPI frame
.address_bits = 8, // Actually it's the control phase in W5500 SPI frame
.mode = 0,
.clock_speed_hz = 10 * 1000 * 1000,
.queue_size = 20
};
// Set SPI module Chip Select GPIO
devcfg.spics_io_num = spi_eth_module_config.spi_cs_gpio;
ESP_ERROR_CHECK(spi_bus_add_device(SPI_HOST, &devcfg, &spi_handle));
// w5500 ethernet driver is based on spi driver
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
// Set remaining GPIO numbers and configuration used by the SPI module
w5500_config.int_gpio_num = spi_eth_module_config.int_gpio;
phy_config_spi.phy_addr = spi_eth_module_config.phy_addr;
phy_config_spi.reset_gpio_num = spi_eth_module_config.phy_reset_gpio;
mac_spi = esp_eth_mac_new_w5500(&w5500_config, &mac_config_spi);
phy_spi = esp_eth_phy_new_w5500(&phy_config_spi);
esp_eth_config_t eth_config_spi = ETH_DEFAULT_CONFIG(mac_spi, phy_spi);
ESP_ERROR_CHECK(esp_eth_driver_install(ð_config_spi, ð_handle_spi));
/* The SPI Ethernet module might not have a burned factory MAC address, we cat to set it manually.
02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control.*/
ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle_spi, ETH_CMD_S_MAC_ADDR, (uint8_t[]) {
0x00, 0x12, 0xCF, 0xC1, 0x55, 0xE2
}));
// attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(eth_netif_spi, esp_eth_new_netif_glue(eth_handle_spi)));
// Register user defined event handers
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
/* start Ethernet driver state machine */
ESP_ERROR_CHECK(esp_eth_start(eth_handle_spi));
mb_register_area_descriptor_t reg_area; // Modbus register area descriptor structure
void* slave_handler = NULL;
// Initialization of Modbus controller
esp_err_t err = mbc_slave_init_tcp(&slave_handler);
MB_RETURN_ON_FALSE((err == ESP_OK && slave_handler != NULL), ESP_ERR_INVALID_STATE,
SLAVE_TAG,
"mb controller initialization fail.");
mb_communication_info_t comm_info = {
.ip_port = MB_TCP_SLAVE_PORT, // Modbus TCP port number (default = 502)
.ip_addr_type = MB_IPV4, // version of IP protocol
.ip_mode = MB_MODE_TCP, // Port communication mode
.ip_addr = NULL, // This field keeps the client IP address to bind, NULL - bind to any client
.ip_netif_ptr = (void*)eth_handle_spi // esp_netif_ptr - pointer to the corresponding network interface
};
// Setup communication parameters and start stack
err = mbc_slave_setup((void*)&comm_info);
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
SLAVE_TAG,
"mbc_slave_setup fail, returns(0x%x).",
(uint32_t)err);
reg_area.type = MB_PARAM_HOLDING; // Set type of register area
reg_area.start_offset = MB_REG_HOLDING_START_AREA0; // Offset of register area in Modbus protocol
reg_area.address = (void*)&holding_reg_area[0]; // Set pointer to storage instance
reg_area.size = sizeof(holding_reg_area) << 1; // Set the size of register storage area in bytes
ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
SLAVE_TAG,
"mbc_slave_set_descriptor fail, returns(0x%x).",
(uint32_t)err);
// Starts of modbus controller and stack
err = mbc_slave_start();
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
SLAVE_TAG,
"mbc_slave_start fail, returns(0x%x).",
(uint32_t)err);
vTaskDelay(5);
printf("modbusTCP initialized\n");
esp_netif_get_ip_info(eth_handle_spi, &ip_info);
ESP_LOGI(SLAVE_TAG, "ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR,
IP2STR(&ip_info.ip),
IP2STR(&ip_info.netmask),
IP2STR(&ip_info.gw));
esp_netif_get_ip_info(eth_netif_spi, &ip_info);
ESP_LOGI(SLAVE_TAG, "ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR,
IP2STR(&ip_info.ip),
IP2STR(&ip_info.netmask),
IP2STR(&ip_info.gw));
holding_reg_area[0] = 0x01;
holding_reg_area[1] = 0x02;
return err;
I can't show you the log right now, but I have no error and it is showing what it is supposed to show. In the beginning, I thought the netif would attach its IP information to the ethernet interface but it didn't work like that, so what I really want to do is manually set the Ip address and subnet mask of my TCP Slave, either by some Modbus config or by the ethernet configuration. Something worth mentioning is that the ethernet interface creates a random IP and subnet mask, but then that same one has randomly changed again after starting the TCP stack. Also, I can't configure the TCP master being used for certain reasons.