Як виправити збій / перезавантаження ESP32 LVGL у lv_tlsf_create() / lv_mem_init()

Проблема:

Коли ви намагаєтесь запустити приклад LVGL, наприклад Мінімальний приклад LVGL графіка для ST7735R для PlatformIO на ESP32, ваш МК неодноразово зазнає збою після ініціалізації (див. нижче повний журнал збою) під час lv_tlsf_create(), який викликається всередині lv_mem_init()

Рішення

Цей збій виникає через те, що одна з бібліотек, пов’язаних з LVGL, використовує ps_malloc(), намагаючись виділити пам’ять із зовнішнього чіпа PSRAM — якого ваша плата не має (і, як правило, не потребує)

Щоб виправити це, спочатку додайте наступний рядок до вашогоplatformio.ini:

platformio.ini
build_flags = -DLV_CONF_INCLUDE_SIMPLE -DLV_CONF_SUPPRESS_DEFINE_CHECK

Тепер створіть новий файл include/lv_conf.h, який ми використаємо для перевизначення значень за замовчуванням. Це основано на Як використовувати власний lv_conf.h LVGL з бібліотекою Adafruit LittlevGL Glue на PlatformIO.

Вставте наступний вміст у include/lv_conf.h

lv_conf.h
/**
 * @file lv_conf.h
 * Файл конфігурації для v8.0.2
 */

/*
 * СКОПІЮЙТЕ ЦЕЙ ФАЙЛ ЯК `lv_conf.h` ПОРЯД ІЗ папкою `lvgl`
 */
#if 1 /*Встановіть "1", щоб увімкнути вміст*/

#ifndef LV_CONF_H
#define LV_CONF_H
/*clang-format off*/

#include <stdint.h>

/*====================
   НАЛАШТУВАННЯ КОЛЬОРІВ
 *====================*/

/*Глибина кольору: 1 (1 байт на піксель), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 16

/* Поміняти місцями 2 байти кольору RGB565.
 * Корисно, якщо дисплей має 8-бітний інтерфейс (напр. SPI)*/
#if defined(ADAFRUIT_PYPORTAL)
#define LV_COLOR_16_SWAP 1
#else
#define LV_COLOR_16_SWAP 0
#endif

/*Увімкнути складніші процедури малювання для керування прозорістю екранів.
 *Можна використовувати, якщо інтерфейс знаходиться поверх іншого шару, напр.
 *OSD-меню або відеоплеєр.
 *Потребує `LV_COLOR_DEPTH = 32` кольорів, а `bg_opa` екрана має бути
 *встановлено у значення, відмінне від LV_OPA_COVER*/
#define LV_COLOR_SCREEN_TRANSP 0

/*Пікселі зображень цього кольору не буде намальовано, якщо вони використовують chroma key)*/
#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00) /*чистий зелений*/

/*=========================
   НАЛАШТУВАННЯ ПАМ'ЯТІ
 *=========================*/

/*1: використовувати власний malloc/free, 0: використовувати вбудовані `lv_mem_alloc()` і
 * `lv_mem_free()`*/
#define LV_MEM_CUSTOM 0
#if LV_MEM_CUSTOM == 0
/*Розмір пам'яті, доступної для `lv_mem_alloc()`, у байтах (>= 2кБ)*/
#define LV_MEM_SIZE (32U * 1024U) /*[байт]*/

/*Встановити адресу для пулу пам'яті замість виділення як звичайного масиву.
 * Може бути також у зовнішній SRAM.*/
#define LV_MEM_ADR 0 /*0: не використовується*/

// Для ESP32 вкажіть алокатор пулу пам'яті та використовуйте PSRAM замість flash
#ifdef ESP32
#if LV_MEM_ADR == 0
#define LV_MEM_POOL_INCLUDE <stdlib.h>
#define LV_MEM_POOL_ALLOC malloc
#endif
#endif

#else /*LV_MEM_CUSTOM*/
#define LV_MEM_CUSTOM_INCLUDE                                                  \
  <stdlib.h> /*Заголовок для функції динамічної пам'яті*/
