mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-30 19:19:21 +00:00
esp32: Fixes several issues in core dump feature
1) PS is fixed up to allow GDB backtrace to work properly 2) MR!341 discussion: in core dump module: esp_panicPutXXX was replaced by ets_printf. 3) MR!341 discussion: core dump flash magic number was changed. 4) MR!341 discussion: SPI flash access API was redesigned to allow flexible critical section management. 5) test app for core dump feature was added 6) fixed base64 file reading issues on Windows platform 7) now raw bin core file is deleted upon core loader failure by epscoredump.py
This commit is contained in:
@@ -141,7 +141,7 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu()
|
||||
esp_intr_noniram_enable();
|
||||
}
|
||||
|
||||
void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_panic()
|
||||
void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_no_os()
|
||||
{
|
||||
const uint32_t cpuid = xPortGetCoreID();
|
||||
const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0;
|
||||
@@ -154,7 +154,7 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_panic()
|
||||
spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]);
|
||||
}
|
||||
|
||||
void IRAM_ATTR spi_flash_enable_interrupts_caches_panic()
|
||||
void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os()
|
||||
{
|
||||
const uint32_t cpuid = xPortGetCoreID();
|
||||
|
||||
@@ -195,7 +195,7 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu()
|
||||
esp_intr_noniram_enable();
|
||||
}
|
||||
|
||||
void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_panic()
|
||||
void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_no_os()
|
||||
{
|
||||
// Kill interrupts that aren't located in IRAM
|
||||
esp_intr_noniram_disable();
|
||||
@@ -203,7 +203,7 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_panic()
|
||||
spi_flash_disable_cache(0, &s_flash_op_cache_state[0]);
|
||||
}
|
||||
|
||||
void IRAM_ATTR spi_flash_enable_interrupts_caches_panic()
|
||||
void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os()
|
||||
{
|
||||
// Re-enable cache on this CPU
|
||||
spi_flash_restore_cache(0, s_flash_op_cache_state[0]);
|
||||
|
@@ -41,13 +41,13 @@ void spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
void spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
|
||||
// Disables non-IRAM interrupt handlers on current CPU and caches on both CPUs.
|
||||
// This function is implied to be called from panic handler
|
||||
// This function is implied to be called from panic handler or when no OS is present
|
||||
// when non-current CPU is halted and can not execute code from flash.
|
||||
void spi_flash_disable_interrupts_caches_and_other_cpu_panic();
|
||||
void spi_flash_disable_interrupts_caches_and_other_cpu_no_os();
|
||||
|
||||
// Enable cache, enable interrupts (to be added in future) on current CPU.
|
||||
// This function is implied to be called from panic handler
|
||||
// This function is implied to be called from panic handler or when no OS is present
|
||||
// when non-current CPU is halted and can not execute code from flash.
|
||||
void spi_flash_enable_interrupts_caches_panic();
|
||||
void spi_flash_enable_interrupts_caches_no_os();
|
||||
|
||||
#endif //ESP_SPI_FLASH_CACHE_UTILS_H
|
||||
|
@@ -58,36 +58,23 @@ static spi_flash_counters_t s_flash_stats;
|
||||
|
||||
#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
|
||||
/* SPI flash access critical section management functions */
|
||||
typedef void (*spi_flash_guard_start_func_t)(void);
|
||||
typedef void (*spi_flash_guard_end_func_t)(void);
|
||||
|
||||
/**
|
||||
* Structure holding SPI flash access critical section management functions
|
||||
*/
|
||||
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_guard_funcs_t;
|
||||
|
||||
#define FLASH_GUARD_START(_gp_) do{if((_gp_)) (_gp_)->start();}while(0)
|
||||
#define FLASH_GUARD_END(_gp_) do{if((_gp_)) (_gp_)->end();}while(0)
|
||||
|
||||
static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc);
|
||||
static esp_err_t spi_flash_erase_range_internal(uint32_t start_addr, uint32_t size, const spi_flash_guard_funcs_t *flash_guard);
|
||||
static esp_err_t spi_flash_write_internal(size_t dst, const void *srcv, size_t size, const spi_flash_guard_funcs_t *flash_guard);
|
||||
static esp_err_t spi_flash_read_internal(size_t src, void *dstv, size_t size, const spi_flash_guard_funcs_t *flash_guard);
|
||||
|
||||
const DRAM_ATTR spi_flash_guard_funcs_t s_flash_guard_ops = {
|
||||
const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_default_ops = {
|
||||
.start = spi_flash_disable_interrupts_caches_and_other_cpu,
|
||||
.end = spi_flash_enable_interrupts_caches_and_other_cpu
|
||||
};
|
||||
|
||||
const DRAM_ATTR spi_flash_guard_funcs_t s_flash_guard_panic_ops = {
|
||||
.start = spi_flash_disable_interrupts_caches_and_other_cpu_panic,
|
||||
.end = spi_flash_enable_interrupts_caches_panic
|
||||
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,
|
||||
.end = spi_flash_enable_interrupts_caches_no_os
|
||||
};
|
||||
|
||||
static const spi_flash_guard_funcs_t *s_flash_guard_ops;
|
||||
|
||||
void spi_flash_init()
|
||||
{
|
||||
spi_flash_init_lock();
|
||||
@@ -96,6 +83,11 @@ void spi_flash_init()
|
||||
#endif
|
||||
}
|
||||
|
||||
void spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs)
|
||||
{
|
||||
s_flash_guard_ops = funcs;
|
||||
}
|
||||
|
||||
size_t spi_flash_get_chip_size()
|
||||
{
|
||||
return g_rom_flashchip.chip_size;
|
||||
@@ -120,16 +112,6 @@ esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sec)
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
{
|
||||
return spi_flash_erase_range_internal(start_addr, size, &s_flash_guard_ops);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_erase_range_panic(uint32_t start_addr, uint32_t size)
|
||||
{
|
||||
return spi_flash_erase_range_internal(start_addr, size, &s_flash_guard_panic_ops);
|
||||
}
|
||||
|
||||
static esp_err_t IRAM_ATTR spi_flash_erase_range_internal(uint32_t start_addr, uint32_t size, const spi_flash_guard_funcs_t *flash_guard)
|
||||
{
|
||||
if (start_addr % SPI_FLASH_SEC_SIZE != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -144,7 +126,7 @@ static esp_err_t IRAM_ATTR spi_flash_erase_range_internal(uint32_t start_addr, u
|
||||
size_t end = start + size / SPI_FLASH_SEC_SIZE;
|
||||
const size_t sectors_per_block = BLOCK_ERASE_SIZE / SPI_FLASH_SEC_SIZE;
|
||||
COUNTER_START();
|
||||
FLASH_GUARD_START(flash_guard);
|
||||
FLASH_GUARD_START(s_flash_guard_ops);
|
||||
SpiFlashOpResult rc;
|
||||
rc = spi_flash_unlock();
|
||||
if (rc == SPI_FLASH_RESULT_OK) {
|
||||
@@ -160,22 +142,12 @@ static esp_err_t IRAM_ATTR spi_flash_erase_range_internal(uint32_t start_addr, u
|
||||
}
|
||||
}
|
||||
}
|
||||
FLASH_GUARD_END(flash_guard);
|
||||
FLASH_GUARD_END(s_flash_guard_ops);
|
||||
COUNTER_STOP(erase);
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size)
|
||||
{
|
||||
return spi_flash_write_internal(dst, srcv, size, &s_flash_guard_ops);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_write_panic(size_t dst, const void *srcv, size_t size)
|
||||
{
|
||||
return spi_flash_write_internal(dst, srcv, size, &s_flash_guard_panic_ops);
|
||||
}
|
||||
|
||||
static esp_err_t IRAM_ATTR spi_flash_write_internal(size_t dst, const void *srcv, size_t size, const spi_flash_guard_funcs_t *flash_guard)
|
||||
{
|
||||
// Out of bound writes are checked in ROM code, but we can give better
|
||||
// error code here
|
||||
@@ -208,9 +180,9 @@ static esp_err_t IRAM_ATTR spi_flash_write_internal(size_t dst, const void *srcv
|
||||
if (left_size > 0) {
|
||||
uint32_t t = 0xffffffff;
|
||||
memcpy(((uint8_t *) &t) + (dst - left_off), srcc, left_size);
|
||||
FLASH_GUARD_START(flash_guard);
|
||||
FLASH_GUARD_START(s_flash_guard_ops);
|
||||
rc = SPIWrite(left_off, &t, 4);
|
||||
FLASH_GUARD_END(flash_guard);
|
||||
FLASH_GUARD_END(s_flash_guard_ops);
|
||||
if (rc != SPI_FLASH_RESULT_OK) {
|
||||
goto out;
|
||||
}
|
||||
@@ -226,9 +198,9 @@ static esp_err_t IRAM_ATTR spi_flash_write_internal(size_t dst, const void *srcv
|
||||
bool in_dram = true;
|
||||
#endif
|
||||
if (in_dram && (((uintptr_t) srcc) + mid_off) % 4 == 0) {
|
||||
FLASH_GUARD_START(flash_guard);
|
||||
FLASH_GUARD_START(s_flash_guard_ops);
|
||||
rc = SPIWrite(dst + mid_off, (const uint32_t *) (srcc + mid_off), mid_size);
|
||||
FLASH_GUARD_END(flash_guard);
|
||||
FLASH_GUARD_END(s_flash_guard_ops);
|
||||
if (rc != SPI_FLASH_RESULT_OK) {
|
||||
goto out;
|
||||
}
|
||||
@@ -242,9 +214,9 @@ static esp_err_t IRAM_ATTR spi_flash_write_internal(size_t dst, const void *srcv
|
||||
uint32_t t[8];
|
||||
uint32_t write_size = MIN(mid_size, sizeof(t));
|
||||
memcpy(t, srcc + mid_off, write_size);
|
||||
FLASH_GUARD_START(flash_guard);
|
||||
FLASH_GUARD_START(s_flash_guard_ops);
|
||||
rc = SPIWrite(dst + mid_off, t, write_size);
|
||||
FLASH_GUARD_END(flash_guard);
|
||||
FLASH_GUARD_END(s_flash_guard_ops);
|
||||
if (rc != SPI_FLASH_RESULT_OK) {
|
||||
goto out;
|
||||
}
|
||||
@@ -257,9 +229,9 @@ static esp_err_t IRAM_ATTR spi_flash_write_internal(size_t dst, const void *srcv
|
||||
if (right_size > 0) {
|
||||
uint32_t t = 0xffffffff;
|
||||
memcpy(&t, srcc + right_off, right_size);
|
||||
FLASH_GUARD_START(flash_guard);
|
||||
FLASH_GUARD_START(s_flash_guard_ops);
|
||||
rc = SPIWrite(dst + right_off, &t, 4);
|
||||
FLASH_GUARD_END(flash_guard);
|
||||
FLASH_GUARD_END(s_flash_guard_ops);
|
||||
if (rc != SPI_FLASH_RESULT_OK) {
|
||||
goto out;
|
||||
}
|
||||
@@ -307,16 +279,6 @@ esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src,
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
|
||||
{
|
||||
return spi_flash_read_internal(src, dstv, size, &s_flash_guard_ops);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_read_panic(size_t src, void *dstv, size_t size)
|
||||
{
|
||||
return spi_flash_read_internal(src, dstv, size, &s_flash_guard_panic_ops);
|
||||
}
|
||||
|
||||
static esp_err_t IRAM_ATTR spi_flash_read_internal(size_t src, void *dstv, size_t size, const spi_flash_guard_funcs_t *flash_guard)
|
||||
{
|
||||
// Out of bound reads are checked in ROM code, but we can give better
|
||||
// error code here
|
||||
@@ -329,7 +291,7 @@ static esp_err_t IRAM_ATTR spi_flash_read_internal(size_t src, void *dstv, size_
|
||||
|
||||
SpiFlashOpResult rc = SPI_FLASH_RESULT_OK;
|
||||
COUNTER_START();
|
||||
FLASH_GUARD_START(flash_guard);
|
||||
FLASH_GUARD_START(s_flash_guard_ops);
|
||||
/* To simplify boundary checks below, we handle small reads separately. */
|
||||
if (size < 16) {
|
||||
uint32_t t[6]; /* Enough for 16 bytes + 4 on either side for padding. */
|
||||
@@ -403,7 +365,7 @@ static esp_err_t IRAM_ATTR spi_flash_read_internal(size_t src, void *dstv, size_
|
||||
memcpy(dstc + pad_right_off, t, pad_right_size);
|
||||
}
|
||||
out:
|
||||
FLASH_GUARD_END(flash_guard);
|
||||
FLASH_GUARD_END(s_flash_guard_ops);
|
||||
COUNTER_STOP(read);
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
|
@@ -173,12 +173,26 @@ void spi_flash_munmap(spi_flash_mmap_handle_t handle);
|
||||
*/
|
||||
void spi_flash_mmap_dump();
|
||||
|
||||
/**
|
||||
* @brief SPI flash critical section enter function.
|
||||
*/
|
||||
typedef void (*spi_flash_guard_start_func_t)(void);
|
||||
/**
|
||||
* @brief SPI flash critical section exit function.
|
||||
*/
|
||||
typedef void (*spi_flash_guard_end_func_t)(void);
|
||||
|
||||
/**
|
||||
* Structure holding SPI flash access critical section management functions
|
||||
*/
|
||||
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_guard_funcs_t;
|
||||
|
||||
/**
|
||||
* @brief Erase a range of flash sectors.
|
||||
*
|
||||
* @note This version of function is to be called from panic handler.
|
||||
* It does not use any OS primitives and IPC and implies that
|
||||
* only calling CPU is active.
|
||||
*
|
||||
* @param start_address Address where erase operation has to start.
|
||||
* Must be 4kB-aligned
|
||||
@@ -186,42 +200,18 @@ void spi_flash_mmap_dump();
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t spi_flash_erase_range_panic(size_t start_address, size_t size);
|
||||
void spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs);
|
||||
|
||||
/** Default OS-aware flash access critical section functions */
|
||||
extern const spi_flash_guard_funcs_t g_flash_guard_default_ops;
|
||||
|
||||
/**
|
||||
* @brief Write data to Flash.
|
||||
/** Non-OS flash access critical section functions
|
||||
*
|
||||
* @note This version of function is to be called from panic handler.
|
||||
* @note This version of functions is to be used when no OS is present or from panic handler.
|
||||
* It does not use any OS primitives and IPC and implies that
|
||||
* only calling CPU is active.
|
||||
|
||||
* @note If source address is in DROM, this function will return
|
||||
* ESP_ERR_INVALID_ARG.
|
||||
*
|
||||
* @param dest destination address in Flash. Must be a multiple of 4 bytes.
|
||||
* @param src pointer to the source buffer.
|
||||
* @param size length of data, in bytes. Must be a multiple of 4 bytes.
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t spi_flash_write_panic(size_t dest, const void *src, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read data from Flash.
|
||||
*
|
||||
* @note This version of function is to be called from panic handler.
|
||||
* It does not use any OS primitives and IPC and implies that
|
||||
* only calling CPU is active.
|
||||
*
|
||||
* @param src source address of the data in Flash.
|
||||
* @param dest pointer to the destination buffer
|
||||
* @param size length of data
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t spi_flash_read_panic(size_t src, void *dest, size_t size);
|
||||
extern const spi_flash_guard_funcs_t g_flash_guard_no_os_ops;
|
||||
|
||||
#if CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
|
||||
|
Reference in New Issue
Block a user