mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp32: Fixes watchdog problem when printing core dump to uart
Also fixes generation of core dumps when flash cache is disabled
This commit is contained in:
parent
4dd81fddd8
commit
04acc88023
@ -26,16 +26,17 @@
|
|||||||
#if CONFIG_ESP32_ENABLE_COREDUMP
|
#if CONFIG_ESP32_ENABLE_COREDUMP
|
||||||
#define LOG_LOCAL_LEVEL CONFIG_ESP32_CORE_DUMP_LOG_LEVEL
|
#define LOG_LOCAL_LEVEL CONFIG_ESP32_CORE_DUMP_LOG_LEVEL
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
const static char *TAG = "esp_core_dump";
|
const static DRAM_ATTR char TAG[] = "esp_core_dump";
|
||||||
|
|
||||||
#define ESP_COREDUMP_LOGE( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR) { ets_printf(LOG_FORMAT(E, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
|
#define ESP_COREDUMP_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { ets_printf(DRAM_STR(format), esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); }
|
||||||
#define ESP_COREDUMP_LOGW( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_WARN) { ets_printf(LOG_FORMAT(W, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
|
#define ESP_COREDUMP_LOGE( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_ERROR, LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||||
#define ESP_COREDUMP_LOGI( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { ets_printf(LOG_FORMAT(I, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
|
#define ESP_COREDUMP_LOGW( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_WARN, LOG_FORMAT(W, format), ##__VA_ARGS__)
|
||||||
#define ESP_COREDUMP_LOGD( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { ets_printf(LOG_FORMAT(D, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
|
#define ESP_COREDUMP_LOGI( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_INFO, LOG_FORMAT(I, format), ##__VA_ARGS__)
|
||||||
#define ESP_COREDUMP_LOGV( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) { ets_printf(LOG_FORMAT(V, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
|
#define ESP_COREDUMP_LOGD( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_DEBUG, LOG_FORMAT(D, format), ##__VA_ARGS__)
|
||||||
|
#define ESP_COREDUMP_LOGV( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_VERBOSE, LOG_FORMAT(V, format), ##__VA_ARGS__)
|
||||||
|
|
||||||
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
|
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
|
||||||
#define ESP_COREDUMP_LOG_PROCESS( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { ets_printf(LOG_FORMAT(D, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
|
#define ESP_COREDUMP_LOG_PROCESS( format, ... ) ESP_COREDUMP_LOGD(format, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define ESP_COREDUMP_LOG_PROCESS( format, ... ) do{/*(__VA_ARGS__);*/}while(0)
|
#define ESP_COREDUMP_LOG_PROCESS( format, ... ) do{/*(__VA_ARGS__);*/}while(0)
|
||||||
#endif
|
#endif
|
||||||
@ -345,8 +346,9 @@ void esp_core_dump_to_flash(XtExcFrame *frame)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART
|
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART
|
||||||
|
|
||||||
static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8_t *dst) {
|
static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8_t *dst) {
|
||||||
static const char *b64 =
|
const static DRAM_ATTR char b64[] =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
int i, j, a, b, c;
|
int i, j, a, b, c;
|
||||||
|
|
||||||
@ -373,14 +375,14 @@ static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8
|
|||||||
static esp_err_t esp_core_dump_uart_write_start(void *priv)
|
static esp_err_t esp_core_dump_uart_write_start(void *priv)
|
||||||
{
|
{
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
ets_printf("================= CORE DUMP START =================\r\n");
|
ets_printf(DRAM_STR("================= CORE DUMP START =================\r\n"));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t esp_core_dump_uart_write_end(void *priv)
|
static esp_err_t esp_core_dump_uart_write_end(void *priv)
|
||||||
{
|
{
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
ets_printf("================= CORE DUMP END =================\r\n");
|
ets_printf(DRAM_STR("================= CORE DUMP END =================\r\n"));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,7 +400,7 @@ static esp_err_t esp_core_dump_uart_write_data(void *priv, void * data, uint32_t
|
|||||||
memcpy(tmp, addr, len);
|
memcpy(tmp, addr, len);
|
||||||
esp_core_dump_b64_encode((const uint8_t *)tmp, len, (uint8_t *)buf);
|
esp_core_dump_b64_encode((const uint8_t *)tmp, len, (uint8_t *)buf);
|
||||||
addr += len;
|
addr += len;
|
||||||
ets_printf("%s\r\n", buf);
|
ets_printf(DRAM_STR("%s\r\n"), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -427,7 +429,8 @@ void esp_core_dump_to_uart(XtExcFrame *frame)
|
|||||||
wr_cfg.priv = NULL;
|
wr_cfg.priv = NULL;
|
||||||
|
|
||||||
//Make sure txd/rxd are enabled
|
//Make sure txd/rxd are enabled
|
||||||
gpio_pullup_dis(1);
|
// use direct reg access instead of gpio_pullup_dis which can cause exception when flash cache is disabled
|
||||||
|
REG_CLR_BIT(GPIO_PIN_REG_1, FUN_PU);
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
|
||||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD);
|
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD);
|
||||||
|
|
||||||
@ -438,10 +441,6 @@ void esp_core_dump_to_uart(XtExcFrame *frame)
|
|||||||
tm_cur = xthal_get_ccount() / (XT_CLOCK_FREQ / 1000);
|
tm_cur = xthal_get_ccount() / (XT_CLOCK_FREQ / 1000);
|
||||||
if (tm_cur >= tm_end)
|
if (tm_cur >= tm_end)
|
||||||
break;
|
break;
|
||||||
/* Feed the Cerberus. */
|
|
||||||
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
|
|
||||||
TIMERG0.wdt_feed = 1;
|
|
||||||
TIMERG0.wdt_wprotect = 0;
|
|
||||||
ch = esp_core_dump_uart_get_char();
|
ch = esp_core_dump_uart_get_char();
|
||||||
}
|
}
|
||||||
ESP_COREDUMP_LOGI("Print core dump to uart...");
|
ESP_COREDUMP_LOGI("Print core dump to uart...");
|
||||||
@ -455,18 +454,18 @@ void esp_core_dump_init()
|
|||||||
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
|
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
|
||||||
const esp_partition_t *core_part;
|
const esp_partition_t *core_part;
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Init core dump to flash");
|
ESP_COREDUMP_LOGI("Init core dump to flash");
|
||||||
core_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, NULL);
|
core_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, NULL);
|
||||||
if (!core_part) {
|
if (!core_part) {
|
||||||
ESP_LOGE(TAG, "No core dump partition found!");
|
ESP_COREDUMP_LOGE("No core dump partition found!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "Found partition '%s' @ %x %d bytes", core_part->label, core_part->address, core_part->size);
|
ESP_COREDUMP_LOGI("Found partition '%s' @ %x %d bytes", core_part->label, core_part->address, core_part->size);
|
||||||
s_core_part_start = core_part->address;
|
s_core_part_start = core_part->address;
|
||||||
s_core_part_size = core_part->size;
|
s_core_part_size = core_part->size;
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART
|
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART
|
||||||
ESP_LOGI(TAG, "Init core dump to UART");
|
ESP_COREDUMP_LOGI("Init core dump to UART");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +210,10 @@ void start_cpu0_default(void)
|
|||||||
/* init default OS-aware flash access critical section */
|
/* init default OS-aware flash access critical section */
|
||||||
spi_flash_guard_set(&g_flash_guard_default_ops);
|
spi_flash_guard_set(&g_flash_guard_default_ops);
|
||||||
|
|
||||||
|
#if CONFIG_ESP32_ENABLE_COREDUMP
|
||||||
|
esp_core_dump_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_ESP32_PHY_AUTO_INIT
|
#if CONFIG_ESP32_PHY_AUTO_INIT
|
||||||
nvs_flash_init();
|
nvs_flash_init();
|
||||||
do_phy_init();
|
do_phy_init();
|
||||||
@ -221,10 +225,6 @@ void start_cpu0_default(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_ESP32_ENABLE_COREDUMP
|
|
||||||
esp_core_dump_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
xTaskCreatePinnedToCore(&main_task, "main",
|
xTaskCreatePinnedToCore(&main_task, "main",
|
||||||
ESP_TASK_MAIN_STACK, NULL,
|
ESP_TASK_MAIN_STACK, NULL,
|
||||||
ESP_TASK_MAIN_PRIO, NULL, 0);
|
ESP_TASK_MAIN_PRIO, NULL, 0);
|
||||||
|
@ -686,7 +686,7 @@ esp_err_t IRAM_ATTR esp_intr_disable(intr_handle_t handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void esp_intr_noniram_disable()
|
void IRAM_ATTR esp_intr_noniram_disable()
|
||||||
{
|
{
|
||||||
int oldint;
|
int oldint;
|
||||||
int cpu=xPortGetCoreID();
|
int cpu=xPortGetCoreID();
|
||||||
@ -705,7 +705,7 @@ void esp_intr_noniram_disable()
|
|||||||
non_iram_int_disabled[cpu]=oldint&non_iram_int_mask[cpu];
|
non_iram_int_disabled[cpu]=oldint&non_iram_int_mask[cpu];
|
||||||
}
|
}
|
||||||
|
|
||||||
void esp_intr_noniram_enable()
|
void IRAM_ATTR esp_intr_noniram_enable()
|
||||||
{
|
{
|
||||||
int cpu=xPortGetCoreID();
|
int cpu=xPortGetCoreID();
|
||||||
int intmask=non_iram_int_disabled[cpu];
|
int intmask=non_iram_int_disabled[cpu];
|
||||||
|
@ -80,6 +80,7 @@ SECTIONS
|
|||||||
*(.iram1 .iram1.*)
|
*(.iram1 .iram1.*)
|
||||||
*libfreertos.a:(.literal .text .literal.* .text.*)
|
*libfreertos.a:(.literal .text .literal.* .text.*)
|
||||||
*libesp32.a:panic.o(.literal .text .literal.* .text.*)
|
*libesp32.a:panic.o(.literal .text .literal.* .text.*)
|
||||||
|
*libesp32.a:core_dump.o(.literal .text .literal.* .text.*)
|
||||||
*libphy.a:(.literal .text .literal.* .text.*)
|
*libphy.a:(.literal .text .literal.* .text.*)
|
||||||
*librtc.a:(.literal .text .literal.* .text.*)
|
*librtc.a:(.literal .text .literal.* .text.*)
|
||||||
*libpp.a:(.literal .text .literal.* .text.*)
|
*libpp.a:(.literal .text .literal.* .text.*)
|
||||||
|
@ -267,7 +267,7 @@ static void reconfigureAllWdts()
|
|||||||
TIMERG1.wdt_wprotect = 0;
|
TIMERG1.wdt_wprotect = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ESP32_PANIC_GDBSTUB || CONFIG_ESP32_PANIC_PRINT_HALT
|
#if CONFIG_ESP32_PANIC_GDBSTUB || CONFIG_ESP32_PANIC_PRINT_HALT || CONFIG_ESP32_ENABLE_COREDUMP
|
||||||
/*
|
/*
|
||||||
This disables all the watchdogs for when we call the gdbstub.
|
This disables all the watchdogs for when we call the gdbstub.
|
||||||
*/
|
*/
|
||||||
@ -367,11 +367,15 @@ static void commonErrorHandler(XtExcFrame *frame)
|
|||||||
panicPutStr("Entering gdb stub now.\r\n");
|
panicPutStr("Entering gdb stub now.\r\n");
|
||||||
esp_gdbstub_panic_handler(frame);
|
esp_gdbstub_panic_handler(frame);
|
||||||
#else
|
#else
|
||||||
|
#if CONFIG_ESP32_ENABLE_COREDUMP
|
||||||
|
disableAllWdts();
|
||||||
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
|
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
|
||||||
esp_core_dump_to_flash(frame);
|
esp_core_dump_to_flash(frame);
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART && !CONFIG_ESP32_PANIC_SILENT_REBOOT
|
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART && !CONFIG_ESP32_PANIC_SILENT_REBOOT
|
||||||
esp_core_dump_to_uart(frame);
|
esp_core_dump_to_uart(frame);
|
||||||
|
#endif
|
||||||
|
reconfigureAllWdts();
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
|
#if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
|
||||||
panicPutStr("Rebooting...\r\n");
|
panicPutStr("Rebooting...\r\n");
|
||||||
|
@ -62,12 +62,16 @@ static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc);
|
|||||||
|
|
||||||
const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_default_ops = {
|
const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_default_ops = {
|
||||||
.start = spi_flash_disable_interrupts_caches_and_other_cpu,
|
.start = spi_flash_disable_interrupts_caches_and_other_cpu,
|
||||||
.end = spi_flash_enable_interrupts_caches_and_other_cpu
|
.end = spi_flash_enable_interrupts_caches_and_other_cpu,
|
||||||
|
.op_lock = spi_flash_op_lock,
|
||||||
|
.op_unlock = spi_flash_op_unlock
|
||||||
};
|
};
|
||||||
|
|
||||||
const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_no_os_ops = {
|
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,
|
.start = spi_flash_disable_interrupts_caches_and_other_cpu_no_os,
|
||||||
.end = spi_flash_enable_interrupts_caches_no_os
|
.end = spi_flash_enable_interrupts_caches_no_os,
|
||||||
|
.op_lock = 0,
|
||||||
|
.op_unlock = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static const spi_flash_guard_funcs_t *s_flash_guard_ops;
|
static const spi_flash_guard_funcs_t *s_flash_guard_ops;
|
||||||
@ -80,12 +84,12 @@ void spi_flash_init()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs)
|
void IRAM_ATTR spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs)
|
||||||
{
|
{
|
||||||
s_flash_guard_ops = funcs;
|
s_flash_guard_ops = funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t 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;
|
||||||
}
|
}
|
||||||
@ -105,18 +109,32 @@ static SpiFlashOpResult IRAM_ATTR spi_flash_unlock()
|
|||||||
|
|
||||||
static inline void IRAM_ATTR spi_flash_guard_start()
|
static inline void IRAM_ATTR spi_flash_guard_start()
|
||||||
{
|
{
|
||||||
if (s_flash_guard_ops) {
|
if (s_flash_guard_ops && s_flash_guard_ops->start) {
|
||||||
s_flash_guard_ops->start();
|
s_flash_guard_ops->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void IRAM_ATTR spi_flash_guard_end()
|
static inline void IRAM_ATTR spi_flash_guard_end()
|
||||||
{
|
{
|
||||||
if (s_flash_guard_ops) {
|
if (s_flash_guard_ops && s_flash_guard_ops->end) {
|
||||||
s_flash_guard_ops->end();
|
s_flash_guard_ops->end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void IRAM_ATTR spi_flash_guard_op_lock()
|
||||||
|
{
|
||||||
|
if (s_flash_guard_ops && s_flash_guard_ops->op_lock) {
|
||||||
|
s_flash_guard_ops->op_lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void IRAM_ATTR spi_flash_guard_op_unlock()
|
||||||
|
{
|
||||||
|
if (s_flash_guard_ops && s_flash_guard_ops->op_unlock) {
|
||||||
|
s_flash_guard_ops->op_unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sec)
|
esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sec)
|
||||||
{
|
{
|
||||||
return spi_flash_erase_range(sec * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);
|
return spi_flash_erase_range(sec * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);
|
||||||
@ -251,9 +269,9 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size)
|
|||||||
out:
|
out:
|
||||||
COUNTER_STOP(write);
|
COUNTER_STOP(write);
|
||||||
|
|
||||||
spi_flash_op_lock();
|
spi_flash_guard_op_lock();
|
||||||
spi_flash_mark_modified_region(dst, size);
|
spi_flash_mark_modified_region(dst, size);
|
||||||
spi_flash_op_unlock();
|
spi_flash_guard_op_unlock();
|
||||||
|
|
||||||
return spi_flash_translate_rc(rc);
|
return spi_flash_translate_rc(rc);
|
||||||
}
|
}
|
||||||
@ -320,9 +338,9 @@ esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src,
|
|||||||
}
|
}
|
||||||
COUNTER_ADD_BYTES(write, size);
|
COUNTER_ADD_BYTES(write, size);
|
||||||
|
|
||||||
spi_flash_op_lock();
|
spi_flash_guard_op_lock();
|
||||||
spi_flash_mark_modified_region(dest_addr, size);
|
spi_flash_mark_modified_region(dest_addr, size);
|
||||||
spi_flash_op_unlock();
|
spi_flash_guard_op_unlock();
|
||||||
|
|
||||||
return spi_flash_translate_rc(rc);
|
return spi_flash_translate_rc(rc);
|
||||||
}
|
}
|
||||||
@ -444,7 +462,7 @@ esp_err_t IRAM_ATTR spi_flash_read_encrypted(size_t src, void *dstv, size_t size
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc)
|
static esp_err_t IRAM_ATTR spi_flash_translate_rc(SpiFlashOpResult rc)
|
||||||
{
|
{
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
case SPI_FLASH_RESULT_OK:
|
case SPI_FLASH_RESULT_OK:
|
||||||
|
@ -205,9 +205,35 @@ typedef void (*spi_flash_guard_start_func_t)(void);
|
|||||||
* @brief SPI flash critical section exit function.
|
* @brief SPI flash critical section exit function.
|
||||||
*/
|
*/
|
||||||
typedef void (*spi_flash_guard_end_func_t)(void);
|
typedef void (*spi_flash_guard_end_func_t)(void);
|
||||||
|
/**
|
||||||
|
* @brief SPI flash operation lock function.
|
||||||
|
*/
|
||||||
|
typedef void (*spi_flash_op_lock_func_t)(void);
|
||||||
|
/**
|
||||||
|
* @brief SPI flash operation unlock function.
|
||||||
|
*/
|
||||||
|
typedef void (*spi_flash_op_unlock_func_t)(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure holding SPI flash access critical section management functions
|
* Structure holding SPI flash access critical sections management functions.
|
||||||
|
*
|
||||||
|
* Flash API uses two types of flash access management functions:
|
||||||
|
* 1) Functions which prepare/restore flash cache and interrupts before calling
|
||||||
|
* appropriate ROM functions (SPIWrite, SPIRead and SPIEraseBlock):
|
||||||
|
* - 'start' function should disables flash cache and non-IRAM interrupts and
|
||||||
|
* 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.
|
||||||
|
* 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.
|
||||||
|
* 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
|
||||||
|
* it is not guaranteed that OS is functional (accessing flash from exception handler) these
|
||||||
|
* functions cannot use OS primitives or even does not need them (multithreaded access is not possible).
|
||||||
*
|
*
|
||||||
* @note Structure and corresponding guard functions should not reside in flash.
|
* @note Structure and corresponding guard functions should not reside in flash.
|
||||||
* 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.
|
||||||
@ -215,6 +241,8 @@ typedef void (*spi_flash_guard_end_func_t)(void);
|
|||||||
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 func */
|
||||||
spi_flash_guard_end_func_t end; /**< critical section end 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_funcs_t;
|
} spi_flash_guard_funcs_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user