18#if PC_ENABLE_EXC_DECODER && defined(ARDUINO)
21#include <esp_core_dump.h>
22#include <esp_partition.h>
25bool pc_exc_coredump_present(ExcCoreDump *out)
31 if (esp_core_dump_image_get(&addr, &size) != ESP_OK || size == 0)
35 if (esp_core_dump_image_check() != ESP_OK)
41 out->addr = (uint32_t)addr;
47bool pc_exc_coredump_summary(ExcInfo *out)
53#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF
54 esp_core_dump_summary_t s;
55 memset(&s, 0,
sizeof(s));
56 if (esp_core_dump_get_summary(&s) != ESP_OK)
61 memset(out, 0,
sizeof(*out));
66 strncpy(out->cause, s.exc_task,
sizeof(out->cause) - 1);
67 out->cause[
sizeof(out->cause) - 1] =
'\0';
69#if CONFIG_IDF_TARGET_ARCH_XTENSA
71 out->excvaddr = s.ex_info.exc_vaddr;
72 out->has_excvaddr =
true;
73 size_t depth = s.exc_bt_info.depth;
74 if (depth > PC_EXC_MAX_FRAMES)
76 depth = PC_EXC_MAX_FRAMES;
78 for (
size_t i = 0; i < depth; i++)
80 out->frames[i].pc = s.exc_bt_info.bt[i];
81 out->frames[i].sp = 0;
83 out->frame_count = depth;
87 out->excvaddr = s.ex_info.mtval;
88 out->has_excvaddr =
true;
100static bool coredump_locate(
const esp_partition_t **part_out,
size_t *base_out,
size_t *size_out)
103 if (!pc_exc_coredump_present(&img))
107 const esp_partition_t *part =
108 esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP,
nullptr);
109 if (!part || img.addr < part->address)
113 size_t base = (size_t)(img.addr - part->address);
114 if (base + img.size > part->size)
120 *size_out = img.size;
124bool pc_exc_coredump_read(
size_t offset,
void *buf,
size_t len)
135 const esp_partition_t *part =
nullptr;
138 if (!coredump_locate(&part, &base, &size))
143 if (offset > size || len > size - offset)
147 return esp_partition_read(part, base + offset, buf, len) == ESP_OK;
150bool pc_exc_coredump_save(fs::FS &file_sys,
const char *path)
152 if (!path || path[0] ==
'\0')
157 const esp_partition_t *part =
nullptr;
160 if (!coredump_locate(&part, &base, &size))
165 fs::File f = file_sys.open(path, FILE_WRITE);
177 size_t n = (size - off <
sizeof(buf)) ? size - off :
sizeof(buf);
178 if (esp_partition_read(part, base + off, buf, n) != ESP_OK || f.write(buf, n) != n)
188 file_sys.remove(path);
193bool pc_exc_coredump_erase(
void)
195 return esp_core_dump_image_erase() == ESP_OK;
ESP32 panic / exception decoder for a live diagnostics panel (PC_ENABLE_EXC_DECODER).
#define PC_EXC_COREDUMP_CHUNK
Chunk the core-dump image is streamed out of flash in (PC_EXC_COREDUMP_CHUNK).