diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index b535e8008..420399269 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -71,6 +71,7 @@ static spi_flash_counters_t s_flash_stats; static esp_err_t spi_flash_translate_rc(esp_rom_spiflash_result_t rc); static bool is_safe_write_address(size_t addr, size_t size); +static void spi_flash_os_yield(void); const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_default_ops = { .start = spi_flash_disable_interrupts_caches_and_other_cpu, @@ -78,18 +79,20 @@ const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_default_ops = { .op_lock = spi_flash_op_lock, .op_unlock = spi_flash_op_unlock, #if !CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED - .is_safe_write_address = is_safe_write_address + .is_safe_write_address = is_safe_write_address, #endif + .yield = spi_flash_os_yield, }; const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_no_os_ops = { .start = spi_flash_disable_interrupts_caches_and_other_cpu_no_os, .end = spi_flash_enable_interrupts_caches_no_os, - .op_lock = 0, - .op_unlock = 0, + .op_lock = NULL, + .op_unlock = NULL, #if !CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED - .is_safe_write_address = 0 + .is_safe_write_address = NULL, #endif + .yield = NULL, }; static const spi_flash_guard_funcs_t *s_flash_guard_ops; @@ -184,6 +187,13 @@ static inline void IRAM_ATTR spi_flash_guard_op_unlock() } } +static void IRAM_ATTR spi_flash_os_yield(void) +{ +#ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE + vTaskDelay(CONFIG_SPI_FLASH_ERASE_YIELD_TICKS); +#endif +} + static esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock() { static bool unlocked = false; @@ -246,8 +256,10 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) /* 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); + */ + if (s_flash_guard_ops && s_flash_guard_ops->yield) { + s_flash_guard_ops->yield(); + } } #endif } diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index 254e40895..ddcbbf620 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -317,6 +317,10 @@ typedef void (*spi_flash_op_unlock_func_t)(void); * @brief Function to protect SPI flash critical regions corruption. */ typedef bool (*spi_flash_is_safe_write_address_t)(size_t addr, size_t size); +/** + * @brief Function to yield to the OS during erase operation. + */ +typedef void (*spi_flash_os_yield_t)(void); /** * Structure holding SPI flash access critical sections management functions. @@ -357,6 +361,7 @@ typedef struct { #if !CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED spi_flash_is_safe_write_address_t is_safe_write_address; /**< checks flash write addresses.*/ #endif + spi_flash_os_yield_t yield; /**< yield to the OS during flash erase */ } spi_flash_guard_funcs_t; /**