#define LV_MEM_CUSTOM_ALLOC malloc
#define LV_MEM_CUSTOM_FREE free
#define LV_MEM_CUSTOM_REALLOC realloc
#endif /*LV_MEM_CUSTOM*/

/*Використовувати стандартні `memcpy` і `memset` замість власних функцій LVGL. (Може
 * бути швидше, а може й ні).*/
#define LV_MEMCPY_MEMSET_STD 0

/*====================
   НАЛАШТУВАННЯ HAL
 *====================*/

/*Період оновлення дисплея за замовчуванням. LVGL перемальовуватиме змінені ділянки з цим періодом
 * часу*/
#define LV_DISP_DEF_REFR_PERIOD 30 /*[мс]*/

/*Період зчитування пристрою вводу в мілісекундах*/
#define LV_INDEV_DEF_READ_PERIOD 30 /*[мс]*/

/*Використовувати власне джерело тіків, яке повідомляє про минулий час у мілісекундах.
 *Це усуває необхідність вручну оновлювати тік через `lv_tick_inc()`)*/
#define LV_TICK_CUSTOM 0
#if LV_TICK_CUSTOM
#define LV_TICK_CUSTOM_INCLUDE                                                 \
  "Arduino.h" /*Заголовок для функції системного часу*/
#define LV_TICK_CUSTOM_SYS_TIME_EXPR                                           \
  (millis()) /*Вираз, що обчислює поточний системний час у мс*/
#endif       /*LV_TICK_CUSTOM*/

/*Точок на дюйм за замовчуванням. Використовується для ініціалізації розмірів за замовчуванням,
 *таких як розміри віджетів, відступи стилів. (Не так важливо, можете змінити, щоб модифікувати
 *стандартні розміри та інтервали)*/
#define LV_DPI_DEF 130 /*[пікс/дюйм]*/

/*=======================
 * КОНФІГУРАЦІЯ ФУНКЦІЙ
 *=======================*/

/*-------------
 * Малювання
 *-----------*/

/*Увімкнути складний рушій малювання.
 *Необхідно для малювання тіней, градієнтів, заокруглених кутів, кіл, дуг, похилих ліній,
 *перетворень зображень або будь-яких масок*/
#define LV_DRAW_COMPLEX 1
#if LV_DRAW_COMPLEX != 0

/*Дозволити буферизацію деяких обчислень тіней.
 *LV_SHADOW_CACHE_SIZE — макс. розмір тіні для буферизації, де розмір тіні —
 *`shadow_width + radius`. Буферизація має витрати RAM у розмірі LV_SHADOW_CACHE_SIZE^2*/
#define LV_SHADOW_CACHE_SIZE 0
#endif /*LV_DRAW_COMPLEX*/

/*Розмір кешу зображень за замовчуванням. Кешування зображень зберігає їх відкритими.
 *Якщо використовуються лише вбудовані формати зображень, реальної переваги від
 *кешування немає. (Тобто якщо не додано новий декодер зображень) Зі складними декодерами
 *(напр. PNG або JPG) кешування може зекономити постійне відкриття/декодування зображень.
 *Однак відкриті зображення можуть споживати додаткову RAM.
 *0: вимкнути кешування*/
#define LV_IMG_CACHE_DEF_SIZE 0

/*Максимальний розмір буфера для виділення під обертання. Використовується лише якщо програмне обертання
 * увімкнено в драйвері дисплея.*/
#define LV_DISP_ROT_MAX_BUF (10 * 1024)
/*-------------
 * GPU
 *-----------*/

/*Використовувати GPU STM32 DMA2D (aka Chrom Art)*/
#define LV_USE_GPU_STM32_DMA2D 0
#if LV_USE_GPU_STM32_DMA2D
/*Має бути визначено для включення шляху до заголовка CMSIS цільового процесора,
напр. "stm32f769xx.h" або "stm32f429xx.h"*/
#define LV_GPU_DMA2D_CMSIS_INCLUDE
#endif

