LVGL 整体启动链路(你这个工程)
RT-Thread 自动初始化 + 独立 LVGL 线程 模式。
从上电到界面显示,完整流程如下:
- 系统启动进入 RT-Thread 主流程(
rtthread_startup) - 创建并运行
main线程(main_thread_entry) main_thread_entry里先执行rt_components_init()rt_components_init()执行各级INIT_*_EXPORT注册函数- 命中
INIT_ENV_EXPORT(lvgl_thread_init),调用lvgl_thread_init lvgl_thread_init创建并启动LVGL线程LVGL线程入口lvgl_thread_entry顺序执行:lv_init()lv_port_disp_init()lv_port_indev_init()lv_user_gui_init()
lv_user_gui_init()调用lv_demo_music()创建 demo UI- 线程进入循环:
lv_task_handler()+rt_thread_mdelay(...) - 界面持续刷新、动画运行、输入事件生效
每个关键点在干什么
-
lvgl_thread_init只负责"拉起线程":
rt_thread_init+rt_thread_startup。 -
lv_init初始化 LVGL 内核(对象系统、样式、动画、timer 等基础设施)。
-
lv_port_disp_init把 LCD 注册给 LVGL:打开
lcd设备、拿 framebuffer 信息、建 draw buffer、注册flush_cb。 -
lv_port_indev_init把输入设备注册给 LVGL:配置
read_cb,让 LVGL 能取到触摸/指针状态。 -
lv_user_gui_init你的 UI 入口;当前实现是跑
lv_demo_music()。 -
lv_task_handlerLVGL 主调度器:处理输入、事件、动画、重绘;没有它界面就"死的"。
你当前涉及文件职责
-
packages/LVGL-v8.3.11/env_support/rt-thread/lv_rt_thread_port.cLVGL 与 RT-Thread 的线程/初始化胶水层(核心启动文件)
-
applications/lvgl/lv_port_disp.c显示驱动适配(LCD + flush)
-
applications/lvgl/lv_port_indev.c输入驱动适配(pointer read callback)
-
applications/lvgl/demo/lv_demo.c用户 GUI 入口(当前接到 music demo)
-
applications/main.c普通用户
main()(不是直接启动 LVGL 的地方)
运行时时序(可当心智模型)
RT-Thread调度 -> LVGL线程唤醒 -> lv_task_handler ->
需要重绘则调用flush_cb写fb + 读取输入并分发事件 -> 线程delay -> 下一个周期
常见调试抓手(最实用)
- 屏不亮:先查
lv_port_disp_init()里rt_device_find("lcd")、GET_INFO、buffer 分配是否失败。 - 能显示但不能点:查
lv_port_indev_input()是否被底层事件持续喂数据。 - 界面卡顿:调小/调大
LV_DISP_DEF_REFR_PERIOD找平衡。 - 异常重启/HardFault:优先看
PKG_LVGL_THREAD_STACK_SIZE是否太小。 - API 调用异常:确认 LVGL API 是否在 LVGL 线程上下文调用(跨线程需同步)。