7. DRM图形显示框架 您所在的位置:网站首页 嵌入式开发例子图片 7. DRM图形显示框架

7. DRM图形显示框架

2024-07-18 01:34| 来源: 网络整理| 查看: 265

7. DRM图形显示框架¶

以往我们在Linux上为显示设备开发驱动时,通常使用的是FrameBuffer的驱动框架, 在FrameBuffer驱动框架下,我们能够快速开发出可供简单使用的显示驱动。 但是随着芯片显示外设的性能逐渐增强及GPU的引入,FrameBuffer框架看起来似乎就有些落伍了, 最直接的体现,就是在传统的框架下,对于许多芯片显示外设的新特性如: 显示覆盖(菜单层级)、GPU加速、硬件光标等功能并不能得到很好得支持, 并且FrameBuffer框架将底层的显存通过用户空间/dev/fb接口,暴露给了用户空间, 这很容易导致不同的应用程序在操作显存时,产生访问冲突,而且这种方式看起来似乎不是那么安全。

在这背景下,就需要一个现代的图形显示框架来解决这些问题,那么DRM(Direct Rendering Manager,直接图形管理器)诞生。

7.1. 框架简述¶

那么DRM图形显示框架是怎么解决FrameBuffer框架遇到的困境呢? DRM将现代显示领域中会涉及的一些操作进行分层并使这些模块独立, 如过上层应用想操作显存、显示效果抑或是GPU,都必须在一些框架的约束下进行,我们可以来了解一下。

我们可以从用户空间、内核空间的两个角度去了解DRM框架:

用户空间(libdrm driver):

Libdrm(DRM框架在用户空间的Lib)

内核空间(DRM driver):

KMS(Kernel Mode Setting,内核显示模式设置)

GEM(Graphic Execution Manager,图形执行管理器)

7.1.1. Libdrm¶

DRM框架在用户空间提供的Lib,用户或应用程序在用户空间调用libdrm提供的库函数, 即可访问到显示的资源,并对显示资源进行管理和使用。

这样通过libdrm对显示资源进行统一访问,libdrm将命令传递到内核最终由DRM驱动接管各应用的请求并处理, 可以有效避免访问冲突。

7.1.2. KMS(Kernel Mode Setting)¶

KMS属于DRM框架下的一个大模块,主要负责两个功能:显示参数及显示控制。 这两个基本功能可以说是显示驱动必须基本的能力,在DRM框架下, 为了将这两部分适配得符合现代显示设备逻辑,又分出了几部分子模块配合框架。

7.1.2.1. Planes¶

基本的显示控制单位,每个图像拥有一个Planes,Planes的属性控制着图像的显示区域、图像翻转、色彩混合方式等, 最终图像经过Planes并通过CRTC组件,得到多个图像的混合显示或单独显示的等等功能。

7.1.2.2. CRTC¶

CRTC的工作,就是负责把要显示图像,转化为底层硬件层面上的具体时序要求,还负责着帧切换、电源控制、色彩调整等等。

7.1.2.3. Encoder¶

Encoder的工作则是负责电源管理、视频输出格式封装(比如要将视频输出到HDMI接口、MIPI接口等)。

7.1.2.4. Connector¶

Connector连接器负责硬件设备的接入、屏参获取等。

上述的这些组件,最终完成了一个完整的DRM显示控制过程,如下图所示:

参考资料 Kernel Mode Setting (KMS) .

7.1.3. GEM(generic DRM memory-management)¶

顾名思义,GEM负责对DRM使用的内存(如显存)进行管理。

GEM框架提供的功能包括:

内存分配和释放

命令执行

执行命令时的管理

参考资料 The Graphics Execution Manager (GEM) .

7.2. 驱动简述¶

我们通过简单讲解了DRM驱动的框架,简单地带领大家认识了DRM框架下对显示功能的实现方法。 实际的代码细节远比上述给大家介绍的内容复杂得多,给大家讲解框架组件功能只是起到一个抛砖引玉的作用, 如果对代码细节感兴趣的同学,可以在目录 drivers/gpu/drm 中,查看具体的驱动实现。

在实际的使用中,我这里将DRM的驱动实现分为了两个部分,主机驱动和设备驱动。主机驱动指的是片上的负责显示功能的外设驱动,如MP157上的LTDC外设、DSI外设的驱动, 这些一般由芯片厂商如ST、NXP等来负责实现,完成一个DRM-Host,主机驱动代码一般位于 drivers/gpu/drm/xxx/ 目录下,这里xxx代指芯片厂商如ST、NXP。

一般我们要做的,就是现实一个设备驱动,比如针对某款LCD显示屏, 将其参数(LCD Timing、Size…)、显示方式(DSI、HDMI…)等通过设备驱动,和主机驱动关联起来。

在内核的DRM驱动目录中,给出了许多设备驱动的示例,详见目录: drivers/gpu/drm/panel .

一个简单的DRM框架显示设备驱动例子可以参考 drivers/gpu/drm/panel/panel-simple.c .

7.3. 设备树插件描述¶

MP157开发板支持两种接口的LCD显示屏:RGB(MIPI DPI)、MIPI DSI,由于显示原理不同,所以分别对应着两款设备树插件, 使用的也是不同的设备驱动,但是其驱动框架仍是DRM。

重要

两种接口RGB、DSI屏幕不可同时使用!

