diff --git a/components/esp_system/panic.c b/components/esp_system/panic.c index ec46535d93..8e2f5be6ee 100644 --- a/components/esp_system/panic.c +++ b/components/esp_system/panic.c @@ -378,14 +378,8 @@ void esp_panic_handler(panic_info_t *info) } else { disable_all_wdts(); s_dumping_core = true; -#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH - esp_core_dump_to_flash(info); -#endif -#if CONFIG_ESP_COREDUMP_ENABLE_TO_UART && !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT - esp_core_dump_to_uart(info); -#endif + esp_core_dump_write(info); s_dumping_core = false; - esp_panic_handler_reconfigure_wdts(1000); } #endif /* CONFIG_ESP_COREDUMP_ENABLE */ diff --git a/components/espcoredump/Kconfig b/components/espcoredump/Kconfig index 27cb8f69a2..6f2896e719 100644 --- a/components/espcoredump/Kconfig +++ b/components/espcoredump/Kconfig @@ -96,9 +96,9 @@ menu "Core dump" int "Reserved stack size" depends on ESP_COREDUMP_ENABLE range 0 4096 if !ESP_COREDUMP_USE_STACK_SIZE - range 1280 4096 if ESP_COREDUMP_USE_STACK_SIZE + range 1792 4096 if ESP_COREDUMP_USE_STACK_SIZE default 0 if !ESP_COREDUMP_USE_STACK_SIZE - default 1280 if ESP_COREDUMP_USE_STACK_SIZE + default 1792 if ESP_COREDUMP_USE_STACK_SIZE help Size of the memory to be reserved for core dump stack. If 0 core dump process will run on the stack of crashed task/ISR, otherwise special stack will be allocated. diff --git a/components/espcoredump/include/esp_core_dump.h b/components/espcoredump/include/esp_core_dump.h index 04b69f47c9..0767de5336 100644 --- a/components/espcoredump/include/esp_core_dump.h +++ b/components/espcoredump/include/esp_core_dump.h @@ -47,51 +47,49 @@ typedef struct { */ void esp_core_dump_init(void); -/** - * @brief Saves core dump to flash. - * - * The structure of data stored in flash is as follows: - * - * | TOTAL_LEN | VERSION | TASKS_NUM | TCB_SIZE | - * | TCB_ADDR_1 | STACK_TOP_1 | STACK_END_1 | TCB_1 | STACK_1 | - * . . . . - * . . . . - * | TCB_ADDR_N | STACK_TOP_N | STACK_END_N | TCB_N | STACK_N | - * | CHECKSUM | - * - * Core dump in flash consists of header and data for every task in the system at the moment of crash. - * For flash data integrity, a checksum is used at the end of core the dump data. - * The structure of core dump data is described below in details. - * 1) Core dump starts with header: - * 1.1) TOTAL_LEN is total length of core dump data in flash including the checksum. Size is 4 bytes. - * 1.2) VERSION field keeps 4 byte version of core dump. - * 1.2) TASKS_NUM is the number of tasks for which data are stored. Size is 4 bytes. - * 1.3) TCB_SIZE is the size of task's TCB structure. Size is 4 bytes. - * 2) Core dump header is followed by the data for every task in the system. - * Task data are started with task header: - * 2.1) TCB_ADDR is the address of TCB in memory. Size is 4 bytes. - * 2.2) STACK_TOP is the top of task's stack (address of the topmost stack item). Size is 4 bytes. - * 2.2) STACK_END is the end of task's stack (address from which task's stack starts). Size is 4 bytes. - * 3) Task header is followed by TCB data. Size is TCB_SIZE bytes. - * 4) Task's stack is placed after TCB data. Size is (STACK_END - STACK_TOP) bytes. - * 5) The checksum is placed at the end of the data. - */ -void esp_core_dump_to_flash(panic_info_t *info); - -/** - * @brief Print base64-encoded core dump to UART. - * - * The structure of core dump data is the same as for data stored in flash (@see esp_core_dump_to_flash) with some notes: - * 1) The checksum is not present in core dump printed to UART. - * 2) Since checksum is omitted TOTAL_LEN does not include its size. - * 3) Printed base64 data are surrounded with special messages to help user recognize the start and end of actual data. - */ -void esp_core_dump_to_uart(panic_info_t *info); - /**************************************************************************************/ /*********************************** USER MODE API ************************************/ /**************************************************************************************/ +/** + * Core dump file consists of header and data (in binary or ELF format) for every task in the system at the moment of crash. + * For the data integrity, a checksum is used at the end of core the dump data. + * The structure of core dump file is described below in details. + * 1) Core dump starts with header: + * 1.1) TOTAL_LEN is total length of core dump data in flash including the checksum. Size is 4 bytes. + * 1.2) VERSION field keeps 4 byte version of core dump. + * 1.2) TASKS_NUM is the number of tasks for which data are stored. Size is 4 bytes. Unused in ELF format + * 1.3) TCB_SIZE is the size of task's TCB structure. Size is 4 bytes. Unused in ELF format + * 1.4) MEM_SEG_NUM is the number of memory segment. Size is 4 bytes. Unused in ELF format + * 1.5) CHIP_REV is the revision of the chip. Size is 4 bytes. + * 2) Core dump header is followed by the data for every task in the system. Data part is differs for the binary + * and elf formats. + * 2.1) The core dump file uses a subset of the ELF structures to store the crash information. + * Loadable ELF segments and ELF notes (ELF.PT_NOTE) used with a special name and type (CORE, NT_PRSTATUS type) + * 2.2) In Binary format task data are started with the task header: + * 2.2.1) TCB_ADDR is the address of TCB in memory. Size is 4 bytes. + * 2.2.2) STACK_TOP is the top of task's stack (address of the topmost stack item). Size is 4 bytes. + * 2.2.3) STACK_END is the end of task's stack (address from which task's stack starts). Size is 4 bytes. + * 2.2.4) Task header is followed by TCB data. Size is TCB_SIZE bytes. + * 2.2.5) Task's stack is placed after TCB data. Size is (STACK_END - STACK_TOP) bytes. + * 2.3) The checksum is placed at the end of the data. + * 3) The structure of the uart data is the same as the data stored in flash + * 3.1) Uart data is printed in base64 format surrounded with special messages to help user recognize the start and + * end of actual data. + * + * For more information about the implementation please check api-guides/core_dump_internals.rst + * + */ + +/** + * @brief Print/store coredump data to the selected destination uart or flash. + * + * @param info Pointer to the panic information. It contains the execution frame. + * + * @return ESP_OK on success, otherwise \see esp_err_t + */ +void esp_core_dump_write(panic_info_t *info); + /** * @brief Check integrity of coredump data in flash. * This function reads the coredump data while calculating their checksum. If it diff --git a/components/espcoredump/include_core_dump/core_dump_binary.h b/components/espcoredump/include_core_dump/core_dump_binary.h deleted file mode 100644 index 164162aaf6..0000000000 --- a/components/espcoredump/include_core_dump/core_dump_binary.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ESP_CORE_DUMP_BINARY_H_ -#define ESP_CORE_DUMP_BINARY_H_ - -#include "esp_core_dump_types.h" - -/** - * @brief Initiate the binary core dump generation. - * - * @param info Exception frame info generated when the panic occured. - * @param write_cfg Structure containing the callbacks that will be called to - * write the generated core dump file. - * - * @return ESP_OK on success, otherwise \see esp_err_t. - */ -esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg); - -#endif diff --git a/components/espcoredump/include_core_dump/core_dump_checksum.h b/components/espcoredump/include_core_dump/core_dump_checksum.h index 193fc012c3..34c63c791b 100644 --- a/components/espcoredump/include_core_dump/core_dump_checksum.h +++ b/components/espcoredump/include_core_dump/core_dump_checksum.h @@ -55,31 +55,31 @@ uint32_t esp_core_dump_elf_version(void); /** * @brief Initialize checksum calculation for the given context. * - * @param wr_data Core dump checksum context to fill. + * @param ctx Core dump checksum context to fill. */ -void esp_core_dump_checksum_init(void ** wr_data); +void esp_core_dump_checksum_init(void *ctx); /** * @brief Update checksum calculation by integrating the given data in the context. * - * @param wr_data Core dump checksum context. + * @param ctx Core dump checksum context. * @param data Pointer to the data to integrate in the checksum calculation. * This is usually the new data to write (or already written) on * the flash. */ -void esp_core_dump_checksum_update(void* wr_data, void* data, size_t data_len); +void esp_core_dump_checksum_update(void *ctx, void *data, size_t data_len); /** * @brief Terminate and return checksum calculated for the given context. * - * @param wr_data Core dump checksum context. + * @param ctx Core dump checksum context. * @param chs_ptr Pointer used to return the checksum calculated. It can be * NULL, in this case, it will be ignored but the correct size * of the checksum will be returned. * * @return The size, in bytes, of the checksum. */ -uint32_t esp_core_dump_checksum_finish(void* wr_data, core_dump_checksum_bytes* chs_ptr); +uint32_t esp_core_dump_checksum_finish(void *ctx, core_dump_checksum_bytes *chs_ptr); /** * @brief Return the size of the checksums. diff --git a/components/espcoredump/include_core_dump/core_dump_elf.h b/components/espcoredump/include_core_dump/core_dump_elf.h deleted file mode 100644 index 39bff0aaa7..0000000000 --- a/components/espcoredump/include_core_dump/core_dump_elf.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ESP_CORE_DUMP_ELF_H_ -#define ESP_CORE_DUMP_ELF_H_ - -#include "esp_core_dump_types.h" - -/** - * @brief Initiate the ELF core dump generation. - * - * @param info Exception frame info generated when the panic occured. - * @param write_cfg Structre containing the callbacks that will be called to - * write the generated core dump data. - * - * @return ESP_OK on success, otherwise \see esp_err_t. - */ -esp_err_t esp_core_dump_write_elf(core_dump_write_config_t *write_cfg); - -#endif diff --git a/components/espcoredump/include_core_dump/esp_core_dump_common.h b/components/espcoredump/include_core_dump/esp_core_dump_common.h index 1d569105be..1c978f4326 100644 --- a/components/espcoredump/include_core_dump/esp_core_dump_common.h +++ b/components/espcoredump/include_core_dump/esp_core_dump_common.h @@ -96,6 +96,46 @@ bool esp_core_dump_in_isr_context(void); uint32_t esp_core_dump_get_user_ram_size(void); +/** + * @brief Prints write start info string according to destination. + */ +void esp_core_dump_print_write_start(void); + +/** + * @brief Prints write end info string according to destination. + */ +void esp_core_dump_print_write_end(void); + +/** + * @brief Initializes the flash/UART hardware for data storage. + */ +esp_err_t esp_core_dump_write_init(void); + +/** + * @brief Prepares the flash/UART for data storage + */ +esp_err_t esp_core_dump_write_prepare(core_dump_write_data_t *wr_data, uint32_t *data_len); + +/** + * @brief Initiates the beginning of data writing. + */ +esp_err_t esp_core_dump_write_start(core_dump_write_data_t *wr_data); + +/** + * @brief Writes a data chunk to the flash/UART + */ +esp_err_t esp_core_dump_write_data(core_dump_write_data_t *wr_data, void *data, uint32_t data_len); + +/** + * @brief Finalizes the data writing process + */ +esp_err_t esp_core_dump_write_end(core_dump_write_data_t *wr_data); + +/** + * @brief Stores the core dump in either binary or ELF format. + */ +esp_err_t esp_core_dump_store(void); + /** * @brief Get TCB length, in bytes. * diff --git a/components/espcoredump/include_core_dump/esp_core_dump_types.h b/components/espcoredump/include_core_dump/esp_core_dump_types.h index 71a2242476..e74afd2d68 100644 --- a/components/espcoredump/include_core_dump/esp_core_dump_types.h +++ b/components/espcoredump/include_core_dump/esp_core_dump_types.h @@ -91,6 +91,39 @@ extern "C" { #error "Coredump cache size must be a multiple of 16" #endif +typedef uint32_t core_dump_crc_t; + +#if CONFIG_ESP_COREDUMP_CHECKSUM_CRC32 + +typedef struct { + core_dump_crc_t crc; + uint32_t total_bytes_checksum; /* Number of bytes used to calculate the checksum */ +} core_dump_crc_ctx_t; + +typedef core_dump_crc_ctx_t checksum_ctx_t; + +#else + +#if CONFIG_IDF_TARGET_ESP32 +#include "mbedtls/sha256.h" /* mbedtls_sha256_context */ +typedef mbedtls_sha256_context sha256_ctx_t; +#else +#include "hal/sha_types.h" /* SHA_CTX */ +typedef SHA_CTX sha256_ctx_t; +#endif + +#define COREDUMP_SHA256_LEN 32 + +typedef struct { + sha256_ctx_t ctx; + uint8_t result[COREDUMP_SHA256_LEN]; + uint32_t total_bytes_checksum; /* Number of bytes used to calculate the checksum */ +} core_dump_sha_ctx_t; + +typedef core_dump_sha_ctx_t checksum_ctx_t; + +#endif + /** * @brief Chip ID associated to this implementation. */ @@ -101,41 +134,9 @@ typedef struct _core_dump_write_data_t uint32_t off; /*!< Current offset of data being written */ uint8_t cached_data[COREDUMP_CACHE_SIZE]; /*!< Cache used to write to flash */ uint8_t cached_bytes; /*!< Number of bytes filled in the cached */ - void *checksum_ctx; /*!< Checksum context */ + checksum_ctx_t checksum_ctx; /*!< Checksum context */ } core_dump_write_data_t; -/** - * @brief Types below define the signatures of the callbacks that are used - * to output a core dump. The destination of the dump is implementation - * dependant. - */ -typedef esp_err_t (*esp_core_dump_write_prepare_t)(core_dump_write_data_t* priv, uint32_t *data_len); -typedef esp_err_t (*esp_core_dump_write_start_t)(core_dump_write_data_t* priv); -typedef esp_err_t (*esp_core_dump_write_end_t)(core_dump_write_data_t* priv); -typedef esp_err_t (*esp_core_dump_flash_write_data_t)(core_dump_write_data_t* priv, - void * data, - uint32_t data_len); - - -/** - * @brief Core dump emitter control structure. - * This structure contains the functions that are called in order to write - * the core dump to the destination (UART or flash). - * The function are called in this order: - * - prepare - * - start - * - write (called once or more) - * - end - */ -typedef struct _core_dump_write_config_t -{ - esp_core_dump_write_prepare_t prepare; /*!< Function called for sanity checks */ - esp_core_dump_write_start_t start; /*!< Function called at the beginning of data writing */ - esp_core_dump_flash_write_data_t write; /*!< Function called to write data chunk */ - esp_core_dump_write_end_t end; /*!< Function called once all data have been written */ - core_dump_write_data_t* priv; /*!< Private context to pass to every function of this structure */ -} core_dump_write_config_t; - /** * @brief Core dump data header * This header predecesses the actual core dump data (ELF or binary). */ @@ -174,17 +175,6 @@ typedef struct _core_dump_mem_seg_header_t uint32_t size; /*!< Memory region size */ } core_dump_mem_seg_header_t; -/** - * @brief Core dump flash init function - */ -void esp_core_dump_flash_init(void); - - -/** - * @brief Common core dump write function - */ -void esp_core_dump_write(panic_info_t *info, core_dump_write_config_t *write_cfg); - #ifdef __cplusplus } #endif diff --git a/components/espcoredump/src/core_dump_binary.c b/components/espcoredump/src/core_dump_binary.c index cdd2231f32..5b389d19d0 100644 --- a/components/espcoredump/src/core_dump_binary.c +++ b/components/espcoredump/src/core_dump_binary.c @@ -7,7 +7,6 @@ #include #include #include "sdkconfig.h" -#include "core_dump_binary.h" #include "esp_core_dump_port.h" #include "esp_core_dump_common.h" #include "hal/efuse_hal.h" @@ -16,9 +15,9 @@ const static char TAG[] __attribute__((unused)) = "esp_core_dump_binary"; +esp_err_t esp_core_dump_store(void) __attribute__((alias("esp_core_dump_write_binary"))); -static esp_err_t esp_core_dump_save_task(core_dump_write_config_t *write_cfg, - core_dump_task_header_t *task) +static esp_err_t esp_core_dump_save_task(core_dump_write_data_t *write_data, core_dump_task_header_t *task) { esp_err_t err = ESP_FAIL; uint32_t stk_vaddr = 0; @@ -28,19 +27,19 @@ static esp_err_t esp_core_dump_save_task(core_dump_write_config_t *write_cfg, stk_len = esp_core_dump_get_memory_len(stk_vaddr, stk_vaddr+stk_len); // Save memory segment header - err = write_cfg->write(write_cfg->priv, (void*)task, sizeof(core_dump_task_header_t)); + err = esp_core_dump_write_data(write_data, task, sizeof(core_dump_task_header_t)); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to write task header, error=%d!", err); return err; } // Save TCB block - err = write_cfg->write(write_cfg->priv, task->tcb_addr, esp_core_dump_get_tcb_len()); + err = esp_core_dump_write_data(write_data, task->tcb_addr, esp_core_dump_get_tcb_len()); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to write TCB, error=%d!", err); return err; } // Save task stack - err = write_cfg->write(write_cfg->priv, (void*)stk_paddr, stk_len); + err = esp_core_dump_write_data(write_data, (void *)stk_paddr, stk_len); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to write stack for task (TCB:%x), stack_start=%x, error=%d!", task->tcb_addr, @@ -49,12 +48,12 @@ static esp_err_t esp_core_dump_save_task(core_dump_write_config_t *write_cfg, return err; } - ESP_COREDUMP_LOG_PROCESS("Task (TCB:%x) dump is saved.", - task->tcb_addr); + ESP_COREDUMP_LOG_PROCESS("Task (TCB:%x) dump is saved.", task->tcb_addr); + return ESP_OK; } -static esp_err_t esp_core_dump_save_mem_segment(core_dump_write_config_t* write_cfg, +static esp_err_t esp_core_dump_save_mem_segment(core_dump_write_data_t* write_data, core_dump_mem_seg_header_t* seg) { esp_err_t err = ESP_FAIL; @@ -64,14 +63,14 @@ static esp_err_t esp_core_dump_save_mem_segment(core_dump_write_config_t* write_ seg->start, seg->size); return ESP_FAIL; } - // Save TCB address, stack base and stack top addr - err = write_cfg->write(write_cfg->priv, (void*)seg, sizeof(core_dump_mem_seg_header_t)); + // Save TCB address, stack base and stack top addrq + err = esp_core_dump_write_data(write_data, seg, sizeof(core_dump_mem_seg_header_t)); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to write memory segment header, error=%d!", err); return err; } // Save memory contents - err = write_cfg->write(write_cfg->priv, (void*)seg->start, seg->size); + err = esp_core_dump_write_data(write_data, (void *)seg->start, seg->size); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to write memory segment, (%x, %lu), error=%d!", seg->start, seg->size, err); @@ -82,18 +81,24 @@ static esp_err_t esp_core_dump_save_mem_segment(core_dump_write_config_t* write_ return ESP_OK; } -esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg) +static esp_err_t esp_core_dump_write_binary(void) { - esp_err_t err = ESP_OK; uint32_t tcb_sz = esp_core_dump_get_tcb_len(); uint32_t data_len = 0; uint32_t bad_tasks_num = 0; + core_dump_write_data_t write_data = { 0 }; core_dump_header_t hdr = { 0 }; core_dump_task_header_t task_hdr = { 0 }; core_dump_mem_seg_header_t mem_seg = { 0 }; TaskIterator_t task_iter; void *cur_task = NULL; + esp_err_t err = esp_core_dump_write_init(); + if (err != ESP_OK) { + ESP_COREDUMP_LOGE("Binary write init failed!"); + return ESP_FAIL; + } + // Verifies all tasks in the snapshot esp_core_dump_reset_tasks_snapshots_iter(); esp_core_dump_task_iterator_init(&task_iter); @@ -162,21 +167,17 @@ esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg) ESP_COREDUMP_LOG_PROCESS("Core dump length=%lu, tasks processed: %d, broken tasks: %d", data_len, hdr.tasks_num, bad_tasks_num); // Prepare write - if (write_cfg->prepare) { - err = write_cfg->prepare(write_cfg->priv, &data_len); - if (err != ESP_OK) { - ESP_COREDUMP_LOGE("Failed to prepare core dump, error=%d!", err); - return err; - } + err = esp_core_dump_write_prepare(&write_data, &data_len); + if (err != ESP_OK) { + ESP_COREDUMP_LOGE("Failed to prepare core dump, error=%d!", err); + return err; } // Write start - if (write_cfg->start) { - err = write_cfg->start(write_cfg->priv); - if (err != ESP_OK) { - ESP_COREDUMP_LOGE("Failed to start core dump, error=%d!", err); - return err; - } + err = esp_core_dump_write_start(&write_data); + if (err != ESP_OK) { + ESP_COREDUMP_LOGE("Failed to start core dump, error=%d!", err); + return err; } // Write header @@ -184,7 +185,7 @@ esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg) hdr.version = COREDUMP_VERSION_BIN_CURRENT; hdr.tcb_sz = tcb_sz; hdr.chip_rev = efuse_hal_chip_revision(); - err = write_cfg->write(write_cfg->priv, &hdr, sizeof(core_dump_header_t)); + err = esp_core_dump_write_data(&write_data, &hdr, sizeof(core_dump_header_t)); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to write core dump header error=%d!", err); return err; @@ -195,7 +196,7 @@ esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg) // Write first crashed task data first (not always first task in the snapshot) ESP_COREDUMP_LOGD("Save first crashed task %x", cur_task); if (esp_core_dump_get_task_snapshot(cur_task, &task_hdr, NULL)) { - err = esp_core_dump_save_task(write_cfg, &task_hdr); + err = esp_core_dump_save_task(&write_data, &task_hdr); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to save first crashed task %x, error=%d!", task_hdr.tcb_addr, err); @@ -212,8 +213,8 @@ esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg) continue; } ESP_COREDUMP_LOGD("Save task %x (TCB:%x, stack:%x..%x)", - task_iter.pxTaskHandle, task_hdr.tcb_addr, task_hdr.stack_start, task_hdr.stack_end); - err = esp_core_dump_save_task(write_cfg, &task_hdr); + task_iter.pxTaskHandle, task_hdr.tcb_addr, task_hdr.stack_start, task_hdr.stack_end); + err = esp_core_dump_save_task(&write_data, &task_hdr); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to save core dump task %x, error=%d!", task_hdr.tcb_addr, err); @@ -230,8 +231,8 @@ esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg) continue; if (mem_seg.size > 0) { ESP_COREDUMP_LOG_PROCESS("Save interrupted task stack %lu bytes @ %x", - mem_seg.size, mem_seg.start); - err = esp_core_dump_save_mem_segment(write_cfg, &mem_seg); + mem_seg.size, mem_seg.start); + err = esp_core_dump_save_mem_segment(&write_data, &mem_seg); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to save interrupted task stack, error=%d!", err); return err; @@ -254,8 +255,8 @@ esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg) mem_seg.start = start; mem_seg.size = esp_core_dump_get_memory_len(start, start + data_sz);; ESP_COREDUMP_LOG_PROCESS("Save user memory region %lu bytes @ %x", - mem_seg.size, mem_seg.start); - err = esp_core_dump_save_mem_segment(write_cfg, &mem_seg); + mem_seg.size, mem_seg.start); + err = esp_core_dump_save_mem_segment(&write_data, &mem_seg); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to save user memory region, error=%d!", err); return err; @@ -265,13 +266,12 @@ esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg) } // Write end - if (write_cfg->end) { - err = write_cfg->end(write_cfg->priv); - if (err != ESP_OK) { - ESP_COREDUMP_LOGE("Failed to end core dump error=%d!", err); - return err; - } + err = esp_core_dump_write_end(&write_data); + if (err != ESP_OK) { + ESP_COREDUMP_LOGE("Failed to end core dump error=%d!", err); + return err; } + if (bad_tasks_num) { ESP_COREDUMP_LOGE("Found %d broken tasks!", bad_tasks_num); } diff --git a/components/espcoredump/src/core_dump_common.c b/components/espcoredump/src/core_dump_common.c index 6f0b4606b4..a1c6aff389 100644 --- a/components/espcoredump/src/core_dump_common.c +++ b/components/espcoredump/src/core_dump_common.c @@ -12,8 +12,6 @@ #include "esp_rom_sys.h" #include "esp_core_dump_port.h" #include "esp_core_dump_common.h" -#include "core_dump_elf.h" -#include "core_dump_binary.h" const static char TAG[] __attribute__((unused)) = "esp_core_dump_common"; @@ -145,26 +143,19 @@ FORCE_INLINE_ATTR void esp_core_dump_report_stack_usage(void) static void* s_exc_frame = NULL; -inline void esp_core_dump_write(panic_info_t *info, core_dump_write_config_t *write_cfg) +inline static void esp_core_dump_write_internal(panic_info_t *info) { -#ifndef CONFIG_ESP_COREDUMP_ENABLE_TO_NONE - esp_err_t err = ESP_ERR_NOT_SUPPORTED; - s_exc_frame = (void*) info->frame; - bool isr_context = esp_core_dump_in_isr_context(); + s_exc_frame = (void *)info->frame; + esp_core_dump_setup_stack(); esp_core_dump_port_init(info, isr_context); -#if CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN - err = esp_core_dump_write_binary(write_cfg); -#elif CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF - err = esp_core_dump_write_elf(write_cfg); -#endif + esp_err_t err = esp_core_dump_store(); if (err != ESP_OK) { - ESP_COREDUMP_LOGE("Core dump write binary failed with error=%d", err); + ESP_COREDUMP_LOGE("Core dump write failed with error=%d", err); } esp_core_dump_report_stack_usage(); -#endif } void __attribute__((weak)) esp_core_dump_init(void) @@ -314,4 +305,15 @@ inline bool esp_core_dump_in_isr_context(void) #endif // CONFIG_ESP_TASK_WDT_EN } +void esp_core_dump_write(panic_info_t *info) +{ +#if CONFIG_ESP_COREDUMP_ENABLE_TO_UART && CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT + return; +#endif + + esp_core_dump_print_write_start(); + esp_core_dump_write_internal(info); + esp_core_dump_print_write_end(); +} + #endif diff --git a/components/espcoredump/src/core_dump_crc.c b/components/espcoredump/src/core_dump_crc.c index 746458b8fb..ecf7ca5531 100644 --- a/components/espcoredump/src/core_dump_crc.c +++ b/components/espcoredump/src/core_dump_crc.c @@ -13,16 +13,7 @@ const static char TAG[] __attribute__((unused)) = "esp_core_dump_crc"; -typedef uint32_t core_dump_crc_t; - -typedef struct { - core_dump_crc_t crc; - uint32_t total_bytes_checksum; /* Number of bytes used to calculate the checksum */ -} core_dump_crc_ctx_t; - -static core_dump_crc_ctx_t s_core_dump_crc_ctx = { 0 }; - -void esp_core_dump_checksum_init(core_dump_checksum_ctx *out_ctx) __attribute__((alias("core_dump_crc_init"))); +void esp_core_dump_checksum_init(core_dump_checksum_ctx cks_ctx) __attribute__((alias("core_dump_crc_init"))); void esp_core_dump_checksum_update(core_dump_checksum_ctx cks_ctx, void* data, size_t data_len) __attribute__((alias("core_dump_crc_update"))); uint32_t esp_core_dump_checksum_finish(core_dump_checksum_ctx cks_ctx, core_dump_checksum_bytes* chs_ptr) __attribute__((alias("core_dump_crc_finish"))); void esp_core_dump_print_checksum(const char* msg, core_dump_checksum_bytes checksum) __attribute__((alias("core_dump_crc_print"))); @@ -49,12 +40,12 @@ static uint32_t core_dump_crc_version(void) return COREDUMP_VERSION_ELF_CRC32; } -static void core_dump_crc_init(core_dump_checksum_ctx *out_ctx) +static void core_dump_crc_init(core_dump_checksum_ctx cks_ctx) { - if (out_ctx) { - s_core_dump_crc_ctx.crc = 0; - s_core_dump_crc_ctx.total_bytes_checksum = 0; - *out_ctx = &s_core_dump_crc_ctx; + if (cks_ctx) { + core_dump_crc_ctx_t *crc_ctx = cks_ctx; + crc_ctx->crc = 0; + crc_ctx->total_bytes_checksum = 0; } } diff --git a/components/espcoredump/src/core_dump_elf.c b/components/espcoredump/src/core_dump_elf.c index b1fec4d48f..c82108af6b 100644 --- a/components/espcoredump/src/core_dump_elf.c +++ b/components/espcoredump/src/core_dump_elf.c @@ -9,7 +9,6 @@ #include "esp_flash_encrypt.h" #include "sdkconfig.h" #include "core_dump_checksum.h" -#include "core_dump_elf.h" #include "esp_core_dump_port.h" #include "esp_core_dump_port_impl.h" #include "esp_core_dump_common.h" @@ -84,7 +83,7 @@ typedef struct _core_dump_elf_t uint16_t elf_stage; uint32_t elf_next_data_offset; uint16_t segs_count; - core_dump_write_config_t * write_cfg; + core_dump_write_data_t write_data; uint32_t note_data_size; /* can be used where static storage needed */ } core_dump_elf_t; @@ -103,6 +102,8 @@ typedef struct { #endif #define ALIGN_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) +esp_err_t esp_core_dump_store(void) __attribute__((alias("esp_core_dump_write_elf"))); + // Builds elf header and check all data offsets static int elf_write_file_header(core_dump_elf_t *self, uint32_t seg_count) { @@ -135,7 +136,7 @@ static int elf_write_file_header(core_dump_elf_t *self, uint32_t seg_count) elf_hdr.e_shnum = 0; // initial section counter is 0 elf_hdr.e_shstrndx = SHN_UNDEF; // do not use string table // write built elf header into elf image - esp_err_t err = self->write_cfg->write(self->write_cfg->priv, (void*)&elf_hdr, sizeof(elf_hdr)); + esp_err_t err = esp_core_dump_write_data(&self->write_data, &elf_hdr, sizeof(elf_hdr)); ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF header failure (%d)", err); ESP_COREDUMP_LOG_PROCESS("Add file header %u bytes", sizeof(elf_hdr)); @@ -151,7 +152,7 @@ static int elf_write_segment_header(core_dump_elf_t *self, elf_phdr* phdr) phdr->p_offset = self->elf_next_data_offset; // set segment data information and write it into image - esp_err_t err = self->write_cfg->write(self->write_cfg->priv, (void*)phdr, sizeof(elf_phdr)); + esp_err_t err = esp_core_dump_write_data(&self->write_data, phdr, sizeof(elf_phdr)); ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF segment header failure (%d)", err); ESP_COREDUMP_LOG_PROCESS("Add segment header %u bytes: type %d, sz %u, off = 0x%x", @@ -192,7 +193,7 @@ static int elf_add_segment(core_dump_elf_t *self, (uint32_t)data_len, self->elf_next_data_offset); // write segment data only when write function is set and phdr = NULL // write data into segment - err = self->write_cfg->write(self->write_cfg->priv, data, (uint32_t)data_len); + err = esp_core_dump_write_data(&self->write_data, data, (uint32_t)data_len); ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF segment data failure (%d)", err); self->elf_next_data_offset += data_len; @@ -211,11 +212,11 @@ static int elf_write_note_header(core_dump_elf_t *self, note_hdr.n_descsz = data_sz; note_hdr.n_type = type; // write note header - esp_err_t err = self->write_cfg->write(self->write_cfg->priv, ¬e_hdr, sizeof(note_hdr)); + esp_err_t err = esp_core_dump_write_data(&self->write_data, ¬e_hdr, sizeof(note_hdr)); ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note header failure (%d)", err); // write note name - err = self->write_cfg->write(self->write_cfg->priv, name_buffer, name_len); + err = esp_core_dump_write_data(&self->write_data, name_buffer, name_len); ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note name failure (%d)", err); @@ -247,13 +248,13 @@ static int elf_write_note(core_dump_elf_t *self, // note data must be aligned in memory. we write aligned byte structures and panic details in strings, // which might not be aligned by default. Therefore, we need to verify alignment and add padding if necessary. - err = self->write_cfg->write(self->write_cfg->priv, data, data_sz); + err = esp_core_dump_write_data(&self->write_data, data, data_sz); if (err == ESP_OK) { int pad_size = data_len - data_sz; if (pad_size != 0) { uint8_t pad_bytes[3] = {0}; ESP_COREDUMP_LOG_PROCESS("Core dump note data needs %d bytes padding", pad_size); - err = self->write_cfg->write(self->write_cfg->priv, pad_bytes, pad_size); + err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size); } } @@ -533,7 +534,7 @@ static void elf_write_core_dump_note_cb(void *opaque, const char *data) param->total_size += data_len; if (!param->size_only) { - esp_err_t err = self->write_cfg->write(self->write_cfg->priv, (void *)data, data_len); + esp_err_t err = esp_core_dump_write_data(&self->write_data, (void *)data, data_len); if (err != ESP_OK) { param->total_size = 0; } @@ -571,7 +572,7 @@ static int elf_add_wdt_panic_details(core_dump_elf_t *self) uint8_t pad_bytes[3] = {0}; uint32_t pad_size = 4 - mod; ESP_COREDUMP_LOG_PROCESS("Core dump note needs %d bytes padding", pad_size); - err = self->write_cfg->write(self->write_cfg->priv, pad_bytes, pad_size); + err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size); ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note padding failure (%d)", err); } } @@ -670,17 +671,18 @@ static int esp_core_dump_do_write_elf_pass(core_dump_elf_t *self) return tot_len; } -esp_err_t esp_core_dump_write_elf(core_dump_write_config_t *write_cfg) +static esp_err_t esp_core_dump_write_elf(void) { - static core_dump_elf_t self = { 0 }; - static core_dump_header_t dump_hdr = { 0 }; - esp_err_t err = ESP_OK; + core_dump_elf_t self = { 0 }; + core_dump_header_t dump_hdr = { 0 }; int tot_len = sizeof(dump_hdr); int write_len = sizeof(dump_hdr); - ELF_CHECK_ERR((write_cfg), ESP_ERR_INVALID_ARG, "Invalid input data."); - - self.write_cfg = write_cfg; + esp_err_t err = esp_core_dump_write_init(); + if (err != ESP_OK) { + ESP_COREDUMP_LOGE("Elf write init failed!"); + return ESP_FAIL; + } // On first pass (do not write actual data), but calculate data length needed to allocate memory self.elf_stage = ELF_STAGE_CALC_SPACE; @@ -692,21 +694,17 @@ esp_err_t esp_core_dump_write_elf(core_dump_write_config_t *write_cfg) ESP_COREDUMP_LOG_PROCESS("============== Data size = %d bytes ============", tot_len); // Prepare write elf - if (write_cfg->prepare) { - err = write_cfg->prepare(write_cfg->priv, (uint32_t*)&tot_len); - if (err != ESP_OK) { - ESP_COREDUMP_LOGE("Failed to prepare core dump storage (%d)!", err); - return err; - } + err = esp_core_dump_write_prepare(&self.write_data, (uint32_t*)&tot_len); + if (err != ESP_OK) { + ESP_COREDUMP_LOGE("Failed to prepare core dump storage (%d)!", err); + return err; } // Write start - if (write_cfg->start) { - err = write_cfg->start(write_cfg->priv); - if (err != ESP_OK) { - ESP_COREDUMP_LOGE("Failed to start core dump (%d)!", err); - return err; - } + err = esp_core_dump_write_start(&self.write_data); + if (err != ESP_OK) { + ESP_COREDUMP_LOGE("Failed to start core dump (%d)!", err); + return err; } // Write core dump header @@ -716,9 +714,7 @@ esp_err_t esp_core_dump_write_elf(core_dump_write_config_t *write_cfg) dump_hdr.tcb_sz = 0; // unused in ELF format dump_hdr.mem_segs_num = 0; // unused in ELF format dump_hdr.chip_rev = efuse_hal_chip_revision(); - err = write_cfg->write(write_cfg->priv, - (void*)&dump_hdr, - sizeof(core_dump_header_t)); + err = esp_core_dump_write_data(&self.write_data, &dump_hdr, sizeof(core_dump_header_t)); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Failed to write core dump header (%d)!", err); return err; @@ -741,13 +737,11 @@ esp_err_t esp_core_dump_write_elf(core_dump_write_config_t *write_cfg) ESP_COREDUMP_LOG_PROCESS("=========== Data written size = %d bytes ==========", write_len); // Write end, update checksum - if (write_cfg->end) { - err = write_cfg->end(write_cfg->priv); - if (err != ESP_OK) { - ESP_COREDUMP_LOGE("Failed to end core dump (%d)!", err); - return err; - } + err = esp_core_dump_write_end(&self.write_data); + if (err != ESP_OK) { + ESP_COREDUMP_LOGE("Failed to end core dump (%d)!", err); } + return err; } diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index f6279d6e31..b6194f83c5 100644 --- a/components/espcoredump/src/core_dump_flash.c +++ b/components/espcoredump/src/core_dump_flash.c @@ -29,10 +29,7 @@ typedef struct _core_dump_partition_t bool encrypted; } core_dump_partition_t; -typedef uint32_t core_dump_crc_t; - -typedef struct _core_dump_flash_config_t -{ +typedef struct _core_dump_flash_config_t { /* Core dump partition config. */ core_dump_partition_t partition; /* CRC of core dump partition config. */ @@ -42,6 +39,14 @@ typedef struct _core_dump_flash_config_t /* Core dump flash data. */ static core_dump_flash_config_t s_core_flash_config; +void esp_core_dump_print_write_start(void) __attribute__((alias("esp_core_dump_flash_print_write_start"))); +void esp_core_dump_print_write_end(void) __attribute__((alias("esp_core_dump_flash_print_write_end"))); +esp_err_t esp_core_dump_write_init(void) __attribute__((alias("esp_core_dump_flash_hw_init"))); +esp_err_t esp_core_dump_write_prepare(core_dump_write_data_t *wr_data, uint32_t *data_len) __attribute__((alias("esp_core_dump_flash_write_prepare"))); +esp_err_t esp_core_dump_write_start(core_dump_write_data_t *wr_data) __attribute__((alias("esp_core_dump_flash_write_start"))); +esp_err_t esp_core_dump_write_end(core_dump_write_data_t *wr_data) __attribute__((alias("esp_core_dump_flash_write_end"))); +esp_err_t esp_core_dump_write_data(core_dump_write_data_t *wr_data, void *data, uint32_t data_len) __attribute__((alias("esp_core_dump_flash_write_data"))); + #define ESP_COREDUMP_FLASH_WRITE(_off_, _data_, _len_) esp_flash_write(esp_flash_default_chip, _data_, _off_, _len_) #define ESP_COREDUMP_FLASH_WRITE_ENCRYPTED(_off_, _data_, _len_) esp_flash_write_encrypted(esp_flash_default_chip, _off_, _data_, _len_) #define ESP_COREDUMP_FLASH_ERASE(_off_, _len_) esp_flash_erase_region(esp_flash_default_chip, _off_, _len_) @@ -49,6 +54,16 @@ static core_dump_flash_config_t s_core_flash_config; esp_err_t esp_core_dump_image_check(void); static esp_err_t esp_core_dump_partition_and_size_get(const esp_partition_t **partition, uint32_t* size); +static void esp_core_dump_flash_print_write_start(void) +{ + ESP_COREDUMP_LOGI("Save core dump to flash..."); +} + +static void esp_core_dump_flash_print_write_end(void) +{ + ESP_COREDUMP_LOGI("Core dump has been saved to flash."); +} + static esp_err_t esp_core_dump_flash_custom_write(uint32_t address, const void *buffer, uint32_t length) { esp_err_t err = ESP_OK; @@ -67,7 +82,35 @@ static inline core_dump_crc_t esp_core_dump_calc_flash_config_crc(void) return esp_rom_crc32_le(0, (uint8_t const *)&s_core_flash_config.partition, sizeof(s_core_flash_config.partition)); } -void esp_core_dump_flash_init(void) +static esp_err_t esp_core_dump_flash_hw_init(void) +{ + /* Check core dump partition configuration. */ + core_dump_crc_t crc = esp_core_dump_calc_flash_config_crc(); + if (s_core_flash_config.partition_config_crc != crc) { + ESP_COREDUMP_LOGE("Core dump flash config is corrupted! CRC=0x%x instead of 0x%x", crc, s_core_flash_config.partition_config_crc); + return ESP_FAIL; + } + + /* Make sure that the partition can at least hold the data length. */ + if (s_core_flash_config.partition.start == 0 || s_core_flash_config.partition.size < sizeof(uint32_t)) { + ESP_COREDUMP_LOGE("Invalid flash partition config!"); + return ESP_FAIL; + } + +#if CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE + if (!s_core_flash_config.partition.empty) { + ESP_COREDUMP_LOGW("Core dump already exists in flash, will not overwrite it with a new core dump"); + return ESP_FAIL; + } +#endif + + /* Initialize non-OS flash access critical section. */ + spi_flash_guard_set(&g_flash_guard_no_os_ops); + esp_flash_app_disable_protect(true); + return ESP_OK; +} + +static void esp_core_dump_partition_init(void) { const esp_partition_t *core_part = NULL; @@ -89,9 +132,8 @@ void esp_core_dump_flash_init(void) } } -static esp_err_t esp_core_dump_flash_write_data(core_dump_write_data_t* priv, uint8_t* data, uint32_t data_size) +static esp_err_t esp_core_dump_flash_write_data(core_dump_write_data_t* wr_data, uint8_t* data, uint32_t data_size) { - core_dump_write_data_t *wr_data = (core_dump_write_data_t *)priv; esp_err_t err = ESP_OK; uint32_t written = 0; uint32_t wr_sz = 0; @@ -126,7 +168,7 @@ static esp_err_t esp_core_dump_flash_write_data(core_dump_write_data_t* priv, ui wr_data->off += COREDUMP_CACHE_SIZE; /* Update checksum with the newly written data on the flash. */ - esp_core_dump_checksum_update(wr_data->checksum_ctx, &wr_data->cached_data, COREDUMP_CACHE_SIZE); + esp_core_dump_checksum_update(&wr_data->checksum_ctx, &wr_data->cached_data, COREDUMP_CACHE_SIZE); /* Reset cache from the next use. */ wr_data->cached_bytes = 0; @@ -164,7 +206,7 @@ static esp_err_t esp_core_dump_flash_write_data(core_dump_write_data_t* priv, ui } /* Update the checksum with the newly written bytes */ - esp_core_dump_checksum_update(wr_data->checksum_ctx, data + written, wr_sz); + esp_core_dump_checksum_update(&wr_data->checksum_ctx, data + written, wr_sz); wr_data->off += wr_sz; written += wr_sz; data_size -= wr_sz; @@ -181,9 +223,8 @@ static esp_err_t esp_core_dump_flash_write_data(core_dump_write_data_t* priv, ui return ESP_OK; } -static esp_err_t esp_core_dump_flash_write_prepare(core_dump_write_data_t *priv, uint32_t *data_len) +static esp_err_t esp_core_dump_flash_write_prepare(core_dump_write_data_t *wr_data, uint32_t *data_len) { - core_dump_write_data_t *wr_data = (core_dump_write_data_t *)priv; esp_err_t err = ESP_OK; uint32_t sec_num = 0; uint32_t cs_len = 0; @@ -233,19 +274,17 @@ static esp_err_t esp_core_dump_flash_write_prepare(core_dump_write_data_t *priv, return err; } -static esp_err_t esp_core_dump_flash_write_start(core_dump_write_data_t* priv) +static esp_err_t esp_core_dump_flash_write_start(core_dump_write_data_t *wr_data) { - core_dump_write_data_t *wr_data = (core_dump_write_data_t *)priv; esp_core_dump_checksum_init(&wr_data->checksum_ctx); return ESP_OK; } -static esp_err_t esp_core_dump_flash_write_end(core_dump_write_data_t* priv) +static esp_err_t esp_core_dump_flash_write_end(core_dump_write_data_t *wr_data) { esp_err_t err = ESP_OK; core_dump_checksum_bytes checksum = NULL; uint32_t cs_len = 0; - core_dump_write_data_t *wr_data = (core_dump_write_data_t *)priv; /* Get the size, in bytes of the checksum. */ cs_len = esp_core_dump_checksum_size(); @@ -262,14 +301,14 @@ static esp_err_t esp_core_dump_flash_write_end(core_dump_write_data_t* priv) } /* Update the checksum with the data written, including the padding. */ - esp_core_dump_checksum_update(wr_data->checksum_ctx, wr_data->cached_data, COREDUMP_CACHE_SIZE); + esp_core_dump_checksum_update(&wr_data->checksum_ctx, wr_data->cached_data, COREDUMP_CACHE_SIZE); wr_data->off += COREDUMP_CACHE_SIZE; wr_data->cached_bytes = 0; } /* All data have been written to the flash, the cache is now empty, we can * terminate the checksum calculation. */ - esp_core_dump_checksum_finish(wr_data->checksum_ctx, &checksum); + esp_core_dump_checksum_finish(&wr_data->checksum_ctx, &checksum); /* Use the cache to write the checksum if its size doesn't match the requirements. * (e.g. its size is not a multiple of 32) */ @@ -300,43 +339,9 @@ static esp_err_t esp_core_dump_flash_write_end(core_dump_write_data_t* priv) return err; } -void esp_core_dump_to_flash(panic_info_t *info) -{ - static core_dump_write_config_t wr_cfg = { 0 }; - static core_dump_write_data_t wr_data = { 0 }; - - /* Check core dump partition configuration. */ - core_dump_crc_t crc = esp_core_dump_calc_flash_config_crc(); - if (s_core_flash_config.partition_config_crc != crc) { - ESP_COREDUMP_LOGE("Core dump flash config is corrupted! CRC=0x%x instead of 0x%x", crc, s_core_flash_config.partition_config_crc); - return; - } - - /* Make sure that the partition can at least hold the data length. */ - if (s_core_flash_config.partition.start == 0 || s_core_flash_config.partition.size < sizeof(uint32_t)) { - ESP_COREDUMP_LOGE("Invalid flash partition config!"); - return; - } - - /* Initialize non-OS flash access critical section. */ - spi_flash_guard_set(&g_flash_guard_no_os_ops); - esp_flash_app_disable_protect(true); - - /* Register the callbacks that will be called later by the generic part. */ - wr_cfg.prepare = esp_core_dump_flash_write_prepare; - wr_cfg.start = esp_core_dump_flash_write_start; - wr_cfg.end = esp_core_dump_flash_write_end; - wr_cfg.write = (esp_core_dump_flash_write_data_t) esp_core_dump_flash_write_data; - wr_cfg.priv = &wr_data; - - ESP_COREDUMP_LOGI("Save core dump to flash..."); - esp_core_dump_write(info, &wr_cfg); - ESP_COREDUMP_LOGI("Core dump has been saved to flash."); -} - void esp_core_dump_init(void) { - esp_core_dump_flash_init(); + esp_core_dump_partition_init(); #if CONFIG_ESP_COREDUMP_CHECK_BOOT const esp_partition_t *partition = 0; @@ -392,7 +397,7 @@ esp_err_t esp_core_dump_image_check(void) } /* Update the checksum according to what was just read. */ - esp_core_dump_checksum_update(wr_data.checksum_ctx, wr_data.cached_data, toread); + esp_core_dump_checksum_update(&wr_data.checksum_ctx, wr_data.cached_data, toread); /* Move the offset forward and decrease the remaining size. */ offset += toread; @@ -400,7 +405,7 @@ esp_err_t esp_core_dump_image_check(void) } /* The coredump has been totally read, finish the checksum calculation. */ - esp_core_dump_checksum_finish(wr_data.checksum_ctx, &checksum_calc); + esp_core_dump_checksum_finish(&wr_data.checksum_ctx, &checksum_calc); /* Read the checksum from the flash and compare to the one just * calculated. */ diff --git a/components/espcoredump/src/core_dump_sha.c b/components/espcoredump/src/core_dump_sha.c index 834abcb2d9..5de67eaa56 100644 --- a/components/espcoredump/src/core_dump_sha.c +++ b/components/espcoredump/src/core_dump_sha.c @@ -10,29 +10,10 @@ #include #include "esp_core_dump_types.h" -#if CONFIG_IDF_TARGET_ESP32 -#include "mbedtls/sha256.h" /* mbedtls_sha256_context */ -#else -#include "hal/sha_types.h" /* SHA_CTX */ -#endif const static char TAG[] __attribute__((unused)) = "esp_core_dump_sha"; -#define COREDUMP_SHA256_LEN 32 - -typedef struct { -#if CONFIG_IDF_TARGET_ESP32 - mbedtls_sha256_context ctx; -#else - SHA_CTX ctx; -#endif - uint8_t result[COREDUMP_SHA256_LEN]; - uint32_t total_bytes_checksum; /* Number of bytes used to calculate the checksum */ -} core_dump_sha_ctx_t; - -static core_dump_sha_ctx_t s_core_dump_sha_ctx = { 0 }; - -void esp_core_dump_checksum_init(core_dump_checksum_ctx *cks_ctx) __attribute__((alias("core_dump_sha_init"))); +void esp_core_dump_checksum_init(core_dump_checksum_ctx cks_ctx) __attribute__((alias("core_dump_sha_init"))); void esp_core_dump_checksum_update(core_dump_checksum_ctx cks_ctx, void* data, size_t data_len) __attribute__((alias("core_dump_sha_update"))); uint32_t esp_core_dump_checksum_finish(core_dump_checksum_ctx cks_ctx, core_dump_checksum_bytes* chs_ptr) __attribute__((alias("core_dump_sha_finish"))); void esp_core_dump_print_checksum(const char* msg, core_dump_checksum_bytes checksum) __attribute__((alias("core_dump_sha256_print"))); @@ -107,12 +88,12 @@ static uint32_t core_dump_sha_version(void) return COREDUMP_VERSION_ELF_SHA256; } -static void core_dump_sha_init(core_dump_checksum_ctx *out_ctx) +static void core_dump_sha_init(core_dump_checksum_ctx cks_ctx) { - if (out_ctx) { - core_dump_sha256_start(&s_core_dump_sha_ctx); - s_core_dump_sha_ctx.total_bytes_checksum = 0; - *out_ctx = &s_core_dump_sha_ctx; + if (cks_ctx) { + core_dump_sha_ctx_t *sha_ctx = cks_ctx; + core_dump_sha256_start(sha_ctx); + sha_ctx->total_bytes_checksum = 0; } } diff --git a/components/espcoredump/src/core_dump_uart.c b/components/espcoredump/src/core_dump_uart.c index c5bce534d5..32e3ceeb2d 100644 --- a/components/espcoredump/src/core_dump_uart.c +++ b/components/espcoredump/src/core_dump_uart.c @@ -17,6 +17,14 @@ const static char TAG[] __attribute__((unused)) = "esp_core_dump_uart"; #if CONFIG_ESP_COREDUMP_ENABLE_TO_UART +void esp_core_dump_print_write_start(void) __attribute__((alias("esp_core_dump_uart_print_write_start"))); +void esp_core_dump_print_write_end(void) __attribute__((alias("esp_core_dump_uart_print_write_end"))); +esp_err_t esp_core_dump_write_init(void) __attribute__((alias("esp_core_dump_uart_hw_init"))); +esp_err_t esp_core_dump_write_prepare(core_dump_write_data_t *wr_data, uint32_t *data_len) __attribute__((alias("esp_core_dump_uart_write_prepare"))); +esp_err_t esp_core_dump_write_start(core_dump_write_data_t *wr_data) __attribute__((alias("esp_core_dump_uart_write_start"))); +esp_err_t esp_core_dump_write_end(core_dump_write_data_t *wr_data) __attribute__((alias("esp_core_dump_uart_write_end"))); +esp_err_t esp_core_dump_write_data(core_dump_write_data_t *wr_data, void *data, uint32_t data_len) __attribute__((alias("esp_core_dump_uart_write_data"))); + /* This function exists on every board, thus, we don't need to specify * explicitly the header for each board. */ int esp_clk_cpu_freq(void); @@ -46,32 +54,40 @@ static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8 dst[j++] = '\0'; } -static esp_err_t esp_core_dump_uart_write_start(core_dump_write_data_t *priv) +static void esp_core_dump_uart_print_write_start(void) +{ + ESP_COREDUMP_LOGI("Print core dump to uart..."); +} + +static void esp_core_dump_uart_print_write_end(void) +{ + ESP_COREDUMP_LOGI("Core dump has been written to uart."); +} + +static esp_err_t esp_core_dump_uart_write_start(core_dump_write_data_t *wr_data) { esp_err_t err = ESP_OK; - core_dump_write_data_t *wr_data = (core_dump_write_data_t *)priv; - ESP_COREDUMP_ASSERT(priv != NULL); + ESP_COREDUMP_ASSERT(wr_data != NULL); esp_core_dump_checksum_init(&wr_data->checksum_ctx); ESP_COREDUMP_PRINT("================= CORE DUMP START =================\r\n"); return err; } -static esp_err_t esp_core_dump_uart_write_prepare(core_dump_write_data_t *priv, uint32_t *data_len) +static esp_err_t esp_core_dump_uart_write_prepare(core_dump_write_data_t *wr_data, uint32_t *data_len) { ESP_COREDUMP_ASSERT(data_len != NULL); *data_len += esp_core_dump_checksum_size(); return ESP_OK; } -static esp_err_t esp_core_dump_uart_write_end(core_dump_write_data_t *priv) +static esp_err_t esp_core_dump_uart_write_end(core_dump_write_data_t *wr_data) { esp_err_t err = ESP_OK; char buf[64 + 4] = { 0 }; core_dump_checksum_bytes cs_addr = NULL; - core_dump_write_data_t *wr_data = (core_dump_write_data_t *)priv; if (wr_data) { - size_t cs_len = esp_core_dump_checksum_finish(wr_data->checksum_ctx, &cs_addr); + size_t cs_len = esp_core_dump_checksum_finish(&wr_data->checksum_ctx, &cs_addr); wr_data->off += cs_len; esp_core_dump_b64_encode((const uint8_t *)cs_addr, cs_len, (uint8_t*)&buf[0]); ESP_COREDUMP_PRINT("%s\r\n", buf); @@ -85,13 +101,12 @@ static esp_err_t esp_core_dump_uart_write_end(core_dump_write_data_t *priv) return err; } -static esp_err_t esp_core_dump_uart_write_data(core_dump_write_data_t *priv, void * data, uint32_t data_len) +static esp_err_t esp_core_dump_uart_write_data(core_dump_write_data_t *wr_data, void * data, uint32_t data_len) { esp_err_t err = ESP_OK; char buf[64 + 4] = { 0 }; char *addr = data; char *end = addr + data_len; - core_dump_write_data_t *wr_data = (core_dump_write_data_t *)priv; ESP_COREDUMP_ASSERT(data != NULL); @@ -108,7 +123,7 @@ static esp_err_t esp_core_dump_uart_write_data(core_dump_write_data_t *priv, voi if (wr_data) { wr_data->off += data_len; - esp_core_dump_checksum_update(wr_data->checksum_ctx, data, data_len); + esp_core_dump_checksum_update(&wr_data->checksum_ctx, data, data_len); } return err; } @@ -122,16 +137,8 @@ static int esp_core_dump_uart_get_char(void) { return i; } -void esp_core_dump_to_uart(panic_info_t *info) +static esp_err_t esp_core_dump_uart_hw_init(void) { - core_dump_write_data_t wr_data = { 0 }; - core_dump_write_config_t wr_cfg = { - .prepare = esp_core_dump_uart_write_prepare, - .start = esp_core_dump_uart_write_start, - .end = esp_core_dump_uart_write_end, - .write = esp_core_dump_uart_write_data, - .priv = (void*)&wr_data - }; uint32_t tm_end = 0; uint32_t tm_cur = 0; int ch = 0; @@ -158,9 +165,8 @@ void esp_core_dump_to_uart(panic_info_t *info) } ch = esp_core_dump_uart_get_char(); } - ESP_COREDUMP_LOGI("Print core dump to uart..."); - esp_core_dump_write(info, &wr_cfg); - ESP_COREDUMP_LOGI("Core dump has been written to uart."); + + return ESP_OK; } void esp_core_dump_init(void)