news 2026/4/29 16:41:19

LVGL显示移植:lv_port_disp.c 详情介绍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LVGL显示移植:lv_port_disp.c 详情介绍

lv_port_disp.c 详情介绍

lv_port_disp.c是 LVGL 显示移植核心,负责把 LVGL 渲染结果从内存缓冲刷到物理屏幕。
可以把它理解为 3 个阶段:初始化显示对象、接收刷新区域、完成硬件提交。

1. 文件职责与执行时序

  1. LVGL 初始化时调用lv_port_disp_init()完成显示驱动注册。
  2. LVGL 产生重绘后触发flush_cb(即disp_flush(...))。
  3. disp_flushcolor_p/px_map指向的像素数据送入 LCD 控制器或 SPI 驱动。
  4. 提交完成后通知 LVGL 刷新结束(LVGL8 常见为lv_disp_flush_ready)。

如果第 4 步缺失,现象通常是界面只刷一帧后卡死。

2. ra6m3-hmi-board 实现要点

对应文件:bsp/renesas/ra6m3-hmi-board/board/lvgl/lv_port_disp.c

  1. 显示接口

    • 使用 GLCDC;
    • 通过R_GLCDC_BufferChange(...)在刷新时切换到新帧缓冲。
  2. Vsync 同步

    • 通过DisplayVsyncCallback(...)+_SemaphoreVsync做同步;
    • 目的:在正确时机切缓冲,减少 tearing(撕裂)。
  3. LVGL8/LVGL9 双分支

    • LVGL8 分支使用lv_disp_drv_t/lv_disp_draw_buf_t
    • LVGL9 分支使用lv_display_createlv_display_set_flush_cblv_display_set_buffers
  4. 缓冲模式

    • 使用fb_background双缓冲(direct render 路径);
    • 分辨率变化后要同步检查缓冲大小与底层显存定义。

3. ra6m3-ek 实现要点

对应文件:bsp/renesas/ra6m3-ek/board/lvgl/lv_port_disp.c

  1. 两条输出路径

    • PKG_USING_ILI9341:SPI 屏路径,调用lcd_fill_array_spi(...)
    • 非 SPI 分支:直接写 framebuffer(RGB/LCD 设备)。
  2. 软件拷贝路径

    • 非 GPU 分支下,逐像素把 LVGL 颜色写入 framebuffer;
    • 包含区域裁剪逻辑(防止越界写显存)。
  3. 显存缓冲

    • buf_1通过链接段放在固定地址;
    • COLOR_BUFFER = LV_HOR_RES_MAX * LV_VER_RES_MAX / 4,表示四分之一屏缓冲。
  4. 刷新完成通知

    • disp_flush末尾调用lv_disp_flush_ready(disp_drv)
    • 该调用必须在所有输出分支都可达。

4. 常改参数与接口

  1. 分辨率联动

    • disp_drv.hor_res/ver_res(LVGL8)或lv_display_create参数(LVGL9);
    • 必须与lv_conf.hLV_HOR_RES_MAX/LV_VER_RES_MAX一致。
  2. flush 提交函数

    • RGB 屏:替换为平台 LCD 控制器切缓冲/拷贝接口;
    • SPI 屏:替换为 SPI 批量刷图函数。
  3. 缓冲策略

    • 单缓冲:省内存,可能更卡;
    • 双缓冲:更流畅,RAM 占用更高;
    • 部分缓冲(如 1/4 屏):折中方案,常用于 RAM 紧张场景。
  4. 同步机制

    • 使用 Vsync/中断/信号量时,要避免死等和时序反转;
    • flush偶发卡住,优先排查信号量初值与回调触发条件。

5. 常见故障与定位

  • 黑屏:确认lv_port_disp_init()是否被调用、LCD 设备是否打开成功、分辨率是否一致。
  • 只刷一次:确认每次flush都有flush_ready通知。
  • 花屏/偏色:核对LV_COLOR_DEPTH、字节序、像素格式转换逻辑。
  • 撕裂明显:检查是否在 Vsync 同步点提交缓冲。
  • 拖动卡顿:检查COLOR_BUFFER大小、是否走了低效逐像素路径、SPI 时钟是否过低。

6. 推荐调试步骤(显示链路)

  1. 先用纯色填充测试确认“能亮屏”;
  2. 再跑简单控件(label/button)确认flush连续触发;
  3. 再引入动画或列表滚动观察帧率与撕裂;
  4. 最后再开 GPU/2D 加速做性能优化。

7.lv_port_disp_init()详解

lv_port_disp_init()是显示移植的入口函数,它决定了 LVGL 后续能否正常刷新。
核心任务可以概括为 5 步:准备硬件资源 -> 准备绘图缓冲 -> 创建显示驱动对象 -> 绑定刷新回调 -> 注册到 LVGL

7.1 通用流程(抽象视角)

  1. 准备底层显示资源

    • 打开 LCD/SPI 设备,或准备 GLCDC 控制器;
    • 可选:创建同步资源(如 Vsync 信号量)。
  2. 初始化 draw buffer

    • 告诉 LVGL 使用哪块 RAM 作为绘图缓冲;
    • 决定单缓冲、双缓冲或部分缓冲策略。
  3. 创建并配置 display driver/display 对象

    • LVGL8:lv_disp_drv_init(...)
    • LVGL9:lv_display_create(...)
  4. 绑定刷新回调

    • disp_flush(...)绑定给 LVGL;
    • 可选绑定等待回调(如 Vsync wait)。
  5. 完成注册

    • LVGL8:lv_disp_drv_register(...)
    • LVGL9:对象创建并设置完成后即生效。

