mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 04:04:31 +02:00
Merge branch 'feature/spi_flash_lock_recursive' into 'master'
spi_flash: Expose recursive op_lock for atomic multi-part flash operations See merge request !1556
This commit is contained in:
@@ -212,27 +212,27 @@ IRAM_ATTR TEST_CASE("ETSTimers arm & disarm run from IRAM", "[ets_timer]")
|
|||||||
|
|
||||||
/* arm a disabled timer, then disarm a live timer */
|
/* arm a disabled timer, then disarm a live timer */
|
||||||
|
|
||||||
g_flash_guard_default_ops.start(); // Disables flash cache
|
spi_flash_guard_get()->start(); // Disables flash cache
|
||||||
|
|
||||||
ets_timer_arm(&timer1, INTERVAL, false);
|
ets_timer_arm(&timer1, INTERVAL, false);
|
||||||
// redundant call is deliberate (test code path if already armed)
|
// redundant call is deliberate (test code path if already armed)
|
||||||
ets_timer_arm(&timer1, INTERVAL, false);
|
ets_timer_arm(&timer1, INTERVAL, false);
|
||||||
ets_timer_disarm(&timer1);
|
ets_timer_disarm(&timer1);
|
||||||
|
|
||||||
g_flash_guard_default_ops.end(); // Re-enables flash cache
|
spi_flash_guard_get()->end(); // Re-enables flash cache
|
||||||
|
|
||||||
TEST_ASSERT_FALSE(flag); // didn't expire yet
|
TEST_ASSERT_FALSE(flag); // didn't expire yet
|
||||||
|
|
||||||
/* do the same thing but wait for the timer to expire */
|
/* do the same thing but wait for the timer to expire */
|
||||||
|
|
||||||
g_flash_guard_default_ops.start();
|
spi_flash_guard_get()->start();
|
||||||
ets_timer_arm(&timer1, INTERVAL, false);
|
ets_timer_arm(&timer1, INTERVAL, false);
|
||||||
g_flash_guard_default_ops.end();
|
spi_flash_guard_get()->end();
|
||||||
|
|
||||||
vTaskDelay(2 * INTERVAL / portTICK_PERIOD_MS);
|
vTaskDelay(2 * INTERVAL / portTICK_PERIOD_MS);
|
||||||
TEST_ASSERT_TRUE(flag);
|
TEST_ASSERT_TRUE(flag);
|
||||||
|
|
||||||
g_flash_guard_default_ops.start();
|
spi_flash_guard_get()->start();
|
||||||
ets_timer_disarm(&timer1);
|
ets_timer_disarm(&timer1);
|
||||||
g_flash_guard_default_ops.end();
|
spi_flash_guard_get()->end();
|
||||||
}
|
}
|
||||||
|
@@ -105,7 +105,7 @@ TEST_CASE("heap_caps metadata test", "[heap]")
|
|||||||
*/
|
*/
|
||||||
static IRAM_ATTR __attribute__((noinline)) bool iram_malloc_test()
|
static IRAM_ATTR __attribute__((noinline)) bool iram_malloc_test()
|
||||||
{
|
{
|
||||||
g_flash_guard_default_ops.start(); // Disables flash cache
|
spi_flash_guard_get()->start(); // Disables flash cache
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
void *x = heap_caps_malloc(64, MALLOC_CAP_32BIT);
|
void *x = heap_caps_malloc(64, MALLOC_CAP_32BIT);
|
||||||
@@ -114,7 +114,7 @@ static IRAM_ATTR __attribute__((noinline)) bool iram_malloc_test()
|
|||||||
result = result && (y != NULL);
|
result = result && (y != NULL);
|
||||||
heap_caps_free(y);
|
heap_caps_free(y);
|
||||||
|
|
||||||
g_flash_guard_default_ops.end(); // Re-enables flash cache
|
spi_flash_guard_get()->end(); // Re-enables flash cache
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -47,18 +47,18 @@ static volatile int s_flash_op_cpu = -1;
|
|||||||
|
|
||||||
void spi_flash_init_lock()
|
void spi_flash_init_lock()
|
||||||
{
|
{
|
||||||
s_flash_op_mutex = xSemaphoreCreateMutex();
|
s_flash_op_mutex = xSemaphoreCreateRecursiveMutex();
|
||||||
assert(s_flash_op_mutex != NULL);
|
assert(s_flash_op_mutex != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spi_flash_op_lock()
|
void spi_flash_op_lock()
|
||||||
{
|
{
|
||||||
xSemaphoreTake(s_flash_op_mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(s_flash_op_mutex, portMAX_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spi_flash_op_unlock()
|
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
|
If you're going to modify this, keep in mind that while the flash caches of the pro and app
|
||||||
|
@@ -137,6 +137,11 @@ void IRAM_ATTR spi_flash_guard_set(const spi_flash_guard_funcs_t *funcs)
|
|||||||
s_flash_guard_ops = funcs;
|
s_flash_guard_ops = funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const spi_flash_guard_funcs_t *IRAM_ATTR spi_flash_guard_get()
|
||||||
|
{
|
||||||
|
return s_flash_guard_ops;
|
||||||
|
}
|
||||||
|
|
||||||
size_t IRAM_ATTR spi_flash_get_chip_size()
|
size_t IRAM_ATTR spi_flash_get_chip_size()
|
||||||
{
|
{
|
||||||
return g_rom_flashchip.chip_size;
|
return g_rom_flashchip.chip_size;
|
||||||
|
@@ -289,11 +289,15 @@ typedef void (*spi_flash_op_unlock_func_t)(void);
|
|||||||
* is invoked before the call to one of ROM function above.
|
* is invoked before the call to one of ROM function above.
|
||||||
* - 'end' function should restore state of flash cache and non-IRAM interrupts and
|
* - 'end' function should restore state of flash cache and non-IRAM interrupts and
|
||||||
* is invoked after the call to one of ROM function above.
|
* 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.
|
* 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
|
* This functions are mostly intended to synchronize access to flash API internal data
|
||||||
* in multithreaded environment and use OS primitives:
|
* in multithreaded environment and use OS primitives:
|
||||||
* - 'op_lock' locks access to flash API internal data.
|
* - 'op_lock' locks access to flash API internal data.
|
||||||
* - 'op_unlock' unlocks 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
|
* 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
|
* 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
|
* 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.
|
* For example structure can be placed in DRAM and functions in IRAM sections.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
spi_flash_guard_start_func_t start; /**< critical section start func */
|
spi_flash_guard_start_func_t start; /**< critical section start function. */
|
||||||
spi_flash_guard_end_func_t end; /**< critical section end func */
|
spi_flash_guard_end_func_t end; /**< critical section end function. */
|
||||||
spi_flash_op_lock_func_t op_lock; /**< flash access API lock func */
|
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 func */
|
spi_flash_op_unlock_func_t op_unlock; /**< flash access API unlock function.*/
|
||||||
} spi_flash_guard_funcs_t;
|
} spi_flash_guard_funcs_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -320,6 +324,15 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
void spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs);
|
void spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the guard functions used for flash access
|
||||||
|
*
|
||||||
|
* @return The guard functions that were set via spi_flash_guard_set(). These functions
|
||||||
|
* can be called if implementing custom low-level SPI flash operations.
|
||||||
|
*/
|
||||||
|
const spi_flash_guard_funcs_t *spi_flash_guard_get();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default OS-aware flash access guard functions
|
* @brief Default OS-aware flash access guard functions
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user