mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-08-17 23:55:04 +00:00
Improvements & fixes (#589)
This commit is contained in:
parent
b98a813f3c
commit
f21c0df6fe
@ -4,6 +4,7 @@ idf_component_register(
|
|||||||
"Libraries/TactilityKernel/include"
|
"Libraries/TactilityKernel/include"
|
||||||
"Libraries/TactilityFreeRtos/include"
|
"Libraries/TactilityFreeRtos/include"
|
||||||
"Libraries/lvgl/include"
|
"Libraries/lvgl/include"
|
||||||
|
"Libraries/minmea/include"
|
||||||
"Modules/lvgl-module/include"
|
"Modules/lvgl-module/include"
|
||||||
# DRIVER_INCLUDE_DIRS_PLACEHOLDER
|
# DRIVER_INCLUDE_DIRS_PLACEHOLDER
|
||||||
REQUIRES esp_timer
|
REQUIRES esp_timer
|
||||||
@ -13,7 +14,9 @@ idf_component_register(
|
|||||||
add_prebuilt_library(TactilityC Libraries/TactilityC/binary/libTactilityC.a)
|
add_prebuilt_library(TactilityC Libraries/TactilityC/binary/libTactilityC.a)
|
||||||
add_prebuilt_library(TactilityKernel Libraries/TactilityKernel/binary/libTactilityKernel.a)
|
add_prebuilt_library(TactilityKernel Libraries/TactilityKernel/binary/libTactilityKernel.a)
|
||||||
add_prebuilt_library(lvgl Libraries/lvgl/binary/liblvgl.a)
|
add_prebuilt_library(lvgl Libraries/lvgl/binary/liblvgl.a)
|
||||||
|
add_prebuilt_library(minmea Libraries/minmea/binary/libminmea.a)
|
||||||
|
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityC)
|
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityC)
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityKernel)
|
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityKernel)
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE lvgl)
|
target_link_libraries(${COMPONENT_LIB} INTERFACE lvgl)
|
||||||
|
target_link_libraries(${COMPONENT_LIB} INTERFACE minmea)
|
||||||
|
|||||||
@ -185,6 +185,13 @@ def main():
|
|||||||
# elf_loader
|
# elf_loader
|
||||||
{'src': 'Libraries/elf_loader/elf_loader.cmake', 'dst': 'Libraries/elf_loader/'},
|
{'src': 'Libraries/elf_loader/elf_loader.cmake', 'dst': 'Libraries/elf_loader/'},
|
||||||
{'src': 'Libraries/elf_loader/license.txt', 'dst': 'Libraries/elf_loader/'},
|
{'src': 'Libraries/elf_loader/license.txt', 'dst': 'Libraries/elf_loader/'},
|
||||||
|
# minmea
|
||||||
|
{'src': 'build/esp-idf/minmea/libminmea.a', 'dst': 'Libraries/minmea/binary/'},
|
||||||
|
{'src': 'Libraries/minmea/Include/**', 'dst': 'Libraries/minmea/include/'},
|
||||||
|
{'src': 'Libraries/minmea/CMakeLists.txt', 'dst': 'Libraries/minmea/'},
|
||||||
|
{'src': 'Libraries/minmea/README.md', 'dst': 'Libraries/minmea/'},
|
||||||
|
{'src': 'Libraries/minmea/LICENSE*.*', 'dst': 'Libraries/minmea/'},
|
||||||
|
{'src': 'Libraries/minmea/COPYING', 'dst': 'Libraries/minmea/'},
|
||||||
]
|
]
|
||||||
|
|
||||||
map_copy(mappings, target_path)
|
map_copy(mappings, target_path)
|
||||||
@ -192,6 +199,7 @@ def main():
|
|||||||
# Modules
|
# Modules
|
||||||
add_module(target_path, "lvgl-module")
|
add_module(target_path, "lvgl-module")
|
||||||
add_module(target_path, "crypt-module")
|
add_module(target_path, "crypt-module")
|
||||||
|
add_module(target_path, "gps-module")
|
||||||
|
|
||||||
# Drivers - only ones actually built for this target (chip-restricted drivers like
|
# Drivers - only ones actually built for this target (chip-restricted drivers like
|
||||||
# sc2356-module won't have a .a outside ESP32-P4)
|
# sc2356-module won't have a .a outside ESP32-P4)
|
||||||
|
|||||||
@ -111,7 +111,7 @@ void lvgl_devices_detach() {
|
|||||||
|
|
||||||
lv_disp_t* display = lv_disp_get_next(NULL);
|
lv_disp_t* display = lv_disp_get_next(NULL);
|
||||||
while (display != NULL) {
|
while (display != NULL) {
|
||||||
lv_display_delete(display);
|
lvgl_display_remove(display);
|
||||||
display = lv_disp_get_next(NULL);
|
display = lv_disp_get_next(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,26 +6,33 @@
|
|||||||
|
|
||||||
#include <Tactility/Tactility.h>
|
#include <Tactility/Tactility.h>
|
||||||
#include <Tactility/TactilityConfig.h>
|
#include <Tactility/TactilityConfig.h>
|
||||||
|
#include <Tactility/bluetooth/Bluetooth.h>
|
||||||
#include <Tactility/LogMessages.h>
|
|
||||||
#include <Tactility/CpuAffinity.h>
|
#include <Tactility/CpuAffinity.h>
|
||||||
#include <Tactility/MountPoints.h>
|
#include <Tactility/MountPoints.h>
|
||||||
#include <Tactility/app/AppManifestParsing.h>
|
#include <Tactility/app/AppManifestParsing.h>
|
||||||
#include <Tactility/app/AppRegistration.h>
|
#include <Tactility/app/AppRegistration.h>
|
||||||
#include <Tactility/file/File.h>
|
#include <Tactility/file/File.h>
|
||||||
#include <Tactility/file/FileLock.h>
|
#include <Tactility/file/FileLock.h>
|
||||||
|
#include <Tactility/LogMessages.h>
|
||||||
|
#include <Tactility/hal/SdCard.h>
|
||||||
#include <Tactility/network/NtpPrivate.h>
|
#include <Tactility/network/NtpPrivate.h>
|
||||||
|
#include <Tactility/Paths.h>
|
||||||
#include <Tactility/service/ServiceManifest.h>
|
#include <Tactility/service/ServiceManifest.h>
|
||||||
#include <Tactility/service/ServiceRegistration.h>
|
#include <Tactility/service/ServiceRegistration.h>
|
||||||
#include <Tactility/service/audio/Audio.h>
|
#include <Tactility/service/audio/Audio.h>
|
||||||
#include <Tactility/settings/TimePrivate.h>
|
#include <Tactility/settings/TimePrivate.h>
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#include <Tactility/InitEsp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <gps/module.h>
|
#include <gps/module.h>
|
||||||
#include <gps_generic/gps_generic_module.h>
|
#include <gps_generic/gps_generic_module.h>
|
||||||
|
|
||||||
#include <crypt/module.h>
|
#include <crypt/module.h>
|
||||||
#include <lvgl/module.h>
|
#include <lvgl/module.h>
|
||||||
#include <lvgl/widgets/toolbar.h>
|
#include <lvgl/widgets/toolbar.h>
|
||||||
|
|
||||||
#include <tactility/concurrent/thread.h>
|
#include <tactility/concurrent/thread.h>
|
||||||
#include <tactility/drivers/audio_stream.h>
|
#include <tactility/drivers/audio_stream.h>
|
||||||
#include <tactility/drivers/display.h>
|
#include <tactility/drivers/display.h>
|
||||||
@ -36,15 +43,7 @@
|
|||||||
#include <tactility/filesystem/file_system.h>
|
#include <tactility/filesystem/file_system.h>
|
||||||
#include <tactility/kernel_init.h>
|
#include <tactility/kernel_init.h>
|
||||||
#include <tactility/log.h>
|
#include <tactility/log.h>
|
||||||
|
#include <tactility/memory.h>
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#include <Tactility/InitEsp.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Tactility/Paths.h"
|
|
||||||
#include "Tactility/hal/SdCard.h"
|
|
||||||
|
|
||||||
#include <Tactility/bluetooth/Bluetooth.h>
|
|
||||||
|
|
||||||
namespace tt {
|
namespace tt {
|
||||||
|
|
||||||
@ -371,6 +370,8 @@ static void onLvglStarted() {
|
|||||||
#if TT_FEATURE_SCREENSHOT_ENABLED
|
#if TT_FEATURE_SCREENSHOT_ENABLED
|
||||||
addService(service::screenshot::manifest);
|
addService(service::screenshot::manifest);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
memory_trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onLvglStopped() {
|
static void onLvglStopped() {
|
||||||
@ -386,6 +387,8 @@ static void onLvglStopped() {
|
|||||||
check(service::removeService(service::memorychecker::manifest.id));
|
check(service::removeService(service::memorychecker::manifest.id));
|
||||||
check(service::removeService(service::statusbar::manifest.id));
|
check(service::removeService(service::statusbar::manifest.id));
|
||||||
check(service::removeService(service::gui::manifest.id));
|
check(service::removeService(service::gui::manifest.id));
|
||||||
|
|
||||||
|
memory_trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(Module* dtsModules[], DtsDevice dtsDevices[]) {
|
void run(Module* dtsModules[], DtsDevice dtsDevices[]) {
|
||||||
|
|||||||
@ -95,6 +95,7 @@ private:
|
|||||||
// Note: the result code maps to values from cstdlib's errno.h
|
// Note: the result code maps to values from cstdlib's errno.h
|
||||||
lastError = getErrorCodeString(-relocate_result);
|
lastError = getErrorCodeString(-relocate_result);
|
||||||
LOG_E(TAG, "Application failed to load: %s", lastError.c_str());
|
LOG_E(TAG, "Application failed to load: %s", lastError.c_str());
|
||||||
|
esp_elf_deinit(&elf);
|
||||||
elfFileData = nullptr;
|
elfFileData = nullptr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -200,10 +200,10 @@ size_t receiveFile(httpd_req_t* request, size_t length, const std::string& fileP
|
|||||||
auto expected_chunk_size = std::min<size_t>(BUFFER_SIZE, length - bytes_received);
|
auto expected_chunk_size = std::min<size_t>(BUFFER_SIZE, length - bytes_received);
|
||||||
size_t receive_chunk_size = httpd_req_recv(request, buffer, expected_chunk_size);
|
size_t receive_chunk_size = httpd_req_recv(request, buffer, expected_chunk_size);
|
||||||
if (receive_chunk_size <= 0) {
|
if (receive_chunk_size <= 0) {
|
||||||
LOG_E(TAG, "Receive failed");
|
LOG_E(TAG, "Receive failed, got 0 bytes but expected %zu more", length - bytes_received);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (fwrite(buffer, 1, receive_chunk_size, file) != (size_t)receive_chunk_size) {
|
if (fwrite(buffer, 1, receive_chunk_size, file) != receive_chunk_size) {
|
||||||
LOG_E(TAG, "Failed to write all bytes");
|
LOG_E(TAG, "Failed to write all bytes");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include <Tactility/service/ServiceRegistration.h>
|
#include <Tactility/service/ServiceRegistration.h>
|
||||||
|
|
||||||
|
#include <Tactility/Mutex.h>
|
||||||
#include <Tactility/service/ServiceContext.h>
|
#include <Tactility/service/ServiceContext.h>
|
||||||
#include <Tactility/service/ServiceManifest.h>
|
#include <Tactility/service/ServiceManifest.h>
|
||||||
|
|
||||||
@ -9,11 +10,35 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace tt::service {
|
namespace tt::service {
|
||||||
|
|
||||||
constexpr auto* TAG = "ServiceRegistration";
|
constexpr auto* TAG = "ServiceRegistration";
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Tracks the heap allocations addService() makes per registered id, so removeService()
|
||||||
|
// can free them once the kernel confirms the manifest is unregistered. The kernel only
|
||||||
|
// ever stores the raw pointer it's handed (see service_manager_add/_remove) - it never
|
||||||
|
// takes ownership - so the registering side (us) is responsible for the lifetime.
|
||||||
|
struct AllocatedManifest {
|
||||||
|
std::shared_ptr<const ServiceManifest>* persistentManifest;
|
||||||
|
::ServiceManifest* cManifest;
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutex& allocatedManifestsMutex() {
|
||||||
|
static Mutex mutex;
|
||||||
|
return mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, AllocatedManifest>& allocatedManifests() {
|
||||||
|
static std::unordered_map<std::string, AllocatedManifest> map;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// Bridges the kernel's C ServiceManifest/Service callbacks to the C++ Service
|
// Bridges the kernel's C ServiceManifest/Service callbacks to the C++ Service
|
||||||
// instances they wrap. Declared extern "C" to match the linkage of the C
|
// instances they wrap. Declared extern "C" to match the linkage of the C
|
||||||
// function-pointer types they're assigned to (see e.g. gpio_controller.cpp).
|
// function-pointer types they're assigned to (see e.g. gpio_controller.cpp).
|
||||||
@ -48,9 +73,8 @@ void addService(std::shared_ptr<const ServiceManifest> manifest, bool autoStart)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intentionally never freed: removeService() only unregisters the manifest
|
// Freed by removeService() once the kernel confirms the manifest is unregistered.
|
||||||
// from the kernel, it doesn't own this allocation. Keeps id's backing
|
// Keeps id's backing string alive for cManifest.id below in the meantime.
|
||||||
// string alive for cManifest.id below.
|
|
||||||
auto* persistentManifest = new std::shared_ptr(manifest);
|
auto* persistentManifest = new std::shared_ptr(manifest);
|
||||||
auto* cManifest = new ::ServiceManifest {
|
auto* cManifest = new ::ServiceManifest {
|
||||||
.id = (*persistentManifest)->id.c_str(),
|
.id = (*persistentManifest)->id.c_str(),
|
||||||
@ -60,6 +84,12 @@ void addService(std::shared_ptr<const ServiceManifest> manifest, bool autoStart)
|
|||||||
.on_stop = cppOnStopTrampoline,
|
.on_stop = cppOnStopTrampoline,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
auto lock = allocatedManifestsMutex().asScopedLock();
|
||||||
|
lock.lock();
|
||||||
|
allocatedManifests()[id] = AllocatedManifest { persistentManifest, cManifest };
|
||||||
|
}
|
||||||
|
|
||||||
error_t error = service_manager_add(cManifest, autoStart);
|
error_t error = service_manager_add(cManifest, autoStart);
|
||||||
if (error != ERROR_NONE) {
|
if (error != ERROR_NONE) {
|
||||||
LOG_E(TAG, "Failed to add service %s: %s", id.c_str(), error_to_string(error));
|
LOG_E(TAG, "Failed to add service %s: %s", id.c_str(), error_to_string(error));
|
||||||
@ -85,6 +115,20 @@ bool removeService(const std::string& id) {
|
|||||||
LOG_E(TAG, "Failed to remove service %s: %s", id.c_str(), error_to_string(error));
|
LOG_E(TAG, "Failed to remove service %s: %s", id.c_str(), error_to_string(error));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The kernel has confirmed the manifest is unregistered, so id (which points into
|
||||||
|
// persistentManifest's string) is no longer needed by anything - safe to free now.
|
||||||
|
{
|
||||||
|
auto lock = allocatedManifestsMutex().asScopedLock();
|
||||||
|
lock.lock();
|
||||||
|
auto iterator = allocatedManifests().find(id);
|
||||||
|
if (iterator != allocatedManifests().end()) {
|
||||||
|
delete iterator->second.cManifest;
|
||||||
|
delete iterator->second.persistentManifest;
|
||||||
|
allocatedManifests().erase(iterator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG_I(TAG, "Removed %s", id.c_str());
|
LOG_I(TAG, "Removed %s", id.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -157,13 +157,20 @@ esp_err_t DevelopmentService::handleAppInstall(httpd_req_t* request) {
|
|||||||
// Create tmp directory
|
// Create tmp directory
|
||||||
const std::string tmp_path = getTempPath();
|
const std::string tmp_path = getTempPath();
|
||||||
if (!file::findOrCreateDirectory(tmp_path, 0777)) {
|
if (!file::findOrCreateDirectory(tmp_path, 0777)) {
|
||||||
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to save file");
|
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to create temp path");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto file_path = std::format("{}/{}", tmp_path, filename_entry->second);
|
std::string safe_name = file::getLastPathSegment(filename_entry->second);
|
||||||
|
if (safe_name.empty() || safe_name.find("..") != std::string::npos ||
|
||||||
|
safe_name.find('/') != std::string::npos || safe_name.find('\\') != std::string::npos) {
|
||||||
|
httpd_resp_send_err(request, HTTPD_400_BAD_REQUEST, "invalid filename");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
auto file_path = std::format("{}/{}", tmp_path, safe_name);
|
||||||
if (network::receiveFile(request, file_size, file_path) != file_size) {
|
if (network::receiveFile(request, file_size, file_path) != file_size) {
|
||||||
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to save file");
|
file::deleteFile(file_path);
|
||||||
|
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to receive file");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -200,6 +200,13 @@ void GuiService::redraw() {
|
|||||||
// Create a default group which adds all objects automatically,
|
// Create a default group which adds all objects automatically,
|
||||||
// and assign all indevs to it.
|
// and assign all indevs to it.
|
||||||
// This enables navigation with limited input, such as encoder wheels.
|
// This enables navigation with limited input, such as encoder wheels.
|
||||||
|
// The previous default group (if any) is no longer referenced by anything
|
||||||
|
// after lv_obj_clean() above, so it must be freed here or it leaks.
|
||||||
|
auto* previous_group = lv_group_get_default();
|
||||||
|
if (previous_group != nullptr) {
|
||||||
|
lv_group_delete(previous_group);
|
||||||
|
}
|
||||||
|
|
||||||
lv_group_t* group = lv_group_create();
|
lv_group_t* group = lv_group_create();
|
||||||
auto* indev = lv_indev_get_next(nullptr);
|
auto* indev = lv_indev_get_next(nullptr);
|
||||||
while (indev) {
|
while (indev) {
|
||||||
@ -279,6 +286,17 @@ void GuiService::onStop(ServiceContext& service) {
|
|||||||
lv_group_delete(keyboardGroup);
|
lv_group_delete(keyboardGroup);
|
||||||
keyboardGroup = nullptr;
|
keyboardGroup = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto* default_group = lv_group_get_default();
|
||||||
|
if (default_group != nullptr) {
|
||||||
|
lv_group_delete(default_group);
|
||||||
|
lv_group_set_default(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* screen_root = lv_screen_active();
|
||||||
|
if (screen_root != nullptr) {
|
||||||
|
lv_obj_clean(screen_root);
|
||||||
|
}
|
||||||
lvgl_unlock();
|
lvgl_unlock();
|
||||||
|
|
||||||
delete thread;
|
delete thread;
|
||||||
|
|||||||
@ -10,12 +10,8 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#include <esp_heap_caps.h>
|
|
||||||
#include <utility>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <tactility/log.h>
|
#include <tactility/log.h>
|
||||||
|
#include <tactility/memory.h>
|
||||||
|
|
||||||
namespace tt::service::loader {
|
namespace tt::service::loader {
|
||||||
|
|
||||||
@ -72,6 +68,8 @@ void LoaderService::onStartAppMessage(const std::string& id, app::LaunchId launc
|
|||||||
appStack.push_back(new_app);
|
appStack.push_back(new_app);
|
||||||
transitionAppToState(new_app, app::State::Created);
|
transitionAppToState(new_app, app::State::Created);
|
||||||
transitionAppToState(new_app, app::State::Showing);
|
transitionAppToState(new_app, app::State::Showing);
|
||||||
|
|
||||||
|
memory_trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoaderService::onStopTopAppMessage(const std::string& id) {
|
void LoaderService::onStopTopAppMessage(const std::string& id) {
|
||||||
@ -125,10 +123,6 @@ void LoaderService::onStopTopAppMessage(const std::string& id) {
|
|||||||
LOG_W(TAG, "Memory leak: Stopped %s, but use count is %d", app_to_stop->getManifest().appId.c_str(), (int)(app_to_stop->getApp().use_count() - 2));
|
LOG_W(TAG, "Memory leak: Stopped %s, but use count is %d", app_to_stop->getManifest().appId.c_str(), (int)(app_to_stop->getApp().use_count() - 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
LOG_I(TAG, "Free heap: %d", (int)heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::shared_ptr<app::AppInstance> instance_to_resume;
|
std::shared_ptr<app::AppInstance> instance_to_resume;
|
||||||
// If there's a previous app, resume it
|
// If there's a previous app, resume it
|
||||||
if (!appStack.empty()) {
|
if (!appStack.empty()) {
|
||||||
@ -167,6 +161,8 @@ void LoaderService::onStopTopAppMessage(const std::string& id) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memory_trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
int LoaderService::findAppInStack(const std::string& id) const {
|
int LoaderService::findAppInStack(const std::string& id) const {
|
||||||
|
|||||||
11
TactilityKernel/include/tactility/memory.h
Normal file
11
TactilityKernel/include/tactility/memory.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void memory_trace();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
23
TactilityKernel/source/memory.cpp
Normal file
23
TactilityKernel/source/memory.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include <tactility/log.h>
|
||||||
|
#include <tactility/memory.h>
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#include <esp_heap_caps.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr auto* TAG = "memory";
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void memory_trace() {
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
size_t heap_free = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||||
|
size_t heap_total = heap_caps_get_total_size(MALLOC_CAP_INTERNAL);
|
||||||
|
LOG_I(TAG, "Heap: %zu / %zu available", heap_free, heap_total);
|
||||||
|
size_t ext_free = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||||
|
size_t ext_total = heap_caps_get_total_size(MALLOC_CAP_SPIRAM);
|
||||||
|
LOG_I(TAG, "External: %zu / %zu available", ext_free, ext_total);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user