esp32: Replaces magic numbers with CRC for core dump in flash

This commit is contained in:
Alexey Gerenkov 2017-09-13 21:30:48 +03:00 committed by bot
parent 8b5f61eb35
commit a55cc99f50
8 changed files with 90 additions and 91 deletions

View file

@ -306,13 +306,6 @@ config ESP32_CORE_DUMP_UART_DELAY
Config delay (in ms) before printing core dump to UART. Config delay (in ms) before printing core dump to UART.
Delay can be interrupted by pressing Enter key. Delay can be interrupted by pressing Enter key.
config ESP32_CORE_DUMP_LOG_LEVEL
int "Core dump module logging level"
depends on ESP32_ENABLE_COREDUMP
default 1
help
Config core dump module logging level (0-5).
choice NUMBER_OF_UNIVERSAL_MAC_ADDRESS choice NUMBER_OF_UNIVERSAL_MAC_ADDRESS
bool "Number of universally administered (by IEEE) MAC address" bool "Number of universally administered (by IEEE) MAC address"
default FOUR_UNIVERSAL_MAC_ADDRESS default FOUR_UNIVERSAL_MAC_ADDRESS

View file

@ -25,11 +25,12 @@
#include "esp_partition.h" #include "esp_partition.h"
#include "esp_clk.h" #include "esp_clk.h"
#if CONFIG_ESP32_ENABLE_COREDUMP
#define LOG_LOCAL_LEVEL CONFIG_ESP32_CORE_DUMP_LOG_LEVEL
#include "esp_log.h" #include "esp_log.h"
const static DRAM_ATTR char TAG[] = "esp_core_dump"; const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump";
typedef uint32_t core_dump_crc_t;
#if CONFIG_ESP32_ENABLE_COREDUMP
#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_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_LOGE( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_ERROR, LOG_FORMAT(E, format), ##__VA_ARGS__) #define ESP_COREDUMP_LOGE( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_ERROR, LOG_FORMAT(E, format), ##__VA_ARGS__)
#define ESP_COREDUMP_LOGW( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_WARN, LOG_FORMAT(W, format), ##__VA_ARGS__) #define ESP_COREDUMP_LOGW( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_WARN, LOG_FORMAT(W, format), ##__VA_ARGS__)
@ -47,6 +48,7 @@ const static DRAM_ATTR char TAG[] = "esp_core_dump";
#define COREDUMP_MAX_TASKS_NUM 32 #define COREDUMP_MAX_TASKS_NUM 32
#define COREDUMP_MAX_TASK_STACK_SIZE (64*1024) #define COREDUMP_MAX_TASK_STACK_SIZE (64*1024)
typedef esp_err_t (*esp_core_dump_write_prepare_t)(void *priv, uint32_t *data_len); typedef esp_err_t (*esp_core_dump_write_prepare_t)(void *priv, uint32_t *data_len);
typedef esp_err_t (*esp_core_dump_write_start_t)(void *priv); typedef esp_err_t (*esp_core_dump_write_start_t)(void *priv);
typedef esp_err_t (*esp_core_dump_write_end_t)(void *priv); typedef esp_err_t (*esp_core_dump_write_end_t)(void *priv);
@ -143,9 +145,9 @@ static void esp_core_dump_write(XtExcFrame *frame, core_dump_write_config_t *wri
else { else {
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH #if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
XtExcFrame *task_frame2 = (XtExcFrame *)tasks[i].pxTopOfStack; XtExcFrame *task_frame2 = (XtExcFrame *)tasks[i].pxTopOfStack;
#endif
ESP_COREDUMP_LOG_PROCESS("Task EXIT/PC/PS/A0/SP %x %x %x %x %x", ESP_COREDUMP_LOG_PROCESS("Task EXIT/PC/PS/A0/SP %x %x %x %x %x",
task_frame2->exit, task_frame2->pc, task_frame2->ps, task_frame2->a0, task_frame2->a1); task_frame2->exit, task_frame2->pc, task_frame2->ps, task_frame2->a0, task_frame2->a1);
#endif
} }
} }
len = (uint32_t)tasks[i].pxEndOfStack - (uint32_t)tasks[i].pxTopOfStack; len = (uint32_t)tasks[i].pxEndOfStack - (uint32_t)tasks[i].pxTopOfStack;
@ -248,13 +250,10 @@ static void esp_core_dump_write(XtExcFrame *frame, core_dump_write_config_t *wri
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH #if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
// magic numbers to control core dump data consistency
#define COREDUMP_FLASH_MAGIC_START 0xE32C04EDUL
#define COREDUMP_FLASH_MAGIC_END 0xE32C04EDUL
typedef struct _core_dump_write_flash_data_t typedef struct _core_dump_write_flash_data_t
{ {
uint32_t off; uint32_t off; // current offset in partition
core_dump_crc_t crc; // CRC of dumped data
} core_dump_write_flash_data_t; } core_dump_write_flash_data_t;
typedef struct _core_dump_partition_t typedef struct _core_dump_partition_t
@ -267,15 +266,20 @@ typedef struct _core_dump_partition_t
typedef struct _core_dump_flash_config_t typedef struct _core_dump_flash_config_t
{ {
// core dump partition start // core dump partition config
core_dump_partition_t partition; core_dump_partition_t partition;
// core dump partition size // CRC of core dump partition config
uint32_t crc; core_dump_crc_t partition_config_crc;
} core_dump_flash_config_t; } core_dump_flash_config_t;
// core dump flash data // core dump flash data
static core_dump_flash_config_t s_core_flash_config; static core_dump_flash_config_t s_core_flash_config;
static inline core_dump_crc_t esp_core_dump_calc_flash_config_crc(void)
{
return crc32_le(0, (uint8_t const *)&s_core_flash_config.partition, sizeof(s_core_flash_config.partition));
}
static uint32_t esp_core_dump_write_flash_padded(size_t off, uint8_t *data, uint32_t data_size) static uint32_t esp_core_dump_write_flash_padded(size_t off, uint8_t *data, uint32_t data_size)
{ {
esp_err_t err; esp_err_t err;
@ -302,8 +306,9 @@ static uint32_t esp_core_dump_write_flash_padded(size_t off, uint8_t *data, uint
if (len) { if (len) {
// write last bytes with padding, actual TCB len can be retrieved by esptool from core dump header // write last bytes with padding, actual TCB len can be retrieved by esptool from core dump header
rom_data.data32 = 0; rom_data.data32 = 0;
for (k = 0; k < len; k++) for (k = 0; k < len; k++) {
rom_data.data8[k] = *(data + data_len + k); rom_data.data8[k] = *(data + data_len + k);
}
err = spi_flash_write(off + data_len, &rom_data, sizeof(uint32_t)); err = spi_flash_write(off + data_len, &rom_data, sizeof(uint32_t));
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_COREDUMP_LOGE("Failed to finish write data to flash (%d)!", err); ESP_COREDUMP_LOGE("Failed to finish write data to flash (%d)!", err);
@ -322,18 +327,19 @@ static esp_err_t esp_core_dump_flash_write_prepare(void *priv, uint32_t *data_le
core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv; core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv;
// check for available space in partition // check for available space in partition
// add space for 2 magics. TODO: change to CRC if ((*data_len + sizeof(uint32_t)) > s_core_flash_config.partition.size) {
if ((*data_len + 2*sizeof(uint32_t)) > s_core_flash_config.partition.size) {
ESP_COREDUMP_LOGE("Not enough space to save core dump!"); ESP_COREDUMP_LOGE("Not enough space to save core dump!");
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
*data_len += 2*sizeof(uint32_t); // add space for CRC
*data_len += sizeof(core_dump_crc_t);
wr_data->off = 0; memset(wr_data, 0, sizeof(*wr_data));
sec_num = *data_len / SPI_FLASH_SEC_SIZE; sec_num = *data_len / SPI_FLASH_SEC_SIZE;
if (*data_len % SPI_FLASH_SEC_SIZE) if (*data_len % SPI_FLASH_SEC_SIZE) {
sec_num++; sec_num++;
}
assert(sec_num * SPI_FLASH_SEC_SIZE <= s_core_flash_config.partition.size); assert(sec_num * SPI_FLASH_SEC_SIZE <= s_core_flash_config.partition.size);
err = spi_flash_erase_range(s_core_flash_config.partition.start + 0, sec_num * SPI_FLASH_SEC_SIZE); err = spi_flash_erase_range(s_core_flash_config.partition.start + 0, sec_num * SPI_FLASH_SEC_SIZE);
if (err != ESP_OK) { if (err != ESP_OK) {
@ -362,9 +368,7 @@ static esp_err_t esp_core_dump_flash_write_word(core_dump_write_flash_data_t *wr
static esp_err_t esp_core_dump_flash_write_start(void *priv) static esp_err_t esp_core_dump_flash_write_start(void *priv)
{ {
core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv; return ESP_OK;
// save magic 1
return esp_core_dump_flash_write_word(wr_data, COREDUMP_FLASH_MAGIC_START);
} }
static esp_err_t esp_core_dump_flash_write_end(void *priv) static esp_err_t esp_core_dump_flash_write_end(void *priv)
@ -381,17 +385,16 @@ static esp_err_t esp_core_dump_flash_write_end(void *priv)
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_COREDUMP_LOGE("Failed to read flash (%d)!", err); ESP_COREDUMP_LOGE("Failed to read flash (%d)!", err);
return err; return err;
} } else {
else {
ESP_COREDUMP_LOG_PROCESS("Data from flash:"); ESP_COREDUMP_LOG_PROCESS("Data from flash:");
for (uint32_t i = 0; i < sizeof(rom_data)/sizeof(rom_data.data32[0]); i++) { for (uint32_t i = 0; i < sizeof(rom_data)/sizeof(rom_data.data32[0]); i++) {
ESP_COREDUMP_LOG_PROCESS("%x", rom_data.data32[i]); ESP_COREDUMP_LOG_PROCESS("%x", rom_data.data32[i]);
} }
} }
#endif #endif
// write core dump CRC
// save magic 2 ESP_COREDUMP_LOG_PROCESS("Dump data CRC = 0x%x", wr_data->crc);
return esp_core_dump_flash_write_word(wr_data, COREDUMP_FLASH_MAGIC_END); return esp_core_dump_flash_write_word(wr_data, wr_data->crc);
} }
static esp_err_t esp_core_dump_flash_write_data(void *priv, void * data, uint32_t data_len) static esp_err_t esp_core_dump_flash_write_data(void *priv, void * data, uint32_t data_len)
@ -400,10 +403,12 @@ static esp_err_t esp_core_dump_flash_write_data(void *priv, void * data, uint32_
core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv; core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv;
uint32_t len = esp_core_dump_write_flash_padded(s_core_flash_config.partition.start + wr_data->off, data, data_len); uint32_t len = esp_core_dump_write_flash_padded(s_core_flash_config.partition.start + wr_data->off, data, data_len);
if (len != data_len) if (len != data_len) {
return ESP_FAIL; return ESP_FAIL;
}
wr_data->off += len; wr_data->off += len;
wr_data->crc = crc32_le(wr_data->crc, data, data_len);
return err; return err;
} }
@ -413,10 +418,14 @@ void esp_core_dump_to_flash(XtExcFrame *frame)
core_dump_write_config_t wr_cfg; core_dump_write_config_t wr_cfg;
core_dump_write_flash_data_t wr_data; core_dump_write_flash_data_t wr_data;
uint32_t crc = crc32_le(UINT32_MAX, (uint8_t const *)&s_core_flash_config.partition, core_dump_crc_t crc = esp_core_dump_calc_flash_config_crc();
sizeof(s_core_flash_config.partition)); if (s_core_flash_config.partition_config_crc != crc) {
if (s_core_flash_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);
ESP_COREDUMP_LOGE("Core dump flash config is corrupted! CRC=0x%x instead of 0x%x", crc, s_core_flash_config.crc); return;
}
// check that partition can hold at least core dump 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; return;
} }
@ -500,10 +509,11 @@ static esp_err_t esp_core_dump_uart_write_data(void *priv, void * data, uint32_t
static int esp_core_dump_uart_get_char() { static int esp_core_dump_uart_get_char() {
int i; int i;
uint32_t reg = (READ_PERI_REG(UART_STATUS_REG(0)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT; uint32_t reg = (READ_PERI_REG(UART_STATUS_REG(0)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT;
if (reg) if (reg) {
i = READ_PERI_REG(UART_FIFO_REG(0)); i = READ_PERI_REG(UART_FIFO_REG(0));
else } else {
i = -1; i = -1;
}
return i; return i;
} }
@ -532,8 +542,9 @@ void esp_core_dump_to_uart(XtExcFrame *frame)
ch = esp_core_dump_uart_get_char(); ch = esp_core_dump_uart_get_char();
while (!(ch == '\n' || ch == '\r')) { while (!(ch == '\n' || ch == '\r')) {
tm_cur = xthal_get_ccount() / cpu_ticks_per_ms; tm_cur = xthal_get_ccount() / cpu_ticks_per_ms;
if (tm_cur >= tm_end) if (tm_cur >= tm_end){
break; break;
}
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...");
@ -554,10 +565,9 @@ void esp_core_dump_init()
return; return;
} }
ESP_COREDUMP_LOGI("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_flash_config.partition.start = core_part->address; s_core_flash_config.partition.start = core_part->address;
s_core_flash_config.partition.size = core_part->size; s_core_flash_config.partition.size = core_part->size;
s_core_flash_config.crc = crc32_le(UINT32_MAX, (uint8_t const *)&s_core_flash_config.partition, s_core_flash_config.partition_config_crc = esp_core_dump_calc_flash_config_crc();
sizeof(s_core_flash_config.partition));
#endif #endif
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART #if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART
ESP_COREDUMP_LOGI("Init core dump to UART"); ESP_COREDUMP_LOGI("Init core dump to UART");

View file

@ -25,29 +25,29 @@ void esp_core_dump_init();
* @brief Saves core dump to flash. * @brief Saves core dump to flash.
* *
* The structure of data stored in flash is as follows: * The structure of data stored in flash is as follows:
* | MAGIC1 | *
* | TOTAL_LEN | TASKS_NUM | TCB_SIZE | * | TOTAL_LEN | TASKS_NUM | TCB_SIZE |
* | TCB_ADDR_1 | STACK_TOP_1 | STACK_END_1 | TCB_1 | STACK_1 | * | 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 | * | TCB_ADDR_N | STACK_TOP_N | STACK_END_N | TCB_N | STACK_N |
* | MAGIC2 | * | CRC32 |
*
* Core dump in flash consists of header and data for every task in the system at the moment of crash. * Core dump in flash consists of header and data for every task in the system at the moment of crash.
* For flash data integrity control two magic numbers are used at the beginning and the end of core dump. * For flash data integrity control CRC is used at the end of core the dump data.
* The structure of core dump data is described below in details. * The structure of core dump data is described below in details.
* 1) MAGIC1 and MAGIC2 are special numbers stored at the beginning and the end of core dump. * 1) Core dump starts with header:
* They are used to control core dump data integrity. Size of every number is 4 bytes. * 1.1) TOTAL_LEN is total length of core dump data in flash including CRC. Size is 4 bytes.
* 2) Core dump starts with header: * 1.2) TASKS_NUM is the number of tasks for which data are stored. Size is 4 bytes.
* 2.1) TOTAL_LEN is total length of core dump data in flash including magic numbers. Size is 4 bytes. * 1.3) TCB_SIZE is the size of task's TCB structure. Size is 4 bytes.
* 2.2) TASKS_NUM is the number of tasks for which data are stored. Size is 4 bytes. * 2) Core dump header is followed by the data for every task in the system.
* 2.3) TCB_SIZE is the size of task's TCB structure. Size is 4 bytes.
* 3) Core dump header is followed by the data for every task in the system.
* Task data are started with task header: * Task data are started with task header:
* 3.1) TCB_ADDR is the address of TCB in memory. Size is 4 bytes. * 2.1) TCB_ADDR is the address of TCB in memory. Size is 4 bytes.
* 3.2) STACK_TOP is the top of task's stack (address of the topmost stack item). 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.
* 3.2) STACK_END is the end of task's stack (address from which task's stack starts). 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.
* 4) Task header is followed by TCB data. Size is TCB_SIZE bytes. * 3) Task header is followed by TCB data. Size is TCB_SIZE bytes.
* 5) Task's stack is placed after TCB data. Size is (STACK_END - STACK_TOP) bytes. * 4) Task's stack is placed after TCB data. Size is (STACK_END - STACK_TOP) bytes.
* 5) CRC is placed at the end of the data.
*/ */
void esp_core_dump_to_flash(); void esp_core_dump_to_flash();
@ -55,8 +55,8 @@ void esp_core_dump_to_flash();
* @brief Print base64-encoded core dump to UART. * @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: * 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) Magic numbers are not present in core dump printed to UART. * 1) CRC is not present in core dump printed to UART.
* 2) Since magic numbers are omitted TOTAL_LEN does not include their size. * 2) Since CRC 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. * 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(); void esp_core_dump_to_uart();

