mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-05 12:25:03 +02: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:
+80
-347
@@ -15,7 +15,6 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
//#include "esp_attr.h"
|
||||
#include "esp_panic.h"
|
||||
#include "esp_partition.h"
|
||||
|
||||
@@ -26,10 +25,10 @@ const static char *TAG = "esp_core_dump";
|
||||
// TODO: allow user to set this in menuconfig or get tasks iteratively
|
||||
#define COREDUMP_MAX_TASKS_NUM 32
|
||||
|
||||
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_end_t)(void *priv);
|
||||
typedef esp_err_t (*esp_core_dump_flash_write_data_t)(void *priv, void * data, uint32_t data_len);
|
||||
typedef esp_err_t (*esp_core_dump_write_prepare_t)(void *priv, uint32_t *data_len, int verb);
|
||||
typedef esp_err_t (*esp_core_dump_write_start_t)(void *priv, int verb);
|
||||
typedef esp_err_t (*esp_core_dump_write_end_t)(void *priv, int verb);
|
||||
typedef esp_err_t (*esp_core_dump_flash_write_data_t)(void *priv, void * data, uint32_t data_len, int verb);
|
||||
|
||||
typedef struct _core_dump_write_config_t
|
||||
{
|
||||
@@ -67,14 +66,19 @@ static void esp_core_dump_write(XtExcFrame *frame, core_dump_write_config_t *wri
|
||||
if (tasks[i].pxTCB == xTaskGetCurrentTaskHandle()) {
|
||||
// set correct stack top for current task
|
||||
tasks[i].pxTopOfStack = (StackType_t *)frame;
|
||||
if (verb)
|
||||
ets_printf("Current task EXIT/PC/PS/A0/SP %x %x %x %x %x\r\n", frame->exit, frame->pc, frame->ps, frame->a0, frame->a1);
|
||||
}
|
||||
else {
|
||||
if (verb) {
|
||||
esp_panicPutStr("Current task PC/A0/SP ");
|
||||
esp_panicPutHex(frame->pc);
|
||||
esp_panicPutStr(" ");
|
||||
esp_panicPutHex(frame->a0);
|
||||
esp_panicPutStr(" ");
|
||||
esp_panicPutHex(frame->a1);
|
||||
esp_panicPutStr("\r\n");
|
||||
XtSolFrame *task_frame = (XtSolFrame *)tasks[i].pxTopOfStack;
|
||||
if (task_frame->exit == 0) {
|
||||
ets_printf("Task EXIT/PC/PS/A0/SP %x %x %x %x %x\r\n", task_frame->exit, task_frame->pc, task_frame->ps, task_frame->a0, task_frame->a1);
|
||||
}
|
||||
else {
|
||||
XtExcFrame *task_frame2 = (XtExcFrame *)tasks[i].pxTopOfStack;
|
||||
ets_printf("Task EXIT/PC/PS/A0/SP %x %x %x %x %x\r\n", task_frame2->exit, task_frame2->pc, task_frame2->ps, task_frame2->a0, task_frame2->a1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if( portSTACK_GROWTH < 0 )
|
||||
@@ -83,13 +87,7 @@ static void esp_core_dump_write(XtExcFrame *frame, core_dump_write_config_t *wri
|
||||
len = (uint32_t)tasks[i].pxTopOfStack - (uint32_t)tasks[i].pxEndOfStack;
|
||||
#endif
|
||||
if (verb) {
|
||||
esp_panicPutStr("stack len = ");
|
||||
esp_panicPutHex(len);
|
||||
esp_panicPutStr(" ");
|
||||
esp_panicPutHex((int)tasks[i].pxTopOfStack);
|
||||
esp_panicPutStr(" ");
|
||||
esp_panicPutHex((int)tasks[i].pxEndOfStack);
|
||||
esp_panicPutStr("\r\n");
|
||||
ets_printf("Stack len = %lu (%x %x)\r\n", len, tasks[i].pxTopOfStack, tasks[i].pxEndOfStack);
|
||||
}
|
||||
// take stack padding into account
|
||||
if (len % sizeof(uint32_t))
|
||||
@@ -99,28 +97,22 @@ static void esp_core_dump_write(XtExcFrame *frame, core_dump_write_config_t *wri
|
||||
|
||||
// prepare write
|
||||
if (write_cfg->prepare) {
|
||||
err = write_cfg->prepare(write_cfg->priv, &data_len);
|
||||
err = write_cfg->prepare(write_cfg->priv, &data_len, verb);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to prepare core dump ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to prepare core dump (%d)!\r\n", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (verb) {
|
||||
esp_panicPutStr("Core dump len =");
|
||||
esp_panicPutHex(data_len);
|
||||
esp_panicPutStr("\r\n");
|
||||
ets_printf("Core dump len = %lu\r\n", data_len);
|
||||
}
|
||||
|
||||
// write start marker
|
||||
// write start
|
||||
if (write_cfg->start) {
|
||||
err = write_cfg->start(write_cfg->priv);
|
||||
err = write_cfg->start(write_cfg->priv, verb);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to start core dump ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to start core dump (%d)!\r\n", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -129,49 +121,33 @@ static void esp_core_dump_write(XtExcFrame *frame, core_dump_write_config_t *wri
|
||||
rom_data.data32[0] = data_len;
|
||||
rom_data.data32[1] = task_num;
|
||||
rom_data.data32[2] = tcb_sz;
|
||||
err = write_cfg->write(write_cfg->priv, &rom_data, 3*sizeof(uint32_t));
|
||||
err = write_cfg->write(write_cfg->priv, &rom_data, 3*sizeof(uint32_t), verb);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to write core dump header ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to write core dump header (%d)!\r\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
// write tasks
|
||||
for (i = 0; i < task_num; i++) {
|
||||
if (verb) {
|
||||
esp_panicPutStr("Dump task ");
|
||||
esp_panicPutHex((int)tasks[i].pxTCB);
|
||||
esp_panicPutStr("\r\n");
|
||||
ets_printf("Dump task %x\r\n", tasks[i].pxTCB);
|
||||
}
|
||||
// save TCB address, stack base and stack top addr
|
||||
rom_data.data32[0] = (uint32_t)tasks[i].pxTCB;
|
||||
rom_data.data32[1] = (uint32_t)tasks[i].pxTopOfStack;
|
||||
rom_data.data32[2] = (uint32_t)tasks[i].pxEndOfStack;
|
||||
err = write_cfg->write(write_cfg->priv, &rom_data, 3*sizeof(uint32_t));
|
||||
err = write_cfg->write(write_cfg->priv, &rom_data, 3*sizeof(uint32_t), verb);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to write task header ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to write task header (%d)!\r\n", err);
|
||||
return;
|
||||
}
|
||||
// save TCB
|
||||
err = write_cfg->write(write_cfg->priv, tasks[i].pxTCB, tcb_sz);
|
||||
err = write_cfg->write(write_cfg->priv, tasks[i].pxTCB, tcb_sz, verb);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to write task header ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to write TCB (%d)!\r\n", err);
|
||||
return;
|
||||
}
|
||||
// save task stack
|
||||
/*int k;
|
||||
for (k = 0; k < 8*4; k++) {
|
||||
esp_panicPutStr("stack[");
|
||||
esp_panicPutDec(k);
|
||||
esp_panicPutStr("] = ");
|
||||
esp_panicPutHex(((uint8_t *)tasks[i].pxTopOfStack)[k]);
|
||||
esp_panicPutStr("\r\n");
|
||||
}*/
|
||||
err = write_cfg->write(write_cfg->priv,
|
||||
#if( portSTACK_GROWTH < 0 )
|
||||
tasks[i].pxTopOfStack,
|
||||
@@ -180,22 +156,18 @@ static void esp_core_dump_write(XtExcFrame *frame, core_dump_write_config_t *wri
|
||||
tasks[i].pxEndOfStack,
|
||||
(uint32_t)tasks[i].pxTopOfStack - (uint32_t)tasks[i].pxEndOfStack
|
||||
#endif
|
||||
);
|
||||
, verb);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to write task header ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to write task stack (%d)!\r\n", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// write end marker
|
||||
// write end
|
||||
if (write_cfg->end) {
|
||||
err = write_cfg->end(write_cfg->priv);
|
||||
err = write_cfg->end(write_cfg->priv, verb);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to end core dump ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to end core dump (%d)!\r\n", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -204,8 +176,8 @@ static void esp_core_dump_write(XtExcFrame *frame, core_dump_write_config_t *wri
|
||||
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
|
||||
|
||||
// magic numbers to control core dump data consistency
|
||||
#define COREDUMP_FLASH_MAGIC_START 0xDEADBEEFUL
|
||||
#define COREDUMP_FLASH_MAGIC_END 0xACDCFEEDUL
|
||||
#define COREDUMP_FLASH_MAGIC_START 0xE32C04EDUL
|
||||
#define COREDUMP_FLASH_MAGIC_END 0xE32C04EDUL
|
||||
|
||||
typedef struct _core_dump_write_flash_data_t
|
||||
{
|
||||
@@ -228,11 +200,9 @@ static uint32_t esp_core_dump_write_flash_padded(size_t off, uint8_t *data, uint
|
||||
} rom_data;
|
||||
|
||||
data_len = (data_size / sizeof(uint32_t)) * sizeof(uint32_t);
|
||||
err = spi_flash_write_panic(off, data, data_len);
|
||||
err = spi_flash_write(off, data, data_len);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to write data");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to write data to flash (%d)!\r\n", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -242,11 +212,9 @@ static uint32_t esp_core_dump_write_flash_padded(size_t off, uint8_t *data, uint
|
||||
rom_data.data32 = 0;
|
||||
for (k = 0; k < len; k++)
|
||||
rom_data.data8[k] = *(data + data_len + k);
|
||||
err = spi_flash_write_panic(off + data_len, &rom_data, sizeof(uint32_t));
|
||||
err = spi_flash_write(off + data_len, &rom_data, sizeof(uint32_t));
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to write data end");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to finish write data to flash (%d)!\r\n", err);
|
||||
return 0;
|
||||
}
|
||||
data_len += sizeof(uint32_t);
|
||||
@@ -255,37 +223,27 @@ static uint32_t esp_core_dump_write_flash_padded(size_t off, uint8_t *data, uint
|
||||
return data_len;
|
||||
}
|
||||
|
||||
static esp_err_t esp_core_dump_flash_write_prepare(void *priv, uint32_t *data_len)
|
||||
static esp_err_t esp_core_dump_flash_write_prepare(void *priv, uint32_t *data_len, int verb)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t sec_num;
|
||||
core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv;
|
||||
|
||||
esp_panicPutStr("Core dump len1 = ");
|
||||
esp_panicPutHex(*data_len);
|
||||
esp_panicPutStr("\r\n");
|
||||
|
||||
// add space for 2 magics. TODO: change to CRC
|
||||
*data_len += 2*sizeof(uint32_t);
|
||||
if (*data_len > s_core_part_size) {
|
||||
esp_panicPutStr("ERROR: Not enough space to save core dump!");
|
||||
if ((*data_len + 2*sizeof(uint32_t)) > s_core_part_size) {
|
||||
ets_printf("ERROR: Not enough space to save core dump!\r\n");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_panicPutStr("Core dump len2 = ");
|
||||
esp_panicPutHex(*data_len);
|
||||
esp_panicPutStr("\r\n");
|
||||
*data_len += 2*sizeof(uint32_t);
|
||||
|
||||
wr_data->off = 0;
|
||||
|
||||
sec_num = *data_len / SPI_FLASH_SEC_SIZE;
|
||||
if (*data_len % SPI_FLASH_SEC_SIZE)
|
||||
sec_num++;
|
||||
err = spi_flash_erase_range_panic(s_core_part_start + 0, sec_num * SPI_FLASH_SEC_SIZE);
|
||||
err = spi_flash_erase_range(s_core_part_start + 0, sec_num * SPI_FLASH_SEC_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to erase flash ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to erase flash (%d)!\r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -297,11 +255,9 @@ static esp_err_t esp_core_dump_flash_write_word(core_dump_write_flash_data_t *wr
|
||||
esp_err_t err = ESP_OK;
|
||||
uint32_t data32 = word;
|
||||
|
||||
err = spi_flash_write_panic(s_core_part_start + wr_data->off, &data32, sizeof(uint32_t));
|
||||
err = spi_flash_write(s_core_part_start + wr_data->off, &data32, sizeof(uint32_t));
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("Failed to write to flash ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
ets_printf("ERROR: Failed to write to flash (%d)!\r\n", err);
|
||||
return err;
|
||||
}
|
||||
wr_data->off += sizeof(uint32_t);
|
||||
@@ -309,14 +265,14 @@ static esp_err_t esp_core_dump_flash_write_word(core_dump_write_flash_data_t *wr
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t esp_core_dump_flash_write_start(void *priv)
|
||||
static esp_err_t esp_core_dump_flash_write_start(void *priv, int verb)
|
||||
{
|
||||
core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv;
|
||||
// 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, int verb)
|
||||
{
|
||||
core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv;
|
||||
uint32_t i;
|
||||
@@ -326,31 +282,27 @@ static esp_err_t esp_core_dump_flash_write_end(void *priv)
|
||||
uint32_t data32[4];
|
||||
} rom_data;
|
||||
|
||||
// TEST READ START
|
||||
esp_err_t err = spi_flash_read_panic(s_core_part_start + 0, &rom_data, sizeof(rom_data));
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to read flash ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
return err;
|
||||
}
|
||||
else {
|
||||
esp_panicPutStr("Data from flash:\r\n");
|
||||
for (i = 0; i < sizeof(rom_data)/sizeof(rom_data.data32[0]); i++) {
|
||||
esp_panicPutHex(rom_data.data32[i]);
|
||||
esp_panicPutStr("\r\n");
|
||||
if (verb) {
|
||||
// TEST READ START
|
||||
esp_err_t err = spi_flash_read(s_core_part_start + 0, &rom_data, sizeof(rom_data));
|
||||
if (err != ESP_OK) {
|
||||
ets_printf("ERROR: Failed to read flash (%d)!\r\n", err);
|
||||
return err;
|
||||
}
|
||||
// rom_data[4] = 0;
|
||||
// esp_panicPutStr(rom_data);
|
||||
// esp_panicPutStr("\r\n");
|
||||
else {
|
||||
ets_printf("Data from flash:\r\n");
|
||||
for (i = 0; i < sizeof(rom_data)/sizeof(rom_data.data32[0]); i++) {
|
||||
ets_printf("%x\r\n", rom_data.data32[i]);
|
||||
}
|
||||
}
|
||||
// TEST READ END
|
||||
}
|
||||
// TEST READ END
|
||||
|
||||
// save magic 2
|
||||
return esp_core_dump_flash_write_word(wr_data, COREDUMP_FLASH_MAGIC_END);
|
||||
}
|
||||
|
||||
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, int verb)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv;
|
||||
@@ -375,223 +327,25 @@ static esp_err_t esp_core_dump_flash_write_data(void *priv, void * data, uint32_
|
||||
*/
|
||||
void esp_core_dump_to_flash(XtExcFrame *frame)
|
||||
{
|
||||
#if 1
|
||||
core_dump_write_config_t wr_cfg;
|
||||
core_dump_write_flash_data_t wr_data;
|
||||
|
||||
/* init non-OS flash access critical section */
|
||||
spi_flash_guard_set(&g_flash_guard_no_os_ops);
|
||||
|
||||
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;
|
||||
wr_cfg.priv = &wr_data;
|
||||
|
||||
esp_panicPutStr("Save core dump to flash...\r\n");
|
||||
esp_core_dump_write(frame, &wr_cfg, 1);
|
||||
#else
|
||||
union
|
||||
{
|
||||
uint8_t data8[16];
|
||||
uint32_t data32[4];
|
||||
} rom_data;
|
||||
//const esp_partition_t *core_part;
|
||||
esp_err_t err;
|
||||
TaskSnapshot_t tasks[COREDUMP_MAX_TASKS_NUM];
|
||||
UBaseType_t tcb_sz, task_num;
|
||||
uint32_t data_len = 0, i, len, sec_num;
|
||||
size_t off;
|
||||
|
||||
esp_panicPutStr("Save core dump to flash...\r\n");
|
||||
task_num = uxTaskGetSnapshotAll(tasks, COREDUMP_MAX_TASKS_NUM, &tcb_sz);
|
||||
// take TCB padding into account, actual TCB size will be stored in header
|
||||
if (tcb_sz % sizeof(uint32_t))
|
||||
len = (tcb_sz / sizeof(uint32_t) + 1) * sizeof(uint32_t);
|
||||
else
|
||||
len = tcb_sz;
|
||||
// header + magic2 + tasknum*(tcb + stack start/end + tcb addr)
|
||||
data_len = 5*sizeof(uint32_t) + task_num*(len + 2*sizeof(uint32_t) + sizeof(uint32_t *));
|
||||
for (i = 0; i < task_num; i++) {
|
||||
if (tasks[i].pxTCB == xTaskGetCurrentTaskHandle()) {
|
||||
// set correct stack top for current task
|
||||
tasks[i].pxTopOfStack = (StackType_t *)frame;
|
||||
esp_panicPutStr("Current task PC/A0/SP ");
|
||||
esp_panicPutHex(frame->pc);
|
||||
esp_panicPutStr(" ");
|
||||
esp_panicPutHex(frame->a0);
|
||||
esp_panicPutStr(" ");
|
||||
esp_panicPutHex(frame->a1);
|
||||
esp_panicPutStr("\r\n");
|
||||
}
|
||||
#if( portSTACK_GROWTH < 0 )
|
||||
len = (uint32_t)tasks[i].pxEndOfStack - (uint32_t)tasks[i].pxTopOfStack;
|
||||
#else
|
||||
len = (uint32_t)tasks[i].pxTopOfStack - (uint32_t)tasks[i].pxEndOfStack;
|
||||
#endif
|
||||
esp_panicPutStr("stack len = ");
|
||||
esp_panicPutHex(len);
|
||||
esp_panicPutStr(" ");
|
||||
esp_panicPutHex((int)tasks[i].pxTopOfStack);
|
||||
esp_panicPutStr(" ");
|
||||
esp_panicPutHex((int)tasks[i].pxEndOfStack);
|
||||
esp_panicPutStr("\r\n");
|
||||
// take stack padding into account
|
||||
if (len % sizeof(uint32_t))
|
||||
len = (len / sizeof(uint32_t) + 1) * sizeof(uint32_t);
|
||||
data_len += len;
|
||||
}
|
||||
esp_panicPutStr("Core dump len =");
|
||||
esp_panicPutHex(data_len);
|
||||
esp_panicPutStr("\r\n");
|
||||
if (data_len > s_core_part_size) {
|
||||
esp_panicPutStr("ERROR: Not enough space to save core dump!");
|
||||
return;
|
||||
}
|
||||
|
||||
// TEST READ START
|
||||
err = spi_flash_read_panic(s_core_part_start + 0, &rom_data, sizeof(rom_data));
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to read flash ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
esp_panicPutStr("Data from flash:\r\n");
|
||||
for (i = 0; i < sizeof(rom_data)/sizeof(rom_data.data32[0]); i++) {
|
||||
esp_panicPutHex(rom_data.data32[i]);
|
||||
esp_panicPutStr("\r\n");
|
||||
}
|
||||
// rom_data[4] = 0;
|
||||
// esp_panicPutStr(rom_data);
|
||||
// esp_panicPutStr("\r\n");
|
||||
}
|
||||
// TEST READ END
|
||||
|
||||
sec_num = data_len / SPI_FLASH_SEC_SIZE;
|
||||
if (data_len % SPI_FLASH_SEC_SIZE)
|
||||
sec_num++;
|
||||
err = spi_flash_erase_range_panic(s_core_part_start + 0, sec_num * SPI_FLASH_SEC_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to erase flash ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rom_data.data32[0] = COREDUMP_FLASH_MAGIC_START;
|
||||
rom_data.data32[1] = data_len;
|
||||
rom_data.data32[2] = task_num;
|
||||
rom_data.data32[3] = tcb_sz;
|
||||
err = spi_flash_write_panic(s_core_part_start + 0, &rom_data, sizeof(rom_data));
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to write core dump header ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
return;
|
||||
}
|
||||
off = sizeof(rom_data);
|
||||
|
||||
for (i = 0; i < task_num; i++) {
|
||||
esp_panicPutStr("Dump task ");
|
||||
esp_panicPutHex((int)tasks[i].pxTCB);
|
||||
esp_panicPutStr("\r\n");
|
||||
|
||||
// save TCB address, stack base and stack top addr
|
||||
rom_data.data32[0] = (uint32_t)tasks[i].pxTCB;
|
||||
rom_data.data32[1] = (uint32_t)tasks[i].pxTopOfStack;
|
||||
rom_data.data32[2] = (uint32_t)tasks[i].pxEndOfStack;
|
||||
err = spi_flash_write_panic(s_core_part_start + off, &rom_data, 3*sizeof(uint32_t));
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("ERROR: Failed to write task header ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
return;
|
||||
}
|
||||
off += 3*sizeof(uint32_t);
|
||||
// save TCB
|
||||
len = esp_core_dump_write_flash_padded(s_core_part_start + off, tasks[i].pxTCB, tcb_sz);
|
||||
if (len == 0)
|
||||
return;
|
||||
off += len;
|
||||
// save task stack
|
||||
/*int k;
|
||||
for (k = 0; k < 8*4; k++) {
|
||||
esp_panicPutStr("stack[");
|
||||
esp_panicPutDec(k);
|
||||
esp_panicPutStr("] = ");
|
||||
esp_panicPutHex(((uint8_t *)tasks[i].pxTopOfStack)[k]);
|
||||
esp_panicPutStr("\r\n");
|
||||
}*/
|
||||
len = esp_core_dump_write_flash_padded(s_core_part_start + off,
|
||||
#if( portSTACK_GROWTH < 0 )
|
||||
tasks[i].pxTopOfStack,
|
||||
(uint32_t)tasks[i].pxEndOfStack - (uint32_t)tasks[i].pxTopOfStack
|
||||
#else
|
||||
tasks[i].pxEndOfStack,
|
||||
(uint32_t)tasks[i].pxTopOfStack - (uint32_t)tasks[i].pxEndOfStack
|
||||
#endif
|
||||
);
|
||||
if (len == 0)
|
||||
return;
|
||||
off += len;
|
||||
}
|
||||
|
||||
rom_data.data32[0] = COREDUMP_FLASH_MAGIC_END;
|
||||
err = spi_flash_write_panic(s_core_part_start + off, &rom_data, sizeof(uint32_t));
|
||||
if (err != ESP_OK) {
|
||||
esp_panicPutStr("Failed to write to flash ");
|
||||
esp_panicPutHex(err);
|
||||
esp_panicPutStr("!\r\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
esp_panicPutStr("Core dump has been saved to flash.\r\n");
|
||||
ets_printf("Save core dump to flash...\r\n");
|
||||
esp_core_dump_write(frame, &wr_cfg, 0);
|
||||
ets_printf("Core dump has been saved to flash.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART
|
||||
#if 0
|
||||
#define BASE64_ENCODE_BODY(_src, _src_len, _dst) \
|
||||
do { \
|
||||
static const char *b64 = \
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; \
|
||||
int i, j, a, b, c; \
|
||||
\
|
||||
for (i = j = 0; i < _src_len; i += 3) { \
|
||||
a = _src[i]; \
|
||||
b = i + 1 >= _src_len ? 0 : _src[i + 1]; \
|
||||
c = i + 2 >= _src_len ? 0 : _src[i + 2]; \
|
||||
\
|
||||
/*BASE64_OUT(b64[a >> 2], _dst[j]);*/ \
|
||||
_dst[j++] = b64[a >> 2]; \
|
||||
/*BASE64_OUT(b64[((a & 3) << 4) | (b >> 4)], _dst[j]);*/ \
|
||||
_dst[j++] = b64[((a & 3) << 4) | (b >> 4)]; \
|
||||
j++; \
|
||||
if (i + 1 < _src_len) { \
|
||||
BASE64_OUT(b64[(b & 15) << 2 | (c >> 6)], _dst[j]); \
|
||||
j++; \
|
||||
} \
|
||||
if (i + 2 < _src_len) { \
|
||||
BASE64_OUT(b64[c & 63], _dst[j]); \
|
||||
j++; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
while (j % 4 != 0) { \
|
||||
BASE64_OUT('=', _dst); \
|
||||
} \
|
||||
BASE64_FLUSH(_dst) \
|
||||
} while(0)
|
||||
|
||||
#define BASE64_OUT(ch, _dst) \
|
||||
do { \
|
||||
_dst = (ch); \
|
||||
} while (0)
|
||||
|
||||
#define BASE64_FLUSH(_dst) \
|
||||
do { \
|
||||
_dst = '\0'; \
|
||||
} while (0)
|
||||
#endif
|
||||
static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8_t *dst) {
|
||||
// BASE64_ENCODE_BODY(src, src_len, dst);
|
||||
static const char *b64 =
|
||||
@@ -618,38 +372,26 @@ 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_prepare(void *priv, uint32_t *data_len)
|
||||
static esp_err_t esp_core_dump_uart_write_start(void *priv, int verb)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
return err;
|
||||
}*/
|
||||
|
||||
static esp_err_t esp_core_dump_uart_write_start(void *priv)
|
||||
{
|
||||
// core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv;
|
||||
esp_err_t err = ESP_OK;
|
||||
esp_panicPutStr("================= CORE DUMP START =================\r\n");
|
||||
ets_printf("================= CORE DUMP START =================\r\n");
|
||||
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, int verb)
|
||||
{
|
||||
// core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv;
|
||||
esp_err_t err = ESP_OK;
|
||||
esp_panicPutStr("================= CORE DUMP END =================\r\n");
|
||||
ets_printf("================= CORE DUMP END =================\r\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t esp_core_dump_uart_write_data(void *priv, void * data, uint32_t data_len)
|
||||
static esp_err_t esp_core_dump_uart_write_data(void *priv, void * data, uint32_t data_len, int verb)
|
||||
{
|
||||
// core_dump_write_flash_data_t *wr_data = (core_dump_write_flash_data_t *)priv;
|
||||
esp_err_t err = ESP_OK;
|
||||
char buf[64 + 4], *addr = data;
|
||||
char *end = addr + data_len;
|
||||
|
||||
// esp_panicPutStr("CORE DUMP SEC: ");
|
||||
// esp_panicPutDec(data_len);
|
||||
// esp_panicPutStr("bytes\r\n");
|
||||
|
||||
while (addr < end) {
|
||||
size_t len = end - addr;
|
||||
@@ -659,15 +401,7 @@ static esp_err_t esp_core_dump_uart_write_data(void *priv, void * data, uint32_t
|
||||
memcpy(tmp, addr, len);
|
||||
esp_core_dump_b64_encode((const uint8_t *)tmp, len, (uint8_t *)buf);
|
||||
addr += len;
|
||||
esp_panicPutStr(buf);
|
||||
// for (size_t i = 0; buf[i] != '\0'; i++) {
|
||||
// panicPutChar(buf[i]);
|
||||
// }
|
||||
//if (addr % 96 == 0)
|
||||
esp_panicPutStr("\r\n");
|
||||
/* Feed the Cerberus. */
|
||||
// TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
|
||||
// TIMERG0.wdt_feed = 1;
|
||||
ets_printf("%s\r\n", buf);
|
||||
}
|
||||
|
||||
return err;
|
||||
@@ -676,17 +410,16 @@ static esp_err_t esp_core_dump_uart_write_data(void *priv, void * data, uint32_t
|
||||
void esp_core_dump_to_uart(XtExcFrame *frame)
|
||||
{
|
||||
core_dump_write_config_t wr_cfg;
|
||||
//core_dump_write_flash_data_t wr_data;
|
||||
|
||||
wr_cfg.prepare = NULL;//esp_core_dump_uart_write_prepare;
|
||||
wr_cfg.prepare = NULL;
|
||||
wr_cfg.start = esp_core_dump_uart_write_start;
|
||||
wr_cfg.end = esp_core_dump_uart_write_end;
|
||||
wr_cfg.write = esp_core_dump_uart_write_data;
|
||||
wr_cfg.priv = NULL;
|
||||
|
||||
esp_panicPutStr("Save core dump to flash...\r\n");
|
||||
ets_printf("Print core dump to uart...\r\n");
|
||||
esp_core_dump_write(frame, &wr_cfg, 0);
|
||||
esp_panicPutStr("Core dump has been written to uart.\r\n");
|
||||
ets_printf("Core dump has been written to uart.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -203,6 +203,8 @@ void start_cpu0_default(void)
|
||||
#endif
|
||||
esp_ipc_init();
|
||||
spi_flash_init();
|
||||
/* init default OS-aware flash access critical section */
|
||||
spi_flash_guard_set(&g_flash_guard_default_ops);
|
||||
|
||||
#if CONFIG_ESP32_PHY_AUTO_INIT
|
||||
nvs_flash_init();
|
||||
|
||||
@@ -24,10 +24,6 @@
|
||||
*/
|
||||
|
||||
void esp_set_breakpoint_if_jtag(void *fn);
|
||||
void esp_panicPutChar(char c);
|
||||
void esp_panicPutStr(const char *c);
|
||||
void esp_panicPutHex(int a);
|
||||
void esp_panicPutDec(int a);
|
||||
|
||||
#define ESP_WATCHPOINT_LOAD 0x40000000
|
||||
#define ESP_WATCHPOINT_STORE 0x80000000
|
||||
|
||||
+41
-41
@@ -47,61 +47,61 @@
|
||||
|
||||
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT
|
||||
//printf may be broken, so we fix our own printing fns...
|
||||
void esp_panicPutChar(char c)
|
||||
static void panicPutChar(char c)
|
||||
{
|
||||
while (((READ_PERI_REG(UART_STATUS_REG(0)) >> UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT) >= 126) ;
|
||||
WRITE_PERI_REG(UART_FIFO_REG(0), c);
|
||||
}
|
||||
|
||||
void esp_panicPutStr(const char *c)
|
||||
static void panicPutStr(const char *c)
|
||||
{
|
||||
int x = 0;
|
||||
while (c[x] != 0) {
|
||||
esp_panicPutChar(c[x]);
|
||||
panicPutChar(c[x]);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
void esp_panicPutHex(int a)
|
||||
static void panicPutHex(int a)
|
||||
{
|
||||
int x;
|
||||
int c;
|
||||
for (x = 0; x < 8; x++) {
|
||||
c = (a >> 28) & 0xf;
|
||||
if (c < 10) {
|
||||
esp_panicPutChar('0' + c);
|
||||
panicPutChar('0' + c);
|
||||
} else {
|
||||
esp_panicPutChar('a' + c - 10);
|
||||
panicPutChar('a' + c - 10);
|
||||
}
|
||||
a <<= 4;
|
||||
}
|
||||
}
|
||||
|
||||
void esp_panicPutDec(int a)
|
||||
static void panicPutDec(int a)
|
||||
{
|
||||
int n1, n2;
|
||||
n1 = a % 10;
|
||||
n2 = a / 10;
|
||||
if (n2 == 0) {
|
||||
esp_panicPutChar(' ');
|
||||
panicPutChar(' ');
|
||||
} else {
|
||||
esp_panicPutChar(n2 + '0');
|
||||
panicPutChar(n2 + '0');
|
||||
}
|
||||
esp_panicPutChar(n1 + '0');
|
||||
panicPutChar(n1 + '0');
|
||||
}
|
||||
#else
|
||||
//No printing wanted. Stub out these functions.
|
||||
void esp_panicPutChar(char c) { }
|
||||
void esp_panicPutStr(const char *c) { }
|
||||
void esp_panicPutHex(int a) { }
|
||||
void esp_panicPutDec(int a) { }
|
||||
static void panicPutChar(char c) { }
|
||||
static void panicPutStr(const char *c) { }
|
||||
static void panicPutHex(int a) { }
|
||||
static void panicPutDec(int a) { }
|
||||
#endif
|
||||
|
||||
void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName )
|
||||
{
|
||||
esp_panicPutStr("***ERROR*** A stack overflow in task ");
|
||||
esp_panicPutStr((char *)pcTaskName);
|
||||
esp_panicPutStr(" has been detected.\r\n");
|
||||
panicPutStr("***ERROR*** A stack overflow in task ");
|
||||
panicPutStr((char *)pcTaskName);
|
||||
panicPutStr(" has been detected.\r\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -220,25 +220,25 @@ void xt_unhandled_exception(XtExcFrame *frame)
|
||||
int x;
|
||||
|
||||
haltOtherCore();
|
||||
esp_panicPutStr("Guru Meditation Error of type ");
|
||||
panicPutStr("Guru Meditation Error of type ");
|
||||
x = regs[20];
|
||||
if (x < 40) {
|
||||
esp_panicPutStr(edesc[x]);
|
||||
panicPutStr(edesc[x]);
|
||||
} else {
|
||||
esp_panicPutStr("Unknown");
|
||||
panicPutStr("Unknown");
|
||||
}
|
||||
esp_panicPutStr(" occurred on core ");
|
||||
esp_panicPutDec(xPortGetCoreID());
|
||||
panicPutStr(" occurred on core ");
|
||||
panicPutDec(xPortGetCoreID());
|
||||
if (esp_cpu_in_ocd_debug_mode()) {
|
||||
esp_panicPutStr(" at pc=");
|
||||
esp_panicPutHex(regs[1]);
|
||||
esp_panicPutStr(". Setting bp and returning..\r\n");
|
||||
panicPutStr(" at pc=");
|
||||
panicPutHex(regs[1]);
|
||||
panicPutStr(". Setting bp and returning..\r\n");
|
||||
//Stick a hardware breakpoint on the address the handler returns to. This way, the OCD debugger
|
||||
//will kick in exactly at the context the error happened.
|
||||
setFirstBreakpoint(regs[1]);
|
||||
return;
|
||||
}
|
||||
esp_panicPutStr(". Exception was unhandled.\r\n");
|
||||
panicPutStr(". Exception was unhandled.\r\n");
|
||||
commonErrorHandler(frame);
|
||||
}
|
||||
|
||||
@@ -293,16 +293,16 @@ static void putEntry(uint32_t pc, uint32_t sp)
|
||||
if (pc & 0x80000000) {
|
||||
pc = (pc & 0x3fffffff) | 0x40000000;
|
||||
}
|
||||
esp_panicPutStr(" 0x");
|
||||
esp_panicPutHex(pc);
|
||||
esp_panicPutStr(":0x");
|
||||
esp_panicPutHex(sp);
|
||||
panicPutStr(" 0x");
|
||||
panicPutHex(pc);
|
||||
panicPutStr(":0x");
|
||||
panicPutHex(sp);
|
||||
}
|
||||
|
||||
static void doBacktrace(XtExcFrame *frame)
|
||||
{
|
||||
uint32_t i = 0, pc = frame->pc, sp = frame->a1;
|
||||
esp_panicPutStr("\r\nBacktrace:");
|
||||
panicPutStr("\r\nBacktrace:");
|
||||
/* Do not check sanity on first entry, PC could be smashed. */
|
||||
putEntry(pc, sp);
|
||||
pc = frame->a0;
|
||||
@@ -318,7 +318,7 @@ static void doBacktrace(XtExcFrame *frame)
|
||||
break;
|
||||
}
|
||||
}
|
||||
esp_panicPutStr("\r\n\r\n");
|
||||
panicPutStr("\r\n\r\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -342,17 +342,17 @@ static void commonErrorHandler(XtExcFrame *frame)
|
||||
the register window is no longer useful.
|
||||
*/
|
||||
if (!abort_called) {
|
||||
esp_panicPutStr("Register dump:\r\n");
|
||||
panicPutStr("Register dump:\r\n");
|
||||
|
||||
for (x = 0; x < 24; x += 4) {
|
||||
for (y = 0; y < 4; y++) {
|
||||
if (sdesc[x + y][0] != 0) {
|
||||
esp_panicPutStr(sdesc[x + y]);
|
||||
esp_panicPutStr(": 0x");
|
||||
esp_panicPutHex(regs[x + y + 1]);
|
||||
esp_panicPutStr(" ");
|
||||
panicPutStr(sdesc[x + y]);
|
||||
panicPutStr(": 0x");
|
||||
panicPutHex(regs[x + y + 1]);
|
||||
panicPutStr(" ");
|
||||
}
|
||||
esp_panicPutStr("\r\n");
|
||||
panicPutStr("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,7 +362,7 @@ static void commonErrorHandler(XtExcFrame *frame)
|
||||
|
||||
#if CONFIG_ESP32_PANIC_GDBSTUB
|
||||
disableAllWdts();
|
||||
esp_panicPutStr("Entering gdb stub now.\r\n");
|
||||
panicPutStr("Entering gdb stub now.\r\n");
|
||||
esp_gdbstub_panic_handler(frame);
|
||||
#else
|
||||
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
|
||||
@@ -372,14 +372,14 @@ static void commonErrorHandler(XtExcFrame *frame)
|
||||
esp_core_dump_to_uart(frame);
|
||||
#endif
|
||||
#if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
|
||||
esp_panicPutStr("Rebooting...\r\n");
|
||||
panicPutStr("Rebooting...\r\n");
|
||||
for (x = 0; x < 100; x++) {
|
||||
ets_delay_us(1000);
|
||||
}
|
||||
software_reset();
|
||||
#else
|
||||
disableAllWdts();
|
||||
esp_panicPutStr("CPU halted.\r\n");
|
||||
panicPutStr("CPU halted.\r\n");
|
||||
while (1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user