(一)- DRM架构

一,DRM简介

linux内核中包含两类图形显示设备驱动框架:

  • FB设备:Framebuffer图形显示框架;

  • DRM:直接渲染管理器(Direct Rendering Manager),是linux目前主流的图形显示框架;

1,Frambebuffer驱动

Frambebuffer驱动具有以下特征:

  • 直接控制显卡的帧缓冲区,提供基本的显卡输出功能;

  • 使用一些内核数据结构和API来管理图形界面,并提供一组接口与用户空间的应用程序进行通信;

  • 相对简单,适合于嵌入式系统或者不需要高性能图形的应用场景。

2,DRM驱动

相比FB(Framebuffer)架构,DRM更能适应当前日益更新的显示硬件;

  • 提供一种分离的图形驱动架构,将硬件驱动程序、内核模块和用户空间驱动程序进行分离;

  • 支持多个应用程序同时访问显卡,并提供了更丰富的图形功能,例如硬件加速和3D加速;

  • 提供了一些内核接口,可以让用户空间应用程序与驱动程序进行交互;

  • 支持多显示器(Display)和多GPU的配置;

总之,一句话,DRM是Linux目前主流的图形显示框架,相比FB架构,DRM更能适应当前日益更新的显示硬。尽管FB退出历史舞台,但是并未将其遗弃,而是集合到DRM中,供部分嵌入式设备使用。

二,DRM框架

DRM是Linux目前主流的图形显示框架,相比FB架构,DRM更能适应当前日益更新的显示硬件。比如FB原生不支持多层合成,不支持VSYNC,不支持DMA-BUF,不支持异步更新,不支持fence机制等等,而这些功能DRM原生都支持。同时DRM可以统一管理GPU和Display驱动,使得软件架构更为统一,方便管理和维护

1,DRM模块划分

DRM从模块上划分,可以简单分为3部分:libdrm、KMS、GEM

1)libdrm

对底层接口进行封装,向上层提供通用的API接口,主要是对各种IOCTL接口进行封装。

2)KMS

Kernel Mode Setting,所谓Mode setting,其实说白了就两件事:更新画面和设置显示参数。

更新画面:显示buffer的切换,多图层的合成方式,以及每个图层的显示位置。

设置显示参数:包括分辨率、刷新率、电源状态(休眠唤醒)等。

3)GEM

Graphic Execution Manager,主要负责显示buffer的分配和释放,也是GPU唯一用到DRM的地方。

2,基本元素

DRM框架涉及到的元素很多,大致如下:

KMS:CRTC,ENCODER,CONNECTOR,PLANE,FB,VBLANK,property

GEM:DUMB、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 驱动之间的耦合度。

耦合的产生:

(1)connector 的主要作用就是获取显示参数,所以会在 LCD 驱动中去构造 connector object。但是 connector 初始化时需要 attach 上一个 encoder object,而这个 encoder object 往往是在另一个硬件驱动中生成的,为了访问该 encoder object,势必会产生一部分耦合的代码。

(2)encoder 除了扮演信号转换的角色,还担任着通知显示设备休眠唤醒的角色。因此,当 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。

1,MIPI 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

2,MIPI 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

3,MIPI 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 就在哪里

参考链接:

DRM(Direct Rendering Manager)学习简介-CSDN博客

DRM 驱动程序开发(开篇)_spi 何小龙 csdn-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/916715.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

远程控制步骤

当远在千里之外的朋友想求助你帮他找到他电脑上的文件、或者是给他安装软件时。但是你给他说了他又找不到,那么这时你就可以通过控制对方的电脑去做一系列的操作。 如何远程控制对方的电脑非常关键。 方法一(Windows自带远程桌面功能)&#…

InternVL 多模态模型部署微调实践 | 书生大模型

文章目录 多模态大模型简介基本介绍例子常见设计模式BLIP 2Q-Former 模块细节应用案例:MiniGPT - 4Q-Former 的缺点 LLaVALLaVA - 1.5 - HDLLaVA - Next InternVL2 介绍架构设计Intern VitPixel ShuffleDynamic High - ResolutionMultitask output 训练方法 环境配置…

javaScript交互补充(元素的三大系列)

1、元素的三大系列 1.1、offset系列 1.1.1、offset初相识 使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等 获得元素距离带有定位祖先元素的位置获得元素自身的大小(宽度高度)注意:返回的数值都不…

AI大模型(二):AI编程实践

一、软件安装 1. 安装 Visual Studio Code VSCode官方下载:Visual Studio Code - Code Editing. Redefined 根据自己的电脑系统选择相应的版本下载 安装完成! 2. 安装Tongyi Lingma 打开VSCode,点击左侧菜单栏【extensions】,…

linux c 语言回调函数学习

动机 最近在看 IO多路复用,包括 select() poll () epoll() 的原理以及libevent, 对里面提及的回调机制 比较头大,特写此文用例记录学习笔记。 什么是回调函数 网上看到的最多的一句话便是:回调函数 就是 函数指针的一种用法&am…

Python 正则表达式的一些介绍和使用方法说明(数字、字母和数字、电子邮件地址、网址、电话号码(简单)、IPv4 )

