Skip to content

Commit

Permalink
spi_flash(LEGACY_IMPL): Add vTaskDelay while a long erasing
Browse files Browse the repository at this point in the history
Added Kconfig options to enable yield operation during flash erase

Closes: #2083
Closes: #4916
Closes: IDFGH-261
  • Loading branch information
KonstantinKondrashov committed May 4, 2020
1 parent f7a2bfc commit 1554fd3
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
22 changes: 22 additions & 0 deletions components/spi_flash/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,28 @@ menu "SPI Flash driver"
The implementation of SPI flash has been greatly changed in IDF v4.0.
Enable this option to use the legacy implementation.

config SPI_FLASH_YIELD_DURING_ERASE
bool "Enables yield operation during flash erase"
default y
help
This allows to yield the CPUs between erase commands.
Prevents starvation of other tasks.

config SPI_FLASH_ERASE_YIELD_DURATION_MS
int "Duration of erasing to yield CPUs (ms)"
depends on SPI_FLASH_YIELD_DURING_ERASE
default 20
help
If a duration of one erase command is large
then it will yield CPUs after finishing a current command.

config SPI_FLASH_ERASE_YIELD_TICKS
int "CPU release time (tick)"
depends on SPI_FLASH_YIELD_DURING_ERASE
default 1
help
Defines how many ticks will be before returning to continue a erasing.

menu "Auto-detect flash chips"

config SPI_FLASH_SUPPORT_ISSI_CHIP
Expand Down
14 changes: 14 additions & 0 deletions components/spi_flash/flash_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "cache_utils.h"
#include "esp_flash.h"
#include "esp_attr.h"
#include "esp_timer.h"


/* bytes erased by SPIEraseBlock() ROM function */
Expand Down Expand Up @@ -235,7 +236,13 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(size_t start_addr, size_t size)
esp_rom_spiflash_result_t rc;
rc = spi_flash_unlock();
if (rc == ESP_ROM_SPIFLASH_RESULT_OK) {
#ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE
int64_t no_yield_time_us = 0;
#endif
for (size_t sector = start; sector != end && rc == ESP_ROM_SPIFLASH_RESULT_OK; ) {
#ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE
int64_t start_time_us = esp_timer_get_time();
#endif
spi_flash_guard_start();
if (sector % sectors_per_block == 0 && end - sector >= sectors_per_block) {
rc = esp_rom_spiflash_erase_block(sector / sectors_per_block);
Expand All @@ -247,6 +254,13 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(size_t start_addr, size_t size)
COUNTER_ADD_BYTES(erase, SPI_FLASH_SEC_SIZE);
}
spi_flash_guard_end();
#ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE
no_yield_time_us += (esp_timer_get_time() - start_time_us);
if (no_yield_time_us / 1000 >= CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS) {
no_yield_time_us = 0;
vTaskDelay(CONFIG_SPI_FLASH_ERASE_YIELD_TICKS);
}
#endif
}
}
COUNTER_STOP(erase);
Expand Down

0 comments on commit 1554fd3

Please sign in to comment.