7.2ra6m3-hmi-board中的初始化细节

对应:bsp/renesas/ra6m3-hmi-board/board/lvgl/lv_port_disp.c

  1. 先创建_SemaphoreVsync,用于刷新同步;
  2. LVGL8 路径:
    • lv_disp_draw_buf_init(&disp_buf, &fb_background[0][0], &fb_background[1][0], sizeof(fb_background[0]))
    • 双缓冲直接对接fb_background
    • 设置disp_drv.hor_res/ver_resflush_cb
    • lv_disp_drv_register(&disp_drv)完成注册。
  3. LVGL9 路径:
    • lv_display_create(LV_HOR_RES_MAX, LV_VER_RES_MAX)
    • 设置lv_display_set_flush_cb(...)lv_display_set_flush_wait_cb(...)
    • lv_display_set_buffers(..., LV_DISPLAY_RENDER_MODE_DIRECT)配置 direct 模式双缓冲。
  4. 最后置lvgl_init_flag = 1,使 Vsync 回调开始真正参与同步。

7.3ra6m3-ek中的初始化细节

对应:bsp/renesas/ra6m3-ek/board/lvgl/lv_port_disp.c

  1. 先走硬件分支初始化:
    • SPI 屏分支:spi_lcd_init(20)
    • RGB/LCD 分支:查找并打开lcd设备,读取rt_device_graphic_info
  2. 初始化绘图缓冲:
    • lv_disp_draw_buf_init(&disp_buf, buf_1, NULL, COLOR_BUFFER)
    • 当前是单缓冲(第二缓冲传NULL)。
  3. 初始化显示驱动:
    • lv_disp_drv_init(&disp_drv)
    • 设置hor_res/ver_resdraw_bufflush_cb
  4. 可选 GPU 路径:
    • 若使能DLG_LVGL_USE_GPU_RA6M3,会额外lv_port_gpu_init()
  5. lv_disp_drv_register(&disp_drv)完成注册。

7.4 这个函数最容易出错的点

  • 分辨率不一致lv_conf.hlv_port_disp_init()设置不一致,会导致越界、显示异常或黑屏。
  • 缓冲大小不够:改分辨率后没同步改COLOR_BUFFER或底层 framebuffer。
  • 回调未绑定flush_cb未设置或被条件编译排除,界面不刷新。
  • 设备未打开rt_device_find/open失败,后续写 framebuffer 会异常。
  • 同步对象时序问题:Vsync 信号量初值、等待时机不当,可能导致flush卡死。

7.5 建议的最小验证法(只测 init)

  1. 断点或日志确认lv_port_disp_init()执行到末尾;
  2. 输出当前分辨率、缓冲地址和缓冲长度;
  3. 统计disp_flush调用次数(确认刷新链路已建立);
  4. 屏幕显示单个静态 label(先不加动画)验证基本通路。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 16:40:24

Windows风扇控制终极指南:用Fan Control告别电脑噪音与过热烦恼

Windows风扇控制终极指南:用Fan Control告别电脑噪音与过热烦恼 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Tr…

作者头像 李华
网站建设 2026/4/29 16:39:44

从物理约束到AI加速:NVIDIA PhysicsNeMo如何重塑科学计算范式

从物理约束到AI加速:NVIDIA PhysicsNeMo如何重塑科学计算范式 【免费下载链接】modulus Open-source deep-learning framework for building, training, and fine-tuning deep learning models using state-of-the-art Physics-ML methods 项目地址: https://gitc…

作者头像 李华
网站建设 2026/4/29 16:36:53

正邦科技全面复苏:2025年营收大增66.8%,生猪出栏翻倍

4月28日晚间,正邦科技(002157.SZ)发布公告,报告显示,正邦科技的经营规模正呈现爆发式增长。2025年公司实现营业总收入147.95亿元,同比上升66.80%;2026年第一季度实现营业收入37.62亿元&#xff…

作者头像 李华
网站建设 2026/4/29 16:35:23

C++27静态反射元编程(仅限GCC 14.3+/Clang 19.0+可用的5个隐藏特性)

更多请点击: https://intelliparadigm.com 第一章:C27静态反射元编程的演进脉络与核心价值 C27 将首次将静态反射(Static Reflection)作为标准核心特性正式纳入语言规范,标志着元编程范式从模板元编程(TMP…

作者头像 李华
网站建设 2026/4/29 16:34:09

为什么你的Windows系统越来越慢?3分钟掌握Winhance终极优化指南

为什么你的Windows系统越来越慢?3分钟掌握Winhance终极优化指南 【免费下载链接】Winhance-zh_CN A Chinese version of Winhance. C# application designed to optimize and customize your Windows experience. 项目地址: https://gitcode.com/gh_mirrors/wi/Wi…

作者头像 李华
网站建设 2026/4/29 16:31:57

盘点全球五大海底光缆,数字孪生赋能安防监控

海底光缆是什么?全球互联的信息动脉海底光缆,是敷设在深海与近海海底的光纤通信电缆,由数根头发丝般纤细的光纤外加多层钢丝铠装、绝缘层和保护套构成。每条海缆直径仅17毫米左右——全球99%的跨境数据流量正是经由这些细如常的“信息动脉”完…

作者头像 李华