I'm thinking that we need a better community coordination mechanism ... I am reading this thread and it seems we now have THREE independent WebSockets implementations ... http://www.esp8266.com/viewtopic.php?f=29&t=4603
I'm not understanding the overlap.
A WDT reset problem can be created using the example program ESP8266WebServer/HelloServer with periodic calls to noInterrupts(). The same program works correctly when built with 1.6.4-673-g8cd3697.
Modify the example program to add SSID/PSK. Verify it connects. Ping the ESP server using sudo ping -A <ESP IP addr>
. This sends about 1000 pings/sec which the ESP handles correctly. My test was done using a package built from git commit aafacdcb.
Next modify the loop() function to add noInterrupts(). The idea for this was derived from a program that updates WS281x/NeoPixel LEDs from network packets received at 30 updates/sec. The LED code has been removed since it was discovered on the NeoPixelBus repo chat that the key factor is disabling interrupts with lots of WiFi traffic.
uint32_t lastTime = 0;
void loop()
{
server.handleClient();
// Every 30 ms, disable interupts
if ((millis() - lastTime) > 30) {
//uint32_t savedPS;
lastTime = millis();
//savedPS = xt_rsil(15); // does not work either
noInterrupts();
delayMicroseconds(2000);
interrupts();
//xt_wsr_ps(savedPS);
Serial.println(lastTime);
}
}
After downloading the modified example code, do sudo ping -A <ESP IP addr>
. On my system this results in WDT reset less than 10 seconds. The rate of pings can be reduced with various ping options but the WDT reset still occurs but less frequently.
Removing noInterrupts/interrupts eliminates the WDT reset but bit banging the WS281x LED protocol requires interrupts off. However, this demonstrates the problem is caused by disabling interrupts and not the addition of 2 ms delay to loop().
After putting the noInterrupts/interrupts back in, build with 1.6.4-673-g8cd3697. On my system, the WDT resets do not occur even when handling 1000 pings/sec for 10 minutes.
ets_isr_mask(B1111111)
The test program has been modified to show the pending interrupt(s) before enabling interrupts. As soon as interrupts are enabled pending interrupt(s) must be handled. In all cases with WDT reset, the pending interrupt is bit 0. However, bit 0 is the pending interrupt in many other cases that do not fail. I assume bit 0 is WiFi since when pinging is stopped, this bit is almost always 0. When pinging starts, it is almost always 1.
uint32_t lastTime = 0;
#define get_ints_pending(ints_pending) __asm__ __volatile__("esync; rsr %0,226; esync":"=a" (ints_pending))
void loop()
{
server.handleClient();
// Every 30 ms, disable interupts
if ((millis() - lastTime) > 30) {
uint32_t ints_pending_before, ints_pending_after;
lastTime = millis();
noInterrupts();
get_ints_pending(ints_pending_before);
//Serial.printf("ints pending %lx\r\n", ints_pending_before);
delayMicroseconds(2000);
get_ints_pending(ints_pending_after);
//Serial.printf("ints pending %lx\r\n", ints_pending_after);
Serial.printf("ints changed %lx\r\n", ints_pending_before ^ ints_pending_after);
interrupts();
}
}
An example of a failure.
ints changed 1
ints changed 0
ints changed 1
ints changed 1
ints changed 1
ints changed 1
ints changed 401
ints changed 1
ints changed 401
ints changed 1
ets Jan 8 2013,rst cause:4, boot mode:(3,6)
wdt reset
load 0x4010f000, len 1264, room 16
tail 0
chksum 0x42
csum 0x42
~ld
Ok, added ets_isr_mask instead of noInterrupts/interrupts. I hope I did it correctly.
uint32_t lastTime = 0;
#define get_ints_pending(ints_pending) __asm__ __volatile__("esync; rsr %0,226; esync":"=a" (ints_pending))
void loop()
{
server.handleClient();
// Every 30 ms, disable interupts
if ((millis() - lastTime) > 30) {
uint32_t ints_pending_before, ints_pending_after;
lastTime = millis();
//noInterrupts();
ets_isr_mask(B1111110);
get_ints_pending(ints_pending_before);
//Serial.printf("ints pending %lx\r\n", ints_pending_before);
delayMicroseconds(2000);
get_ints_pending(ints_pending_after);
//Serial.printf("ints pending %lx\r\n", ints_pending_after);
Serial.printf("ints changed %lx\r\n", ints_pending_before ^ ints_pending_after);
//interrupts();
ets_isr_mask(0);
}
}
No failures after 7.5 minutes of 1000 pings/second. Note "ints changed" is now always 0. However, allowing WiFi interrupt during this time will throw off the LED bit bang timing. But it does confirm WiFi interrupts cannot be disabled even for a few milliseconds.
uint32_t lastTime = 0;
#define get_ints_pending(ints_pending) __asm__ __volatile__("esync; rsr %0,226; esync":"=a" (ints_pending))
void loop()
{
server.handleClient();
// Every 30 ms, disable interupts
if ((millis() - lastTime) > 30) {
uint32_t ints_pending_before, ints_pending_after;
lastTime = millis();
ets_isr_mask(B1111110);
noInterrupts();
get_ints_pending(ints_pending_before);
//Serial.printf("ints pending %lx\r\n", ints_pending_before);
delayMicroseconds(2000);
get_ints_pending(ints_pending_after);
//Serial.printf("ints pending %lx\r\n", ints_pending_after);
Serial.printf("ints changed %lx\r\n", ints_pending_before ^ ints_pending_after);
interrupts();
ets_isr_mask(0);
}
}