ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

RT-Thread 图形子系统(Graphic DM)架构解析:从平面(Plane)管理、EDID 到设备驱动接入实战

RT-Thread 图形子系统(Graphic DM)架构解析:从平面(Plane)管理、EDID 到设备驱动接入实战 操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载本篇技术指南聚焦 RT-Thread 新一代设备模型DM下的图形子系统graphic DM它以struct rt_graphic_device为核心将显示控制器封装为多平面primary/cursor/overlay帧缓冲设备并集成 EDID 解析、背光控制、Linux 风格 fb ioctl 与旧版rt_device_graphic_ops兼容层。读完本文你将掌握 RT-Thread 图形驱动的分层架构、核心数据结构与注册 API 的调用关系并能基于真实 probe 流程为自己的 DSI/LCD/简单帧缓冲控制器编写可运行的驱动。一、Graphic DM 是什么模块边界与文件分工RT-Thread 的graphic DM位于 components/drivers/graphic核心头文件为 components/drivers/include/drivers/graphic.h。它把显示控制器抽象为多平面multi-plane帧缓冲一个primary_plane必选、一个cursor_plane可选、若干overlay0..NEDID完整的 VESA EDID 结构体与解析逻辑背光可选的backlight设备PWM/GPIO兼容层Linux 风格fbioctl 以及旧版rt_device_graphic_ops通过rt_graphic_device_switch_primary提供。实现按文件拆分各司其职文件职责components/drivers/graphic/graphic.c设备注册、control分发、平面管理、EDID 解析、自动刷新定时器、OFW 背光绑定components/drivers/graphic/graphic_simple.c合成 EDIDfill_edidrt_graphic_device_simple_register简易注册路径components/drivers/graphic/graphic_primary.crt_graphic_device_switch_primary→ 在主帧缓冲上实现set_pixel/draw_hline等旧版绘图回调components/drivers/graphic/framebuffer/fb-simple.cDTsimple-framebuffer驱动把固定reg内存映射为帧缓冲应用层可见的像素格式与RTGRAPHIC_CTRL_*命令定义在 components/drivers/include/drivers/classes/graphic.hDM 类型、平面与注册 API 则集中在 components/drivers/include/drivers/graphic.h。二、Kconfig如何打开图形子系统图形子系统依赖 DM 基础设施相关配置项如下对应 components/drivers/graphic/Kconfig配置项作用RT_USING_DM必需父开关graphic DM 的一切都建立在设备模型之上RT_USING_GRAPHIC核心图形栈graphic.c、graphic_primary.c、graphic_simple.cdepends on RT_USING_DMRT_GRAPHIC_FB帧缓冲驱动子菜单默认开启并select RT_USING_LCDRT_GRAPHIC_FB_SIMPLEsimple-framebuffer支持依赖RT_USING_OFW默认开启RT_GRAPHIC_FB_ILI9486ILI9486 帧缓冲支持依赖 SPIRT_GRAPHIC_BACKLIGHT背光类设备 PWM/GPIO 实现RT_GRAPHIC_LOGO注册时渲染启动 LogoPPM 图像默认开启可切换 RT-Thread 彩色/白色 Logo 或关闭具体选项可参见 framebuffer/Kconfig 与 logo/Kconfig。BSP 侧通过SOC_DM_GRAPHIC_FB_DIR、SOC_DM_GRAPHIC_LOGO_DIR等路径变量把 SoC 自有驱动挂载进来。三、整体架构与数据流Controller driver (DSI, LCD, simple-fb, …) | | alloc_plane plane_ops (update / fb_remap / fb_cleanup) v struct rt_graphic_device primary_plane (required, one) cursor_plane (optional, one) overlay_nodes (0..N) edid, ops, backlight, update_timer | | rt_graphic_device_register - rt_device fbN v Apps: rt_device_find RTGRAPHIC_CTRL_* / read-write FB | | rt_graphic_device_switch_primary(gdev) v dev-user_data rt_device_graphic_ops (graphic_primary.c)各层职责划分层责任rt_graphic_plane_ops硬件相关分配帧缓冲、把像素推送到屏幕update、销毁fb_cleanuprt_graphic_device_ops设备级DPMS、vsync、亮度、厂商自定义controlgraphic.c标准rt_deviceAPI、矩形刷新、模式设置、热插拔、周期刷新定时器四、核心数据结构4.1struct rt_graphic_plane定义见 graphic.h字段语义字段含义typePRIMARY仅一个、CURSOR仅一个、OVERLAY链表0..Nmode/modes[]像素格式取值来自classes/graphic.h的RTGRAPHIC_PIXEL_FORMAT_*framebuffer/line_length/screen_len/framebuffer_lenCPU 可见缓冲区若framebuffer_len screen_len表示多缓冲双缓冲翻页ops驱动回调见 4.2x/y/z/rotate/alpha平面位置、Z 序、旋转0/90/180/270、透明度0~100priv[0]柔性数组跟随平面分配用于存放驱动私有数据注意graphic.h中mode初始为RTGRAPHIC_PIXEL_FORMAT_MONO见rt_graphic_device_alloc_plane实现注册或模式切换时由fb_remap更新。4.2struct rt_graphic_plane_ops回调何时被调用契约fb_remap模式或分辨率变化为moderect分配/映射帧缓冲设置plane-framebuffer等字段fb_cleanup重映射前 /del_plane释放硬件资源unmap、释放 GPU 资源updateRTGRAPHIC_CTRL_RECT_UPDATE或自动刷新定时器把rect区域推送到显示width/height 0表示仅更新位置如光标fb_pan_displayRTGRAPHIC_CTRL_PAN_DISPLAY/open把扫描输出指向framebuffer内的偏移用于双缓冲翻页prop_set可选Z 序、旋转、alphaenum rt_graphic_plane_prop在graphic.c中plane_fb_remap会先调用fb_cleanup再调用fb_remap成功后同步更新plane-mode/x/y/width/heightplane_fb_pan_display则对偏移做越界校验后转交驱动。4.3struct rt_graphic_device_ops回调角色dpms_switchRT_GRAPHIC_DPMS_*ON/STANDBY/SUSPEND/OFF常与rt_graphic_device_update_auto周期联动wait_vsync对应RTGRAPHIC_CTRL_WAIT_VSYNCset_brightness/get_brightness面板亮度可委托给gdev-backlightget_status可选连接器状态查询current_plane覆盖GET_INFO/ 刷新所使用平面默认主平面control厂商自定义命令可选 3D / 加速路径struct rt_graphic_device还携带 DPMS 状态、overlay_nodes链表、plane_ida、edid、可选backlightRT_GRAPHIC_BACKLIGHT使能时、update_timer、事件通知与自旋锁见 graphic.h。4.4 EDIDgraphic.h 中struct edid完整镜像 VESA EDID 1.4 布局128 字节头、厂商/产品信息、版本、色度坐标、established/standard/detailed timings、扩展块数与校验和。RTGRAPHIC_CTRL_GET_EXT会把gdev-edid整体拷贝给应用见graphic.c_graphic_control的RTGRAPHIC_CTRL_GET_EXT分支。注册时若主平面没有尺寸width/height为 0核心调用graphic_edid_res()从首个 detailed timing 解出分辨率再触发plane_fb_remap见 graphic.c 与注册流程 graphic.c。如果 EDID 无效注册会直接失败。对没有 DDC 的固定面板或快速 bring-up 场景graphic_simple.c 提供rt_graphic_device_simple_edid(gdev, w, h, refresh_hz)按 100 DPI 推算物理尺寸、自动计算 blanking 时序、填充 sRGB 色度坐标与 monitor range 描述符最后补全校验和edid_checksum。五、注册 API 全景API作用rt_graphic_device_alloc_plane(gdev, priv_size, ops, modes, modes_nr, type)分配平面priv[0]尾部空间存驱动私有数据校验type合法、modes非空rt_graphic_device_add_plane(gdev, plane)挂载 primary/cursor/overlay分配plane_idaid两个 PRIMARY 会返回-RT_EINVALrt_graphic_device_register(gdev)要求已存在primary_plane通过RT_DM_IDA命名设备为fb%u若尺寸为零则按 EDID 映射 FB同时完成 OFW 背光绑定、Logo 渲染、PM 注册rt_graphic_device_unregister(gdev)DPMS off、停止定时器、删除并释放所有平面、rt_device_unregisterrt_graphic_device_simple_register(...)一条龙分配主平面 合成 EDID 注册不走完整 EDID 路径rt_graphic_device_simple_unregister(gdev)unregister的别名设备命名graphic.c中static struct rt_dm_ida graphic_ida RT_DM_IDA_INIT(GRAPHIC_FRAMEBUFFER);注册时rt_dm_dev_set_name(gdev-parent, fb%u, device_id)因此设备依次为fb0、fb1……OFW 背光绑定注册流程内的graphic_ofw_init见 graphic.c在启用RT_USING_OFW时解析dev-ofw_node上的backlightphandle找到后打开对应背光设备并存入gdev-backlight。六、应用 / 框架层控制命令以下命令定义于 classes/graphic.h统一由 graphic.c 的_graphic_control处理命令行为RTGRAPHIC_CTRL_RECT_UPDATE在当前平面plane_get_current默认 primary上调用ops-update(plane, rect)RTGRAPHIC_CTRL_SET_MODE若模式位于plane-modes[]内执行fb_remapRTGRAPHIC_CTRL_GET_MODE返回当前平面modeRTGRAPHIC_CTRL_GET_INFO用当前平面填充struct rt_device_graphic_info格式、bpp、pitch、宽高、framebuffer、smem_lenRTGRAPHIC_CTRL_GET_EXT拷贝gdev-edid到应用缓冲区RTGRAPHIC_CTRL_SET/GET_BRIGHTNESS优先走gdev-ops否则委托gdev-backlightRTGRAPHIC_CTRL_POWERON / POWEROFFDPMS 切换 启用背光时背光电源管理RTGRAPHIC_CTRL_PAN_DISPLAY按 framebuffer 内偏移翻页双缓冲RTGRAPHIC_CTRL_WAIT_VSYNC调用驱动wait_vsyncRT_DEVICE_CTRL_CURSOR_SET_POSITION / SET_TYPE光标平面位置/位图位置更新时update以width/height 0表示仅移动FBIOGET_VSCREENINFO/FBIOPUT_VSCREENINFO等Linux fb 兼容 ioctl启用时含 var screeninfo、pixclock 换算、pan display、FBIOBLANK 到 DPMS 的映射所有控制命令都在gdev-lock自旋锁保护下执行wait_vsync类命令会先解锁、再调用驱动回调。自动刷新rt_graphic_device_update_auto(gdev, ms)创建周期定时器默认周期参考RT_GRAPHIC_UPDATE_MS 16定义于 graphic.h超时回调graphic_device_update依次对 primary、overlay 全矩形调用update并对 cursor 以仅位置方式调用传0则停止并销毁定时器。rt_graphic_device_enter/leave在热插拔/modeset 期间暂停/恢复该定时器。热插拔rt_graphic_device_hotplug_event(gdev)在enter/leave保护下重新解析 EDID 尺寸、对主平面fb_remap随后通过event_notify通知应用见 graphic.c。七、主显示兼容层rt_graphic_device_switch_primarystruct rt_device_graphic_ops *rt_graphic_device_switch_primary(struct rt_graphic_device *gdev);设置全局primary_gdev并按主平面 bpp8/16/24/32/64返回对应的rt_device_graphic_ops实现见 graphic_primary.c。旧版宏graphic.hrt_graphix_ops(dev)调用switch_primary后读取dev-user_data在classes/graphic.h中另有直接读user_data的旧定义二者通过#undef覆盖。供 finsh / LVGL / Logo 等通过set_pixel、draw_hline直接画帧缓冲、而不走RTGRAPHIC_CTRL_RECT_UPDATE的传统绘图代码使用。因此在register之后应先在目标 head 上调用一次switch_primary再使用rt_graphix_ops。八、控制器驱动 probe 范式SoC 侧参考文档给出的标准流程结合源码补充完整平面分配、时钟/复位/电源可按需补充static const rt_uint32_t my_modes[] { RTGRAPHIC_PIXEL_FORMAT_RGB565, RTGRAPHIC_PIXEL_FORMAT_ARGB888, }; static const struct rt_graphic_plane_ops my_plane_ops { .fb_remap my_fb_remap, .fb_cleanup my_fb_cleanup, .update my_fb_update, }; static rt_err_t my_probe(struct rt_platform_device *pdev) { struct my_drv *priv; struct rt_graphic_plane *plane; rt_err_t err; priv rt_dm_dev_iomap(pdev-parent.parent, 0); /* or embed in pdev-priv */ /* clocks, resets, regulator — 参见设备模型相关文档 */ priv-gdev.ops my_gdev_ops; plane rt_graphic_device_alloc_plane(priv-gdev, sizeof(*priv), my_plane_ops, my_modes, RT_ARRAY_SIZE(my_modes), RT_GRAPHIC_PLANE_TYPE_PRIMARY); if (!plane) return -RT_ENOMEM; err rt_graphic_device_add_plane(priv-gdev, plane); if (err) goto err; /* Fill EDID from DDC or rt_graphic_device_simple_edid() */ err rt_graphic_device_register(priv-gdev); if (err) goto err; rt_graphic_device_switch_primary(priv-gdev); rt_graphic_device_update_auto(priv-gdev, RT_GRAPHIC_UPDATE_MS); return RT_EOK; }简单帧缓冲fb-simple.c是这条路径的最佳参考实现simplefb_probe解析 DT 的width/height/stride/format属性rt_dm_dev_get_address取reg地址后rt_ioremap_wt映射显存可选使能时钟数组rt_clk_array_prepare_enable与*-supply稳压器最终调用rt_graphic_device_simple_register完成注册其fb_remap仅把plane-framebuffer指向已映射的screen_base。支持的 format 名包括r5g6b5RGB565、r8g8b8RGB888、x8r8g8b8/a8r8g8b8ARGB888、x8b8g8r8/a8b8g8r8ABGR888驱动通过RT_PLATFORM_DRIVER_EXPORT(simplefb_driver)导出compatible simple-framebuffer。九、上电顺序与资源依赖资源说明像素/链路时钟设备模型时钟框架DSI/DP PHY物理层驱动MIPI D-PHY 等面板背光背光设备DTbacklight属性关联一致性帧缓冲 / Cachehwcache、DMA 框架Bring-up 顺序regulator → clock → panel init →register→ backlightPOWERON→RTGRAPHIC_CTRL_POWERON。十、工程师检查清单移植自文档并补充验证点实现rt_graphic_plane_ops至少fb_remap、update、fb_cleanupregister之前add_planePRIMARYcursor/overlay 按需在注册后添加填充edidDDC 读取或直接使用simple_register/simple_edidregister→switch_primary以便旧绘图 API 可用remove阶段unregister自动释放所有平面再按逆序释放 clock/reset/regulator热插拔在enter/leave保护下、EDID/模式变更后调用hotplug_event。十一、常见陷阱Pitfalls开了定时器刷新就没问题若没有启用自动刷新update_auto未调用或周期为 0应用 CPU 写完帧缓冲后必须主动发RTGRAPHIC_CTRL_RECT_UPDATE否则画面不会到达面板。注册时主平面尺寸为 0核心会尝试按 EDID 执行fb_remapEDID 无效将导致 probe 失败务必先保证edid有效或显式指定分辨率。两个 PRIMARY 平面add_plane返回-RT_EINVAL源码在add_plane中检查gdev-primary_plane是否已存在。DMA / CacheCPU 绘制帧缓冲必须使用正确的 MMU 属性若扫描输出非一致性内存update前需同步 cache参考hwcache框架。switch_primary是全局的只有一个primary_gdev。多显示头场景应使用rt_device_find(fb1) graphic ctrl 命令而不是单独依赖rt_graphix_ops。DPMS off 后不停止刷新挂起期间应调用rt_graphic_device_update_auto(gdev, 0)或enter避免定时器继续推流。十二、延伸阅读components/drivers/include/drivers/graphic.h —— DM 图形类型、平面、注册 APIcomponents/drivers/include/drivers/classes/graphic.h —— 像素格式、RTGRAPHIC_CTRL_*、rt_device_graphic_info/rt_device_graphic_opscomponents/drivers/graphic/graphic.c —— 核心实现注册、control、平面、EDID、热插拔、自动刷新components/drivers/graphic/graphic_simple.c —— 合成 EDID 与simple_registercomponents/drivers/graphic/graphic_primary.c —— 旧版绘图回调兼容层components/drivers/graphic/framebuffer/fb-simple.c ——simple-framebuffer参考驱动components/drivers/graphic/backlight —— PWM/GPIO 背光实现components/drivers/graphic/logo —— 启动 LogoPPM渲染与选择赞分享操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载相关推荐RT-Thread i.MX RT 系列 BSP 外设驱动全景指南从 I/O 设备框架到三类驱动实战RT Thread i.MX RT 系列 BSP 外设驱动全景指南从 I/O 设备框架到三类驱动实战 RT Thread 为 i.MX RT 系列RT101操作系统嵌入式物联网嵌入式OSRTOSRT-Thread DM 框架下的 NVMe 设备模型DM架构与移植指南RT Thread DM 框架下的 NVMe 设备模型DM架构与移植指南 RT Thread 的 Device ModelDM框架为存储类外设提供了一套操作系统嵌入式物联网嵌入式OSRTOSTanStack Angular 表单字段封装指令 TanStackAppField 完全指南从注入机制到源码级实现TanStack Angular 表单字段封装指令 TanStackAppField 完全指南从注入机制到源码级实现 TanStackAppField 是 操作系统嵌入式物联网嵌入式OSRTOS上一篇Unlock Music重新定义你的数字音乐自由之旅下一篇TouchGal专为Galgame玩家打造的纯净交流平台创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表