既然作为显示设备,那么设备树上描述的属性必然是和显示屏相关的内容, 比如:屏幕的display timing、ddc读取显示器EDID结构等, 详见及参考内核 Documentation/devicetree/bindings/display/panel 目录下的各种dt-bingdings,如:

通用的bingdings文档:

Documentation/devicetree/bindings/display/panel/panel-common.txt Documentation/devicetree/bindings/display/panel/panel-dpi.txt Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt

各种实例显示设备的bingdings文档。

各种的bingdings文档,可以帮助你快速了解一个设备树里描述的属性内容,及如何去写一个对应的设备树节点。

这里再补充一些知识,MIPI联盟提出了许多显示规范,有:DBI(Display Bus Interface带控制器及显存的并行接口显示模块)、 DPI(Display Pixel Interface不带控制器或显存的并行接口显示模块)、DSI(Display Serial Interface高速串行接口)、 DCS(Display Command Set用显示命令集操作的显示模块)。我们常说的RGB接口屏幕,也就是不带控制器及显存的并行接口屏幕,DBI的代表则有80接口MCU屏, 至于DSI则是串行接口屏幕了,手机中常用的就是DSI接口屏幕。

参考资料: MIPI Specifications .

7.3.1. RGB-LCD设备树插件¶

设备树插件的源码非常长,此处不便展示,源码位于如下目录:

arch/arm/boot/dts/overlays/stm-fire-lcd-overlay.dts

其驱动目录对应为:

drivers/gpu/drm/panel/panel-simple.c 7.3.2. DSI-LCD设备树插件¶

源码位于如下目录:

arch/arm/boot/dts/overlays/stm-fire-mipi-overlay.dts

其驱动目录对应为:

drivers/gpu/drm/panel/panel-himax-hx8394.c 7.4. 实验准备¶

下面我们就以野火的4.3寸RGB屏幕为例,为大家测试在DRM驱动框架下的驱动效果,我们进行屏幕的测试。

7.4.1. 添加设备树插件¶

方法参考如下:

重要

如果使用DSI屏幕,请将 stm-fire-lcd.dtbo 及 stm-fire-mipi.dtbo 设备树插件同时打开。 若使用RGB屏幕,则只将 stm-fire-lcd.dtbo 打开。

以野火的4.3寸RGB屏幕为例,操作如下:

如需调整屏幕参数,请使用fire-config工具调整,参考:

《fire-config修改液晶参数》

如若运行代码时出现“Device or resource busy”或者运行代码卡死等等现象, 请按上述情况检查并按上述步骤操作。

如出现 Permission denied 或类似字样,请注意用户权限,大部分操作硬件外设的功能,几乎都需要root用户权限,简单的解决方案是在执行语句前加入sudo或以root用户运行程序。

7.4.2. libdrm测试程序¶

野火MP157开发板中,DRM驱动默认被配置为编译进内核,驱动加载后,会在 /dev/dri/ 目录下创建显示设备的节点, 我们的应用程序就是通过open这些节点,调用libdrm的API去进行LCD控制和显示的。

如下图,我们的RGB显示屏即为 /dev/dri/card0 节点.

编写一个libdrm的测试程序较为复杂,这里我们使用libdrm官方的测试工具来进行测试,我们可以在这里下载源码并进行交叉编译出测试工具,以供在开发板上使用: libdrm .

新版的libdrm使用meson+ninja的构建方式,而不是老版的autotools,没有基础的同学构建新版libdrm会比较痛苦。 建议直接使用我们给大家编译好的测试程序,测试程序位于\linux_driver\framework_drm\modetest。

对libdrm测试程序感兴趣的同学,可以下载libdrm源码解压,在其目录/libdrm-2.4.105/tests/下,查看modetest.c文件,此为测试程序源码。

7.5. 实验操作¶

将上述的modetest测试程序上传至开发板中,并使用chmod添加执行权限。

运行modetest程序,点击图片可放大:

待程序检测执行完毕,会列举出开发板上的DRM框架下的显示设备。

其中一些字样如Encoders、Connectors、CRTCs经过前面的介绍,大家都应该有了一点印象。

DRM框架下的显示过程如下图示:

我们要做的,就是找出前面终端中打印的RGB屏幕对应的connectors、CRTCs的ID:

图中状态为connected的connectorsID为31,并且从name中可以看出为DPI接口的屏幕,正是我们的RGB屏。 CRTCs对象中,唯一个id为34的CRTC,参数也为我们的RGB屏幕参数。

则我们可以执行如下命令进行测试:

./modetest -M stm -s 31@34:480x272

其中31、34分别为我们屏幕的Connectors ID、CRTCs ID,实验现象如图示:

在终端中按下回车键退出测试。

关于测试的更多相关内容,可以参考 linux DRM/KMS 测试工具 modetest .

文章末尾补充小知识,虽说DRM功能符合现代显示设备的需求,但是仍有众多的老设备及软件需要Framebuffer的支持。 所以在DRM框架下,有部分代码用于实现在DRM框架下,去模拟FB设备。

在ST提供的显示驱动代码中,也有模拟FB设备的相关代码,参见drivers/gpu/drm/stm/drv.c文件, 最终效果就是设备目录下,出现熟悉的身影 /dev/fb0 。

我们可以通过传统测试FrameBuffer设备的方式,使用如下命令来测试它:

# 会得到类似花屏的效果 cat /dev/random > /dev/fb0

相关新闻可以查看 Generic-FBDEV-Emulation .



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有