Function with IRAM_ATTR gets blocked by spi flash operation in different task on different core

t23319222
Posts: 11
Joined: Tue Mar 04, 2025 6:29 pm

Function with IRAM_ATTR gets blocked by spi flash operation in different task on different core

Postby t23319222 » Fri Mar 21, 2025 8:16 am

Hi,

I want to write a function that gets executed even during a flash write operation. I have already tried this:
I have delared two tasks (on different cores):

Code: Select all

void setup() {
   Serial.begin(9600);
   delay(2000);
   // Create task1 on Core 0
   xTaskCreatePinnedToCore(task1, "Task1", 2048, NULL, 1, NULL, 0);
   // Create task2 on Core 1
   xTaskCreatePinnedToCore(task2, "Task2", 4096, NULL, 2, NULL, 1);
}
task1: increments a counter continuously
task2: writes to flash memory for 5 seconds and then waits 5 seconds

During the 5 seconds of writing to flash the counter only gets incremented by about 400, and in the 5 second interval when there is no write happening, the counter gets incremented by 4000:

Pogram output:
write start:
Counter: 2
Counter: 112
Counter: 223
Counter: 331
Counter: 437
write end
Counter difference during flash write: 536
Counter: 604
Counter: 1604
Counter: 2604
Counter: 3604
Counter: 4604
Starting flash write to app1...
write start

And this happens even though I put a iram attribute on the counter function:

Code: Select all

void IRAM_ATTR task1(void *pvParameter) {
   while (1) {
       counter++;  // Increment counter continuously
       vTaskDelay(1 / portTICK_PERIOD_MS);  // Small delay
   }
}
My question is, how can I make a task, that runs continuously, even when a flash operation is ongoing?
My code is:

Code: Select all

#include <Arduino.h>
#include "esp_partition.h"
volatile uint32_t counter = 0;  // Shared counter
void IRAM_ATTR task1(void *pvParameter) {
   while (1) {
       counter++;  // Increment counter continuously
       vTaskDelay(1 / portTICK_PERIOD_MS);  // Small delay
   }
}
void task2(void *pvParameter) {
 // Locate the app1 partition
 const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL);
 if (!partition) {
     Serial.println("app1 partition not found!");
     return;
 }
 while (1) {
     Serial.println("Starting flash write to app1...");
     uint32_t startCounter = counter;
     Serial.println("------------ write start ----------------");
     auto start = millis();
     do
     {
          // Data to write
         uint8_t data[256] = {0x55};  // 256 bytes of dummy data (0x55 pattern)
         // Erase sector before writing (necessary for raw flash writes)
         esp_err_t err = esp_partition_erase_range(partition, 0, 4096);
         if (err == ESP_OK) {
             err = esp_partition_write(partition, 0, data, sizeof(data));
         }
     } while (millis() - start < 5000);
     Serial.println("------------ write end ----------------");
     uint32_t endCounter = counter;
     Serial.printf("Counter difference during flash write: %d\n", endCounter - startCounter);
     // Wait before the next write
     vTaskDelay(5000 / portTICK_PERIOD_MS);
 }
}

void setup() {
   Serial.begin(9600);
   delay(2000);
   // Create task1 on Core 0
   xTaskCreatePinnedToCore(task1, "Task1", 2048, NULL, 1, NULL, 0);
   // Create task2 on Core 1
   xTaskCreatePinnedToCore(task2, "Task2", 4096, NULL, 2, NULL, 1);
}
void loop() {
   // Print counter value every second
   Serial.printf("Counter: %d\n", counter);
   delay(1000);
}

MicroController
Posts: 2668
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Function with IRAM_ATTR gets blocked by spi flash operation in different task on different core

Postby MicroController » Fri Mar 21, 2025 10:58 am

All tasks (except for one) are stopped during writes to flash. The only thing which stays alive is interrupt service routines (ISR) that are in IRAM and registered as such; functions have to be put into IRAM so that they can be called from IRAM ISRs even during flash writes.

Who is online

Users browsing this forum: Amazon [Bot], Bytespider, Google [Bot] and 5 guests