mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-08 20:46:52 +03:00
add HIMEM debugging tools (check free size, and memory test) (#1852)
* Update defines.h * Update esp_sys.h * Update esp_sys.cpp * Add files via upload * Update perfmon.c * Update main.cpp * Update main.cpp * Delete himem_memory_check.c * Add files via upload * Update defines.h * Update himem_memory_check.cpp * Update main.cpp * Update himem_memory_check.cpp * Update himem_memory_check.h * Update main.cpp
This commit is contained in:
@@ -9,13 +9,6 @@
|
|||||||
|
|
||||||
#include "esp_chip_info.h"
|
#include "esp_chip_info.h"
|
||||||
|
|
||||||
// for esp_spiram_get_size
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
#include <esp32/spiram.h>
|
|
||||||
#include <esp32/himem.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Restart() {
|
void Restart() {
|
||||||
esp_restart();
|
esp_restart();
|
||||||
@@ -126,6 +119,8 @@ std::string get_device_info()
|
|||||||
else
|
else
|
||||||
espInfoResultStr += " External Flash memory\n";
|
espInfoResultStr += " External Flash memory\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_HIMEM_IF_AVAILABLE
|
||||||
sprintf(aMsgBuf,"spiram size %u\n", esp_spiram_get_size());
|
sprintf(aMsgBuf,"spiram size %u\n", esp_spiram_get_size());
|
||||||
espInfoResultStr += std::string(aMsgBuf);
|
espInfoResultStr += std::string(aMsgBuf);
|
||||||
sprintf(aMsgBuf,"himem free %u\n", esp_himem_get_free_size());
|
sprintf(aMsgBuf,"himem free %u\n", esp_himem_get_free_size());
|
||||||
@@ -133,6 +128,8 @@ std::string get_device_info()
|
|||||||
sprintf(aMsgBuf,"himem phys %u\n", esp_himem_get_phys_size());
|
sprintf(aMsgBuf,"himem phys %u\n", esp_himem_get_phys_size());
|
||||||
espInfoResultStr += std::string(aMsgBuf);
|
espInfoResultStr += std::string(aMsgBuf);
|
||||||
sprintf(aMsgBuf,"himem reserved %u\n", esp_himem_reserved_area_size());
|
sprintf(aMsgBuf,"himem reserved %u\n", esp_himem_reserved_area_size());
|
||||||
|
espInfoResultStr += std::string(aMsgBuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
return espInfoResultStr;
|
return espInfoResultStr;
|
||||||
}
|
}
|
||||||
@@ -163,6 +160,19 @@ size_t getMinEverFreeMemInternal(){ //Min. Ever Free Size
|
|||||||
size_t getMinEverFreeMemSPIRAM(){ //Min. Ever Free Size
|
size_t getMinEverFreeMemSPIRAM(){ //Min. Ever Free Size
|
||||||
return heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM);
|
return heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM);
|
||||||
}
|
}
|
||||||
//#endif // ESP_IDF_VERSION
|
|
||||||
|
#ifdef USE_HIMEM_IF_AVAILABLE
|
||||||
|
size_t getHimemTotSpace(){
|
||||||
|
return esp_himem_get_phys_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getHimemFreeSpace(){
|
||||||
|
return esp_himem_get_free_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getHimemReservedArea(){
|
||||||
|
return esp_himem_reserved_area_size();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif //DEBUG_ENABLE_SYSINFO
|
#endif //DEBUG_ENABLE_SYSINFO
|
||||||
@@ -16,6 +16,14 @@
|
|||||||
#include <esp_spi_flash.h>
|
#include <esp_spi_flash.h>
|
||||||
#include <esp_heap_caps.h>
|
#include <esp_heap_caps.h>
|
||||||
|
|
||||||
|
// for esp_spiram_get_size
|
||||||
|
extern "C" {
|
||||||
|
#include <esp32/spiram.h>
|
||||||
|
#ifdef USE_HIMEM_IF_AVAILABLE
|
||||||
|
#include <esp32/himem.h>
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Restart();
|
void Restart();
|
||||||
@@ -26,15 +34,6 @@
|
|||||||
uint32_t GetFreeHeap();
|
uint32_t GetFreeHeap();
|
||||||
uint32_t GetLeastHeapFreeSinceBoot();
|
uint32_t GetLeastHeapFreeSinceBoot();
|
||||||
|
|
||||||
/*
|
|
||||||
bool CHIP_FEATURE_EMB_FLASH; //Chip has embedded flash memory.
|
|
||||||
bool CHIP_FEATURE_WIFI_BGN; //Chip has 2.4GHz WiFi.
|
|
||||||
bool CHIP_FEATURE_BLE; //Chip has Bluetooth LE.
|
|
||||||
bool CHIP_FEATURE_BT; //Chip has Bluetooth Classic.
|
|
||||||
bool CHIP_FEATURE_IEEE802154; //Chip has IEEE 802.15.4 (Zigbee/Thread)
|
|
||||||
bool CHIP_FEATURE_EMB_PSRAM; //Chip has embedded psram.
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::string get_device_info();
|
std::string get_device_info();
|
||||||
|
|
||||||
size_t getFreeMemoryInternal();
|
size_t getFreeMemoryInternal();
|
||||||
@@ -43,6 +42,12 @@
|
|||||||
size_t getLargestFreeBlockSPIRAM();
|
size_t getLargestFreeBlockSPIRAM();
|
||||||
size_t getMinEverFreeMemInternal();
|
size_t getMinEverFreeMemInternal();
|
||||||
size_t getMinEverFreeMemSPIRAM();
|
size_t getMinEverFreeMemSPIRAM();
|
||||||
|
#ifdef USE_HIMEM_IF_AVAILABLE
|
||||||
|
size_t getHimemTotSpace();
|
||||||
|
size_t getHimemFreeSpace();
|
||||||
|
size_t getHimemReservedArea();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif //ESP_SYS_H
|
#endif //ESP_SYS_H
|
||||||
|
|
||||||
|
|||||||
115
code/components/jomjol_helper/himem_memory_check.cpp
Normal file
115
code/components/jomjol_helper/himem_memory_check.cpp
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
|
||||||
|
// need [env:esp32cam-dev-himem]
|
||||||
|
//CONFIG_SPIRAM_BANKSWITCH_ENABLE=y
|
||||||
|
//CONFIG_SPIRAM_BANKSWITCH_RESERVE=4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "../../include/defines.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG_HIMEM_MEMORY_CHECK
|
||||||
|
|
||||||
|
#include "himem_memory_check.h"
|
||||||
|
|
||||||
|
//source adapted from : https://github.com/espressif/esp-idf/blob/master/examples/system/himem/main/himem_example_main.c
|
||||||
|
|
||||||
|
|
||||||
|
//Fill memory with pseudo-random data generated from the given seed.
|
||||||
|
//Fills the memory in 32-bit words for speed.
|
||||||
|
static void fill_mem_seed(int seed, void *mem, int len)
|
||||||
|
{
|
||||||
|
uint32_t *p = (uint32_t *)mem;
|
||||||
|
unsigned int rseed = seed ^ 0xa5a5a5a5;
|
||||||
|
for (int i = 0; i < len / 4; i++) {
|
||||||
|
*p++ = rand_r(&rseed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check the memory filled by fill_mem_seed. Returns true if the data matches the data
|
||||||
|
//that fill_mem_seed wrote (when given the same seed).
|
||||||
|
//Returns true if there's a match, false when the region differs from what should be there.
|
||||||
|
static bool check_mem_seed(int seed, void *mem, int len, int phys_addr)
|
||||||
|
{
|
||||||
|
uint32_t *p = (uint32_t *)mem;
|
||||||
|
unsigned int rseed = seed ^ 0xa5a5a5a5;
|
||||||
|
for (int i = 0; i < len / 4; i++) {
|
||||||
|
uint32_t ex = rand_r(&rseed);
|
||||||
|
if (ex != *p) {
|
||||||
|
//printf("check_mem_seed: %x has 0x%08"PRIx32" expected 0x%08"PRIx32"\n", phys_addr+((char*)p-(char*)mem), *p, ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Allocate a himem region, fill it with data, check it and release it.
|
||||||
|
static bool test_region(int check_size, int seed)
|
||||||
|
{
|
||||||
|
esp_himem_handle_t mh; //Handle for the address space we're using
|
||||||
|
esp_himem_rangehandle_t rh; //Handle for the actual RAM.
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
//Allocate the memory we're going to check.
|
||||||
|
ESP_ERROR_CHECK(esp_himem_alloc(check_size, &mh));
|
||||||
|
//Allocate a block of address range
|
||||||
|
ESP_ERROR_CHECK(esp_himem_alloc_map_range(ESP_HIMEM_BLKSZ, &rh));
|
||||||
|
for (int i = 0; i < check_size; i += ESP_HIMEM_BLKSZ) {
|
||||||
|
uint32_t *ptr = NULL;
|
||||||
|
//Map in block, write pseudo-random data, unmap block.
|
||||||
|
ESP_ERROR_CHECK(esp_himem_map(mh, rh, i, 0, ESP_HIMEM_BLKSZ, 0, (void**)&ptr));
|
||||||
|
fill_mem_seed(i ^ seed, ptr, ESP_HIMEM_BLKSZ); //
|
||||||
|
ESP_ERROR_CHECK(esp_himem_unmap(rh, ptr, ESP_HIMEM_BLKSZ));
|
||||||
|
}
|
||||||
|
vTaskDelay(5); //give the OS some time to do things so the task watchdog doesn't bark
|
||||||
|
for (int i = 0; i < check_size; i += ESP_HIMEM_BLKSZ) {
|
||||||
|
uint32_t *ptr;
|
||||||
|
//Map in block, check against earlier written pseudo-random data, unmap block.
|
||||||
|
ESP_ERROR_CHECK(esp_himem_map(mh, rh, i, 0, ESP_HIMEM_BLKSZ, 0, (void**)&ptr));
|
||||||
|
if (!check_mem_seed(i ^ seed, ptr, ESP_HIMEM_BLKSZ, i)) {
|
||||||
|
//printf("Error in block %d\n", i / ESP_HIMEM_BLKSZ);
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(esp_himem_unmap(rh, ptr, ESP_HIMEM_BLKSZ));
|
||||||
|
if (!ret) break; //don't check rest of blocks if error occurred
|
||||||
|
}
|
||||||
|
//Okay, all done!
|
||||||
|
ESP_ERROR_CHECK(esp_himem_free(mh));
|
||||||
|
ESP_ERROR_CHECK(esp_himem_free_map_range(rh));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string himem_memory_check()
|
||||||
|
{
|
||||||
|
size_t memcnt=esp_himem_get_phys_size();
|
||||||
|
size_t memfree=esp_himem_get_free_size();
|
||||||
|
|
||||||
|
std::string espInfoResultStr = "";
|
||||||
|
char aMsgBuf[40];
|
||||||
|
|
||||||
|
espInfoResultStr += "Running HIMEM memory check";
|
||||||
|
|
||||||
|
sprintf(aMsgBuf,"Himem has %dKiB of memory", (int)memcnt/1024);
|
||||||
|
espInfoResultStr += std::string(aMsgBuf);
|
||||||
|
|
||||||
|
sprintf(aMsgBuf,"%dKiB of which is free", (int)memfree/1024);
|
||||||
|
espInfoResultStr += std::string(aMsgBuf);
|
||||||
|
|
||||||
|
espInfoResultStr += "\n please wait ....\n";
|
||||||
|
|
||||||
|
//running memory checks
|
||||||
|
//assert(test_region(memfree, 0xaaaa));
|
||||||
|
|
||||||
|
if(test_region(memfree, 0xaaaa)) {
|
||||||
|
espInfoResultStr += "Himem check Failed!\n";
|
||||||
|
} else {
|
||||||
|
espInfoResultStr += "Himem check Done!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return espInfoResultStr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DEBUG_HIMEM_MEMORY_CHECK
|
||||||
41
code/components/jomjol_helper/himem_memory_check.h
Normal file
41
code/components/jomjol_helper/himem_memory_check.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
// need [env:esp32cam-dev-himem]
|
||||||
|
//CONFIG_SPIRAM_BANKSWITCH_ENABLE=y
|
||||||
|
//CONFIG_SPIRAM_BANKSWITCH_RESERVE=4
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../include/defines.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG_HIMEM_MEMORY_CHECK
|
||||||
|
|
||||||
|
#ifndef HIMEM_MEMORY_CHECK_H
|
||||||
|
#define HIMEM_MEMORY_CHECK_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//source : //source : https://github.com/espressif/esp-idf/blob/master/examples/system/himem/main/himem_example_main.c
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "esp32/himem.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "esp32/himem.h"
|
||||||
|
|
||||||
|
|
||||||
|
std::string himem_memory_check();
|
||||||
|
|
||||||
|
#endif //HIMEM_MEMORY_CHECK_H
|
||||||
|
|
||||||
|
#endif // DEBUG_HIMEM_MEMORY_CHECK
|
||||||
@@ -2,6 +2,23 @@
|
|||||||
|
|
||||||
#include "../../include/defines.h"
|
#include "../../include/defines.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
ESP32 CPU usage monitor
|
||||||
|
Gives you a rough idea of how the Xtensa cores are utilized.
|
||||||
|
|
||||||
|
Works by attaching idle hooks and measuring how often they get called. The core usage is calculated: usage% = idle ticks since last measurement / expected idle ticks if core were idle * 100%. The expected idle tick count was measured by running an empty program.
|
||||||
|
|
||||||
|
Limitations:
|
||||||
|
Should only be used for user information, not in logic that needs accurate values
|
||||||
|
New IDF versions could optimize performance and therefore introduce an error to usage estimation.
|
||||||
|
When one core is at 100% the other might report a negative value
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
#include "perfmon.h"
|
||||||
|
Call perfmon_start() once
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLE_PERFMON
|
#ifdef DEBUG_ENABLE_PERFMON
|
||||||
|
|
||||||
#include "perfmon.h"
|
#include "perfmon.h"
|
||||||
|
|||||||
@@ -14,8 +14,14 @@
|
|||||||
//#define DEBUG_DISABLE_BROWNOUT_DETECTOR
|
//#define DEBUG_DISABLE_BROWNOUT_DETECTOR
|
||||||
//#define DEBUG_ENABLE_SYSINFO
|
//#define DEBUG_ENABLE_SYSINFO
|
||||||
//#define DEBUG_ENABLE_PERFMON
|
//#define DEBUG_ENABLE_PERFMON
|
||||||
|
//#define DEBUG_HIMEM_MEMORY_CHECK
|
||||||
|
// need [env:esp32cam-dev-himem]
|
||||||
|
//=> CONFIG_SPIRAM_BANKSWITCH_ENABLE=y
|
||||||
|
//=> CONFIG_SPIRAM_BANKSWITCH_RESERVE=4
|
||||||
|
|
||||||
|
|
||||||
|
// use himem //https://github.com/jomjol/AI-on-the-edge-device/issues/1842
|
||||||
|
#define USE_HIMEM_IF_AVAILABLE
|
||||||
|
|
||||||
/* Uncomment this to generate task list with stack sizes using the /heap handler
|
/* Uncomment this to generate task list with stack sizes using the /heap handler
|
||||||
PLEASE BE AWARE: The following CONFIG parameters have to to be set in
|
PLEASE BE AWARE: The following CONFIG parameters have to to be set in
|
||||||
|
|||||||
@@ -54,6 +54,14 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif //DEBUG_ENABLE_SYSINFO
|
#endif //DEBUG_ENABLE_SYSINFO
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_HIMEM_IF_AVAILABLE
|
||||||
|
#include "esp32/himem.h"
|
||||||
|
#ifdef DEBUG_HIMEM_MEMORY_CHECK
|
||||||
|
#include "himem_memory_check.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
extern const char* GIT_TAG;
|
extern const char* GIT_TAG;
|
||||||
extern const char* GIT_REV;
|
extern const char* GIT_REV;
|
||||||
extern const char* GIT_BRANCH;
|
extern const char* GIT_BRANCH;
|
||||||
@@ -160,12 +168,6 @@ extern "C" void app_main(void)
|
|||||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
|
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLE_SYSINFO
|
|
||||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL( 4, 0, 0 )
|
|
||||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Device Info" + get_device_info() );
|
|
||||||
ESP_LOGD(TAG, "Device infos %s", get_device_info().c_str());
|
|
||||||
#endif
|
|
||||||
#endif //DEBUG_ENABLE_SYSINFO
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "\n\n\n\n\n"); // Add mark on log to see when it restarted
|
ESP_LOGI(TAG, "\n\n\n\n\n"); // Add mark on log to see when it restarted
|
||||||
|
|
||||||
@@ -201,6 +203,20 @@ extern "C" void app_main(void)
|
|||||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, versionFormated);
|
LogFile.WriteToFile(ESP_LOG_INFO, TAG, versionFormated);
|
||||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Reset reason: " + getResetReason());
|
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Reset reason: " + getResetReason());
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLE_SYSINFO
|
||||||
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL( 4, 0, 0 )
|
||||||
|
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Device Info : " + get_device_info() );
|
||||||
|
ESP_LOGD(TAG, "Device infos %s", get_device_info().c_str());
|
||||||
|
#endif
|
||||||
|
#endif //DEBUG_ENABLE_SYSINFO
|
||||||
|
|
||||||
|
#ifdef USE_HIMEM_IF_AVAILABLE
|
||||||
|
#ifdef DEBUG_HIMEM_MEMORY_CHECK
|
||||||
|
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Himem mem check : " + himem_memory_check() );
|
||||||
|
ESP_LOGD(TAG, "Himem mem check %s", himem_memory_check().c_str());
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
CheckIsPlannedReboot();
|
CheckIsPlannedReboot();
|
||||||
CheckOTAUpdate();
|
CheckOTAUpdate();
|
||||||
CheckUpdate();
|
CheckUpdate();
|
||||||
|
|||||||
Reference in New Issue
Block a user