Merge branch 'bugfix/erase_with_vtaskdelay_v3.2' into 'release/v3.2'
spi_flash: Add vTaskDelay while a long erasing (v3.2) See merge request idf/esp-idf!4875
This commit is contained in:
commit
f6bfe13eb3
2 changed files with 37 additions and 0 deletions
|
@ -77,6 +77,28 @@ config SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED
|
||||||
bool "Allowed"
|
bool "Allowed"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config SPI_FLASH_YIELD_DURING_ERASE
|
||||||
|
bool "Enables yield operation during flash erase"
|
||||||
|
default n
|
||||||
|
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
|
endmenu
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "esp_flash_partitions.h"
|
#include "esp_flash_partitions.h"
|
||||||
#include "esp_ota_ops.h"
|
#include "esp_ota_ops.h"
|
||||||
#include "cache_utils.h"
|
#include "cache_utils.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
|
||||||
/* bytes erased by SPIEraseBlock() ROM function */
|
/* bytes erased by SPIEraseBlock() ROM function */
|
||||||
#define BLOCK_ERASE_SIZE 65536
|
#define BLOCK_ERASE_SIZE 65536
|
||||||
|
@ -217,6 +218,9 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||||
rc = spi_flash_unlock();
|
rc = spi_flash_unlock();
|
||||||
if (rc == ESP_ROM_SPIFLASH_RESULT_OK) {
|
if (rc == ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||||
for (size_t sector = start; sector != end && 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();
|
spi_flash_guard_start();
|
||||||
if (sector % sectors_per_block == 0 && end - sector >= sectors_per_block) {
|
if (sector % sectors_per_block == 0 && end - sector >= sectors_per_block) {
|
||||||
rc = esp_rom_spiflash_erase_block(sector / sectors_per_block);
|
rc = esp_rom_spiflash_erase_block(sector / sectors_per_block);
|
||||||
|
@ -228,6 +232,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);
|
COUNTER_ADD_BYTES(erase, SPI_FLASH_SEC_SIZE);
|
||||||
}
|
}
|
||||||
spi_flash_guard_end();
|
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);
|
COUNTER_STOP(erase);
|
||||||
|
|
Loading…
Reference in a new issue