如何修复 ESP32 LVGL 在 lv_tlsf_create() / lv_mem_init() 中的崩溃/重启

问题:

尝试在 ESP32 上运行 LVGL 示例(如 PlatformIO 的 ST7735R 最小 LVGL 图表示例)时,你的 MCU 在初始化后反复崩溃(完整崩溃日志见下文),在 lv_mem_init() 内调用的 lv_tlsf_create() 期间

解决方案

此崩溃是由于某个 LVGL 相关库使用 ps_malloc(),尝试从外部 PSRAM 芯片分配内存 - 而你的板子没有(通常也不需要)

要修复它,首先在 platformio.ini 中添加以下行:

platformio.ini
build_flags = -DLV_CONF_INCLUDE_SIMPLE -DLV_CONF_SUPPRESS_DEFINE_CHECK

现在,创建一个新文件 include/lv_conf.h,我们将用它来覆盖默认设置。这基于如何在 PlatformIO 上使用自定义 LVGL lv_conf.h 与 Adafruit LittlevGL Glue Library。

将以下内容粘贴到 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

/* 交换 RGB565 颜色的 2 个字节。
 * 如果显示器有 8 位接口(如 SPI)则很有用*/
#if defined(ADAFRUIT_PYPORTAL)
#define LV_COLOR_16_SWAP 1
#else
#define LV_COLOR_16_SWAP 0
#endif

/*启用更复杂的绘图例程来管理屏幕透明度。
 *如果 UI 在另一层之上,例如 OSD 菜单或视频
 *播放器,则可以使用。
 *需要 `LV_COLOR_DEPTH = 32` 颜色,并且屏幕的 `bg_opa` 应设置为
 *非 LV_OPA_COVER 值*/
#define LV_COLOR_SCREEN_TRANSP 0

/*如果图像像素是色键透明的,则此颜色的像素不会被绘制)*/
#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()` 可用的内存大小(字节)(>= 2kB)*/
#define LV_MEM_SIZE (32U * 1024U) /*[字节]*/

/*为内存池设置地址,而不是将其分配为普通数组。
 * 也可以在外部 SRAM 中。*/
#define LV_MEM_ADR 0 /*0:未使用*/

// 对于 ESP32,提供内存池分配器并使用 PSRAM 而非闪存
#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
 *-----------*/

/*使用 STM32 的 DMA2D(即 Chrom Art)GPU*/
#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

/*使用 NXP 的 PXP GPU iMX RTxxx 平台*/
#define LV_USE_GPU_NXP_PXP 0
#if LV_USE_GPU_NXP_PXP
/*1:为 PXP 添加默认裸机和 FreeRTOS 中断处理例程
 *(lv_gpu_nxp_pxp_osa.c) 并在 lv_init() 期间自动调用 lv_gpu_nxp_pxp_init()。
 *注意必须定义符号 SDK_OS_FREE_RTOS 才能使用
 *FreeRTOS OSA,否则选择裸机实现。0:
 *lv_gpu_nxp_pxp_init() 必须在 lv_init() 之前手动调用
 */
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
#endif

/*使用 NXP 的 VG-Lite GPU 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*/

/*-------------
 * 断言
 *-----------*/

/*如果操作失败或发现无效数据,则启用断言。
 *如果启用了 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 /*检查对象的类型和存在性(例如未被删除)。(慢)*/

/*当断言发生时添加自定义处理程序,例如重启 MCU*/
#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*/

/*=====================
 *  编译器设置
 *====================*/

/*对于大端系统设置为 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 加速操作中使用的变量添加前缀,这些变量通常需要
 * 放置在可 DMA 访问的 RAM 段中*/
#define LV_ATTRIBUTE_DMA

/*将整数常量导出到绑定。此宏用于
 *LV_<CONST> 形式的常量,这些常量也应出现在 LVGL 绑定 API 中,如
 *Micropython。*/
#define LV_EXPORT_CONST_INT(int_value)                                         \
  struct _silence_gcc_warning /*默认值仅防止 GCC 警告*/

/*通过使用 int32_t 代替 int16_t 将默认的 -32k..32k 坐标范围
 * 扩展到 -4M..4M*/
#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

/*-----------
 * 布局
 *----------*/

/*类似于 CSS 中 Flexbox 的布局。*/
#define LV_USE_FLEX 1

/*类似于 CSS 中 Grid 的布局。*/
#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