spi_flash(LEGACY_IMPL): Add vTaskDelay while a long erasing

Added Kconfig options to enable yield operation during flash erase

Closes: https://github.com/espressif/esp-idf/issues/2083
Closes: https://github.com/espressif/esp-idf/issues/4916
Closes: IDFGH-261
pull/5191/head
KonstantinKondrashov 2020-04-02 14:27:33 +08:00
rodzic 9300615a13
commit 3cb655eaab
2 zmienionych plików z 36 dodań i 0 usunięć

Wyświetl plik

@ -100,6 +100,28 @@ menu "SPI Flash driver"
this option, and the lock will be bypassed on SPI1 bus. Otherwise if extra devices
are needed to attach to SPI1 bus, enable this option.
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

Wyświetl plik

@ -44,6 +44,7 @@
#include "cache_utils.h"
#include "esp_flash.h"
#include "esp_attr.h"
#include "esp_timer.h"
esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size);
@ -238,7 +239,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);
@ -250,6 +257,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);