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

ESP32 Core v2.0.1 / 2.0.1 RC1 crashes if using float in ISR #5892

Closed
khoih-prog opened this issue Nov 15, 2021 · 11 comments
Closed

ESP32 Core v2.0.1 / 2.0.1 RC1 crashes if using float in ISR #5892

khoih-prog opened this issue Nov 15, 2021 · 11 comments

Comments

@khoih-prog
Copy link

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


@chegewara
Copy link
Contributor

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

@khoih-prog
Copy link
Author

Thanks @chegewara. I'll use double instead.
But why it's OK with core v1.0.6- ?

@chegewara
Copy link
Contributor

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.

@khoih-prog
Copy link
Author

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,

@me-no-dev
Copy link
Member

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.

@khoih-prog
Copy link
Author

Thanks,

There is a possible link here

@VojtechBartoska VojtechBartoska added the Status: Awaiting triage Issue is waiting for triage label Nov 16, 2021
@me-no-dev
Copy link
Member

@khoih-prog I will turn on that option and soon have it in master branch for the next release :)

@me-no-dev me-no-dev reopened this Nov 16, 2021
@me-no-dev me-no-dev self-assigned this Nov 16, 2021
@VojtechBartoska VojtechBartoska added Status: To be implemented Selected for Development and removed Status: Awaiting triage Issue is waiting for triage labels Nov 16, 2021
@VojtechBartoska VojtechBartoska added this to the 2.1.0 milestone Nov 16, 2021
@VojtechBartoska VojtechBartoska added this to Selected for Development in (Archived) Arduino Core ESP32 RoadMap Nov 16, 2021
@atanisoft
Copy link
Collaborator

@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.

@khoih-prog
Copy link
Author

@atanisoft

The ESP32 C3/S2 are single core, so they don't crash as this happens only to dual-core ESP32

  1. Test for ESP32-C3 is OK with float using 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

  1. Test for ESP32-S2 is OK with float using this RPM_Measure, after changing RPM_Measure.ino#L76-L77 to float.
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

@igrr
Copy link
Member

igrr commented Nov 16, 2021

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).

@me-no-dev me-no-dev moved this from Selected for Development to In Development in (Archived) Arduino Core ESP32 RoadMap Nov 19, 2021
@me-no-dev me-no-dev moved this from In Development to Development Complete in (Archived) Arduino Core ESP32 RoadMap Nov 19, 2021
@me-no-dev
Copy link
Member

Merged in master :)

@VojtechBartoska VojtechBartoska removed this from the 2.1.0 milestone Jan 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
No open projects
Development

No branches or pull requests

6 participants