拓冰建站拓冰建站
首页 / 资讯中心 / 正文

STM32F746G-DISCO 移植 LVGL 9.0 与性能基准测试实践

在 STM32F746G-DISCO 上移植 LVGL 9.0并跑一遍性能基准测试是评估这块板子适合承载什么样 UI 的快速方法。很多开发者拿到官方评估板后第一反应是下载一个 LVGL 示例工程烧进去看到屏幕亮起来就认为移植完成。但实际项目里真正重要的不是“能不能显示”而是“在多少帧率下显示”“复杂动画是否可接受”“CPU 还剩多少余量给业务逻辑”。这篇文章从硬件和框架匹配开始逐步完成 LVGL 9.0 的移植适配再通过官方 Benchmark 和自定义测试采集数据最后给出优化方向和排查思路。适合正在学习 LVGL、想把图形界面搬到 STM32 上或准备做 UI 性能选型的嵌入式开发者。1. 先理解 STM32F746G-DISCO 与 LVGL 9.0 的匹配关系1.1 这块板子凭什么能跑 LVGL 9.0STM32F746G-DISCO 是 ST 官方评估板核心是 STM32F746 系列 MCU。和很多低功耗单片机不同它具备跑图形界面的基础条件主频最高 216MHz属于 Cortex-M7 核心带 FPU 和 DSP 指令。芯片自带 LTDC 液晶显示控制器可以直接驱动 RGB 接口 LCD。板载 SDRAM可以存放较大帧缓冲和 LVGL 内存池。集成 DMA2D 图形加速器可以加速颜色填充、像素拷贝和混合。板载屏幕通常是 RGB 接口 TFT LCD分辨率常见为 480x272。对于这类分辨率像素格式用 RGB565 时一帧图像约 480 乘 272 乘 2 字节约 250KB 左右。如果只用内部 SRAM 会非常紧张所以 SDRAM 几乎是必须的。这也是 F746G-DISCO 适合跑 LVGL 的原因LTDC 负责扫描显示SDRAM 提供帧缓冲DMA2D 分担像素操作CPU 可以更多地跑 LVGL 渲染和业务代码。移植前一定要确认几个硬件事实板载 LCD 的具体面板型号、分辨率、像素格式、触控 IC 型号以及 SDRAM 大小和片选地址。不同批次的开发板可能使用不同面板不能只看网上的代码就认为一定匹配。1.2 LVGL 9.0 和 8.x 在移植时的差异LVGL 9.0 是 LVGL 的一个大版本升级和 8.x 在移植接口上并不完全兼容。如果直接翻出以前 8.x 的移植代码很可能编译不过或者显示异常。主要差异集中在显示驱动部分。LVGL 9.0 使用lv_display_t来描述显示设备注册显示器和设置 flush 回调的方式与 8.x 的lv_disp_drv_t、lv_disp_drv_register不同。缓冲区设置也从lv_disp_draw_buf_init改成了lv_display_set_buffers。输入设备部分同样重构为lv_indev_t回调函数参数也有变化。另一个容易踩坑的地方是lv_conf.h里的配置项。9.0 保留用户配置文件但很多宏被重命名或合并。比如颜色深度相关的宏依然是LV_COLOR_DEPTH但绘制缓冲区、日志、Demo 开关的位置都可能有调整。最安全的做法是使用官方发布的 9.0 源码中自带的lv_conf_template.h拷贝一份修改而不是从 8.x 工程里直接搬。LVGL 9.0 的官方 Demo 里仍然包含lv_demo_benchmark这对我们做性能基准测试很有帮助。但 Demo 目录需要单独启用LV_USE_DEMO_BENCHMARK默认通常是关闭的。1.3 为什么要做性能基准测试嵌入式 GUI 的性能不是单一指标能说清的。有时界面看起来流畅是因为缺少复杂动画有时卡顿不是因为 CPU 主频低而是帧缓冲策略不合理。性能基准测试的作用是把画面渲染、内存拷贝、LCD 刷新这些环节拆开用统一场景量化数据。在 F746G-DISCO 上做基准测试至少能得到四类信息每秒实际刷新帧数也就是 FPS。单帧渲染耗时定位哪一类绘制操作最慢。像素填充速度衡量 DMA2D 和内存带宽是否成为瓶颈。CPU 占用比例看 LVGL 主循环是否吃掉了大部分性能。有了这些数据后续从 30 帧优化到 60 帧时才不会靠感觉改代码。后面的移植步骤会围绕“先跑起来再量化再优化”这条主线展开。2. 准备环境与最小工程2.1 软件开发环境推荐使用 STM32CubeIDE 完成整个工程搭建。它内置了 STM32CubeMX 和 GCC 工具链可以直接生成 HAL 底层代码再引入 LVGL 源码编译。如果习惯 Keil 或 IAR也可以但配置路径时要注意编译器的头文件包含语法差异。LVGL 9.0 源码建议从 GitHub 或官网下载 release 包。使用 Git 的话可以按指定分支拉取git clone --branch v9.0.0 --depth 1 https://github.com/lvgl/lvgl.git如果下载不便也可以直接下载压缩包。这里要注意的是release 包名称和分支名称会随着版本变化落地前先确认目标版本号。LVGL 9.0 后续的小版本可能会修复一些 bug建议选用较新的 9.x release。除了 LVGL 源码还需要准备STM32F7 系列 HAL 库。一个可以输出日志的调试串口。ST-Link 驱动和调试软件。日志输出对 LVGL 性能测试非常关键因为 Benchmark 结果可以通过LV_LOG_USER打印到串口。2.2 用 STM32CubeMX 生成基础工程新建 STM32CubeMX 工程芯片选择 STM32F746IGH6 或板卡对应的具体型号。时钟配置这里要确认 HSE 是否焊接PLL 最终输出目标设置为 216MHz。STM32F746 的 LTDC 时钟来自 PLLSAI需要单独配置像素时钟像素时钟大小取决于 LCD 面板型号和分辨率不能随意设置。基础外设建议按下面表格配置外设作用配置要点FMC SDRAM提供帧缓冲和 LVGL 内存池根据板载 SDRAM 芯片手册配置时序行列地址宽度、刷新周期LTDC输出 RGB 图像到 LCD配置分辨率、像素格式、层大小、帧缓冲地址DMA2D加速像素操作使能时钟后续可由 HAL 库调用USART输出 LVGL 日志配置波特率重定向printf或fputcGPIOLCD 背光、复位控制确认开发板的背光引脚和有效电平I2C 或 SPI触摸屏控制器如果有在接输入设备时用生成工程后不要急着写 LVGL 代码。先下载一个不会画任何图像的测试程序把 SDRAM 读写测一遍再把 LTDC 输出纯色或颜色条确认屏幕能点亮且帧缓冲地址正确。这一步能避免后续花屏时在 LVGL 和硬件配置之间反复猜测。2.3 工程目录和源码集成LVGL 源码加入工程时建议保持目录独立性。一个常见结构如下project_root/ ├─ Core/ ├─ Drivers/ ├─ Middlewares/ │ └─ lvgl/ │ ├─ src/ │ ├─ demos/ │ ├─ lv_conf.h │ └─ lvgl.h ├─ App/ │ ├─ lv_port_disp.c │ ├─ lv_port_disp.h │ ├─ lv_port_indev.c │ └─ lv_port_indev.h ├─ STM32CubeIDE/ └─ Debug/把 LVGL 的src目录全部加入源文件搜索路径demos目录也加入但后续可以在配置里决定是否编译。头文件路径需要加入Middlewares/lvgl和App。如果使用lv_conf.h作为独立配置文件还要在C/C 设置的预处理器中添加宏定义LV_CONF_INCLUDE_SIMPLE这样lvgl.h才能找到lv_conf.h。这是最常见的编译错误来源之一。3. 移植适配让 LVGL 9.0 显示到屏幕3.1 修改 lv_conf.h 配置LVGL 9.0 源码中会带一份lv_conf_template.h把它拷贝到工程目录并改名为lv_conf.h。重点修改以下几项。#define LV_COLOR_DEPTH 16 #define LV_USE_LOG 1 #define LV_LOG_LEVEL LV_LOG_LEVEL_INFO #define LV_DEF_REFR_PERIOD 30 #define LV_MEM_SIZE (64 * 1024) #define LV_USE_DEMO_BENCHMARK 1LV_COLOR_DEPTH必须和 LTDC 配置的像素格式一致。如果 LTDC 配置成 RGB565LVGL 也使用 16 位颜色深度否则颜色会错乱。LV_DEF_REFR_PERIOD是 LVGL 内部刷新周期单位是毫秒默认 30ms 对应大约 33FPS 上限。这个值可以后续调整但要清楚它只是一个刷新周期不是真实帧率。LV_MEM_SIZE是 LVGL 内部动态内存池大小如果跑 Benchmark 发现内存不足要适当增大。对 F746G-DISCO 来说SDRAM 空间足够可以给到 128KB 甚至更大。LV_USE_LOG和LV_LOG_LEVEL在性能测试阶段建议打开。日志级别设置为LV_LOG_LEVEL_USER或LV_LOG_LEVEL_INFO可以输出 Benchmark 的统计信息。正式项目发布前再把日志关闭避免串口打印占用时间。3.2 实现显示驱动 flush 回调LVGL 渲染完一帧后会通过 flush 回调把像素数据交给底层。在 9.0 中回调原型接近这样static void disp_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) { uint32_t w lv_area_get_width(area); uint32_t h lv_area_get_height(area); uint32_t dest_addr LCD_FB_ADDR (area-y1 * LCD_WIDTH area-x1) * 2; memcpy((void *)dest_addr, px_map, w * h * 2); lv_display_flush_ready(disp); }这里LCD_FB_ADDR是 LTDC 实际使用的帧缓冲地址。px_map是 LVGL 渲染完成的像素数据。flush 回调的任务就是把这块数据拷贝到帧缓冲告诉 LVGL 已经处理完成。在 F746G-DISCO 上memcpy可以用 DMA2D 的存储器到存储器模式替代这样 CPU 不用参与大块拷贝。DMA2D 配置示例可以用 HAL 库完成DMA2D_HandleTypeDef hdma2d; hdma2d.Init.Mode DMA2D_M2M; hdma2d.Init.ColorMode DMA2D_RGB565; hdma2d.Init.OutputOffset 0; HAL_DMA2D_Init(hdma2d); HAL_DMA2D_Start(hdma2d, (uint32_t)px_map, dest_addr, w, h, 0); HAL_DMA2D_PollForTransfer(hdma2d, 100);使用 DMA2D 后flush 回调会等待 DMA 传输完成然后调用lv_display_flush_ready。这里的等待会占用 CPU但相比逐点复制仍然更快。如果希望进一步优化可以改为 DMA2D 中断方式在传输完成中断里调用lv_display_flush_ready这会让 LVGL 和 DMA 传输并行工作但复杂度更高。3.3 创建显示设备和缓冲区在 main 函数或一个独立的 init 函数中注册显示设备。LVGL 9.0 的风格如下static lv_display_t *disp; static uint8_t buf1[LCD_WIDTH * LCD_HEIGHT / 4 * 2]; static uint8_t buf2[LCD_WIDTH * LCD_HEIGHT / 4 * 2]; void lv_port_disp_init(void) { disp lv_display_create(LCD_WIDTH, LCD_HEIGHT); lv_display_set_flush_cb(disp, disp_flush_cb); lv_display_set_buffers(disp, buf1, buf2, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL); }这里的缓冲区大小可以按需调整。LV_DISPLAY_RENDER_MODE_PARTIAL表示 LVGL 只渲染需要更新的区域这是推荐模式。如果使用 full 模式LVGL 每帧都会重绘整个屏幕性能压力大很多。缓冲区是否放在 SDRAM 取决于内存规划。因为 LTDC 帧缓冲已经占用了不少 SDRAM 空间LVGL 的绘制缓冲区也可以放在 SDRAM但要特别留意后续 Cache 一致性问题。放在内部 SRAM 时访问速度更快但容量有限放在 SDRAM 时容量充足但可能有总线等待。3.4 触摸输入适配如果开发板带触摸屏需要把触摸芯片的数据接入 LVGL。LVGL 9.0 的输入设备回调示例static void indev_touchpad_read_cb(lv_indev_t *indev, lv_indev_data_t *data) { uint16_t x, y; uint8_t touched; touch_read(x, y, touched); if (touched) { >lv_indev_t *indev lv_indev_create(); lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); lv_indev_set_read_cb(indev, indev_touchpad_read_cb);触摸坐标需要和屏幕分辨率方向一致。如果发现点击位置偏移可能需要交换 X/Y 或做坐标镜像。3.5 运行 LVGL 主循环最简单的运行方式是裸机主循环while (1) { lv_timer_handler(); HAL_Delay(5); }lv_timer_handler()是 LVGL 的心跳入口它负责处理计时器、检测需要刷新的区域、执行绘制并调用 flush 回调。HAL_Delay(5)一方面限制主循环频率另一方面给其他外设处理留时间。如果后续集成 FreeRTOS可以创建一个任务任务里循环调用lv_timer_handler()并设置合适的任务优先级和堆栈大小。不要忘记提供 LVGL 的 tick 时间基准。如果使用裸机且没有配置 systickLVGL 需要一个时间函数。最简单的方式是在主循环里调用lv_tick_inc(HAL_GetTick() - last_tick)这种模式或者在已有 HAL 时配置 LV_TICK_CUSTOM 定时器。4. 跑通 LVGL 官方 Benchmark Demo4.1 添加并启用 DemoLVGL 官方提供了多个 Demo其中lv_demo_benchmark是专门用来测性能的。在lv_conf.h中启用#define LV_USE_DEMO_BENCHMARK 1然后在完成lv_init()、显示设备、输入设备初始化后调用lv_demo_benchmark();这个函数会启动一组预设的绘制场景自动运行并统计性能。屏幕会依次显示不同的测试页面例如填充、色块、文字、图像混合等。编译时如果找不到lv_demo_benchmark需要确认demos目录是否加入了编译路径。某些版本的源码要求demos/benchmark目录下的.c文件被包含进项目不能只添加src目录。4.2 验证显示是否正常烧录后首先观察屏幕是否点亮并显示 Benchmark 场景。正常情况应该看到多组彩色图案依次切换最后显示一个性能报告页面。如果只亮但不显示内容优先排查LTDC 层是否 enable。帧缓冲地址是否指向有效 SDRAM 区域。disp_flush_cb是否调用了lv_display_flush_ready。LV_COLOR_DEPTH是否和 LTDC 格式一致。如果画面花屏优先检查 SDRAM 配置和 Cache 一致性。F746 的 D-Cache 如果开启需要保证 flush 回调写入的帧缓冲位于 Cache 可管理区域或者在写入后执行 Clean 操作。4.3 读取 Benchmark 结果Benchmark 结果有两种读取方式屏幕直接显示统计结果。串口输出日志。在lv_conf.h开启LV_USE_LOG后可以把后面这类日志放到串口打印[Benchmark] FPS: 41.0 [Benchmark] CPU: 32.0% [Benchmark] Render time: 12 ms不同版本的 LVGL 输出格式可能不完全一样但基本都会有帧率和耗时信息。第一次跑出来的数据就是后续优化的基线建议记录到表格或文档中。这里要强调具体数字会受到时钟配置、缓冲区大小、优化等级、是否使用 DMA2D、是否开启 Cache 等多种因素影响不同板卡之间直接对比没有意义。5. 性能数据采集与瓶颈分析5.1 先用官方 Benchmark 建立基线官方 Benchmark 适合作为整体健康度检查。它包含多种常见绘制场景能反映综合性能。建议记录以下指标指标说明性能差时的表现平均 FPS每秒刷新帧数数值低于 20 时动画明显卡顿最慢单帧耗时绘制最复杂一帧的耗时最慢帧耗时超过刷新周期会造成掉帧CPU 占用LVGL 渲染占用的 CPU 比例比例过高会影响业务任务内存池剩余LVGL 动态内存使用量内存不足可能导致对象创建失败第一次跑出来的结果不需要做到很高重点是确认“能测”和“结果稳定”。之后每次改动都用同一条测试路径对比。5.2 自定义一组可控场景测试官方 Benchmark 是综合测试但有时候需要单独验证某类绘制操作。比如想知道纯色填充速度或者文本渲染性能可以自己写一个简单测试。用定时器配合 LVGL 对象刷新的方式粗略统计每秒刷新次数static uint32_t frame_count 0; static uint32_t last_tick 0; static void perf_timer_cb(lv_timer_t *timer) { frame_count; uint32_t now lv_tick_get(); if (now - last_tick 1000) { LV_LOG_USER(render count per second %ld, frame_count); frame_count 0; last_tick now; } lv_obj_invalidate(lv_screen_active()); }在主程序中创建一个容器对象并在容器里添加不同类型的子对象然后用上面的定时器不断使屏幕无效统计每秒刷新次数。这个方法不如 Benchmark 精确但可以快速观察改动前后性能趋势。5.3 测量单帧渲染耗时单帧耗时是定位卡顿的关键。可以利用 Cortex-M7 的 DWT 周期计数器在 flush 回调前后打时间戳CoreDebug-DEMCR | CoreDebug_DEMCR_TRCENA_Msk; DWT-CTRL | DWT_CTRL_CYCCNTENA_Msk; DWT-CYCCNT 0;然后在 flush 函数里uint32_t t0 DWT-CYCCNT; // 执行像素拷贝 uint32_t t1 DWT-CYCCNT; LV_LOG_USER(flush cost %d cycles, (int)(t1 - t0));DWT 计数器频率等于 CPU 频率216MHz 下每秒计数 216000000 次。把差值除以主频就得到耗时秒数。这个计时方法在开发调试阶段非常实用能清楚看到是渲染计算慢还是 DMA 拷贝慢。5.4 从数据判断瓶颈拿到数据后按以下思路分析如果 FPS 低但单帧渲染时间不高说明刷新周期设置或主循环调度有问题比如LV_DEF_REFR_PERIOD太大。如果单帧渲染时间明显高于刷新周期说明 LVGL 渲染计算吃紧需要优化绘制操作或开启 GPU 加速。如果渲染时间不高但 flush 等待时间很长说明像素拷贝或 LCD 刷新是瓶颈优先优化 DMA2D 和缓冲区布局。如果 CPU 占用过高考虑把部分绘制工作交给 DMA2D或者降低刷新率。6. 优化方向从 30 帧到更高帧率6.1 配置合适的帧缓冲策略LVGL 的缓冲区策略直接影响内存带宽和帧率。常见模式有三种模式描述优点缺点单缓冲全屏一个全屏缓冲区直接作为 LTDC 帧缓冲简单省内存闪烁明显LVGL 和 LTDC 访问冲突双缓冲全屏两个全屏缓冲区一个显示一个渲染画面流畅内存需求大部分缓冲 脏矩形一个小缓冲区只渲染变更区域内存占用低需要正确配置刷新区域F746G-DISCO 板载 SDRAM但 LTDC 帧缓冲已经占用了显存。对 480x272 RGB565 来说一帧约 250KB双缓冲就是 500KB。如果还要给 LVGL 内存池预留空间最好使用部分缓冲模式让 LVGL 自己计算脏矩形。LV_DISPLAY_RENDER_MODE_PARTIAL就是这个用途。6.2 启用 DMA2D 代替 memcpy像素拷贝是 GUI 最大的内存操作之一。DMA2D 做 M2M 拷贝时可以释放 CPU让它继续执行 LVGL 的下一步逻辑。最理想的 flush 是 DMA2D 和 CPU 并行CPU 渲染下一帧DMA2D 搬运上一帧。但要注意DMA2D 在传输完成后需要通知 LVGL。用中断方式时在 DMA2D 中断回调里调用lv_display_flush_ready避免轮询等待。这会增加一点代码复杂度但收益明显。6.3 CPU Cache 与内存屏障Cortex-M7 的 D-Cache 是性能利器也是显示异常的常见来源。如果 LVGL 缓冲区或帧缓冲位于 SDRAM并且开启了 D-CacheCPU 写入的数据可能暂时停留在 Cache 中DMA2D 或 LTDC 读 SDRAM 时无法看到最新数据。常见的处理方式有两种在每次 flush 回调用SCB_CleanDCache_by_Addr清理相应地址范围的缓存。为存储区域配置 MPU将帧缓冲区域设置为不缓存。第一种方式比较常用但要注意清理范围必须覆盖 flush 回调写入的整个区域。第二种方式用 MPU 将帧缓冲设为 Write-Through 或直接关闭缓存能避免大部分一致性问题但性能略有损失。具体取舍要根据实际测试结果决定。6.4 编译优化和日志开关编译器优化等级对字符串渲染、Alpha 混合等计算密集任务影响很大。使用 STM32CubeIDE 时可以在 Release 配置中把优化等级改为-O2或-O3。开启-O2一般就能看到帧率提升。同时性能测试后要把 LVGL 日志级别调低或关闭。开发阶段打开日志有助于定位问题但每次打印都会通过串口输出占用可观的 CPU 时间。发布前建议设置#define LV_USE_LOG 0关闭日志后再测一次基线往往会有意外收获。6.5 避免全屏刷新LVGL 本身支持脏矩形机制只要不使用全屏缓冲模式它只刷新变化区域。不要在自己代码里调用lv_obj_invalidate(lv_screen_active())这类“强制全部刷新”的操作除非确实需要全屏重绘。高频全屏刷新会让 LVGL 退化成“纯软件渲染整屏”性能断崖式下降。7. 移植和测试中的常见问题排查7.1 高频问题对照表问题现象常见原因检查方式处理建议白屏LTDC 层没有使能或帧缓冲地址错误检查 LTDC 层配置、帧缓冲地址是否映射到有效 SDRAM先输出纯色测试画面再接入 LVGL花屏LTDC 像素格式与 LVGL 颜色深度不一致确认LV_COLOR_DEPTH和 LTDC 配置统一使用 RGB565 或 RGB888画面闪烁单缓冲且刷新效率低观察是否只有刷新时才闪烁改为部分缓冲并确认脏矩形生效画面不更新没有调用lv_display_flush_ready在 flush 回调打断点在拷贝完成后立即调用唤醒 LVGL触摸位置偏移触摸坐标方向或缩放未处理打印触摸原始坐标映射到屏幕分辨率并做方向校准Benchmark 编译报错demos目录未加入工程检查源码目录是否包含demos添加路径或在工程中导入demos/benchmark源文件串口无 LVGL 日志LV_USE_LOG未开启或 printf 未重定向先打印普通字符串测试串口重定向fputc到串口并打开 LVGL 日志7.2 推荐排查链路遇到显示问题时不要先怀疑 LVGL 代码。按这个顺序排查先确认硬件通路下载一个不包含 LVGL 的例程用 LTDC 直接显示纯色或颜色条。如果纯色正常再检查 LVGL 配置颜色深度、分辨率宏、缓冲区大小。最后检查 flush 回调像素数据是否被正确拷贝到帧缓冲是否及时调用lv_display_flush_ready。如果加入 SDRAM 后花屏检查 FMC SDRAM 读写测试是否通过Cache 是否处理正确。一条经验是LVGL 的移植问题大多数不是 LVGL 本身的问题而是底层显示通路和内存访问不一致。8. 最佳实践与后续扩展8.1 移植前检查清单每次换新板卡或新版本 LVGL 时可以先走一遍这个清单确认 MCU 主频和 SDRAM 容量。用 CubeMX 生成 HAL 工程并先跑 SDRAM 读写测试。用 LTDC 输出纯色确认 RGB 屏幕通路正常。确认触摸 IC 型号并提前准备驱动代码。使用官方lv_conf_template.h生成lv_conf.h。只开启必要的 Demo先跑通显示再跑性能测试。记录初始帧率、单帧耗时和 CPU 占用。8.2 从基准测试到真实 UI 的注意事项Benchmark 结果好不代表真实界面一定流畅。真实 UI 包含多图层、大量控件、异步数据刷新和动画Benchmark 只是压力测试基线。实际项目中还要注意图片资源不要直接解码大尺寸 JPEG尽量使用 RGB565 压缩格式或 LZ4 压缩。频繁创建和销毁控件会消耗 LVGL 内存池尽量复用对象。主循环里不要做长时间阻塞操作否则会拖慢 LVGL 刷新。字体文件尽量使用小字号和子集化减少渲染开销。8.3 扩展方向完成这次移植后可以考虑几个方向集成 FreeRTOS将 LVGL 放到独立任务中用消息队列传递 UI 事件。把文件系统接入 LVGL支持从 SD 卡或 Flash 加载字体和图片。探索 LVGL 9.0 的多绘制单元模式让渲染任务可以并发执行。针对 F746 的 DMA2D 做更多定制例如混合模式、颜色格式转换。将性能测试结果作为项目基准每次改动后回归对比。移植 LVGL 9.0 到 F746G-DISCO 并不是终点性能基准测试的真正价值在于建立一套可重复的性能对比基线。建议拿到板卡后先把环境确认完再让官方 Demo 跑起来记录一组初始数据之后每次调整缓冲区、优化选项或驱动实现都用同一组场景重新测量。只有这样优化方向才不是靠感觉而是由数据驱动。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门