diff --git a/P4_Display_Firmware/Changelog.txt b/P4_Display_Firmware/Changelog.txt index 3f7f158..dcdea60 100644 --- a/P4_Display_Firmware/Changelog.txt +++ b/P4_Display_Firmware/Changelog.txt @@ -1,3 +1,15 @@ +Version 1.9.8: +- Der Stillstand beim Wechsel in den Standby ist gefunden und behoben. LVGL legt für JEDE + Textglyphe einen eigenen Zwischenpuffer an - bei der großen Uhr rund 48 KB pro Ziffer, mit + zwei parallel arbeitenden Zeicheneinheiten fast 100 KB gleichzeitig. Der interne + LVGL-Speicher hatte nur rund 98 KB am Stück frei; es reichte knapp nicht. Schlägt die + Anforderung fehl, hält LVGL per Zusicherung in einer Endlosschleife an - kein Absturz, + keine Meldung, das Display steht einfach. Deshalb brach der Mitschnitt ohne Fehler ab. +- Große Glyphenpuffer liegen jetzt im externen Speicher (PSRAM, 32 MB frei). Kleine bleiben + im internen, der ist schneller - sonst würde jeder Text langsamer. +- Hält LVGL künftig wegen einer verletzten Zusicherung an, sagt es das jetzt, statt stumm + stehen zu bleiben. + Version 1.9.7: - Messpunkte für den Stillstand beim Wechsel in den Standby: Beide Abläufe - der Haupt- und der Zeichenablauf - melden jetzt alle zwei Sekunden einen Herzschlag mit Speicherstand. diff --git a/P4_Display_Firmware/lv_conf.h b/P4_Display_Firmware/lv_conf.h index fae483c..793c519 100644 --- a/P4_Display_Firmware/lv_conf.h +++ b/P4_Display_Firmware/lv_conf.h @@ -374,8 +374,10 @@ #define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/ /*Add a custom handler when assert happens e.g. to restart the MCU*/ -#define LV_ASSERT_HANDLER_INCLUDE -#define LV_ASSERT_HANDLER while(1); /*Halt by default*/ +#define LV_ASSERT_HANDLER_INCLUDE +// Frueher hielt LVGL hier stumm in einer Endlosschleife an - das Display stand, ohne dass +// irgendwo etwas davon zu sehen war. Jetzt sagt es wenigstens, dass es angehalten hat. +#define LV_ASSERT_HANDLER esp_rom_printf("[LVGL] Zusicherung verletzt - Zeichenablauf haelt an\n"); while(1); /*------------- * Debug diff --git a/P4_Display_Firmware/ui.cpp b/P4_Display_Firmware/ui.cpp index d8d52fa..0cb1357 100644 --- a/P4_Display_Firmware/ui.cpp +++ b/P4_Display_Firmware/ui.cpp @@ -18,6 +18,7 @@ #include #include #include // Dashboard-Design P4-lokal merken (NVS) +#include // esp_ptr_external_ram(): welcher Speicher einen Puffer traegt #include // Verlaufs-Historie im PSRAM allozieren (interner RAM ist knapp) #include "ui.h" #include @@ -3571,6 +3572,36 @@ static void ui_heartbeat_cb(lv_timer_t*) { (unsigned)m.free_size, (unsigned)m.total_size, (unsigned)m.free_biggest_size); } +// LVGL legt fuer JEDE Textglyphe einen eigenen Zwischenpuffer an - Breite mal Hoehe, ein +// Byte je Bildpunkt. Bei der grossen Standby-Uhr sind das 190 x 256 = rund 48 KB pro Ziffer, +// und mit zwei parallel arbeitenden Zeicheneinheiten fast 100 KB gleichzeitig. Der interne +// LVGL-Speicher fasst nur 245 KB, wovon rund 98 KB am Stueck frei sind - es reichte knapp +// nicht. Schlaegt die Anforderung fehl, haelt LVGL per Zusicherung in einer Endlosschleife +// an: kein Absturz, keine Meldung, das Display steht einfach. Genau das war der Stillstand +// beim Wechsel in den Standby. +// +// Diese Puffer wandern daher in den externen Speicher (PSRAM, 32 MB frei). Kleine Glyphen +// bleiben im internen Speicher, weil der schneller ist und Text sonst ueberall langsamer +// wuerde; nur die grossen gehen nach aussen. +#define FONT_BUF_EXTERN_AB 16384 // ab dieser Groesse in den externen Speicher + +static void* font_buf_malloc(size_t size, lv_color_format_t cf) { + LV_UNUSED(cf); + size += LV_DRAW_BUF_ALIGN - 1; + if (size >= FONT_BUF_EXTERN_AB) { + void* p = heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (p) return p; + } + return lv_malloc(size); +} + +static void font_buf_free(void* buf) { + // Der externe Speicher liegt ausserhalb des LVGL-Bereichs; daran ist zu erkennen, + // welcher der beiden Wege den Puffer vergeben hat. + if (esp_ptr_external_ram(buf)) heap_caps_free(buf); + else lv_free(buf); +} + static void refr_monitor_install() { lv_display_t* d = lv_display_get_default(); if (!d) return; @@ -3981,6 +4012,10 @@ void ui_init(ProtocolClient* client) { show_page(PG_DASH); if (g_client) g_client->sendListProfiles(); + // Glyphenpuffer umlenken, bevor der erste Text gezeichnet wird. + lv_draw_buf_handlers_t* fh = lv_draw_buf_get_font_handlers(); + fh->buf_malloc_cb = font_buf_malloc; + fh->buf_free_cb = font_buf_free; refr_monitor_install(); lv_timer_create(ui_heartbeat_cb, 2000, nullptr); g_uiReady = true;