/*Використовувати GPU NXP PXP на платформах iMX RTxxx*/
#define LV_USE_GPU_NXP_PXP 0
#if LV_USE_GPU_NXP_PXP
/*1: Додати стандартні обробники переривань bare metal та FreeRTOS для PXP
 *(lv_gpu_nxp_pxp_osa.c) і викликати lv_gpu_nxp_pxp_init() автоматично під час
 *lv_init(). Зверніть увагу, що символ SDK_OS_FREE_RTOS має бути визначений для використання
 *FreeRTOS OSA, інакше обирається реалізація bare-metal. 0:
 *lv_gpu_nxp_pxp_init() має викликатися вручну перед lv_init()
 */
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
#endif

/*Використовувати GPU NXP VG-Lite на платформах iMX RTxxx*/
#define LV_USE_GPU_NXP_VG_LITE 0

/*-------------
 * Журналювання
 *-----------*/

/*Увімкнути модуль журналювання*/
#define LV_USE_LOG 1
#if LV_USE_LOG

/*Наскільки важливі логи додавати:
 *LV_LOG_LEVEL_TRACE       Багато логів для детальної інформації
 *LV_LOG_LEVEL_INFO        Журналювати важливі події
 *LV_LOG_LEVEL_WARN        Журналювати, якщо сталося щось небажане, але це не спричинило
 *проблеми LV_LOG_LEVEL_ERROR       Лише критична проблема, коли система може дати збій
 *LV_LOG_LEVEL_USER        Лише логи, додані користувачем
 *LV_LOG_LEVEL_NONE        Нічого не журналювати*/
#define LV_LOG_LEVEL LV_LOG_LEVEL_INFO

/*1: Виводити лог через 'printf';
 *0: Користувачу потрібно зареєструвати зворотний виклик через `lv_log_register_print_cb()`*/
#define LV_LOG_PRINTF 0

/*Увімкнути/вимкнути LV_LOG_TRACE у модулях, які створюють велику кількість логів*/
#define LV_LOG_TRACE_MEM 1
#define LV_LOG_TRACE_TIMER 1
#define LV_LOG_TRACE_INDEV 1
#define LV_LOG_TRACE_DISP_REFR 1
#define LV_LOG_TRACE_EVENT 1
#define LV_LOG_TRACE_OBJ_CREATE 1
#define LV_LOG_TRACE_LAYOUT 1
#define LV_LOG_TRACE_ANIM 1

#endif /*LV_USE_LOG*/

/*-------------
 * Перевірки (Asserts)
 *-----------*/

/*Увімкнути перевірки, якщо операція завершилася невдало або знайдено некоректні дані.
 *Якщо увімкнено LV_USE_LOG, при помилці буде виведено повідомлення*/
#define LV_USE_ASSERT_NULL                                                     \
  1 /*Перевірити, чи параметр NULL. (Дуже швидко, рекомендовано)*/
#define LV_USE_ASSERT_MALLOC                                                   \
  1 /*Перевіряє, чи пам'ять успішно виділено чи ні. (Дуже швидко,        \
       рекомендовано)*/
#define LV_USE_ASSERT_STYLE                                                    \
  0 /*Перевірити, чи стилі коректно ініціалізовано. (Дуже швидко, рекомендовано)*/
#define LV_USE_ASSERT_MEM_INTEGRITY                                            \
  0 /*Перевірити цілісність `lv_mem` після критичних операцій. (Повільно)*/
#define LV_USE_ASSERT_OBJ                                                      \
  0 /*Перевірити тип та існування об'єкта (напр. не видалено). (Повільно)*/

/*Додати власний обробник при спрацюванні assert, напр. для перезапуску МК*/
#define LV_ASSERT_HANDLER_INCLUDE <stdint.h>
#define LV_ASSERT_HANDLER                                                      \
  while (1)                                                                    \
    ; /*Зупинити за замовчуванням*/

/*-------------
 * Інше
 *-----------*/

/*1: Показувати використання CPU та лічильник FPS у правому нижньому куті*/
#define LV_USE_PERF_MONITOR 0

/*1: Показувати використану пам'ять та фрагментацію пам'яті у лівому нижньому
 * куті Потребує LV_MEM_CUSTOM = 0*/
#define LV_USE_MEM_MONITOR 0

