Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ethernet Static IP Fails #5733

Closed
weswitt opened this issue Oct 4, 2021 · 7 comments · Fixed by #5836
Closed

Ethernet Static IP Fails #5733

weswitt opened this issue Oct 4, 2021 · 7 comments · Fixed by #5836

Comments

@weswitt
Copy link

weswitt commented Oct 4, 2021

Using Arduino ESP32 v2.0.0 and Arduino IDE v1.8.16. Board is a WESP32 with the ETH_PHY_RTL8201 chip.

I cannot get static IP to work -- very simple code below. The network initializes just fine but I get a DHCP address. I tried calling ETH.config before ETH.begin but that results in the system crashing. Is there a way to get a static IP to work?

ETH.begin(0, -1, 16, 17, ETH_PHY_RTL8201);
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL);
ETH.config(
    IPAddress(192,168,10,186),
    IPAddress(192,168,10,1),
    IPAddress(255,255,255,0),
    IPAddress(192,168,10,1),
    IPAddress(8,8,8,8));
@weswitt
Copy link
Author

weswitt commented Oct 6, 2021

Very strange. I received a notification from a user that looked like a response to this issue, however there is no response here.

the user wrote this:

Try this:
IPAddress local_IP(192, 168, 10, 186);
IPAddress gateway(192, 168, 10, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress primaryDNS(192, 168, 10, 1);
IPAddress secondaryDNS(8, 8, 8, 8);

// Configures static IP address
if (!ETH.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("ETH Failed to configure");
}
ETH.begin(0, -1, 16, 17, ETH_PHY_RTL8201);
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL);

First, calling ETH.config before ETH.begin causes a device panic. This has been reported on Github before but it has not been fixed:

Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

Core 1 register dump:
PC : 0x400d9773 PS : 0x00060130 A0 : 0x800d82b9 A1 : 0x3ffb26a0
A2 : 0x00000000 A3 : 0x00000000 A4 : 0x3f401bd8 A5 : 0x0000ff00
A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x800d86fb A9 : 0x3ffb26a0
A10 : 0x3ffc6ea4 A11 : 0x00000000 A12 : 0x00000001 A13 : 0x3ffb2480
A14 : 0x00000031 A15 : 0x00000004 SAR : 0x00000019 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000020 LBEG : 0x40089c19 LEND : 0x40089c29 LCOUNT : 0xfffffff3

Backtrace:0x400d9770:0x3ffb26a00x400d82b6:0x3ffb26e0 0x4017abd2:0x3ffb2700 0x400d422b:0x3ffb2750 0x4017917e:0x3ffb2820

Exception Cause: Not found

0x400d9773: esp_netif_dhcpc_stop at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_netif/lwip/esp_netif_lwip.c:1047
0x40089c19: strlen at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/machine/xtensa/strlen.S:84
0x40089c29: strlen at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/machine/xtensa/strlen.S:96
0x400d9770: esp_netif_dhcpc_stop at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_netif/lwip/esp_netif_lwip.c:1047
0x400d82b6: tcpip_adapter_dhcpc_stop at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/tcpip_adapter/tcpip_adapter_compat.c:248
0x4017abd2: ETHClass::config(IPAddress, IPAddress, IPAddress, IPAddress, IPAddress) at d:/dev/arduino-1.8.16/hardware/esp32/ESP32/libraries/WiFi/src/ETH.cpp:390
0x400d422b: setup() at D:\dev\src\homeauto\weather\controller-poe2/controller.cpp:433
0x4017917e: loopTask(void*) at d:/dev/arduino-1.8.16/hardware/esp32/ESP32/cores/ESP32/main.cpp:38

So I moved the call to after ETH.begin and it fails.

@SuGlider SuGlider self-assigned this Oct 6, 2021
@SuGlider
Copy link
Collaborator

SuGlider commented Oct 6, 2021

@weswitt , could you please set the "Core Debug Level" option to "Verbose" and report back the messages in both cases (config() before begin() and vice-versa)?

@weswitt
Copy link
Author

weswitt commented Oct 6, 2021

setting the core debug level to 5 changes the timing and i get a different behavior. it will succeed always with a good/expected set of messages. with the debug level set to zero the static ip will work sometimes and fail other times. even when it works i get the message: "E (4906) esp_netif_handlers: invalid static ip". with the core debug level set to zero the behavior is very flakey.

in looking at the code paths for ETH.config it seems that calling it before ETH.begin is not supported. it expects things to be setup and will panic. it looks like it ends up referencing a null pointer that is expected to be valid.

@SuGlider
Copy link
Collaborator

SuGlider commented Oct 6, 2021

It sounds like the sketch may have to wait for a while after begin(), before calling config (), is it right?

