ESP32 Core v2.0.1 / 2.0.1 RC1 crashes if using float in ISR
khoih-prog opened this issue ยท 11 comments
Core ESP32 Core v2.0.1 / 2.0.0 crashes if using float inside ISR. No issue with core v2.0.0-
This creates issue with some ESP32 TimerInterrupt-related libraries, such as mentioned in ESP32_New_TimerInterrupt Important Notes
With the following simple sketch, it's working OK if using
#define USING_FLOAT_IN_ISR false
but crashes if using
#define USING_FLOAT_IN_ISR true
Minimal, Reproducible Example (MRE) sketch
#define USING_FLOAT_IN_ISR true //false
volatile int interruptCounter;
volatile float interruptFloatCounter;
int totalInterruptCounter;
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR onTimer()
{
portENTER_CRITICAL_ISR(&timerMux);
#if USING_FLOAT_IN_ISR
interruptFloatCounter += 1.0f;
#else
interruptCounter++;
#endif
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup()
{
Serial.begin(115200);
while (!Serial);
delay(100);
Serial.print(F("\nStarting ESP32TimerInterrupt_Float_Bug on ")); Serial.println(ARDUINO_BOARD);
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 1000000, true);
timerAlarmEnable(timer);
}
void loop()
{
if (interruptCounter > 0)
{
portENTER_CRITICAL(&timerMux);
#if USING_FLOAT_IN_ISR
interruptFloatCounter -= 1.0f;
#else
interruptCounter--;
#endif
portEXIT_CRITICAL(&timerMux);
totalInterruptCounter++;
Serial.print("An interrupt as occurred. Total number: ");
Serial.println(totalInterruptCounter);
}
}
Debug Output if not using float
Starting ESP32TimerInterrupt_Float_Bug on ESP32_DEV
An interrupt as occurred. Total number: 1
An interrupt as occurred. Total number: 2
An interrupt as occurred. Total number: 3
An interrupt as occurred. Total number: 4
An interrupt as occurred. Total number: 5
An interrupt as occurred. Total number: 6
An interrupt as occurred. Total number: 7
An interrupt as occurred. Total number: 8
An interrupt as occurred. Total number: 9
An interrupt as occurred. Total number: 10
An interrupt as occurred. Total number: 11
An interrupt as occurred. Total number: 12
An interrupt as occurred. Total number: 13
An interrupt as occurred. Total number: 14
An interrupt as occurred. Total number: 15
An interrupt as occurred. Total number: 16
An interrupt as occurred. Total number: 17
An interrupt as occurred. Total number: 18
An interrupt as occurred. Total number: 19
Debug Output if using float
Starting ESP32TimerInterrupt_Float_Bug on ESP32_DEV
Guru Meditation Error: Core 1 panic'ed (Coprocessor exception).
Core 1 register dump:
PC : 0x4008110d PS : 0x00060033 A0 : 0x800d1168 A1 : 0x3ffbedb0
A2 : 0x3ffbdb68 A3 : 0x00000001 A4 : 0x80089bd1 A5 : 0x00000000
A6 : 0x3ffc15dc A7 : 0x3ffc15dc A8 : 0x3ffc10f8 A9 : 0x3ffbee30
A10 : 0x00060021 A11 : 0x3ffc15dc A12 : 0x3ffc15d4 A13 : 0xb33fffff
A14 : 0x00000001 A15 : 0x00000000 SAR : 0x00000020 EXCCAUSE: 0x00000004
EXCVADDR: 0x00000000 LBEG : 0x40085b68 LEND : 0x40085b73 LCOUNT : 0xffffffff
Backtrace:0x4008110a:0x3ffbedb00x400d1165:0x3ffbee90 0x400840ad:0x3ffbeeb0 0x400899c7:0x3ffb2750 0x40088601:0x3ffb2770 0x400d1f08:0x3ffb27b0 0x400d146d:0x3ffb27e0 0x400d1505:0x3ffb2800 0x400d1baa:0x3ffb2820
ELF file SHA256: 0000000000000000
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1420
ho 0 tail 12 room 4
load:0x40078000,len:13540
load:0x40080400,len:3604
entry 0x400805f0
Exception Decoder
PC: 0x4008110d: onTimer() at /home/kh/Arduino/Testing/ESP32TimerInterrupt/ESP32TimerInterrupt_Float_Bug/ESP32TimerInterrupt_Float_Bug.ino line 17
EXCVADDR: 0x00000000
Decoding stack results
0x4008110a: onTimer() at /home/kh/Arduino/Testing/ESP32TimerInterrupt/ESP32TimerInterrupt_Float_Bug/ESP32TimerInterrupt_Float_Bug.ino line 17
0x400d1165: __timerISR at /home/kh/.arduino15/packages/esp32/hardware/esp32/2.0.1/cores/esp32/esp32-hal-timer.c line 110
0x400899c7: xTaskGetSchedulerState at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/hal/esp32/include/hal/cpu_ll.h line 39
0x40088601: xQueueSemaphoreTake at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/queue.c line 1554
0x400d1f08: uartAvailable at /home/kh/.arduino15/packages/esp32/hardware/esp32/2.0.1/cores/esp32/esp32-hal-uart.c line 192
0x400d146d: HardwareSerial::available() at /home/kh/.arduino15/packages/esp32/hardware/esp32/2.0.1/cores/esp32/HardwareSerial.cpp line 193
0x400d1505: serialEventRun() at /home/kh/.arduino15/packages/esp32/hardware/esp32/2.0.1/cores/esp32/HardwareSerial.cpp line 98
0x400d1baa: loopTask(void*) at /home/kh/.arduino15/packages/esp32/hardware/esp32/2.0.1/cores/esp32/main.cpp line 47
There is few topics on forum about this and it is not arduino related. Here is just few:
https://esp32.com/viewtopic.php?t=1292
https://esp32.com/viewtopic.php?t=1292&start=10
https://www.esp32.com/viewtopic.php?t=831
Thanks @chegewara. I'll use double instead.
But why it's OK with core v1.0.6- ?
A bug? optimization?
It has something to do with esp-idf, but as you can see the first problems with float in ISR are dated at 2016, so you just got lucky it worked in 1.0.6.
so you just got lucky it worked in 1.0.6.
I don't believe in luck at all. But we have to accept the reality that some mods in esp-idf (and/or core v2.0.0+) disrupted the float usage in ISR. Good to know.
Thanks anyway,
there was something we had to do to get it working. I'll ask around to see if anyone has a clue what was the fix.
Thanks,
There is a possible link here
@khoih-prog I will turn on that option and soon have it in master branch for the next release :)
@khoih-prog Do you have a C3/S2 that you can test your minimal sketch with to confirm if they crash similarly?
@me-no-dev that flag appears to be ESP32 specific so it may introduce discrepancy between platform support.
The ESP32 C3/S2 are single core, so they don't crash as this happens only to dual-core ESP32
- Test for ESP32-C3 is OK with
floatusing the same sketch
Starting ESP32TimerInterrupt_Float_Bug on ESP32C3_DEV
An interrupt as occurred. Total number: 1
An interrupt as occurred. Total number: 2
An interrupt as occurred. Total number: 3
An interrupt as occurred. Total number: 4
An interrupt as occurred. Total number: 5
An interrupt as occurred. Total number: 6
An interrupt as occurred. Total number: 7
An interrupt as occurred. Total number: 8
An interrupt as occurred. Total number: 9
An interrupt as occurred. Total number: 10
An interrupt as occurred. Total number: 11
An interrupt as occurred. Total number: 12
An interrupt as occurred. Total number: 13
An interrupt as occurred. Total number: 14
An interrupt as occurred. Total number: 15
An interrupt as occurred. Total number: 16
- Test for ESP32-S2 is OK with
floatusing this RPM_Measure, after changing RPM_Measure.ino#L76-L77 tofloat.
float RPM = 0;
float avgRPM = 0;
//uint32_t RPM = 0;
//uint32_t avgRPM = 0;
This mod will crash ESP32 immediately while OK with ESP32_S2. Somehow, ESP32_S2 can't use the minimal sketch code
Starting RPM_Measure on ESP32S2_DEV
ESP32_New_TimerInterrupt v1.0.1
CPU Frequency = 240 MHz
Starting ITimer0 OK, millis() = 643
RPM = 740.74, avgRPM = 529.53
RPM = 740.74, avgRPM = 625.56
RPM = 740.74, avgRPM = 694.70
RPM = 0.00, avgRPM = 173.68
RPM = 0.00, avgRPM = 43.42
RPM = 0.00, avgRPM = 10.85
RPM = 0.00, avgRPM = 2.71
RPM = 0.00, avgRPM = 0.68
RPM = 0.00, avgRPM = 0.17
RPM = 0.00, avgRPM = 0.04
RPM = 0.00, avgRPM = 0.01
Note that using floats in ISRs shouldn't be a problem on S2 or C3 because neither have a hardware floating point unit. However this might be an issue on the ESP32-S3 (same way as it is an issue on the ESP32).
Merged in master :)