View file

@ -24,6 +24,7 @@ import struct
import array import array
import errno import errno
import base64 import base64
import binascii
idf_path = os.getenv('IDF_PATH') idf_path = os.getenv('IDF_PATH')
if idf_path: if idf_path:
@ -35,7 +36,7 @@ except ImportError:
print("Esptool is not found! Set proper $IDF_PATH in environment.") print("Esptool is not found! Set proper $IDF_PATH in environment.")
sys.exit(2) sys.exit(2)
__version__ = "0.2-dev" __version__ = "0.3-dev"
if os.name == 'nt': if os.name == 'nt':
CLOSE_FDS = False CLOSE_FDS = False
@ -690,12 +691,10 @@ class ESPCoreDumpFileLoader(ESPCoreDumpLoader):
class ESPCoreDumpFlashLoader(ESPCoreDumpLoader): class ESPCoreDumpFlashLoader(ESPCoreDumpLoader):
"""Core dump flash loader class """Core dump flash loader class
""" """
ESP32_COREDUMP_FLASH_MAGIC_START = 0xE32C04ED ESP32_COREDUMP_FLASH_CRC_FMT = '<L'
ESP32_COREDUMP_FLASH_MAGIC_END = 0xE32C04ED ESP32_COREDUMP_FLASH_CRC_SZ = struct.calcsize(ESP32_COREDUMP_FLASH_CRC_FMT)
ESP32_COREDUMP_FLASH_MAGIC_FMT = '<L' ESP32_COREDUMP_FLASH_LEN_FMT = '<L'
ESP32_COREDUMP_FLASH_MAGIC_SZ = struct.calcsize(ESP32_COREDUMP_FLASH_MAGIC_FMT) ESP32_COREDUMP_FLASH_LEN_SZ = struct.calcsize(ESP32_COREDUMP_FLASH_LEN_FMT)
ESP32_COREDUMP_FLASH_HDR_FMT = '<4L'
ESP32_COREDUMP_FLASH_HDR_SZ = struct.calcsize(ESP32_COREDUMP_FLASH_HDR_FMT)
def __init__(self, off, tool_path=None, chip='esp32', port=None, baud=None): def __init__(self, off, tool_path=None, chip='esp32', port=None, baud=None):
"""Constructor for core dump flash loader """Constructor for core dump flash loader
@ -722,7 +721,7 @@ class ESPCoreDumpFlashLoader(ESPCoreDumpLoader):
tool_args.extend(['-p', self.port]) tool_args.extend(['-p', self.port])
if self.baud: if self.baud:
tool_args.extend(['-b', str(self.baud)]) tool_args.extend(['-b', str(self.baud)])
tool_args.extend(['read_flash', str(off), str(self.ESP32_COREDUMP_FLASH_HDR_SZ), '']) tool_args.extend(['read_flash', str(off), str(self.ESP32_COREDUMP_FLASH_LEN_SZ), ''])
self.fcore_name = None self.fcore_name = None
try: try:
@ -750,26 +749,20 @@ class ESPCoreDumpFlashLoader(ESPCoreDumpLoader):
def _read_core_dump_length(self, f): def _read_core_dump_length(self, f):
"""Reads core dump length """Reads core dump length
""" """
data = f.read(4*4) data = f.read(self.ESP32_COREDUMP_FLASH_LEN_SZ)
mag1,tot_len,task_num,tcbsz = struct.unpack_from(self.ESP32_COREDUMP_FLASH_HDR_FMT, data) tot_len, = struct.unpack_from(self.ESP32_COREDUMP_FLASH_LEN_FMT, data)
if mag1 != self.ESP32_COREDUMP_FLASH_MAGIC_START:
raise ESPCoreDumpLoaderError("Invalid start magic number!")
return tot_len return tot_len
def create_corefile(self, core_fname=None, rom_elf=None): def create_corefile(self, core_fname=None, rom_elf=None):
"""Checks flash coredump data integrity and creates ELF file """Checks flash coredump data integrity and creates ELF file
""" """
data = self.read_data(0, self.ESP32_COREDUMP_FLASH_MAGIC_SZ) data = self.read_data(self.dump_sz - self.ESP32_COREDUMP_FLASH_CRC_SZ, self.ESP32_COREDUMP_FLASH_CRC_SZ)
mag1, = struct.unpack_from(self.ESP32_COREDUMP_FLASH_MAGIC_FMT, data) dump_crc, = struct.unpack_from(self.ESP32_COREDUMP_FLASH_CRC_FMT, data)
if mag1 != self.ESP32_COREDUMP_FLASH_MAGIC_START: data = self.read_data(0, self.dump_sz - self.ESP32_COREDUMP_FLASH_CRC_SZ)
raise ESPCoreDumpLoaderError("Invalid start marker %x" % mag1) data_crc = binascii.crc32(data) & 0xffffffff
if dump_crc != data_crc:
data = self.read_data(self.dump_sz-self.ESP32_COREDUMP_FLASH_MAGIC_SZ, self.ESP32_COREDUMP_FLASH_MAGIC_SZ) raise ESPCoreDumpLoaderError("Invalid core dump CRC %x, should be %x" % (data_crc, dump_crc))
mag2, = struct.unpack_from(self.ESP32_COREDUMP_FLASH_MAGIC_FMT, data) return super(ESPCoreDumpFlashLoader, self).create_corefile(core_fname)
if mag2 != self.ESP32_COREDUMP_FLASH_MAGIC_END:
raise ESPCoreDumpLoaderError("Invalid end marker %x" % mag2)
return super(ESPCoreDumpFlashLoader, self).create_corefile(core_fname, off=self.ESP32_COREDUMP_FLASH_MAGIC_SZ, rom_elf=rom_elf)
class GDBMIOutRecordHandler(object): class GDBMIOutRecordHandler(object):

