diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 53a0caf8ee..63c6692cee 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -47,18 +47,18 @@ static volatile int s_flash_op_cpu = -1; void spi_flash_init_lock() { - s_flash_op_mutex = xSemaphoreCreateMutex(); + s_flash_op_mutex = xSemaphoreCreateRecursiveMutex(); assert(s_flash_op_mutex != NULL); } void spi_flash_op_lock() { - xSemaphoreTake(s_flash_op_mutex, portMAX_DELAY); + xSemaphoreTakeRecursive(s_flash_op_mutex, portMAX_DELAY); } void spi_flash_op_unlock() { - xSemaphoreGive(s_flash_op_mutex); + xSemaphoreGiveRecursive(s_flash_op_mutex); } /* If you're going to modify this, keep in mind that while the flash caches of the pro and app @@ -214,7 +214,7 @@ void spi_flash_op_unlock() void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() { - spi_flash_op_lock(); + spi_flash_op_lockspi_flash_op_lock(); esp_intr_noniram_disable(); spi_flash_disable_cache(0, &s_flash_op_cache_state[0]); } diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index fc48fd2301..7d6a03612b 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -289,11 +289,15 @@ typedef void (*spi_flash_op_unlock_func_t)(void); * is invoked before the call to one of ROM function above. * - 'end' function should restore state of flash cache and non-IRAM interrupts and * is invoked after the call to one of ROM function above. + * These two functions are not recursive. * 2) Functions which synchronizes access to internal data used by flash API. * This functions are mostly intended to synchronize access to flash API internal data * in multithreaded environment and use OS primitives: * - 'op_lock' locks access to flash API internal data. * - 'op_unlock' unlocks access to flash API internal data. + * These two functions are recursive and can be used around the outside of multiple calls to + * 'start' & 'end', in order to create atomic multi-part flash operations. + * * Different versions of the guarding functions should be used depending on the context of * execution (with or without functional OS). In normal conditions when flash API is called * from task the functions use OS primitives. When there is no OS at all or when @@ -304,10 +308,10 @@ typedef void (*spi_flash_op_unlock_func_t)(void); * For example structure can be placed in DRAM and functions in IRAM sections. */ typedef struct { - spi_flash_guard_start_func_t start; /**< critical section start func */ - spi_flash_guard_end_func_t end; /**< critical section end func */ - spi_flash_op_lock_func_t op_lock; /**< flash access API lock func */ - spi_flash_op_unlock_func_t op_unlock; /**< flash access API unlock func */ + spi_flash_guard_start_func_t start; /**< critical section start function. */ + spi_flash_guard_end_func_t end; /**< critical section end function. */ + spi_flash_op_lock_func_t op_lock; /**< flash access API lock function.*/ + spi_flash_op_unlock_func_t op_unlock; /**< flash access API unlock function.*/ } spi_flash_guard_funcs_t; /**