Read from SPIFFS through http server handler results in Guru Meditation

MarcelKr
Posts: 6
Joined: Thu Jan 14, 2021 1:35 pm

Read from SPIFFS through http server handler results in Guru Meditation

Postby MarcelKr » Sat Apr 23, 2022 3:46 pm

I'm trying to read contents of a file on a SPIFFS partition from a HTTP server path handler which mostly results in a Guru Meditaion: Cache disabled but cached memory region accessed exception. It seems, the larger the File I'm reading from (-> the more time the function takes), the more likely the exception occures.

As I understand, when accessing the files on the SPIFFS partition, the cache gets disabled but my function tries to access cached data. How can I resolve this problem?

This is the function which is called from the HTTP server:

Code: Select all

ssize_t valuelogger_get(channel_id_t channel_id, time_t from_time, sensor_val_t** values) {
  char* filename;
  char line[32];
  uint32_t val_idx = 0;
  uint32_t line_num = 0;
  asprintf(&filename, "/spiffs/%d.txt", channel_id);

  ESP_LOGI(TAG, "Retrieving content of %s where time >= %lu", filename, from_time);

  FILE* fp = fopen(filename, "r");
  if (fp == NULL) {
    ESP_LOGE(TAG, "Failed to open file");
    free(filename);
    return -1;
  }

  int32_t startingPos = -1;
  int32_t filepos = ftell(fp);
  int32_t value_num = 0;
  while (fgets(line, 64, fp)) {
    char* token = strtok(line, ",");
    time_t time = 0;
    float val = 0;
    char* end;

    for (uint8_t i = 0; i < 2 && token; i++) {
      if (i == 0) {
        time = strtoul(token, &end, 10);
      } else if (i == 1) {
        val = strtod(token, &end);
      }
      token = strtok(NULL, ",");
    }

    if (time != 0 && val != 0) {
      // ESP_LOGI(TAG, "Parsed values: t=%lu, val=%.2f", time, val);
      if (time >= from_time) {
        value_num++;
        if (startingPos == -1) {
          startingPos = filepos;
        }
      }
    } else {
      ESP_LOGW(TAG, "Line errornous (line: %s)", line);
    }
    line_num++;
    filepos = ftell(fp);
  }

  ESP_LOGI(TAG, "Allocating for %u values", value_num);
  *values = malloc(value_num * sizeof(sensor_val_t));

  fseek(fp, startingPos, SEEK_SET);
  while (fgets(line, 64, fp)) {
    char* token = strtok(line, ",");
    time_t time = 0;
    float val = 0;
    char* end;

    for (uint8_t i = 0; i < 2 && token; i++) {
      if (i == 0) {
        time = strtoul(token, &end, 10);
      } else if (i == 1) {
        val = strtod(token, &end);
      }
      token = strtok(NULL, ",");
    }

    if (time != 0 && val != 0) {
      if (time >= from_time) {
        (*values)[val_idx++] = (sensor_val_t){.time = time, .value = val};
      }
    }
  }

  fclose(fp);
  free(filename);
  ESP_LOGI(TAG, "Retrieved %u values of total %u", val_idx, line_num);
  return val_idx;
}
This is the exception I get:

Code: Select all

I (20258) VALLOG: Retrieving content of /spiffs/0.txt where time >= 1650683590
Guru Meditation Error: Core  0 panic'ed (Cache disabled but cached memory region accessed). 

Core  0 register dump:
PC      : 0x4017ae40  PS      : 0x00060035  A0      : 0x8008229c  A1      : 0x3ffbe8d0  
0x4017ae40: rmt_ll_get_tx_err_interrupt_status at /home/marcel/esp/esp-idf/components/hal/esp32/include/hal/rmt_ll.h:307

A2      : 0x3ffbf2dc  A3      : 0x00000000  A4      : 0x00000001  A5      : 0x00000001  
A6      : 0x00000000  A7      : 0x00000000  A8      : 0x80083d50  A9      : 0x000e0f20  
A10     : 0x3ff56000  A11     : 0x3ffbe8d4  A12     : 0x3ffba0f8  A13     : 0x3ffba14c  
A14     : 0x00060023  A15     : 0x00000000  SAR     : 0x0000001d  EXCCAUSE: 0x00000007  
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0xffffffff  


Backtrace:0x4017ae3d:0x3ffbe8d00x40082299:0x3ffbe910 0x40082cfd:0x3ffbe930 0x400847f2:0x3ffb01b0 0x40083310:0x3ffb01d0 
0x4017ae3d: rmt_ll_enable_tx_err_interrupt at /home/marcel/esp/esp-idf/components/hal/esp32/include/hal/rmt_ll.h:252

0x40082299: shared_intr_isr at /home/marcel/esp/esp-idf/components/esp_hw_support/intr_alloc.c:407

0x40082cfd: _xt_lowint1 at /home/marcel/esp/esp-idf/components/freertos/port/xtensa/xtensa_vectors.S:1111

0x400847f2: spi_flash_op_block_func at /home/marcel/esp/esp-idf/components/spi_flash/cache_utils.c:122

0x40083310: ipc_task at /home/marcel/esp/esp-idf/components/esp_ipc/src/esp_ipc.c:77





ELF file SHA256: 7bc1ea7c6dccd751

Rebooting...
Some more details:
  • IDF Version 4.4
  • Custom PCB with a ESP32-WROMM-32E

ESP_Sprite
Posts: 9577
Joined: Thu Nov 26, 2015 4:08 am

Re: Read from SPIFFS through http server handler results in Guru Meditation

Postby ESP_Sprite » Sun Apr 24, 2022 3:17 am

rmt_ll_enable_tx_err_interrupt
Looks like the issue is here. Generally, the thing is that the RMT driver interrupt is installed with the flag indicating it's safe to trigger when cache is disabled (=when you're writing to flash) when in actuality, it's not. In order for an interrupt to be safe like that, it and all routines it calls need to be in IRAM, and it should not use any data that is located in PSRAM.

Does that help?

MarcelKr
Posts: 6
Joined: Thu Jan 14, 2021 1:35 pm

Re: Read from SPIFFS through http server handler results in Guru Meditation

Postby MarcelKr » Sun Apr 24, 2022 12:21 pm

Absolutely perfect. I'm using https://github.com/DavidAntliff/esp32-owb and https://github.com/DavidAntliff/esp32-ds18b20 which use the RMT for data RX/TX. The driver is initialized like this:

Code: Select all

rmt_driver_install(rmt_tx.channel, 0, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_SHARED)
Once I remove the ESP_INTR_FLAG_IRAM it works. Thanks ESP_Sprite for this accurate and quick help!

Who is online

Users browsing this forum: No registered users and 96 guests