/*1: Малювати випадкові кольорові прямокутники поверх перемальованих ділянок*/
#define LV_USE_REFR_DEBUG 0

/*Змінити вбудовані функції (v)snprintf*/
#define LV_SPRINTF_CUSTOM 0
#if LV_SPRINTF_CUSTOM
#define LV_SPRINTF_INCLUDE <stdio.h>
#define lv_snprintf snprintf
#define lv_vsnprintf vsnprintf
#else /*LV_SPRINTF_CUSTOM*/
#define LV_SPRINTF_USE_FLOAT 0
#endif /*LV_SPRINTF_CUSTOM*/

#define LV_USE_USER_DATA 1

/*Налаштування Збирача сміття
 *Використовується, якщо lvgl прив'язано до мови вищого рівня, а пам'яттю керує
 *ця мова*/
#define LV_ENABLE_GC 0
#if LV_ENABLE_GC != 0
#define LV_GC_INCLUDE "gc.h" /*Включити пов'язане із Збирачем сміття*/
#endif                       /*LV_ENABLE_GC*/

/*=====================
 *  НАЛАШТУВАННЯ КОМПІЛЯТОРА
 *====================*/

/*Для систем з big endian встановіть 1*/
#define LV_BIG_ENDIAN_SYSTEM 0

/*Визначити власний атрибут для функції `lv_tick_inc`*/
#ifdef ESP32
#define LV_ATTRIBUTE_TICK_INC IRAM_ATTR
#else
#define LV_ATTRIBUTE_TICK_INC
#endif

/*Визначити власний атрибут для функції `lv_timer_handler`*/
#define LV_ATTRIBUTE_TIMER_HANDLER

/*Визначити власний атрибут для функції `lv_disp_flush_ready`*/
#define LV_ATTRIBUTE_FLUSH_READY

/*Необхідний розмір вирівнювання для буферів*/
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE

/*Буде додано там, де пам'ять потребує вирівнювання (з -Os дані можуть не бути
 * вирівняні до межі за замовчуванням). Напр. __attribute__((aligned(4)))*/
#define LV_ATTRIBUTE_MEM_ALIGN

/*Атрибут для позначення великих константних масивів, наприклад бітових карт шрифтів*/
#define LV_ATTRIBUTE_LARGE_CONST

/*Префікс компілятора для оголошення великого масиву в RAM*/
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY

/*Розмістити критичні до продуктивності функції у швидшу пам'ять (напр. RAM)*/
#ifdef ESP32
#define LV_ATTRIBUTE_FAST_MEM IRAM_ATTR
#else
#define LV_ATTRIBUTE_FAST_MEM
#endif

/*Префікс для змінних, що використовуються у GPU-прискорених операціях; часто їх потрібно
 * розмістити у розділах RAM, доступних для DMA*/
#define LV_ATTRIBUTE_DMA

/*Експортувати цілу константу у прив'язку. Цей макрос використовується з константами у
 *формі LV_<CONST>, які також мають з'являтися в API прив'язки LVGL, такому як
 *Micropython.*/
#define LV_EXPORT_CONST_INT(int_value)                                         \
  struct _silence_gcc_warning /*Значення за замовчуванням лише запобігає попередженню GCC*/

/*Розширити стандартний діапазон координат -32k..32k до -4M..4M, використовуючи int32_t для
 * координат замість int16_t*/
#define LV_USE_LARGE_COORD 0

/*==================
 *   ВИКОРИСТАННЯ ШРИФТІВ
 *===================*/

/*Шрифти Montserrat з діапазоном ASCII та деякими символами, використовуючи bpp = 4
 *https://fonts.google.com/specimen/Montserrat*/