View file

@ -1,4 +1,4 @@
espcoredump.py v0.2-dev espcoredump.py v0.3-dev
=============================================================== ===============================================================
==================== ESP32 CORE DUMP START ==================== ==================== ESP32 CORE DUMP START ====================

View file

@ -1,4 +1,4 @@
espcoredump.py v0.2-dev espcoredump.py v0.3-dev
=============================================================== ===============================================================
==================== ESP32 CORE DUMP START ==================== ==================== ESP32 CORE DUMP START ====================

View file

@ -300,7 +300,12 @@ extern void vPortCleanUpTCB ( void *pxTCB );
#define configXT_BOARD 1 /* Board mode */ #define configXT_BOARD 1 /* Board mode */
#define configXT_SIMULATOR 0 #define configXT_SIMULATOR 0
#define configENABLE_TASK_SNAPSHOT 1 #if CONFIG_ESP32_ENABLE_COREDUMP
#define configENABLE_TASK_SNAPSHOT 1
#endif
#ifndef configENABLE_TASK_SNAPSHOT
#define configENABLE_TASK_SNAPSHOT 1
#endif
#if CONFIG_SYSVIEW_ENABLE #if CONFIG_SYSVIEW_ENABLE
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__

View file

@ -24,9 +24,7 @@ There are a number of core dump related configuration options which user can cho
* Save core dump to flash * Save core dump to flash
* Print core dump to UART * Print core dump to UART
2. Logging level of core dump module (`Components -> ESP32-specific config -> Core dump module logging level`). Value is a number from 0 (no output) to 5 (most verbose). 2. Delay before core dump will be printed to UART (`Components -> ESP32-specific config -> Core dump print to UART delay`). Value is in ms.
3. Delay before core dump will be printed to UART (`Components -> ESP32-specific config -> Core dump print to UART delay`). Value is in ms.
Save core dump to flash Save core dump to flash