If a delay(1000) is used between them, it works?

I guess that some SPI communication is going on in a separated task in paralell with the sketch task.
Maybe some kind of isETH_alreadyRunning() would be helpful...

It could be a racing condition.

@weswitt
Copy link
Author

weswitt commented Oct 6, 2021

thanks @SuGlider . your analysis seems to be correct. i added a 1 second delay after calling ETH.begin and it now seems to be reliable and i do not get the "invalid static ip" message.

@SuGlider
Copy link
Collaborator

SuGlider commented Oct 6, 2021

Anyway, it means that some RTOS lock is necessary in the code in order to make config() wait until begin() is done.

Feel free to send a PR to fix Arduino Ethernet Library, it f you want to do so.

@SuGlider SuGlider moved this from 2.0.1 release to In Development in (Archived) Arduino Core ESP32 RoadMap Oct 22, 2021
@SuGlider
Copy link
Collaborator

SuGlider commented Nov 3, 2021

I was able to reproduce this issue using an ESP32-Ethernet-Kit_A_V1.2 board (https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-ethernet-kit.html)

I've got 2 possible error messages:

E (3499) esp_netif_handlers: invalid static ip
This error message didn't impact Ethernet functionality and it sets static IP correctly.
It has to do with IDF DHCP server events and it is reported in IDF forum as "no worries about it"

[ 1767][E][ETH.cpp:397] config(): STA IP could not be configured! Error: 20487
This error message impacts Ethernet functionality and does not set static IP.
It can be repoduced by adding a delay(0); right before calling ETH.config()

Sketch used to reproduce both issues:

#include <ETH.h>

#define ETH_ADDR        1
#define ETH_POWER_PIN   5
#define ETH_TYPE        ETH_PHY_IP101

static bool eth_connected = false;

void WiFiEvent(WiFiEvent_t event)
{
  switch (event) {
    case ARDUINO_EVENT_ETH_START:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname("esp32-ethernet");
      break;
    case ARDUINO_EVENT_ETH_CONNECTED:
      Serial.println("ETH Connected");
      break;
    case ARDUINO_EVENT_ETH_GOT_IP:
      Serial.print("ETH MAC: ");
      Serial.print(ETH.macAddress());
      Serial.print(", IPv4: ");
      Serial.print(ETH.localIP());
      if (ETH.fullDuplex()) {
        Serial.print(", FULL_DUPLEX");
      }
      Serial.print(", ");
      Serial.print(ETH.linkSpeed());
      Serial.println("Mbps");
      eth_connected = true;
      break;
    case ARDUINO_EVENT_ETH_DISCONNECTED:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
    case ARDUINO_EVENT_ETH_STOP:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default:
      break;
  }
}

void testClient(const char * host, uint16_t port)
{
  Serial.print("\nconnecting to ");
  Serial.println(host);

  WiFiClient client;
  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    return;
  }
  client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
  while (client.connected() && !client.available());
  while (client.available()) {
    Serial.write(client.read());
  }

  Serial.println("closing connection\n");
  client.stop();
}

void setup()
{
  Serial.begin(115200);
  WiFi.onEvent(WiFiEvent);
  ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_TYPE);

  // In order to see the error messages, please set Debug Level to "Error"
  // keeping <delay(0)> will produce this error message and it will not set Static IP: [  1767][E][ETH.cpp:397] config(): STA IP could not be configured! Error: 20487
  // commetting out <delay(0)> will produce this error message and it will set static IP OK:  E (3499) esp_netif_handlers: invalid static ip
  delay(0);
  
  ETH.config(
    IPAddress(192, 168, 1, 250),    // Own IP Addr
    IPAddress(192, 168, 1, 1),      // Gateway
    IPAddress(255, 255, 255, 0),    // Netmask
    IPAddress(192, 168, 1, 1),      // DNS1
    IPAddress(8, 8, 8, 8));         // DNS2
}


void loop()
{
  if (eth_connected) {
    testClient("google.com", 80);
    Serial.print("My IP: ");
    Serial.print(ETH.localIP());
    Serial.println();
  }
  delay(30000);
}

me-no-dev pushed a commit that referenced this issue Nov 9, 2021
Summary

Only affects ETH (not WiFi)

This PR solves #5733 by allowing the DHCP IDF server to complete its tasks and only then it sets a static IP.
This also solves another related failure reported in this issue (#5733 (comment)).

fix #5733

Impact

Adds a delay in order to wait for DHCP to actually terminate before setting the static IP configuration in ETH.
@VojtechBartoska VojtechBartoska moved this from In Development to Development Complete in (Archived) Arduino Core ESP32 RoadMap Nov 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

2 participants