#define LV_FONT_MONTSERRAT_8 0
#define LV_FONT_MONTSERRAT_10 0
#define LV_FONT_MONTSERRAT_12 0
#define LV_FONT_MONTSERRAT_14 1
#define LV_FONT_MONTSERRAT_16 0
#define LV_FONT_MONTSERRAT_18 0
#define LV_FONT_MONTSERRAT_20 0
#define LV_FONT_MONTSERRAT_22 0
#define LV_FONT_MONTSERRAT_24 0
#define LV_FONT_MONTSERRAT_26 0
#define LV_FONT_MONTSERRAT_28 0
#define LV_FONT_MONTSERRAT_30 0
#define LV_FONT_MONTSERRAT_32 0
#define LV_FONT_MONTSERRAT_34 0
#define LV_FONT_MONTSERRAT_36 0
#define LV_FONT_MONTSERRAT_38 0
#define LV_FONT_MONTSERRAT_40 0
#define LV_FONT_MONTSERRAT_42 0
#define LV_FONT_MONTSERRAT_44 0
#define LV_FONT_MONTSERRAT_46 0
#define LV_FONT_MONTSERRAT_48 0

/*Демонстрація спеціальних функцій*/
#define LV_FONT_MONTSERRAT_12_SUBPX 0
#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW                                       \
  0 /*Іврит, арабські, перські літери та всі їхні форми*/
#define LV_FONT_SIMSUN_16_CJK 0 /*1000 найпоширеніших CJK-радикалів*/

/*Піксельно точні моноширинні шрифти*/
#define LV_FONT_UNSCII_8 0
#define LV_FONT_UNSCII_16 0

/*За бажанням оголосіть власні шрифти тут.
 *Ви можете використовувати ці шрифти як шрифт за замовчуванням, і вони будуть доступні
 *глобально. Напр. #define LV_FONT_CUSTOM_DECLARE   LV_FONT_DECLARE(my_font_1)
 *LV_FONT_DECLARE(my_font_2)*/
#define LV_FONT_CUSTOM_DECLARE

/*Завжди встановлюйте шрифт за замовчуванням*/
#define LV_FONT_DEFAULT &lv_font_montserrat_14

/*Увімкнути обробку великих шрифтів та/або шрифтів із великою кількістю символів.
 *Обмеження залежить від розміру шрифту, гарнітури та bpp.
 *Помилка компілятора виникне, якщо шрифт цього потребує.*/
#define LV_FONT_FMT_TXT_LARGE 0

/*Увімкнути/вимкнути підтримку стиснених шрифтів.*/
#define LV_USE_FONT_COMPRESSED 0

/*Увімкнути субпіксельний рендеринг*/
#define LV_USE_FONT_SUBPX 0
#if LV_USE_FONT_SUBPX
/*Встановити порядок пікселів дисплея. Фізичний порядок RGB-каналів. Не
 * має значення для "звичайних" шрифтів.*/
#define LV_FONT_SUBPX_BGR 0 /*0: RGB; 1: порядок BGR*/
#endif

/*=================
 *  НАЛАШТУВАННЯ ТЕКСТУ
 *=================*/

/**
 * Оберіть кодування символів для рядків.
 * Ваше IDE або редактор повинен мати те саме кодування символів
 * - LV_TXT_ENC_UTF8
 * - LV_TXT_ENC_ASCII
 */
#define LV_TXT_ENC LV_TXT_ENC_UTF8

/*Може переносити (обгортати) тексти на цих символах*/
#define LV_TXT_BREAK_CHARS " ,.;:-_"

/*Якщо слово має принаймні таку довжину, перенос відбудеться там, де "найкраще"
 *Щоб вимкнути, встановіть значення <= 0*/
#define LV_TXT_LINE_BREAK_LONG_LEN 0

/*Мінімальна кількість символів у довгому слові для розміщення в рядку до переносу.
 *Залежить від LV_TXT_LINE_BREAK_LONG_LEN.*/
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3

/*Мінімальна кількість символів у довгому слові для розміщення в рядку після переносу.
 *Залежить від LV_TXT_LINE_BREAK_LONG_LEN.*/
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3

/*Керуючий символ для сигналізації про перекраску тексту.*/
#define LV_TXT_COLOR_CMD "#"

