diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index f285319..1949711 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -17,7 +17,7 @@ else() endif() idf_component_register(SRCS ${ALL_SRCS} - PRIV_REQUIRES esp_psram spi_flash nvs_flash esp_event rpc constants config rmt esp_driver_gptimer dataLink flatbuffers esp_driver_ledc oled app_update vl53l0x + PRIV_REQUIRES esp_psram spi_flash nvs_flash esp_event rpc constants config rmt esp_driver_gptimer dataLink flatbuffers esp_driver_ledc oled app_update vl53l0x espcoredump INCLUDE_DIRS "include") if(DEFINED SRC_BOARD AND SRC_BOARD) diff --git a/main/RemoteDebugging.cpp b/main/RemoteDebugging.cpp index 8c89c96..ba746a8 100644 --- a/main/RemoteDebugging.cpp +++ b/main/RemoteDebugging.cpp @@ -1,9 +1,13 @@ #include #include +#include #include "RemoteDebugging.h" #include "freertos/FreeRTOS.h" #include "esp_debug_helpers.h" +#include "esp_core_dump.h" + +#define TAG "RemoteDebugging" std::string RemoteDebugging::get_task_manager() { std::string out; @@ -22,6 +26,87 @@ std::string RemoteDebugging::get_logs() { return out; } +std::string RemoteDebugging::get_coredump_summary() { + esp_err_t check_err = esp_core_dump_image_check(); + if (check_err == ESP_ERR_NOT_FOUND) { + ESP_LOGW(TAG, "No core dump found in flash."); + return "No core dump found in flash.\n"; + } + if (check_err == ESP_ERR_NOT_SUPPORTED) { + ESP_LOGW(TAG, "Core dump partition not found."); + return "Core dump partition not found.\n"; + } + if (check_err == ESP_ERR_INVALID_CRC) { + ESP_LOGW(TAG, "Core dump flash is corrupted (checksum mismatch)"); + return "Core dump in flash is corrupted (checksum mismatch).\n"; + } + if (check_err != ESP_OK) { + ESP_LOGW(TAG, "Core dump check failed: 0x%x", check_err); + char buf[80]; + snprintf(buf, sizeof(buf), "Core dump check failed: 0x%x\n", check_err); + return buf; + } + + esp_core_dump_summary_t *summary = static_cast( + malloc(sizeof(esp_core_dump_summary_t))); + if (!summary) { + ESP_LOGW(TAG, "Failed to allocate memory for core dump summary"); + return "Failed to allocate memory for core dump summary.\n"; + } + + std::string out; + esp_err_t err = esp_core_dump_get_summary(summary); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to get core dump summary: 0x%x", err); + char buf[64]; + snprintf(buf, sizeof(buf), "Failed to get core dump summary: 0x%x\n", err); + out = std::string(buf); + free(summary); + return out; + } + + // Panic reason + char reason[200] = {}; + if (esp_core_dump_get_panic_reason(reason, sizeof(reason)) == ESP_OK) { + ESP_LOGI(TAG, "Panic reason: %s", reason); + out += "Panic reason: "; + out += reason; + out += "\n"; + } + + // Faulting task and PC + char line[128]; + snprintf(line, sizeof(line), + "Faulting task: %s (TCB: 0x%08" PRIx32 ")\n" + "Exception PC: 0x%08" PRIx32 "\n" + "Exception cause: %" PRIu32 " vaddr: 0x%08" PRIx32 "\n", + summary->exc_task, + summary->exc_tcb, + summary->exc_pc, + summary->ex_info.exc_cause, + summary->ex_info.exc_vaddr); + out += line; + + ESP_LOGI(TAG, "%s", line); + + // Backtrace + out += "Backtrace:"; + for (uint32_t i = 0; i < summary->exc_bt_info.depth && i < 16; i++) { + char bt_entry[16]; + snprintf(bt_entry, sizeof(bt_entry), " 0x%08" PRIx32, summary->exc_bt_info.bt[i]); + out += bt_entry; + } + if (summary->exc_bt_info.corrupted) { + out += " (corrupted)"; + } + out += "\n"; + + ESP_LOGI(TAG, "Backtrace: %s", out); + + free(summary); + return out; +} + void RemoteDebugging::register_calls(MessagingInterface &messaging_interface) { messaging_interface.register_function(2, [](const uint8_t *parameters, size_t parameter_size, Writer& writer) { auto out = get_task_manager(); @@ -36,6 +121,10 @@ void RemoteDebugging::register_calls(MessagingInterface &messaging_interface) { messaging_interface.register_function(69, [](const uint8_t *parameters, size_t parameter_size, Writer& writer) { uint8_t out = esp_reset_reason(); std::vector vec{out}; + }); + messaging_interface.register_function(13, [](const uint8_t *parameters, size_t parameter_size, Writer& writer) { + auto out = get_coredump_summary(); + std::vector vec(out.begin(), out.end()); writer.write(vec); }); } diff --git a/main/include/RemoteDebugging.h b/main/include/RemoteDebugging.h index 6e614b7..6978e00 100644 --- a/main/include/RemoteDebugging.h +++ b/main/include/RemoteDebugging.h @@ -17,6 +17,7 @@ class RemoteDebugging { public: static std::string get_task_manager(); static std::string get_logs(); + static std::string get_coredump_summary(); static int custom_log_write(const char *data, va_list args); static void register_calls(MessagingInterface &messaging_interface); private: diff --git a/partitions.csv b/partitions.csv new file mode 100644 index 0000000..001e8b2 --- /dev/null +++ b/partitions.csv @@ -0,0 +1,8 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap,,,, +nvs, data, nvs, , 0x6000, +otadata, data, ota, , 0x2000, +phy_init, data, phy, , 0x1000, +ota_0, app, ota_0, , 1648K, +ota_1, app, ota_1, , 1648K, +coredump,data,coredump,,64k, \ No newline at end of file diff --git a/sdkconfig b/sdkconfig index 07826de..2812e67 100644 --- a/sdkconfig +++ b/sdkconfig @@ -586,10 +586,10 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set -CONFIG_PARTITION_TABLE_TWO_OTA_LARGE=y -# CONFIG_PARTITION_TABLE_CUSTOM is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set +CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_two_ota_large.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table @@ -1307,6 +1307,26 @@ CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi +# +# Core dump +# +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_NONE is not set +# CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN is not set +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_CRC32=y +# CONFIG_ESP_COREDUMP_CHECKSUM_SHA256 is not set +# CONFIG_ESP_COREDUMP_CAPTURE_DRAM is not set +CONFIG_ESP_COREDUMP_CHECK_BOOT=y +CONFIG_ESP_COREDUMP_ENABLE=y +CONFIG_ESP_COREDUMP_LOGS=y +CONFIG_ESP_COREDUMP_MAX_TASKS_NUM=64 +# CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE is not set +CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y +CONFIG_ESP_COREDUMP_STACK_SIZE=1792 +# end of Core dump + # # FreeRTOS # @@ -1356,7 +1376,7 @@ CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_ISR_STACKSIZE=2096 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y # CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y @@ -2121,6 +2141,16 @@ CONFIG_WPA_MBEDTLS_TLS_CLIENT=y # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set # CONFIG_WPA_WPS_STRICT is not set # CONFIG_WPA_DEBUG_PRINT is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE is not set +# CONFIG_ESP32_COREDUMP_DATA_FORMAT_BIN is not set +CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP32_COREDUMP_CHECKSUM_CRC32=y +# CONFIG_ESP32_COREDUMP_CHECKSUM_SHA256 is not set +CONFIG_ESP32_ENABLE_COREDUMP=y +CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM=64 +CONFIG_ESP32_CORE_DUMP_STACK_SIZE=1792 CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10