[debug] Use stack buffers with buf_append helper instead of std::string (#13020)

This commit is contained in:
J. Nick Koston authored and GitHub committed 2026-01-07 10:19:10 -10:00
1 parent 050e9b0d4a
commit 44eac36e05
8 files changed
+320 -208

No files matched your search

+121 -97
View File
@@ -15,14 +15,14 @@ static const char *const TAG = "debug";
constexpr std::uintptr_t MBR_PARAM_PAGE_ADDR = 0xFFC;
constexpr std::uintptr_t MBR_BOOTLOADER_ADDR = 0xFF8;
static void show_reset_reason(std::string &reset_reason, bool set, const char *reason) {
static size_t append_reset_reason(char *buf, size_t size, size_t pos, bool set, const char *reason) {
if (!set) {
return;
return pos;
}
if (!reset_reason.empty()) {
reset_reason += ", ";
if (pos > 0) {
pos = buf_append(buf, size, pos, ", ");
}
reset_reason += reason;
return buf_append(buf, size, pos, "%s", reason);
}
static inline uint32_t read_mem_u32(uintptr_t addr) {
@@ -56,33 +56,47 @@ static inline uint32_t sd_version_get() {
return 0;
}
std::string DebugComponent::get_reset_reason_() {
const char *DebugComponent::get_reset_reason_(std::span<char, RESET_REASON_BUFFER_SIZE> buffer) {
char *buf = buffer.data();
const size_t size = RESET_REASON_BUFFER_SIZE;
uint32_t cause;
auto ret = hwinfo_get_reset_cause(&cause);
if (ret) {
ESP_LOGE(TAG, "Unable to get reset cause: %d", ret);
return "";
buf[0] = '\0';
return buf;
}
std::string reset_reason;
size_t pos = 0;
show_reset_reason(reset_reason, cause & RESET_PIN, "External pin");
show_reset_reason(reset_reason, cause & RESET_SOFTWARE, "Software reset");
show_reset_reason(reset_reason, cause & RESET_BROWNOUT, "Brownout (drop in voltage)");
show_reset_reason(reset_reason, cause & RESET_POR, "Power-on reset (POR)");
show_reset_reason(reset_reason, cause & RESET_WATCHDOG, "Watchdog timer expiration");
show_reset_reason(reset_reason, cause & RESET_DEBUG, "Debug event");
show_reset_reason(reset_reason, cause & RESET_SECURITY, "Security violation");
show_reset_reason(reset_reason, cause & RESET_LOW_POWER_WAKE, "Waking up from low power mode");
show_reset_reason(reset_reason, cause & RESET_CPU_LOCKUP, "CPU lock-up detected");
show_reset_reason(reset_reason, cause & RESET_PARITY, "Parity error");
show_reset_reason(reset_reason, cause & RESET_PLL, "PLL error");
show_reset_reason(reset_reason, cause & RESET_CLOCK, "Clock error");
show_reset_reason(reset_reason, cause & RESET_HARDWARE, "Hardware reset");
show_reset_reason(reset_reason, cause & RESET_USER, "User reset");
show_reset_reason(reset_reason, cause & RESET_TEMPERATURE, "Temperature reset");
pos = append_reset_reason(buf, size, pos, cause & RESET_PIN, "External pin");
pos = append_reset_reason(buf, size, pos, cause & RESET_SOFTWARE, "Software reset");
pos = append_reset_reason(buf, size, pos, cause & RESET_BROWNOUT, "Brownout (drop in voltage)");
pos = append_reset_reason(buf, size, pos, cause & RESET_POR, "Power-on reset (POR)");
pos = append_reset_reason(buf, size, pos, cause & RESET_WATCHDOG, "Watchdog timer expiration");
pos = append_reset_reason(buf, size, pos, cause & RESET_DEBUG, "Debug event");
pos = append_reset_reason(buf, size, pos, cause & RESET_SECURITY, "Security violation");
pos = append_reset_reason(buf, size, pos, cause & RESET_LOW_POWER_WAKE, "Waking up from low power mode");
pos = append_reset_reason(buf, size, pos, cause & RESET_CPU_LOCKUP, "CPU lock-up detected");
pos = append_reset_reason(buf, size, pos, cause & RESET_PARITY, "Parity error");
pos = append_reset_reason(buf, size, pos, cause & RESET_PLL, "PLL error");
pos = append_reset_reason(buf, size, pos, cause & RESET_CLOCK, "Clock error");
pos = append_reset_reason(buf, size, pos, cause & RESET_HARDWARE, "Hardware reset");
pos = append_reset_reason(buf, size, pos, cause & RESET_USER, "User reset");
pos = append_reset_reason(buf, size, pos, cause & RESET_TEMPERATURE, "Temperature reset");
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
return reset_reason;
// Ensure null termination if nothing was written
if (pos == 0) {
buf[0] = '\0';
}
ESP_LOGD(TAG, "Reset Reason: %s", buf);
return buf;
}
const char *DebugComponent::get_wakeup_cause_(std::span<char, RESET_REASON_BUFFER_SIZE> buffer) {
// Zephyr doesn't have detailed wakeup cause like ESP32
return "";
}
uint32_t DebugComponent::get_free_heap_() { return INT_MAX; }
@@ -118,175 +132,183 @@ void DebugComponent::log_partition_info_() {
flash_area_foreach(fa_cb, nullptr);
}
void DebugComponent::get_device_info_(std::string &device_info) {
std::string supply = "Main supply status: ";
if (nrf_power_mainregstatus_get(NRF_POWER) == NRF_POWER_MAINREGSTATUS_NORMAL) {
supply += "Normal voltage.";
} else {
supply += "High voltage.";
}
ESP_LOGD(TAG, "%s", supply.c_str());
device_info += "|" + supply;
size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE> buffer, size_t pos) {
constexpr size_t size = DEVICE_INFO_BUFFER_SIZE;
char *buf = buffer.data();
std::string reg0 = "Regulator stage 0: ";
// Main supply status
const char *supply_status =
(nrf_power_mainregstatus_get(NRF_POWER) == NRF_POWER_MAINREGSTATUS_NORMAL) ? "Normal voltage." : "High voltage.";
ESP_LOGD(TAG, "Main supply status: %s", supply_status);
pos = buf_append(buf, size, pos, "|Main supply status: %s", supply_status);
// Regulator stage 0
if (nrf_power_mainregstatus_get(NRF_POWER) == NRF_POWER_MAINREGSTATUS_HIGH) {
reg0 += nrf_power_dcdcen_vddh_get(NRF_POWER) ? "DC/DC" : "LDO";
reg0 += ", ";
const char *reg0_type = nrf_power_dcdcen_vddh_get(NRF_POWER) ? "DC/DC" : "LDO";
const char *reg0_voltage;
switch (NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) {
case (UICR_REGOUT0_VOUT_DEFAULT << UICR_REGOUT0_VOUT_Pos):
reg0 += "1.8V (default)";
reg0_voltage = "1.8V (default)";
break;
case (UICR_REGOUT0_VOUT_1V8 << UICR_REGOUT0_VOUT_Pos):
reg0 += "1.8V";
reg0_voltage = "1.8V";
break;
case (UICR_REGOUT0_VOUT_2V1 << UICR_REGOUT0_VOUT_Pos):
reg0 += "2.1V";
reg0_voltage = "2.1V";
break;
case (UICR_REGOUT0_VOUT_2V4 << UICR_REGOUT0_VOUT_Pos):
reg0 += "2.4V";
reg0_voltage = "2.4V";
break;
case (UICR_REGOUT0_VOUT_2V7 << UICR_REGOUT0_VOUT_Pos):
reg0 += "2.7V";
reg0_voltage = "2.7V";
break;
case (UICR_REGOUT0_VOUT_3V0 << UICR_REGOUT0_VOUT_Pos):
reg0 += "3.0V";
reg0_voltage = "3.0V";
break;
case (UICR_REGOUT0_VOUT_3V3 << UICR_REGOUT0_VOUT_Pos):
reg0 += "3.3V";
reg0_voltage = "3.3V";
break;
default:
reg0 += "???V";
reg0_voltage = "???V";
}
ESP_LOGD(TAG, "Regulator stage 0: %s, %s", reg0_type, reg0_voltage);
pos = buf_append(buf, size, pos, "|Regulator stage 0: %s, %s", reg0_type, reg0_voltage);
} else {
reg0 += "disabled";
ESP_LOGD(TAG, "Regulator stage 0: disabled");
pos = buf_append(buf, size, pos, "|Regulator stage 0: disabled");
}
ESP_LOGD(TAG, "%s", reg0.c_str());
device_info += "|" + reg0;
std::string reg1 = "Regulator stage 1: ";
reg1 += nrf_power_dcdcen_get(NRF_POWER) ? "DC/DC" : "LDO";
ESP_LOGD(TAG, "%s", reg1.c_str());
device_info += "|" + reg1;
// Regulator stage 1
const char *reg1_type = nrf_power_dcdcen_get(NRF_POWER) ? "DC/DC" : "LDO";
ESP_LOGD(TAG, "Regulator stage 1: %s", reg1_type);
pos = buf_append(buf, size, pos, "|Regulator stage 1: %s", reg1_type);
std::string usb_power = "USB power state: ";
// USB power state
const char *usb_state;
if (nrf_power_usbregstatus_vbusdet_get(NRF_POWER)) {
if (nrf_power_usbregstatus_outrdy_get(NRF_POWER)) {
/**< From the power viewpoint, USB is ready for working. */
usb_power += "ready";
usb_state = "ready";
} else {
/**< The USB power is detected, but USB power regulator is not ready. */
usb_power += "connected (regulator is not ready)";
usb_state = "connected (regulator is not ready)";
}
} else {
/**< No power on USB lines detected. */
usb_power += "disconected";
usb_state = "disconnected";
}
ESP_LOGD(TAG, "%s", usb_power.c_str());
device_info += "|" + usb_power;
ESP_LOGD(TAG, "USB power state: %s", usb_state);
pos = buf_append(buf, size, pos, "|USB power state: %s", usb_state);
// Power-fail comparator
bool enabled;
nrf_power_pof_thr_t pof_thr;
pof_thr = nrf_power_pofcon_get(NRF_POWER, &enabled);
std::string pof = "Power-fail comparator: ";
nrf_power_pof_thr_t pof_thr = nrf_power_pofcon_get(NRF_POWER, &enabled);
if (enabled) {
const char *pof_voltage;
switch (pof_thr) {
case POWER_POFCON_THRESHOLD_V17:
pof += "1.7V";
pof_voltage = "1.7V";
break;
case POWER_POFCON_THRESHOLD_V18:
pof += "1.8V";
pof_voltage = "1.8V";
break;
case POWER_POFCON_THRESHOLD_V19:
pof += "1.9V";
pof_voltage = "1.9V";
break;
case POWER_POFCON_THRESHOLD_V20:
pof += "2.0V";
pof_voltage = "2.0V";
break;
case POWER_POFCON_THRESHOLD_V21:
pof += "2.1V";
pof_voltage = "2.1V";
break;
case POWER_POFCON_THRESHOLD_V22:
pof += "2.2V";
pof_voltage = "2.2V";
break;
case POWER_POFCON_THRESHOLD_V23:
pof += "2.3V";
pof_voltage = "2.3V";
break;
case POWER_POFCON_THRESHOLD_V24:
pof += "2.4V";
pof_voltage = "2.4V";
break;
case POWER_POFCON_THRESHOLD_V25:
pof += "2.5V";
pof_voltage = "2.5V";
break;
case POWER_POFCON_THRESHOLD_V26:
pof += "2.6V";
pof_voltage = "2.6V";
break;
case POWER_POFCON_THRESHOLD_V27:
pof += "2.7V";
pof_voltage = "2.7V";
break;
case POWER_POFCON_THRESHOLD_V28:
pof += "2.8V";
pof_voltage = "2.8V";
break;
default:
pof_voltage = "???V";
break;
}
if (nrf_power_mainregstatus_get(NRF_POWER) == NRF_POWER_MAINREGSTATUS_HIGH) {
pof += ", VDDH: ";
const char *vddh_voltage;
switch (nrf_power_pofcon_vddh_get(NRF_POWER)) {
case NRF_POWER_POFTHRVDDH_V27:
pof += "2.7V";
vddh_voltage = "2.7V";
break;
case NRF_POWER_POFTHRVDDH_V28:
pof += "2.8V";
vddh_voltage = "2.8V";
break;
case NRF_POWER_POFTHRVDDH_V29:
pof += "2.9V";
vddh_voltage = "2.9V";
break;
case NRF_POWER_POFTHRVDDH_V30:
pof += "3.0V";
vddh_voltage = "3.0V";
break;
case NRF_POWER_POFTHRVDDH_V31:
pof += "3.1V";
vddh_voltage = "3.1V";
break;
case NRF_POWER_POFTHRVDDH_V32:
pof += "3.2V";
vddh_voltage = "3.2V";
break;
case NRF_POWER_POFTHRVDDH_V33:
pof += "3.3V";
vddh_voltage = "3.3V";
break;
case NRF_POWER_POFTHRVDDH_V34:
pof += "3.4V";
vddh_voltage = "3.4V";
break;
case NRF_POWER_POFTHRVDDH_V35:
pof += "3.5V";
vddh_voltage = "3.5V";
break;
case NRF_POWER_POFTHRVDDH_V36:
pof += "3.6V";
vddh_voltage = "3.6V";
break;
case NRF_POWER_POFTHRVDDH_V37:
pof += "3.7V";
vddh_voltage = "3.7V";
break;
case NRF_POWER_POFTHRVDDH_V38:
pof += "3.8V";
vddh_voltage = "3.8V";
break;
case NRF_POWER_POFTHRVDDH_V39:
pof += "3.9V";
vddh_voltage = "3.9V";
break;
case NRF_POWER_POFTHRVDDH_V40:
pof += "4.0V";
vddh_voltage = "4.0V";
break;
case NRF_POWER_POFTHRVDDH_V41:
pof += "4.1V";
vddh_voltage = "4.1V";
break;
case NRF_POWER_POFTHRVDDH_V42:
pof += "4.2V";
vddh_voltage = "4.2V";
break;
default:
vddh_voltage = "???V";
break;
}
ESP_LOGD(TAG, "Power-fail comparator: %s, VDDH: %s", pof_voltage, vddh_voltage);
pos = buf_append(buf, size, pos, "|Power-fail comparator: %s, VDDH: %s", pof_voltage, vddh_voltage);
} else {
ESP_LOGD(TAG, "Power-fail comparator: %s", pof_voltage);
pos = buf_append(buf, size, pos, "|Power-fail comparator: %s", pof_voltage);
}
} else {
pof += "disabled";
ESP_LOGD(TAG, "Power-fail comparator: disabled");
pos = buf_append(buf, size, pos, "|Power-fail comparator: disabled");
}
ESP_LOGD(TAG, "%s", pof.c_str());
device_info += "|" + pof;
auto package = [](uint32_t value) {
switch (value) {
@@ -373,6 +395,8 @@ void DebugComponent::get_device_info_(std::string &device_info) {
"NRFFW %s\n"
"NRFHW %s",
uicr(NRF_UICR->NRFFW, 13).c_str(), uicr(NRF_UICR->NRFHW, 12).c_str());
return pos;
}
void DebugComponent::update_platform_() {}