## 正则表达式的概念和用途 正则表达式(Regular Expression,简称Regex)是对字符串操作的一种逻辑公式,由一些事先定义好的特定字符以及这些特定字符的组合所构成。这些特定字符及其组合被用来描述在搜索文本时要匹配的一个或多个…

DreamClear:字节跳动开源了高性能图像修复技术,中科院加持,商业免费使用

哇,字节跳动开源了DreamClear项目,采用的是Apache-2.0开源协议,可以商用,并且用户可以自由地使用、复制、修改和分发该软件,甚至可以用于私有项目中。这对于开发者和企业来说是个好消息,因为它们可以利用这…

Flutter:android studio无法运行到模拟机的问题

提示如下错误信息: Entrypoint is not a Dart filenot applicable for the "main.dart" configurat点击运行按钮提示让填写以下信息 或者出现无法选择模拟机的情况 发下下列问题: 无法运行的项目默认根目录地址: 可以正常运行…

FromData格式提交接口时入参被转成JSON格式问题

本地上传文件后通过事件提交文件,一般先通过前端组件生成文本流,在通过接口提交文本流,提交文本流一般使用FormData的入参形式传入,接口请求头也默认"Content-Type": “multipart/form-data”,但是某些场景统…

<AI 学习> 下载 Stable Diffusions via Windows OS

注意: 不能使用 网络路径 不再支持 HTTPS 登录,需要 Token 1. 获得合法的授权 Stability AI License — Stability AI 上面的链接打开,去申请 许可 2. 拥有 HuggingFace 账号 注册:https://huggingface.co/ 3. 配置 Tok…

MySQL缓存使用率超过80%的解决方法

MySQL缓存使用率超过80%的解决方法 一、识别缓存使用率过高的问题1.1 使用SHOW GLOBAL STATUS命令监控1.2 监控其他相关指标二、分析缓存使用率过高的原因2.1 数据量增长2.2 查询模式变化2.3 配置不当三、解决缓存使用率过高的方法3.1 调整Buffer Pool大小3.1.1 计算合理的Buff…

39.安卓逆向-壳-smali语法3(方法)

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:图灵Python学院 本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要盲目相信。 工…

《FreeRTOS任务基础知识以及任务创建相关函数》

目录 1.FreeRTOS多任务系统与传统单片机单任务系统的区别 2.FreeRTOS中的任务(Task)介绍 2.1 任务特性 2.2 FreeRTOS中的任务状态 2.3 FreeRTOS中的任务优先级 2.4 在任务函数中退出 2.5 任务控制块和任务堆栈 2.5.1 任务控制块 2.5.2 任务堆栈…

RHCE的学习(18)

第二章 变量和引用 深入认识变量 在程序设计语言中,变量是一个非常重要的概念。也是初学者在进行Shell程序设计之前必须掌握的一个非常基础的概念。只有理解变量的使用方法,才能设计出良好的程序。本节将介绍Shell中变量的相关知识。 什么是变量 顾名思义…

AG32 FPGA部分简单开发

环境 Quartus 13.0(Quartus 不能使用Lite 版本,需要使用Full 版本)AGM SDKSupra(快捷方式在SDK目录下,具体路径为AgRV_pio\packages\tool-agrv_logic\bin) FPGA编程 在AG32芯片中,拥有异构双…

__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined

VUE_PROD_HYDRATION_MISMATCH_DETAILS 未明确定义。您正在运行 Vue 的 esm-bundler 构建,它期望这些编译时功能标志通过捆绑器配置全局注入,以便在生产捆绑包中获得更好的tree-shaking优化。 Vue.js应用程序正在使用ESM(ECMAScript模块&#…

Spring——事务

事务 JdbcTemplate 简介 Spring框架对JDBC进行封装&#xff0c;使用JdbcTemplate方便实现对数据库操作 准备工作 ①搭建子模块 搭建子模块&#xff1a;spring-jdbc-tx ②加入依赖 <dependencies><!--spring jdbc Spring 持久化层支持jar包--><dependenc…

集合类源码浅析のJDK1.8ConcurrentHashMap(下篇)

文章目录 前言一、分段扩容1、addCount2、transfer3、helpTransfer 二、查询二、删除总结 前言 主要记录ConcurrentHashMap&#xff08;笔记中简称CHM&#xff09;的查询&#xff0c;删除&#xff0c;以及扩容方法的关键源码分析。 一、分段扩容 1、addCount 扩容的逻辑主要在…

H5页面多个视频如何只同时播放一个?

目录 背景1. 首先介绍下 muted 属性2. 监听播放和暂停操作3. 视频播放完毕后返回桌面&#xff0c;再进入H5页面发现视频封面丢失置灰解决思路&#xff1a; 背景 页面模块同时有个四个视频模块&#xff0c;发现可以同时播放四个视频&#xff0c;但是理想的是每次只播放一个。 …

D69【 python 接口自动化学习】- python 基础之数据库

day69 Python 执行 SQL 语句 学习日期&#xff1a;20241115 学习目标&#xff1a; MySQL 数据库&#xfe63;- Python连接redis 学习笔记&#xff1a; redis数据库的用途 使用Python访问redis数据库 使用Python对redis数据库进行读写操作 总结 1. redis是一款高性能的键…