(solved) Esp8266 using v3.1.1 pow() throwing exception (feed your dog)

The following code runs fine on other platforms, including ESP32, but throws an exception on Esp8266. I am using the the board support version 3.1.1 (latest) and I have tried both IDE 1.9.19 and the 2.0.4 (v2 and serial isn't a fun experience let alone I couldn't find the ESP exception decoder in the tools menu).

void setup() {
    Serial.begin(115200);
    Serial.println();
    Serial.println("Initializing...");
}

void loop() {
    Serial.println();
    Serial.println("Running...");
    // 36000-56000 delta 20000 causes exception
    // 10000 - 31000 causes exception
    // 10000 - 21000 works fine
    // 21000 - 31000 works fine
    for (uint32_t elem = 10000; elem <= 31000; elem++) { 
      float unitValue = elem / 65535.0f;
      float unitValueMod = pow((unitValue + 0.16f) / 1.16f, 3.0f);
    
      uint16_t elemMod = static_cast<uint16_t>(65535.0f * unitValueMod + 0.5f);
    }
}

The output will look like

Initializing...
Running...
Running...
Running...
Running...
-------------- - CUT HERE FOR EXCEPTION DECODER-------------- -

The exception decoded results in the following call stack

Decoding stack results
0x40202699: uart_flush(uart_t*) at C : \Users\<user>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\cores\esp8266\uart.cpp line 587
0x401009a0: malloc(size_t) at C : \Users\<user>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 912
0x402025d0: uart_write(uart_t*, char const*, size_t) at C : \Users\<user>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\cores\esp8266\uart.cpp line 547
0x4020a52c: powf at / workdir / repo / newlib / newlib / libm / math / wf_pow.c line 35
0x402010c7 : loop() at C : \Users\<user>\Documents\Arduino\powf_failure_smaller / powf_failure_smaller.ino line 18
0x402018d4: loop_wrapper() at C : \Users\<user>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.1\cores\esp8266\core_esp8266_main.cpp line 258

The things I noted with this.

  • The loop counters matter, make it narrow and it doesn't happen. Make it larger and it never finishes a single run.
  • With the current counter settings, it completes a run four times before failing.
  • I don't trust anything in the call stack after the pow, as I suspect it is just outputting the error.

I would love to get someone to confirm it fails for them on similar hardware to remove the possibility it's a hardware issue.

This works on an Arduino Uno, and returns expected results:

void setup() {
Serial.begin(115200);
float unitValue, unitValueMod;
while(!Serial);

    for (uint32_t elem = 10000; elem <= 31000; elem++) { 
      unitValue = elem / 65535.0f;
      unitValueMod = pow((unitValue + 0.16f) / 1.16f, 3.0f);
}
Serial.println(unitValue);
Serial.println(unitValueMod); //final values
}

void loop() {}

The issue was that the task (main loop) was not servicing the software watch dog and it triggers.

Solved by putting either a ESP.wdtFeed() or a yield() in the for loop.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.