refactor(spi_flash): optimize flash functions to save iram memory

This commit is contained in:
C.S.M 2025-02-26 18:28:49 +08:00
parent 8014ffa225
commit b66e140fbc
11 changed files with 139 additions and 61 deletions

View File

@ -3,8 +3,6 @@ archive: libhal.a
entries:
if APP_BUILD_TYPE_PURE_RAM_APP = n:
mmu_hal (noflash)
spi_flash_hal_iram (noflash)
spi_flash_encrypt_hal_iram (noflash)
if IDF_TARGET_ESP32 = y:
cache_hal_esp32 (noflash)
else:
@ -15,8 +13,6 @@ entries:
wdt_hal_iram (noflash)
if SOC_SYSTIMER_SUPPORTED = y && HAL_SYSTIMER_USE_ROM_IMPL = n:
systimer_hal (noflash)
if SOC_GPSPI_SUPPORTED = y && IDF_TARGET_ESP32 = n:
spi_flash_hal_gpspi (noflash)
if SOC_PMU_SUPPORTED = y:
pmu_hal (noflash)
if SOC_GPIO_PORT != 0:

View File

@ -153,6 +153,17 @@ menu "Main Flash configuration"
whether suspend is valid instead of waiting for a specific long time, which can save a
lot of time and benefit for performance improvement.
config SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM
bool "Place spi_flash operation functions into IRAM" if SPI_FLASH_AUTO_SUSPEND
default y
help
When disabled, certain functions in `spi_flash` component will be placed into Flash memory
instead of IRAM. Disabling this option will save almost 10KB of IRAM depending on which
functions are used.
When enabled, these functions will be placed in internal RAM, with better performance.
For more information please refer to programming guide.
endmenu
endmenu

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -183,7 +183,7 @@ extern rom_spiflash_api_func_t *esp_flash_api_funcs;
call rom_spiflash_api_funcs->end() before returning.
*/
#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV
static esp_err_t IRAM_ATTR spiflash_start_default(esp_flash_t *chip)
static esp_err_t spiflash_start_default(esp_flash_t *chip)
{
if (chip->os_func != NULL && chip->os_func->start != NULL) {
esp_err_t err = chip->os_func->start(chip->os_func_data);
@ -197,7 +197,7 @@ static esp_err_t IRAM_ATTR spiflash_start_default(esp_flash_t *chip)
/* Static function to notify OS that SPI flash operation is complete.
*/
static esp_err_t IRAM_ATTR spiflash_end_default(esp_flash_t *chip, esp_err_t err)
static esp_err_t spiflash_end_default(esp_flash_t *chip, esp_err_t err)
{
if (chip->os_func != NULL
&& chip->os_func->end != NULL) {
@ -210,7 +210,7 @@ static esp_err_t IRAM_ATTR spiflash_end_default(esp_flash_t *chip, esp_err_t err
}
// check that the 'chip' parameter is properly initialised
static IRAM_ATTR esp_err_t check_chip_pointer_default(esp_flash_t **inout_chip)
static esp_err_t check_chip_pointer_default(esp_flash_t **inout_chip)
{
esp_flash_t *chip = *inout_chip;
if (chip == NULL) {
@ -223,7 +223,7 @@ static IRAM_ATTR esp_err_t check_chip_pointer_default(esp_flash_t **inout_chip)
return ESP_OK;
}
static IRAM_ATTR esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length)
static esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length)
{
if (!bus_acquired) {
// Try to acquire the bus again to flush the cache before exit.
@ -247,13 +247,13 @@ static IRAM_ATTR esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t er
static esp_err_t detect_spi_flash_chip(esp_flash_t *chip);
bool IRAM_ATTR esp_flash_chip_driver_initialized(const esp_flash_t *chip)
bool esp_flash_chip_driver_initialized(const esp_flash_t *chip)
{
if (!chip->chip_drv) return false;
return true;
}
esp_err_t IRAM_ATTR esp_flash_init(esp_flash_t *chip)
esp_err_t esp_flash_init(esp_flash_t *chip)
{
// Chip init flow
// 1. Read chip id
@ -324,7 +324,7 @@ esp_err_t IRAM_ATTR esp_flash_init(esp_flash_t *chip)
// Note: This function is only used for internal. Only call this function to initialize the main flash.
// (flash chip on SPI1 CS0)
esp_err_t IRAM_ATTR esp_flash_init_main(esp_flash_t *chip)
esp_err_t esp_flash_init_main(esp_flash_t *chip)
{
// Chip init flow
// 1. Read chip id
@ -455,7 +455,7 @@ esp_err_t esp_flash_read_id(esp_flash_t* chip, uint32_t* out_id)
}
#endif //CONFIG_SPI_FLASH_ROM_IMPL
static esp_err_t IRAM_ATTR NOINLINE_ATTR read_unique_id(esp_flash_t* chip, uint64_t* out_uid)
static esp_err_t NOINLINE_ATTR read_unique_id(esp_flash_t* chip, uint64_t* out_uid)
{
esp_err_t err = rom_spiflash_api_funcs->start(chip);
if (err != ESP_OK) {
@ -490,7 +490,7 @@ esp_err_t esp_flash_read_unique_chip_id(esp_flash_t *chip, uint64_t* out_uid)
return read_unique_id(chip, out_uid);
}
static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip)
static esp_err_t detect_spi_flash_chip(esp_flash_t *chip)
{
esp_err_t err;
uint32_t flash_id = chip->chip_id;
@ -526,7 +526,7 @@ static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip)
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_flash_get_physical_size(esp_flash_t *chip, uint32_t *flash_size)
esp_err_t esp_flash_get_physical_size(esp_flash_t *chip, uint32_t *flash_size)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
if (err != ESP_OK) {
@ -556,9 +556,9 @@ esp_err_t IRAM_ATTR esp_flash_get_physical_size(esp_flash_t *chip, uint32_t *fla
#ifndef CONFIG_SPI_FLASH_ROM_IMPL
/* Return true if regions 'a' and 'b' overlap at all, based on their start offsets and lengths. */
inline static bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len);
inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len);
esp_err_t IRAM_ATTR esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size)
esp_err_t esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
if (err != ESP_OK) {
@ -576,7 +576,7 @@ esp_err_t IRAM_ATTR esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size)
return esp_flash_get_physical_size(chip, out_size);
}
esp_err_t IRAM_ATTR esp_flash_erase_chip(esp_flash_t *chip)
esp_err_t esp_flash_erase_chip(esp_flash_t *chip)
{
esp_err_t err = ESP_OK;
uint32_t size = 0;
@ -589,7 +589,7 @@ esp_err_t IRAM_ATTR esp_flash_erase_chip(esp_flash_t *chip)
return err;
}
esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len)
esp_err_t esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(erase_sector);
@ -711,7 +711,7 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui
* done after the other arguments are checked.
*/
extern esp_err_t rom_esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len);
esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len)
esp_err_t esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len)
{
if (len == 0) {
return ESP_OK;
@ -722,7 +722,7 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui
#ifndef CONFIG_SPI_FLASH_ROM_IMPL
esp_err_t IRAM_ATTR esp_flash_get_chip_write_protect(esp_flash_t *chip, bool *out_write_protected)
esp_err_t esp_flash_get_chip_write_protect(esp_flash_t *chip, bool *out_write_protected)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(get_chip_write_protect);
@ -740,7 +740,7 @@ esp_err_t IRAM_ATTR esp_flash_get_chip_write_protect(esp_flash_t *chip, bool *ou
return rom_spiflash_api_funcs->end(chip, err);
}
esp_err_t IRAM_ATTR esp_flash_set_chip_write_protect(esp_flash_t *chip, bool write_protect)
esp_err_t esp_flash_set_chip_write_protect(esp_flash_t *chip, bool write_protect)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(set_chip_write_protect);
@ -789,7 +789,7 @@ static esp_err_t find_region(const esp_flash_t *chip, const esp_flash_region_t *
return ESP_ERR_NOT_FOUND;
}
esp_err_t IRAM_ATTR esp_flash_get_protected_region(esp_flash_t *chip, const esp_flash_region_t *region, bool *out_protected)
esp_err_t esp_flash_get_protected_region(esp_flash_t *chip, const esp_flash_region_t *region, bool *out_protected)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(get_protected_regions);
@ -818,7 +818,7 @@ esp_err_t IRAM_ATTR esp_flash_get_protected_region(esp_flash_t *chip, const esp_
return rom_spiflash_api_funcs->end(chip, err);
}
esp_err_t IRAM_ATTR esp_flash_set_protected_region(esp_flash_t *chip, const esp_flash_region_t *region, bool protect)
esp_err_t esp_flash_set_protected_region(esp_flash_t *chip, const esp_flash_region_t *region, bool protect)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(set_protected_regions);
@ -848,7 +848,7 @@ esp_err_t IRAM_ATTR esp_flash_set_protected_region(esp_flash_t *chip, const esp_
return rom_spiflash_api_funcs->end(chip, err);
}
esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t address, uint32_t length)
esp_err_t esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t address, uint32_t length)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(read);
@ -925,7 +925,7 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add
}
#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE
static esp_err_t IRAM_ATTR s_check_setting_zero_to_one(esp_flash_t *chip, uint32_t verify_address, uint32_t remain_verify_len, const uint32_t *to_write_buf, bool is_encrypted)
static esp_err_t s_check_setting_zero_to_one(esp_flash_t *chip, uint32_t verify_address, uint32_t remain_verify_len, const uint32_t *to_write_buf, bool is_encrypted)
{
esp_err_t err = ESP_FAIL;
uint8_t verify_buffer[VERIFY_BUF_LEN];
@ -964,7 +964,7 @@ static esp_err_t IRAM_ATTR s_check_setting_zero_to_one(esp_flash_t *chip, uint32
#endif //#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE
#if CONFIG_SPI_FLASH_VERIFY_WRITE
static esp_err_t IRAM_ATTR s_verify_write(esp_flash_t *chip, uint32_t verify_address, uint32_t remain_verify_len, const uint32_t *expected_buf, bool is_encrypted)
static esp_err_t s_verify_write(esp_flash_t *chip, uint32_t verify_address, uint32_t remain_verify_len, const uint32_t *expected_buf, bool is_encrypted)
{
esp_err_t err = ESP_FAIL;
uint8_t verify_buffer[VERIFY_BUF_LEN];
@ -1001,7 +1001,7 @@ static esp_err_t IRAM_ATTR s_verify_write(esp_flash_t *chip, uint32_t verify_add
}
#endif //#if CONFIG_SPI_FLASH_VERIFY_WRITE
esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length)
esp_err_t esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length)
{
esp_err_t ret = ESP_FAIL;
#if CONFIG_SPI_FLASH_VERIFY_WRITE
@ -1123,14 +1123,14 @@ restore_cache:
return err;
}
inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len)
inline static bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len)
{
uint32_t a_end = a_start + a_len;
uint32_t b_end = b_start + b_len;
return (a_end > b_start && b_end > a_start);
}
esp_err_t IRAM_ATTR esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *out_buffer, uint32_t length)
esp_err_t esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *out_buffer, uint32_t length)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
if (err != ESP_OK) return err;
@ -1163,7 +1163,7 @@ esp_err_t IRAM_ATTR esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address
}
// test only, non-public
IRAM_ATTR esp_err_t esp_flash_get_io_mode(esp_flash_t* chip, bool* qe)
esp_err_t esp_flash_get_io_mode(esp_flash_t* chip, bool* qe)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(get_io_mode);
@ -1181,7 +1181,7 @@ IRAM_ATTR esp_err_t esp_flash_get_io_mode(esp_flash_t* chip, bool* qe)
return err;
}
IRAM_ATTR esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe)
esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe)
{
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
VERIFY_CHIP_OP(set_io_mode);
@ -1214,7 +1214,7 @@ FORCE_INLINE_ATTR esp_err_t s_encryption_write_unlock(esp_flash_t *chip) {
return err;
}
esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length)
esp_err_t esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length)
{
esp_err_t ret = ESP_FAIL;
#if CONFIG_SPI_FLASH_VERIFY_WRITE

View File

@ -29,6 +29,10 @@
__attribute__((unused)) static const char TAG[] = "spi_flash";
#if !CONFIG_SPI_FLASH_AUTO_SUSPEND && !CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM
#error "CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM cannot be disabled when CONFIG_SPI_FLASH_AUTO_SUSPEND is disabled."
#endif
/* This pointer is defined in ROM and extern-ed on targets where CONFIG_SPI_FLASH_ROM_IMPL = y*/
#if !CONFIG_SPI_FLASH_ROM_IMPL
esp_flash_t *esp_flash_default_chip = NULL;

View File

@ -2,6 +2,10 @@
archive: libspi_flash.a
entries:
if APP_BUILD_TYPE_PURE_RAM_APP = n:
flash_brownout_hook (noflash)
if SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM = y:
spi_flash_wrap (noflash)
spi_flash_chip_generic (noflash)
spi_flash_chip_issi (noflash)
spi_flash_chip_mxic (noflash)
@ -10,14 +14,71 @@ entries:
spi_flash_chip_boya (noflash)
spi_flash_chip_th (noflash)
memspi_host_driver (noflash)
flash_brownout_hook (noflash)
spi_flash_wrap (noflash)
esp_flash_api: esp_flash_chip_driver_initialized (noflash)
esp_flash_api: esp_flash_init (noflash)
esp_flash_api: esp_flash_init_main (noflash)
esp_flash_api: read_unique_id (noflash)
esp_flash_api: detect_spi_flash_chip (noflash)
esp_flash_api: esp_flash_get_physical_size (noflash)
spi_flash_os_func_app: spi23_start (noflash)
spi_flash_os_func_app: spi23_end (noflash)
spi_flash_os_func_app: spi_flash_os_check_yield (noflash)
spi_flash_os_func_app: spi_flash_os_yield (noflash)
spi_flash_os_func_app: delay_us (noflash)
spi_flash_os_func_app: get_buffer_malloc (noflash)
spi_flash_os_func_app: release_buffer_malloc (noflash)
spi_flash_os_func_app: main_flash_region_protected (noflash)
spi_flash_os_func_app: main_flash_op_status (noflash)
spi_flash_os_func_noos: esp_flash_app_disable_os_functions (noflash)
spi_flash_os_func_noos: get_temp_buffer_not_supported (noflash)
spi_flash_os_func_noos: delay_us (noflash)
if IDF_TARGET_ESP32S3 = y:
spi_flash_chip_mxic_opi (noflash)
if ESPTOOLPY_OCT_FLASH = y || ESPTOOLPY_FLASH_MODE_AUTO_DETECT = y:
spi_flash_oct_flash_init (noflash)
if SPI_FLASH_VERIFY_WRITE = y:
esp_flash_api: s_verify_write (noflash)
if SPI_FLASH_ROM_IMPL = n || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV = y:
esp_flash_api: spiflash_start_default (noflash)
esp_flash_api: spiflash_end_default (noflash)
esp_flash_api: check_chip_pointer_default (noflash)
esp_flash_api: flash_end_flush_cache (noflash)
esp_flash_api: esp_flash_write_encrypted (noflash)
if SPI_FLASH_ROM_IMPL = n:
esp_flash_api: esp_flash_get_size (noflash)
esp_flash_api: esp_flash_erase_chip (noflash)
esp_flash_api: esp_flash_get_chip_write_protect (noflash)
esp_flash_api: esp_flash_set_chip_write_protect (noflash)
esp_flash_api: esp_flash_get_protected_region (noflash)
esp_flash_api: esp_flash_set_protected_region (noflash)
esp_flash_api: esp_flash_read (noflash)
esp_flash_api: esp_flash_write (noflash)
esp_flash_api: esp_flash_read_encrypted (noflash)
esp_flash_api: esp_flash_get_io_mode (noflash)
esp_flash_api: esp_flash_set_io_mode (noflash)
esp_flash_api: esp_flash_erase_region (noflash)
if SPI_FLASH_WARN_SETTING_ZERO_TO_ONE = y:
esp_flash_api: s_check_setting_zero_to_one (noflash)
if SPI_FLASH_HPM_ON = y:
spi_flash_hpm_enable (noflash)
if ESPTOOLPY_OCT_FLASH = y || ESPTOOLPY_FLASH_MODE_AUTO_DETECT = y:
spi_flash_oct_flash_init (noflash)
[mapping:spi_flash_hal]
archive: libhal.a
entries:
if SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM = y:
spi_flash_hal_iram (noflash)
spi_flash_encrypt_hal_iram (noflash)
if SOC_GPSPI_SUPPORTED = y && IDF_TARGET_ESP32 = n:
spi_flash_hal_gpspi (noflash)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -90,13 +90,13 @@ static IRAM_ATTR esp_err_t release_spi_bus_lock(void *arg)
return spi_bus_lock_acquire_end(((app_func_arg_t *)arg)->dev_lock);
}
static IRAM_ATTR esp_err_t spi23_start(void *arg){
static esp_err_t spi23_start(void *arg){
esp_err_t ret = acquire_spi_bus_lock(arg);
on_spi_acquired((app_func_arg_t*)arg);
return ret;
}
static IRAM_ATTR esp_err_t spi23_end(void *arg){
static esp_err_t spi23_end(void *arg){
esp_err_t ret = release_spi_bus_lock(arg);
on_spi_released((app_func_arg_t*)arg);
return ret;
@ -170,7 +170,7 @@ static IRAM_ATTR esp_err_t spi1_end(void *arg)
return ret;
}
static IRAM_ATTR esp_err_t spi_flash_os_check_yield(void *arg, uint32_t chip_status, uint32_t* out_request)
static esp_err_t spi_flash_os_check_yield(void *arg, uint32_t chip_status, uint32_t* out_request)
{
assert (chip_status == 0); //TODO: support suspend
esp_err_t ret = ESP_ERR_TIMEOUT; //Nothing happened
@ -186,7 +186,7 @@ static IRAM_ATTR esp_err_t spi_flash_os_check_yield(void *arg, uint32_t chip_sta
return ret;
}
static IRAM_ATTR esp_err_t spi_flash_os_yield(void *arg, uint32_t* out_status)
static esp_err_t spi_flash_os_yield(void *arg, uint32_t* out_status)
{
if (likely(xTaskGetSchedulerState() == taskSCHEDULER_RUNNING)) {
#ifdef CONFIG_SPI_FLASH_ERASE_YIELD_TICKS
@ -199,13 +199,13 @@ static IRAM_ATTR esp_err_t spi_flash_os_yield(void *arg, uint32_t* out_status)
return ESP_OK;
}
static IRAM_ATTR esp_err_t delay_us(void *arg, uint32_t us)
static esp_err_t delay_us(void *arg, uint32_t us)
{
esp_rom_delay_us(us);
return ESP_OK;
}
static IRAM_ATTR void* get_buffer_malloc(void* arg, size_t reqest_size, size_t* out_size)
static void* get_buffer_malloc(void* arg, size_t reqest_size, size_t* out_size)
{
/* Allocate temporary internal buffer to use for the actual read. If the preferred size
doesn't fit in free internal memory, allocate the largest available free block.
@ -226,12 +226,12 @@ static IRAM_ATTR void* get_buffer_malloc(void* arg, size_t reqest_size, size_t*
return ret;
}
static IRAM_ATTR void release_buffer_malloc(void* arg, void *temp_buf)
static void release_buffer_malloc(void* arg, void *temp_buf)
{
free(temp_buf);
}
static IRAM_ATTR esp_err_t main_flash_region_protected(void* arg, size_t start_addr, size_t size)
static esp_err_t main_flash_region_protected(void* arg, size_t start_addr, size_t size)
{
if (!esp_partition_is_flash_region_writable(start_addr, size)) {
return ESP_ERR_NOT_ALLOWED;
@ -247,7 +247,7 @@ static IRAM_ATTR esp_err_t main_flash_region_protected(void* arg, size_t start_a
return ESP_OK;
}
static IRAM_ATTR void main_flash_op_status(uint32_t op_status)
static void main_flash_op_status(uint32_t op_status)
{
bool is_erasing = op_status & SPI_FLASH_OS_IS_ERASING_STATUS_FLAG;
spi_flash_set_erasing_flag(is_erasing);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -48,7 +48,7 @@ static IRAM_ATTR esp_err_t end(void *arg)
return ESP_OK;
}
static IRAM_ATTR esp_err_t delay_us(void *arg, uint32_t us)
static esp_err_t delay_us(void *arg, uint32_t us)
{
esp_rom_delay_us(us);
return ESP_OK;
@ -56,7 +56,7 @@ static IRAM_ATTR esp_err_t delay_us(void *arg, uint32_t us)
// Currently when the os is not up yet, the caller is supposed to call esp_flash APIs with proper
// buffers.
IRAM_ATTR void* get_temp_buffer_not_supported(void* arg, size_t reqest_size, size_t* out_size)
void* get_temp_buffer_not_supported(void* arg, size_t reqest_size, size_t* out_size)
{
return NULL;
}
@ -72,7 +72,7 @@ const DRAM_ATTR esp_flash_os_functions_t esp_flash_noos_functions = {
.yield = NULL,
};
esp_err_t IRAM_ATTR esp_flash_app_disable_os_functions(esp_flash_t* chip)
esp_err_t esp_flash_app_disable_os_functions(esp_flash_t* chip)
{
chip->os_func = &esp_flash_noos_functions;

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
from pytest_embedded import Dut

View File

@ -206,7 +206,10 @@ TEST_CASE("flash suspend test", "[spi_flash][suspend]")
ESP_LOGI(TAG, "During Erase, ISR interval time:\n\t\t%0.2f us", GET_US_BY_CCOUNT(s_isr_interval_time / (times - 1)));
ESP_LOGI(TAG, "The tsus value which passes the test is:\n\t\t%ld us", isr_interval_time - isr_duration_time);
// 15 stands for threshold. We allow the interval time minus duration time is little bit larger than TSUS value
#if CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM
// Don't check the performance because it should be slow.
TEST_ASSERT_LESS_THAN(CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US + 15, isr_interval_time - isr_duration_time);
#endif
ESP_LOGI(TAG, "Reasonable value!");
ESP_LOGI(TAG, "Finish");

View File

@ -11,6 +11,7 @@ from pytest_embedded import Dut
[
'release',
'i2c_isr_flash',
'text_in_flash_when_suspend',
],
indirect=True,
)

View File

@ -0,0 +1,2 @@
CONFIG_SPI_FLASH_AUTO_SUSPEND=y
CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM=n