-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
calling millis() in an interrupt service routine causes a panic #2758
Comments
Do you have a back trace? I suspect it is crashing in loop() and not in isr(). When the ISR fires, spi_flash disables cache and which will lead to crashes when you attempt to access flash. |
I don't get a stack trace. However, as I said I can call esp_timer_get_time(), which is what millis() calls, with no issues. This is what I have in the console:
|
This line indicates that spi_flash disabled cache but something was accessed outside of the IRAM area. About the only thing I can think of is the 1000ULL but that should be compiled in as a constant. Can you try swapping millis() with micros() ? Also try disabling the flash access in loop() (separate test) to confirm if that is playing a factor. |
micros() works. How do I disable flash access for the other test?
… On May 8, 2019, at 10:28 AM, Mike Dunston ***@***.***> wrote:
Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed)
This line indicates that spi_flash disabled cache but something was accessed outside of the IRAM area. About the only thing I can think of is the 1000ULL but that should be compiled in as a constant. Can you try swapping millis() with micros() ?
Also try disabling the flash access in loop() (separate test) to confirm if that is playing a factor.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Interesting that micros() works but millis() doesn't. @me-no-dev thoughts? As for disabling flash access, comment out the code in loop(), specifically spi_flash_read() |
The whole point of the test is that I am accessing flash when the ISR happens. It works fine without the flash access.
|
It looks like this is because 64 bit divisions call a function (I tried a test which happened to give a compiler error that lead me to this conclusion).
So, that function is not tagged with IRAM_ATTR and so is not safe to call from an ISR. I will figure out how to do this division myself - just need to the source to that library! |
As a work around you might use TickType_t xTaskGetTickCountFromISR(); TickType_t is a uint32_t I use it in the I2C driver that runs in an Interrupt context and supports iCache disabled. Chuck. |
Thanks @stickbreaker, I will look into that. To close the loop on this, it is definitely caused by GCC generating a call to a library. Possibly, if the optimization level was modified for speed, it might not do that. For your edification, here is some code that works - I'm not claiming it is pretty, but it might actually be faster than the GCC library version. The divs10 code is adapted from the 32 bit version here. Adapting the divs1000 code in that paper to 64 bits is beyond me. Anyway, here is the code: #include "Arduino.h"
#include "esp_spi_flash.h"
#include "nvs.h"
#include "nvs_flash.h"
hw_timer_t *timer;
// Code adapted for 64 bits from https://www.hackersdelight.org/divcMore.pdf
int64_t IRAM_ATTR divs10(int64_t n) {
int64_t q, r;
n = n + (n >> 63 & 9);
q = (n >> 1) + (n >> 2);
q = q + (q >> 4);
q = q + (q >> 8);
q = q + (q >> 16);
q = q + (q >> 32);
q = q >> 3;
r = n - q * 10;
return q + ((r + 6) >> 4);
// return q + (r > 9);
}
int64_t IRAM_ATTR divs1000(int64_t n) {
return divs10(divs10(divs10(n)));
}
unsigned long IRAM_ATTR my_millis()
{
return divs1000(esp_timer_get_time());
}
void IRAM_ATTR isr() {
my_millis();
}
void setup() {
Serial.begin(115200);
nvs_flash_init();
timer = timerBegin(0, 80, true); // timer_id = 0; divider=80; countUp = true; So at 80MHz, we have a granularity of 1MHz
timerAttachInterrupt(timer, isr, true);// edge = true
timerAlarmWrite(timer, 100, true);// Period = 100 micro seconds
timerAlarmEnable(timer);
}
void loop() {
const uint32_t n = SPI_FLASH_SEC_SIZE;
uint32_t val_read;
for (uint32_t offset = 0; offset < n; offset += 4) {
if (spi_flash_read(offset, (uint8_t *) &val_read, 4) != ESP_OK) {
break;
}
}
delay(10);
}
` |
done :) |
Works for me using latest. Maybe 1.0.3.
Another issue is: you can’t use switch statements in ISRs either.
… On Jun 9, 2019, at 3:39 AM, Patrick Knöbel ***@***.***> wrote:
This is still a problem for me! "Stable 1.0.2"
The function millis is in DRAM but the div(1000) is not.
So when using it with Preference Library the ESP32 crashes:
Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed) Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400f00f0: bad00bad bad00bad bad00bad Guru Meditation Error: Core 1 panic'ed (IllegalIGuru Meditation Error: Core 1 panic'ed (Unhandled debug exception) Debug exception reason: Stack canary watchpoint triggered (loopTask)
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Interesting ... Gcc can do a lot of unexpected thing! |
Compile and run the code below - you will get a panic in the serial monitor. This is surprising, given that millis() is tagged with IRAM_ATTR. If I call esp_timer_get_time(), there is no crash. I am using release 1.0.2
The text was updated successfully, but these errors were encountered: