专业网站开发哪家公司好,网络推手公司怎么收费,找南昌兼职做网站的,seo优化排名推广一#xff0c;DRM简介
linux内核中包含两类图形显示设备驱动框架#xff1a; FB设备#xff1a;Framebuffer图形显示框架; DRM#xff1a;直接渲染管理器#xff08;Direct Rendering Manager#xff09;#xff0c;是linux目前主流的图形显示框架#xff1b;
1DRM简介
linux内核中包含两类图形显示设备驱动框架 FB设备Framebuffer图形显示框架; DRM直接渲染管理器Direct Rendering Manager是linux目前主流的图形显示框架
1Frambebuffer驱动
Frambebuffer驱动具有以下特征 直接控制显卡的帧缓冲区提供基本的显卡输出功能 使用一些内核数据结构和API来管理图形界面并提供一组接口与用户空间的应用程序进行通信 相对简单适合于嵌入式系统或者不需要高性能图形的应用场景。 2DRM驱动
相比FBFramebuffer架构DRM更能适应当前日益更新的显示硬件 提供一种分离的图形驱动架构将硬件驱动程序、内核模块和用户空间驱动程序进行分离 支持多个应用程序同时访问显卡并提供了更丰富的图形功能例如硬件加速和3D加速 提供了一些内核接口可以让用户空间应用程序与驱动程序进行交互 支持多显示器Display和多GPU的配置 总之一句话DRM是Linux目前主流的图形显示框架相比FB架构DRM更能适应当前日益更新的显示硬。尽管FB退出历史舞台但是并未将其遗弃而是集合到DRM中供部分嵌入式设备使用。 二DRM框架
DRM是Linux目前主流的图形显示框架相比FB架构DRM更能适应当前日益更新的显示硬件。比如FB原生不支持多层合成不支持VSYNC不支持DMA-BUF不支持异步更新不支持fence机制等等而这些功能DRM原生都支持。同时DRM可以统一管理GPU和Display驱动使得软件架构更为统一方便管理和维护 1DRM模块划分
DRM从模块上划分可以简单分为3部分libdrm、KMS、GEM 1libdrm
对底层接口进行封装向上层提供通用的API接口主要是对各种IOCTL接口进行封装。 2KMS
Kernel Mode Setting所谓Mode setting其实说白了就两件事更新画面和设置显示参数。
更新画面显示buffer的切换多图层的合成方式以及每个图层的显示位置。
设置显示参数包括分辨率、刷新率、电源状态休眠唤醒等。 3GEM
Graphic Execution Manager主要负责显示buffer的分配和释放也是GPU唯一用到DRM的地方。 2基本元素
DRM框架涉及到的元素很多大致如下
KMSCRTCENCODERCONNECTORPLANEFBVBLANKproperty
GEMDUMB、PRIME、fence object 说明 plane 硬件图层有的Display硬件支持多层合成显示但所有的Display Controller至少要有1个plane CRTC 对显示buffer进行扫描并产生时序信号的硬件模块通常指Display Controller encoder 负责将CRTC输出的timing时序转换成外部设备所需要的信号的模块如HDMI转换器或DSI Controller connector 连接物理显示设备的连接器如HDMI、DisplayPort、DSI总线通常和Encoder驱动绑定在一起 framebuffer Framebuffer单个图层的显示内容唯一一个和硬件无关的基本元素 VBLANK 软件和硬件的同步机制RGB时序中的垂直消影区软件通常使用硬件VSYNC来实现 property 任何你想设置的参数都可以做成property是DRM驱动中最灵活、最方便的Mode setting机制 DUMB 只支持连续物理内存基于kernel中通用CMA API实现多用于小分辨率简单场景 PRIME 连续、非连续物理内存都支持基于DMA-BUF机制可以实现buffer共享多用于大内存复杂场景 fence buffer同步机制基于内核dma_fence机制实现用于防止显示内容出现异步问题 学习DRM驱动其实就是学习上面各个元素的实现及用法。
三objects
在开始编写 DRM 驱动程序之前我有必要对 DRM 内部的 Objects 进行一番介绍。因为这些 Objects 是 DRM 框架的核心它们缺一不可。 上图蓝色部分则是对物理硬件的抽象黄色部分则是对软件的抽象。虚线以上的为 drm_mode_object虚线以下为 drm_gem_object。 这些 objects 的概念 object 说明 crtc RGB 信号发生源TCON显存切换控制器Dislay Controller plane Display Controller 的数据源通道每个 crtc 至少要有一个 plane encoder RGB 信号转换器DSI Contoller同时也控制显示设备的休眠唤醒 connector 凡是能获取到显示参数的硬件设备但通常和 encoder 绑定在一起 framebuffer 只用于描述显存信息如 format、pitch、size 等不负责显存的分配释放 property atomic 操作的基础任何想要修改的参数都可以做成 property供用户空间使用 gem 负责显存的分配、映射和释放 这些 objects 之间的关系 通过上图可以看到plane 是连接 framebuffer 和 crtc 的纽带而 encoder 则是连接 crtc 和 connector 的纽带。与物理 buffer 直接打交道的是 gem 而不是 framebuffer。 需要注意的是上图蓝色部分即使没有实际的硬件与之对应在软件驱动中也需要实现这些 objects否则 DRM 子系统无法正常运行。 四drm_panel
drm_panel 不属于 objects 的范畴它只是一堆回调函数的集合。但它的存在降低了 LCD 驱动与 encoder 驱动之间的耦合度。 耦合的产生
1connector 的主要作用就是获取显示参数所以会在 LCD 驱动中去构造 connector object。但是 connector 初始化时需要 attach 上一个 encoder object而这个 encoder object 往往是在另一个硬件驱动中生成的为了访问该 encoder object势必会产生一部分耦合的代码。
2encoder 除了扮演信号转换的角色还担任着通知显示设备休眠唤醒的角色。因此当 encoder 通知 LCD 驱动执行相应的 enable/disable 操作时就一定会调用 LCD 驱动导出的全局函数这也必然会产生一部分的耦合代码。 为了解决该耦合的问题DRM 子系统为开发人员提供了 drm_panel 结构体该结构体封装了 connector encoder 对 LCD 访问的常用接口。 于是原来的 Encoder 驱动和 LCD 驱动之间的耦合就转变成了上图中 Encoder 驱动与 drm_panel、drm_panel 与 LCD 驱动之间的“耦合”从而实现了 Encoder 驱动与 LCD 驱动之间的解耦合。 为了方便驱动程序设计通常都将 encoder 与 connector 放在同一个驱动中初始化即 encoder 在哪connector 就在哪。 五如何抽象硬件
对于初学者来说往往让他们迷惑的不是 DRM 中 objects 的概念而是如何去建立这些 objects 与实际硬件的对应关系。因为并不是所有的 Display 硬件都能很好的对应上 plane/crtc/encoder/connector 这些 objects。下面我们就来一起学习如何去抽象显示硬件到具体的 DRM object。
1MIPI DSI 接口
下图为一个典型的 MIPI DSI 接口屏的硬件连接框图 它在软件架构上与 DRM object 的对应关系如下图 多余的细节不做介绍这里只说明为何如此分配 drm object object 说明 crtc RGB timing的产生以及显示数据的更新都需要访问 Dislay Controller 硬件寄存器因此放在 Display Controller 驱动中 plane 对 Overlay 硬件的抽象同样需要访问 Display Controller 寄存器因此也放在 Display Controller 驱动中 encoder 将 RGB 并行信号转换为 DSI 串行信号需要配置 DSI 硬件寄存器因此放在 DSI Controller 驱动中 connector 可以通过 drm_panel 来获取 LCD 的 mode 信息但是 encoder 在哪connector 就在哪因此放在 DSI Controller 驱动中 drm_panel 用于获取 LCD mode 参数并提供 LCD 休眠唤醒的回调接口供 encoder 调用因此放在 LCD 驱动中 驱动参考https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c 2MIPI DPI 接口
DPI 接口也就是我们常说的 RGB 并行接口Video 数据通过 RGB 并行总线传输控制命令如初始化、休眠、唤醒等则通过 SPI/I2C 总线传输比如早期的 S3C2440 SoC 平台。下图为一个典型的 MIPI DPI 接口屏的硬件连接框图 该硬件连接在软件架构上与 DRM object 的对应关系如下图 多余的细节不做介绍这里只说明为何如此分配 drm object object 说明 crtc RGB timing的产生以及显示数据的更新都需要访问 LCD Controller 硬件寄存器因此放在 LCD Controller 驱动中 plane LCDC 没有 Overlay 硬件它只有一个数据源通道被抽象为 Primary Plane同样需要访问 LCDC 硬件寄存器因此放在 LCDC 驱动中 encoder 由于 DPI 接口本身不需要对 RGB 信号做任何转换因此没有哪个硬件与之对应。但是 drm objects 又缺一不可因此实现了一个虚拟的 encoder object。至于为什么要放在 LCDC 驱动中实现纯粹只是为了省事而已你也可以放在一个虚拟的平台驱动中去实现该 encoder object。 connector encoder 在哪connector 就在哪没什么好说的了 drm_panel 用于获取 LCD mode 参数并提供 LCD 休眠唤醒的回调接口供 encoder 调用因此放在 LCD 驱动中 驱动参考https://elixir.bootlin.com/linux/v5.0/source/drivers/gpu/drm/panel/panel-sitronix-st7789v.c 3MIPI DBI 接口
DBI 接口也就是我们平时常说的 MCU 或 SPI 接口屏这类屏的 VIDEO 数据和控制命令都是通过同一总线接口I80、SPI接口进行传输而且这类屏幕必须内置 GRAM 显存否则屏幕无法维持正常显示。 下图为一个典型的 DBI 接口屏的硬件连接框图 该硬件连接在软件架构上与 DRM object 的对应关系如下 上图参考 kernel4.19 tinydrm 软件架构。 object 说明 crtc 这类硬件本身不需要任何 RGB timing 信号因此也没有实际的硬件与之对应。但是 drm objects 缺一不可需要实现一个虚拟的 crtc object。由于更新图像数据的动作需要通过 SPI 总线发送命令才能完成因此放在了 LCD 驱动中 plane 没有实际的硬件与之对应但 crtc 初始化时需要一个 plane object 作为参数传递因此和 crtc 放在一起 encoder 没有实际的硬件与之对应使用虚拟的 encoder object。因为这类硬件并不是将 RGB 信号转换为 SPI 信号而是根本就没有 RGB 信号源也就无从谈起 encoder 设备。但是为了通知 LCD 休眠唤醒需要调用 LCD 驱动的相应接口因此放在 LCD 驱动中 connector 由于没有了 drm_panel需要调用 LCD 接口来获取 mode 参数因此放在 LCD 驱动中 驱动参考https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/tinydrm/ili9341.c 六总结 这 7 个 objects 缺一不可 framebuffer 只是负责描述显存信息gem 则负责显存的分配/释放等操作 encoder 在哪里connector 就在哪里 参考链接
DRMDirect Rendering Manager学习简介-CSDN博客
DRM 驱动程序开发开篇_spi 何小龙 csdn-CSDN博客