Skip to content

Timer Interrupts and SPIFFS will crash the ESP32 #1141

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

Closed
JacoFourie opened this issue Feb 21, 2018 · 4 comments
Closed

Timer Interrupts and SPIFFS will crash the ESP32 #1141

JacoFourie opened this issue Feb 21, 2018 · 4 comments

Comments

@JacoFourie
Copy link

JacoFourie commented Feb 21, 2018

Please fill the info fields, it helps to get you faster support ;)

Decoding 6 results
0x400d2304: timerIsr() at C:\Users\Jaco\Documents\Arduino\ESP32_Websockets_dual_core_WebServer_tng/ESP32_Websockets_dual_core_WebServer_tng.ino line 546
0x40081a84: _xt_lowint1 at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/./xtensa_vectors.S line 1105
0x4008710c: _frxt_int_enter at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/./portasm.S line 119
0x400d2304: timerIsr() at C:\Users\Jaco\Documents\Arduino\ESP32_Websockets_dual_core_WebServer_tng/ESP32_Websockets_dual_core_WebServer_tng.ino line 546
0x40081a81: _xt_lowint1 at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/./xtensa_vectors.S line 1105
0x400823d2: spi_flash_op_block_func at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spi_flash/./cache_utils.c line 81

----------------------------- Remove above -----------------------------

Hardware:

Board: ESP32 Dev Module?
Core Installation/update date: 11/jul/2017?
IDE name: Arduino IDE
Flash Frequency: 40Mhz
Upload Speed: 115200

Description:

If I enable a timer interrupt and I access a SPIFF file the ESP32 will reboot with a panic
If I add the "timerAlarmDisable(timer);" before I do any SPIFFS and then "timerAlarmEnable(timer);" then it seems to work.

This is just an extract of the big program.

Sketch:

void setup() {

  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &timerIsr, true);
  timerAlarmWrite(timer, 1000, true);
  timerAlarmEnable(timer);  

}

bool handleFileRead(String path){
  
  timerAlarmDisable(timer);
  Serial.println("handleFileRead: " + path);
  if(path.endsWith("/")) path += "index.htm";
  String contentType = getContentType(path);
  String pathWithGz = path + ".gz";
  if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)){
    if(SPIFFS.exists(pathWithGz))
      path += ".gz";
    File file = SPIFFS.open(path, "r");
    size_t sent = server.streamFile(file, contentType);
    file.close();
    timerAlarmEnable(timer);
    return true;
  }
  timerAlarmEnable(timer);
  return false;
}


void timerIsr() {
  //portENTER_CRITICAL(&timerMux);  
  encoder.service();
  //portEXIT_CRITICAL(&timerMux);
 
}

Debug Messages:

Guru Meditation Error: Core  1 panic'ed (Cache disabled but cached memory region accessed)
@JacoFourie
Copy link
Author

OK so if you take the SPIFFS example and you just add a Timer you will see it will crash. I need a Fix ASAP.
What could it be or is this the way it is ?

#include "FS.h"
#include "SPIFFS.h"


hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;


void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(fs, file.name(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}

void readFile(fs::FS &fs, const char * path){
    Serial.printf("Reading file: %s\n", path);

    File file = fs.open(path);
    if(!file || file.isDirectory()){
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");
    while(file.available()){
        Serial.write(file.read());
    }
}

void writeFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Writing file: %s\n", path);

    File file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }
    if(file.print(message)){
        Serial.println("File written");
    } else {
        Serial.println("Write failed");
    }
}

void appendFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Appending to file: %s\n", path);

    File file = fs.open(path, FILE_APPEND);
    if(!file){
        Serial.println("Failed to open file for appending");
        return;
    }
    if(file.print(message)){
        Serial.println("Message appended");
    } else {
        Serial.println("Append failed");
    }
}

void renameFile(fs::FS &fs, const char * path1, const char * path2){
    Serial.printf("Renaming file %s to %s\n", path1, path2);
    if (fs.rename(path1, path2)) {
        Serial.println("File renamed");
    } else {
        Serial.println("Rename failed");
    }
}

void deleteFile(fs::FS &fs, const char * path){
    Serial.printf("Deleting file: %s\n", path);
    if(fs.remove(path)){
        Serial.println("File deleted");
    } else {
        Serial.println("Delete failed");
    }
}

void testFileIO(fs::FS &fs, const char * path){
    File file = fs.open(path);
    static uint8_t buf[512];
    size_t len = 0;
    uint32_t start = millis();
    uint32_t end = start;
    if(file && !file.isDirectory()){
        len = file.size();
        size_t flen = len;
        start = millis();
        while(len){
            size_t toRead = len;
            if(toRead > 512){
                toRead = 512;
            }
            file.read(buf, toRead);
            len -= toRead;
        }
        end = millis() - start;
        Serial.printf("%u bytes read for %u ms\n", flen, end);
        file.close();
    } else {
        Serial.println("Failed to open file for reading");
    }


    file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }

    size_t i;
    start = millis();
    for(i=0; i<2048; i++){
        file.write(buf, 512);
    }
    end = millis() - start;
    Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
    file.close();
}

void setup(){
    Serial.begin(115200);
    if(!SPIFFS.begin()){
        Serial.println("SPIFFS Mount Failed");
        return;
    }


    timer = timerBegin(0, 80, true);
    timerAttachInterrupt(timer, &timerIsr, true);
    timerAlarmWrite(timer, 1000, true);
    timerAlarmEnable(timer);  //Comment this out and it will run ..
    
    listDir(SPIFFS, "/", 0);
    writeFile(SPIFFS, "/hello.txt", "Hello ");
    appendFile(SPIFFS, "/hello.txt", "World!\n");
    readFile(SPIFFS, "/hello.txt");
    deleteFile(SPIFFS, "/foo.txt");
    renameFile(SPIFFS, "/hello.txt", "/foo.txt");
    readFile(SPIFFS, "/foo.txt");
    testFileIO(SPIFFS, "/test.txt");
}

void loop(){

}




void timerIsr() {
  portENTER_CRITICAL(&timerMux);       
  portEXIT_CRITICAL(&timerMux);
}

And here is the debug of it.

Decoding 8 results
0x400d0bbc: timerIsr() at C:\Users\Jaco\AppData\Local\Temp\arduino_modified_sketch_175913/SPIFFS_Test.ino line 178
0x400815f4: _xt_lowint1 at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/./xtensa_vectors.S line 1105
0x40086300: _frxt_int_enter at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/./portasm.S line 119

@allex1978
Copy link
Contributor

Hi, change void timerIsr() to void IRAM_ATTR timerIsr() and place it before setup() function.

@JacoFourie
Copy link
Author

@allex1978 thanks so much for the help. I had to add IRAM_ATTR to some more function that the interrupt calls. I followed this https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/ Last time I looked that was not there but it seems it is added now.

@kamilsss655
Copy link

For anyone else having this issue, the solution is to set CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE=y

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants