mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-06-15 12:26:33 +03:00
min_free_mem_
This commit is contained in:
@@ -87,6 +87,7 @@ PButton System::myPButton_;
|
|||||||
bool System::test_set_all_active_ = false;
|
bool System::test_set_all_active_ = false;
|
||||||
uint32_t System::max_alloc_mem_;
|
uint32_t System::max_alloc_mem_;
|
||||||
uint32_t System::heap_mem_;
|
uint32_t System::heap_mem_;
|
||||||
|
uint32_t System::min_free_mem_;
|
||||||
|
|
||||||
// GPIOs
|
// GPIOs
|
||||||
std::vector<uint8_t, AllocatorPSRAM<uint8_t>> System::valid_system_gpios_;
|
std::vector<uint8_t, AllocatorPSRAM<uint8_t>> System::valid_system_gpios_;
|
||||||
@@ -173,7 +174,7 @@ bool System::command_sendmail(const char * value, const int8_t id) {
|
|||||||
delete basic_client;
|
delete basic_client;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
JsonDocument doc;
|
JsonDocument doc(PSRAM_DOC);
|
||||||
String body = value;
|
String body = value;
|
||||||
if (body.length()) {
|
if (body.length()) {
|
||||||
auto error = deserializeJson(doc, (const char *)value);
|
auto error = deserializeJson(doc, (const char *)value);
|
||||||
@@ -922,6 +923,11 @@ void System::heartbeat_json(JsonObject output) {
|
|||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
output["freemem"] = getHeapMem();
|
output["freemem"] = getHeapMem();
|
||||||
output["max_alloc"] = getMaxAllocMem();
|
output["max_alloc"] = getMaxAllocMem();
|
||||||
|
// All-time low watermark of free internal heap (KB). Unlike freemem
|
||||||
|
// (sampled now), this captures the worst transient dip since boot —
|
||||||
|
// the actual metric to watch when measuring the effect of transient
|
||||||
|
// allocation optimisations (e.g. JsonDocument on PSRAM).
|
||||||
|
output["min_free"] = getMinFreeMem();
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
|
||||||
output["temperature"] = (int)temperature_;
|
output["temperature"] = (int)temperature_;
|
||||||
@@ -1076,13 +1082,33 @@ void System::show_system(uuid::console::Shell & shell) {
|
|||||||
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
|
||||||
shell.printfln(" CPU temperature: %d °C", (int)temperature());
|
shell.printfln(" CPU temperature: %d °C", (int)temperature());
|
||||||
#endif
|
#endif
|
||||||
shell.printfln(" Free heap/Max alloc: %lu KB / %lu KB", getHeapMem(), getMaxAllocMem());
|
// Free heap = current; Min free = all-time low watermark (lowest free
|
||||||
|
// heap has ever been since boot). Min free is the actual metric that
|
||||||
|
// reflects optimisations targeting transient peaks (publishes, /api/system,
|
||||||
|
// TLS handshakes). If transient peaks are reduced, min_free goes up.
|
||||||
|
shell.printfln(" Free heap/Max alloc/Min free: %lu KB / %lu KB / %lu KB", getHeapMem(), getMaxAllocMem(), getMinFreeMem());
|
||||||
|
#ifndef EMSESP_STANDALONE
|
||||||
|
// Largest contiguous free block of *internal* SRAM. Network stack
|
||||||
|
// (LwIP/mbedTLS/AsyncTCP) and JSON output allocations need this to be
|
||||||
|
// healthy — total free heap can look fine while this collapses due to
|
||||||
|
// fragmentation. Compare before and after a big API call or MQTT publish.
|
||||||
|
shell.printfln(" Internal heap free/largest block: %u KB / %u KB",
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) / 1024,
|
||||||
|
heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) / 1024);
|
||||||
|
#endif
|
||||||
shell.printfln(" App used/free: %lu KB / %lu KB", appUsed(), appFree());
|
shell.printfln(" App used/free: %lu KB / %lu KB", appUsed(), appFree());
|
||||||
uint32_t FSused = LittleFS.usedBytes() / 1024;
|
uint32_t FSused = LittleFS.usedBytes() / 1024;
|
||||||
shell.printfln(" FS used/free: %lu KB / %lu KB", FSused, FStotal() - FSused);
|
shell.printfln(" FS used/free: %lu KB / %lu KB", FSused, FStotal() - FSused);
|
||||||
shell.printfln(" Flash size: %lu KB", ESP.getFlashChipSize() / 1024);
|
shell.printfln(" Flash size: %lu KB", ESP.getFlashChipSize() / 1024);
|
||||||
if (PSram()) {
|
if (PSram()) {
|
||||||
|
#ifndef EMSESP_STANDALONE
|
||||||
|
shell.printfln(" PSRAM size/free/largest block: %lu KB / %lu KB / %u KB",
|
||||||
|
PSram(),
|
||||||
|
ESP.getFreePsram() / 1024,
|
||||||
|
heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM) / 1024);
|
||||||
|
#else
|
||||||
shell.printfln(" PSRAM size/free: %lu KB / %lu KB", PSram(), ESP.getFreePsram() / 1024);
|
shell.printfln(" PSRAM size/free: %lu KB / %lu KB", PSram(), ESP.getFreePsram() / 1024);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
shell.printfln(" PSRAM: not available");
|
shell.printfln(" PSRAM: not available");
|
||||||
}
|
}
|
||||||
@@ -1227,7 +1253,7 @@ bool System::check_restore() {
|
|||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
File new_file = LittleFS.open(TEMP_FILENAME_PATH);
|
File new_file = LittleFS.open(TEMP_FILENAME_PATH);
|
||||||
if (new_file) {
|
if (new_file) {
|
||||||
JsonDocument jsonDocument;
|
JsonDocument jsonDocument(PSRAM_DOC);
|
||||||
DeserializationError error = deserializeJson(jsonDocument, new_file);
|
DeserializationError error = deserializeJson(jsonDocument, new_file);
|
||||||
if (error == DeserializationError::Ok && jsonDocument.is<JsonObject>()) {
|
if (error == DeserializationError::Ok && jsonDocument.is<JsonObject>()) {
|
||||||
JsonObject input = jsonDocument.as<JsonObject>();
|
JsonObject input = jsonDocument.as<JsonObject>();
|
||||||
@@ -1591,7 +1617,7 @@ void System::exportSettings(const std::string & type, const char * filename, Jso
|
|||||||
File settingsFile = LittleFS.open(filename);
|
File settingsFile = LittleFS.open(filename);
|
||||||
if (settingsFile) {
|
if (settingsFile) {
|
||||||
{
|
{
|
||||||
JsonDocument jsonDocument;
|
JsonDocument jsonDocument(PSRAM_DOC);
|
||||||
DeserializationError error = deserializeJson(jsonDocument, settingsFile);
|
DeserializationError error = deserializeJson(jsonDocument, settingsFile);
|
||||||
settingsFile.close(); // close early, we no longer need the file
|
settingsFile.close(); // close early, we no longer need the file
|
||||||
if (error || !jsonDocument.is<JsonObject>()) {
|
if (error || !jsonDocument.is<JsonObject>()) {
|
||||||
@@ -1650,7 +1676,7 @@ void System::exportSystemBackup(JsonObject output) {
|
|||||||
// special case for custom support
|
// special case for custom support
|
||||||
File file = LittleFS.open(EMSESP_CUSTOMSUPPORT_FILE, "r");
|
File file = LittleFS.open(EMSESP_CUSTOMSUPPORT_FILE, "r");
|
||||||
if (file) {
|
if (file) {
|
||||||
JsonDocument jsonDocument;
|
JsonDocument jsonDocument(PSRAM_DOC);
|
||||||
DeserializationError error = deserializeJson(jsonDocument, file);
|
DeserializationError error = deserializeJson(jsonDocument, file);
|
||||||
file.close(); // close early, we no longer need the file
|
file.close(); // close early, we no longer need the file
|
||||||
if (!error && jsonDocument.is<JsonObject>()) {
|
if (!error && jsonDocument.is<JsonObject>()) {
|
||||||
@@ -1859,7 +1885,7 @@ bool System::get_value_info(JsonObject output, const char * cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fetch all the data from the system in a different json
|
// fetch all the data from the system in a different json
|
||||||
JsonDocument doc;
|
JsonDocument doc(PSRAM_DOC);
|
||||||
JsonObject root = doc.to<JsonObject>();
|
JsonObject root = doc.to<JsonObject>();
|
||||||
(void)command_info("", 0, root);
|
(void)command_info("", 0, root);
|
||||||
|
|
||||||
@@ -1954,7 +1980,7 @@ std::string System::get_metrics_prometheus() {
|
|||||||
result.reserve(16000);
|
result.reserve(16000);
|
||||||
|
|
||||||
// get system data
|
// get system data
|
||||||
JsonDocument doc;
|
JsonDocument doc(PSRAM_DOC);
|
||||||
JsonObject root = doc.to<JsonObject>();
|
JsonObject root = doc.to<JsonObject>();
|
||||||
(void)command_info("", 0, root);
|
(void)command_info("", 0, root);
|
||||||
|
|
||||||
@@ -2233,6 +2259,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
|||||||
node["sdk"] = ESP.getSdkVersion();
|
node["sdk"] = ESP.getSdkVersion();
|
||||||
node["freeMem"] = getHeapMem();
|
node["freeMem"] = getHeapMem();
|
||||||
node["maxAlloc"] = getMaxAllocMem();
|
node["maxAlloc"] = getMaxAllocMem();
|
||||||
|
node["minFree"] = getMinFreeMem(); // all-time low watermark of internal heap
|
||||||
node["freeCaps"] = heap_caps_get_free_size(MALLOC_CAP_8BIT) / 1024; // includes heap and psram
|
node["freeCaps"] = heap_caps_get_free_size(MALLOC_CAP_8BIT) / 1024; // includes heap and psram
|
||||||
node["usedApp"] = EMSESP::system_.appUsed(); // kilobytes
|
node["usedApp"] = EMSESP::system_.appUsed(); // kilobytes
|
||||||
node["freeApp"] = EMSESP::system_.appFree(); // kilobytes
|
node["freeApp"] = EMSESP::system_.appFree(); // kilobytes
|
||||||
|
|||||||
@@ -299,10 +299,20 @@ class System {
|
|||||||
static uint32_t getHeapMem() {
|
static uint32_t getHeapMem() {
|
||||||
return heap_mem_;
|
return heap_mem_;
|
||||||
}
|
}
|
||||||
|
// All-time low watermark of free internal heap (KB).
|
||||||
|
// Unlike getHeapMem() (sampled now), this captures the *lowest* free heap
|
||||||
|
// has ever been since boot — i.e. the worst transient dip during MQTT
|
||||||
|
// publishes, HA discovery, /api/system calls, TLS handshakes, etc.
|
||||||
|
// This is the number that actually reflects optimisations targeting
|
||||||
|
// transient JSON / buffer peaks (e.g. Phase C PSRAM JsonDocuments).
|
||||||
|
static uint32_t getMinFreeMem() {
|
||||||
|
return min_free_mem_;
|
||||||
|
}
|
||||||
static void refreshHeapMem() {
|
static void refreshHeapMem() {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
max_alloc_mem_ = ESP.getMaxAllocHeap() / 1024;
|
max_alloc_mem_ = ESP.getMaxAllocHeap() / 1024;
|
||||||
heap_mem_ = ESP.getFreeHeap() / 1024;
|
heap_mem_ = ESP.getFreeHeap() / 1024;
|
||||||
|
min_free_mem_ = ESP.getMinFreeHeap() / 1024;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,6 +356,7 @@ class System {
|
|||||||
static bool test_set_all_active_; // force all entities in a device to have a value
|
static bool test_set_all_active_; // force all entities in a device to have a value
|
||||||
static uint32_t max_alloc_mem_;
|
static uint32_t max_alloc_mem_;
|
||||||
static uint32_t heap_mem_;
|
static uint32_t heap_mem_;
|
||||||
|
static uint32_t min_free_mem_;
|
||||||
|
|
||||||
uint8_t systemStatus_; // uses SYSTEM_STATUS enum
|
uint8_t systemStatus_; // uses SYSTEM_STATUS enum
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user