Skip to content

Commit

Permalink
spi_flash: 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: IDFGH-261
  • Loading branch information
KonstantinKondrashov authored and espressif-bot committed Apr 23, 2019
1 parent 510f726 commit 7a28858
Show file tree
Hide file tree
Showing 2 changed files with 37 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 @@ -77,6 +77,28 @@ menu "SPI Flash driver"
bool "Allowed"
endchoice

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.

endmenu


15 changes: 15 additions & 0 deletions components/spi_flash/flash_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "esp_flash_partitions.h"
#include "esp_ota_ops.h"
#include "cache_utils.h"
#include "esp_timer.h"

/* bytes erased by SPIEraseBlock() ROM function */
#define BLOCK_ERASE_SIZE 65536
Expand Down Expand Up @@ -224,6 +225,9 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size)
rc = spi_flash_unlock();
if (rc == ESP_ROM_SPIFLASH_RESULT_OK) {
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 @@ -235,6 +239,17 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size)
COUNTER_ADD_BYTES(erase, SPI_FLASH_SEC_SIZE);
}
spi_flash_guard_end();
#ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE
int dt_ms = (esp_timer_get_time() - start_time_us) / 1000;
if (dt_ms >= CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS ||
dt_ms * 2 >= CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS) {
/* For example when dt_ms = 15 and CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS = 20.
* In this case we need to call vTaskDelay because
* the duration of this command + the next command probably will exceed more than 20.
*/
vTaskDelay(CONFIG_SPI_FLASH_ERASE_YIELD_TICKS);
}
#endif
}
}
COUNTER_STOP(erase);
Expand Down

0 comments on commit 7a28858

Please sign in to comment.