/*Підтримка двонаправлених текстів. Дозволяє змішувати текст зліва направо та справа наліво.
 *Напрямок буде оброблено згідно з Двонаправленим алгоритмом Unicode:
 *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
#define LV_USE_BIDI 0
#if LV_USE_BIDI
/*Встановити напрямок за замовчуванням. Підтримувані значення:
 *`LV_BASE_DIR_LTR` Зліва направо
 *`LV_BASE_DIR_RTL` Справа наліво
 *`LV_BASE_DIR_AUTO` визначати базовий напрямок тексту*/
#define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO
#endif

/*Увімкнути обробку арабської/перської
 *У цих мовах символи мають замінюватися іншою формою залежно від
 *їхньої позиції у тексті*/
#define LV_USE_ARABIC_PERSIAN_CHARS 0

/*==================
 *  ВИКОРИСТАННЯ ВІДЖЕТІВ
 *================*/

/*Документація віджетів:
 * https://docs.lvgl.io/latest/en/html/widgets/index.html*/

#define LV_USE_ARC 1

#define LV_USE_ANIMIMG 1

#define LV_USE_BAR 1

#define LV_USE_BTN 1

#define LV_USE_BTNMATRIX 1

#define LV_USE_CANVAS 1

#define LV_USE_CHECKBOX 1

#define LV_USE_DROPDOWN 1 /*Потребує: lv_label*/

#define LV_USE_IMG 1 /*Потребує: lv_label*/

#define LV_USE_LABEL 1
#if LV_USE_LABEL
#define LV_LABEL_TEXT_SELECTION 1 /*Увімкнути виділення тексту мітки*/
#define LV_LABEL_LONG_TXT_HINT                                                 \
  1 /*Зберігати додаткову інформацію в мітках для прискорення малювання дуже довгих текстів*/
#endif

#define LV_USE_LINE 1

#define LV_USE_ROLLER 1 /*Потребує: lv_label*/
#if LV_USE_ROLLER
#define LV_ROLLER_INF_PAGES                                                    \
  7 /*Кількість додаткових "сторінок", коли ролер нескінченний*/
#endif

#define LV_USE_SLIDER 1 /*Потребує: lv_bar*/

#define LV_USE_SWITCH 1

#define LV_USE_TEXTAREA 1 /*Потребує: lv_label*/
#if LV_USE_TEXTAREA != 0
#define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*мс*/
#endif

#define LV_USE_TABLE 1

/*==================
 * ДОДАТКОВІ КОМПОНЕНТИ
 *==================*/

/*-----------
 * Віджети
 *----------*/
#define LV_USE_CALENDAR 1
#if LV_USE_CALENDAR
#define LV_CALENDAR_WEEK_STARTS_MONDAY 0
#if LV_CALENDAR_WEEK_STARTS_MONDAY
#define LV_CALENDAR_DEFAULT_DAY_NAMES                                          \
  { "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su" }
#else
#define LV_CALENDAR_DEFAULT_DAY_NAMES                                          \
  { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }
#endif

#define LV_CALENDAR_DEFAULT_MONTH_NAMES                                        \
  {                                                                            \
    "January", "February", "March", "April", "May", "June", "July", "August",  \
        "September", "October", "November", "December"                         \
  }
#define LV_USE_CALENDAR_HEADER_ARROW 1
#define LV_USE_CALENDAR_HEADER_DROPDOWN 1
#endif /*LV_USE_CALENDAR*/

#define LV_USE_CHART 1

#define LV_USE_COLORWHEEL 1

#define LV_USE_IMGBTN 1

#define LV_USE_KEYBOARD 1

#define LV_USE_LED 1

#define LV_USE_LIST 1

#define LV_USE_METER 1

#define LV_USE_MSGBOX 1

#define LV_USE_SPINBOX 1

#define LV_USE_SPINNER 1

#define LV_USE_TABVIEW 1

#define LV_USE_TILEVIEW 1

#define LV_USE_WIN 1

#define LV_USE_SPAN 1
#if LV_USE_SPAN
/*Рядок тексту може містити макс. кількість дескрипторів span */
#define LV_SPAN_SNIPPET_STACK_SIZE 64
#endif

/*-----------
 * Теми
 *----------*/
/*Проста, вражаюча та дуже повна тема*/
#define LV_USE_THEME_DEFAULT 1
#if LV_USE_THEME_DEFAULT

