mirror of
https://github.com/BotChain-Robots/firmware.git
synced 2026-07-08 09:37:21 +02:00
148 lines
4.6 KiB
C++
148 lines
4.6 KiB
C++
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <cstdio>
|
|
#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;
|
|
out.resize(1024);
|
|
vTaskGetRunTimeStats(out.data());
|
|
out.resize(425);
|
|
return out;
|
|
}
|
|
|
|
std::string RemoteDebugging::get_logs() {
|
|
std::string out;
|
|
auto logs = log_buffer->peek_drain();
|
|
for (auto it = logs.rbegin(); it != logs.rend(); ++it) {
|
|
out.append(*it);
|
|
}
|
|
out.resize(800);
|
|
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<esp_core_dump_summary_t *>(
|
|
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();
|
|
std::vector<uint8_t> vec(out.begin(), out.end());
|
|
writer.write(vec);
|
|
});
|
|
messaging_interface.register_function(3, [](const uint8_t *parameters, size_t parameter_size, Writer& writer) {
|
|
auto out = get_logs();
|
|
std::vector<uint8_t> vec(out.begin(), out.end());
|
|
writer.write(vec);
|
|
});
|
|
messaging_interface.register_function(69, [](const uint8_t *parameters, size_t parameter_size, Writer& writer) {
|
|
uint8_t out = esp_reset_reason();
|
|
std::vector<uint8_t> vec{out};
|
|
});
|
|
messaging_interface.register_function(13, [](const uint8_t *parameters, size_t parameter_size, Writer& writer) {
|
|
auto out = get_coredump_summary();
|
|
std::vector<uint8_t> vec(out.begin(), out.end());
|
|
writer.write(vec);
|
|
});
|
|
}
|
|
|
|
int RemoteDebugging::custom_log_write(const char *data, va_list args) {
|
|
char tmp[512];
|
|
|
|
va_list copy;
|
|
va_copy(copy, args);
|
|
int len = vsnprintf(tmp, sizeof(tmp), data, copy);
|
|
va_end(copy);
|
|
|
|
std::string str;
|
|
str.assign(tmp, len);
|
|
std::cout << str;
|
|
log_buffer->push(std::move(str));
|
|
|
|
return 0;
|
|
}
|