Merge branch 'bugfix/spi_flash_yield_coredump_v4.0' into 'release/v4.0'
spi_flash: don't call vTaskDelay in non-os context (backport v4.0) See merge request espressif/esp-idf!10299
This commit is contained in:
commit
df7028dc52
6 changed files with 42 additions and 7 deletions
|
@ -373,7 +373,9 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui
|
|||
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);
|
||||
if (chip->os_func->yield) {
|
||||
chip->os_func->yield(chip->os_func_data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -72,6 +72,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,
|
||||
|
@ -79,18 +80,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_DANGEROUS_WRITE_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_DANGEROUS_WRITE_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;
|
||||
|
@ -175,6 +178,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
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPI_FLASH_USE_LEGACY_IMPL
|
||||
static esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock()
|
||||
{
|
||||
|
@ -253,7 +263,9 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(size_t start_addr, size_t size)
|
|||
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);
|
||||
if (s_flash_guard_ops && s_flash_guard_ops->yield) {
|
||||
s_flash_guard_ops->yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -50,6 +50,9 @@ typedef struct {
|
|||
|
||||
/** Delay for at least 'us' microseconds. Called in between 'start' and 'end'. */
|
||||
esp_err_t (*delay_us)(void *arg, unsigned us);
|
||||
|
||||
/** Yield to other tasks. Called during erase operations. */
|
||||
esp_err_t (*yield)(void *arg);
|
||||
} esp_flash_os_functions_t;
|
||||
|
||||
/** @brief Structure to describe a SPI flash chip connected to the system.
|
||||
|
|
|
@ -316,6 +316,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.
|
||||
|
@ -356,6 +360,7 @@ typedef struct {
|
|||
#if !CONFIG_SPI_FLASH_DANGEROUS_WRITE_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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "esp_spi_flash.h" //for ``g_flash_guard_default_ops``
|
||||
#include "esp_flash.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -83,6 +85,14 @@ static IRAM_ATTR esp_err_t delay_us(void *arg, unsigned us)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static IRAM_ATTR esp_err_t spi_flash_os_yield(void *arg)
|
||||
{
|
||||
#ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE
|
||||
vTaskDelay(CONFIG_SPI_FLASH_ERASE_YIELD_TICKS);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static IRAM_ATTR esp_err_t main_flash_region_protected(void* arg, size_t start_addr, size_t size)
|
||||
{
|
||||
if (((spi1_app_func_arg_t*)arg)->no_protect || esp_partition_main_flash_region_safe(start_addr, size)) {
|
||||
|
@ -115,14 +125,16 @@ static app_func_arg_t spi3_arg = {
|
|||
const DRAM_ATTR esp_flash_os_functions_t esp_flash_spi1_default_os_functions = {
|
||||
.start = spi1_start,
|
||||
.end = spi1_end,
|
||||
.delay_us = delay_us,
|
||||
.region_protected = main_flash_region_protected,
|
||||
.delay_us = delay_us,
|
||||
.yield = spi_flash_os_yield,
|
||||
};
|
||||
|
||||
const esp_flash_os_functions_t esp_flash_spi23_default_os_functions = {
|
||||
.start = spi23_start,
|
||||
.end = spi23_end,
|
||||
.delay_us = delay_us,
|
||||
.yield = spi_flash_os_yield
|
||||
};
|
||||
|
||||
esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id)
|
||||
|
|
|
@ -48,6 +48,7 @@ const DRAM_ATTR esp_flash_os_functions_t esp_flash_noos_functions = {
|
|||
.end = end,
|
||||
.delay_us = delay_us,
|
||||
.region_protected = NULL,
|
||||
.yield = NULL,
|
||||
};
|
||||
|
||||
esp_err_t IRAM_ATTR esp_flash_app_disable_os_functions(esp_flash_t* chip)
|
||||
|
|
Loading…
Reference in a new issue