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

Wifi connect fails if serial bytes are incoming #1123

Closed
s0170071 opened this issue Mar 19, 2018 · 10 comments
Closed

Wifi connect fails if serial bytes are incoming #1123

s0170071 opened this issue Mar 19, 2018 · 10 comments
Labels
Status: Fixed Commit has been made, ready for testing

Comments

@s0170071
Copy link
Contributor

This affects 2.4.0 + core versions, but only in combination with ESPEasy.

I have 550 bytes incoming on serial (9600bps). Once per second, asynchonously. If I unplug the serial interface, the ESP boots fine. With it connected it stalls after program memory check until the WDT kicks in.

If I re-connect my serial wire after startup- everything is fine.
If I use 2.3.0 everything is fine.
If I use 2.4.0 (minimal webserver example , no ESPEasy) everything is fine.

I tried already:

  • disabling Serial.
  • setting RxBufferSize to 0,127, 128.
  • Initializing Serial as TXonly
  • adding delay(1) all over ESPEasy.ino

The only known workaround is swapping serial to TX2/RX2 pins until WiFi connect has finished and swapping it back a couple of seconds later.

I know that ESPEasy is officially 2.3.0 but I maybe someone has a hint for me on where to look...
Are there interrupts active in ESPEasy ?
Looks like a buffer overflow that is not serviced and stalls the system. But why does it affect ESPEasy only and not the plain webserver example?

@s0170071
Copy link
Contributor Author

just found esp8266/Arduino#4328
Will try it ...

@s0170071
Copy link
Contributor Author

s0170071 commented Mar 20, 2018

ok that PR helped a bit but the issue is still there and it is even stranger than before. The sample sketch doesn't crash any more, thats an improvement. But it doesn't work with ESPEasy yet.

I still have the WD triggered when I got serial bytes incoming during boot. I narrowed it down to WifiAPconfig(). The WD is triggered in line WiFi.softAP() when the parameters equal to "EHZ_5" and "configesp". Variable or const string doesn't matter.

But if I put in my own wifi credentials, it doesn't crash.

@s0170071 s0170071 reopened this Mar 20, 2018
@TD-er
Copy link
Member

TD-er commented Mar 20, 2018

In the current WiFi code, there is something like this:

    #if defined(ESP8266)
      ETS_UART_INTR_DISABLE();
      wifi_station_disconnect();
      ETS_UART_INTR_ENABLE();
    #endif

Maybe something like this is needed here also?

@s0170071
Copy link
Contributor Author

Will try it tomorrow. But where is the connection between the UART interrupt and wifi?

@TD-er
Copy link
Member

TD-er commented Mar 20, 2018

interrupts do interrupt anything.
I can imagine connecting to WiFi may be timing critical and probably also disables running background tasks.
So if too many interrupts lead to too many retries, the watchdog timer will kick in and reboot.

@s0170071
Copy link
Contributor Author

s0170071 commented Mar 21, 2018

@TD-er
Tried disabling UART interrupts - no change.
Interesting:

This does not work:
WiFi.softAP(WifiGetAPssid().c_str(), SecuritySettings.WifiAPKey);

This works:

String SSID2="EHZ_5"; 
const char *pwd = "configesp"; 
WiFi.softAP(SSID2.c_str(),pwd);

printing WifiGetAPssid().c_str() and SecuritySettings.WifiAPKey shows "EHZ_5" and "configesp"
So whats the difference ? And what does it have to do with Serial bytes incoming ?
edit:
If I use either of the parameters it crashes. Don't have to be both.

edit2:
found a workaround:

 // WiFi.softAP(WifiGetAPssid().c_str(), SecuritySettings.WifiAPKey);
 String SSID2=WifiGetAPssid(); 
 String pwd = SecuritySettings.WifiAPKey; 
 WiFi.softAP(SSID2.c_str(),pwd.c_str());

wtf!?

@TD-er
Copy link
Member

TD-er commented Mar 21, 2018

Actually it does make sense.
The same issue was with the MQTT library, which I patched (and reported).
The c_str() function does return a pointer to the address of the first item of the string and makes sure the string ends with a 0.
If that pointer is stored inside the function softAP, instead of copying the data, there is no guarantee the pointer is still valid when used later on.
The String object returned by the function WiFiGetAPssid() is only temporary and will be destructed as soon as it is out of scope.
The String object is actually a container class, which does allocation/deallocation when needed. Those allocations are on the heap.
When freed, there is no guarantee the data that was there is still present. That's implementation dependent and also depending on how soon new memory allocation is being done on the heap.
With a lot of interrupts, it is quite possible this happens quite soon. Possibly within the time needed to connect to the accesspoint.

@s0170071
Copy link
Contributor Author

@TD-er: you made my day. Thanks.
I do perfectly understand when you explain it like that but it would have taken me quite some time to figure that one out myself.
Should we check the code for similar occurrences ?

@TD-er
Copy link
Member

TD-er commented Mar 21, 2018

Quite possible there are bugs like that, but hard to find.

@TD-er TD-er added the Status: Fixed Commit has been made, ready for testing label Mar 23, 2018
@TD-er
Copy link
Member

TD-er commented Mar 23, 2018

This is fixed right?
Can be closed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Fixed Commit has been made, ready for testing
Projects
None yet
Development

No branches or pull requests

2 participants