/*0: Світлий режим; 1: Темний режим*/
#define LV_THEME_DEFAULT_DARK 0

/*1: Увімкнути збільшення при натисканні*/
#define LV_THEME_DEFAULT_GROW 1

/*Час переходу за замовчуванням у [мс]*/
#define LV_THEME_DEFAULT_TRANSITON_TIME 80
#endif /*LV_USE_THEME_DEFAULT*/

/*Дуже проста тема, яка є хорошою відправною точкою для власної теми*/
#define LV_USE_THEME_BASIC 1

/*Тема, розроблена для монохромних дисплеїв*/
#define LV_USE_THEME_MONO 1

/*-----------
 * Макети
 *----------*/

/*Макет, подібний до Flexbox у CSS.*/
#define LV_USE_FLEX 1

/*Макет, подібний до Grid у CSS.*/
#define LV_USE_GRID 1

/*==================
 * ПРИКЛАДИ
 *==================*/

/*Увімкнути збірку прикладів разом із бібліотекою*/
#define LV_BUILD_EXAMPLES 1

/*--КІНЕЦЬ LV_CONF_H--*/

#endif /*LV_CONF_H*/

#endif /*Кінець "Увімкнення вмісту"*/

і тепер спробуйте завантажити вашу програму знову.

Пояснення:

lv_tlsf_trace.cpp
void lv_mem_init(void)
{
    // ...
    tlsf = lv_tlsf_create_with_pool((void *)LV_MEM_POOL_ALLOC(LV_MEM_SIZE), LV_MEM_SIZE);
    // ...
}

із LV_MEM_POOL_ALLOC(LV_MEM_SIZE), за замовчуванням розгортається у ps_malloc — іншими словами, ваш ESP32 намагатиметься виділити це з PSRAM.

Ми виправили це, визначивши у нашому власному lv_conf.h наступне:

lv_init_backtrace.cpp
#define LV_MEM_POOL_INCLUDE <stdlib.h>
#define LV_MEM_POOL_ALLOC malloc

замість значення за замовчуванням

lv_init_stacktrace.cpp
#define LV_MEM_POOL_INCLUDE <esp32-hal-psram.h>
#define LV_MEM_POOL_ALLOC ps_malloc

Прапорці компілятора необхідні для виправлення проблем, пов’язаних із тим, що LVGL очікує lv_conf.h у певному місці.

Сеанс налагодження GDB для дослідження трасування стека

gdb_backtrace.txt
(gdb) i sym 0x400dedf0
lv_tlsf_create + 36 in section .flash.text
(gdb) i sym  0x400d4ce3
lv_init + 43 in section .flash.text
(gdb) i sym 0x400f4506
Adafruit_LvGL_Glue::begin(Adafruit_SPITFT*, void*, bool) + 6 in section .flash.text

Послідовний вивід / журнал збою

serial_crash_log.txt
Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13192
load:0x40080400,len:3028
entry 0x400805e4
Guru Meditation Error: Core  1 panic'ed (StoreProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x400dedfb  PS      : 0x00060830  A0      : 0x800dee25  A1      : 0x3ffb2180
A2      : 0x00000000  A3      : 0x00000000  A4      : 0x0000001b  A5      : 0x00060e23
A6      : 0x007bf388  A7      : 0x003fffff  A8      : 0x00000000  A9      : 0x00000000
A10     : 0x00000480  A11     : 0x00000000  A12     : 0x0000000e  A13     : 0x3ffbcc50
A14     : 0x00000003  A15     : 0x00060023  SAR     : 0x00000005  EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000008  LBEG    : 0x40089691  LEND    : 0x400896a1  LCOUNT  : 0xfffffff5


Backtrace: 0x400dedf8:0x3ffb2180 0x400dee22:0x3ffb21a0 0x400dd607:0x3ffb21c0 0x400d4ceb:0x3ffb21e0 0x400f450e:0x3ffb2200 0x400f462b:0x3ffb2250 0x400d23f9:0x3ffb2270 0x400f54a2:0x3ffb2290

Дивіться схожі статті за категоріями: LVGL PlatformIO