]> granicus.if.org Git - esp-idf/commitdiff
spi_flash: Make spi_flash op_lock/op_unlock recursive
authorAngus Gratton <angus@espressif.com>
Fri, 17 Nov 2017 04:00:16 +0000 (15:00 +1100)
committerAngus Gratton <gus@projectgus.com>
Mon, 20 Nov 2017 04:54:31 +0000 (15:54 +1100)
Allows chaining of multiple flash operations as an atomic operation.

components/spi_flash/cache_utils.c
components/spi_flash/include/esp_spi_flash.h

index 53a0caf8ee82005d648ee970e66e2ff91730feaa..63c6692cee53f2dbde20b92024ccb7ed284b7dee 100644 (file)
@@ -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]);
 }
index fc48fd2301a886f1a3cfca5fb425e6f96933c162..7d6a03612b3457f52669e89b99367614f38ca9b9 100644 (file)
@@ -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;
 
 /**