RK3568笔记八: Display子系统

modetest 是由 libdrm 提供的测试程序,可以查询显示设备的特性,进行基本的显示测试,以及设置显示的模式。

我们可以借助该工具来学习 Linux DRM 应用编程,另外为了深入分析 Rockchip DRM driver,有必要先了解一下这个工具的使用方法和内部实现。

一、准本工作

1、开发板:ATK-DLRK3568 开发板

2、环境:ubuntu20.0 正点原子网盘提供的版本

二、modetest编译

本人没自己编译过,编译过程只供参考,正点的板子自带了

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

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

如果要自己编译libdrm,可以参考下面命令:

git clone https://gitlab.freedesktop.org/mesa/drmsudo apt -y install python3-pip cmake git ninja-buildpython3 -m pip install meson  /*安装之后,重启板卡*/meson . build && ninja -C build

编译之后在build/tests/modetest/下会有modetest程序, 对libdrm测试程序感兴趣的同学,可以下载libdrm源码解压,在其目录/drm/tests/modetest/下,查看modetest.c文件,此为测试程序源码。

三、modetest 使用示例

modetest在bin目录下,板子上电后打开终端进入bin目录
 

cd /bin

1、 查看帮助信息

modetest -h

2、查看组件的信息

modetest -M rockchip

参数说明:

  • -M:用于指定访问 rockchip DRM driver

关键内容:

  • Encoders / Connectors / CRTCs / Planes 的 id,modetest 通过 id 来用于引用这些组件。
  • Connectors 的 modes/props:
    • prop: 任何你想设置的参数,都可以做成 property,是 DRM 驱动中最灵活、最方便的 Mode setting 机制;
    • modes: 显示模式,mode 里包含分辨率/刷新率等显示相关的信息;
  • CRTCs 的 props;
  • Planes 的 formats/props;

3、查看各组件的 id

modetest -M rockchip | cut -f1 | grep -E ^[0-9A-Z]\|id

正点原子的RK3568提供了一路的MIPI DSI 接口,所以测试MIPI

modetest -M rockchip -s 163@115:720x1280

四、最简单DRM(drm-single)

直接上代码,目录根据yolov5的那个程序修改的,替换mian.cc文件后需要添加drm库和头文件。

// Copyright (c) 2021 by Rockchip Electronics Co., Ltd. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License./*-------------------------------------------Includes
-------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <dlfcn.h>
#include <vector>
#include <string>#include "drm_func.h"
#include "rga_func.h"
#include "rknn_api.h"
#include "yolo.h"#include "RgaUtils.h"
#include "im2d.h"
#include "opencv2/core/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include <opencv2/opencv.hpp>
#include "rga.h"
#include <xf86drm.h>
#include <xf86drmMode.h>#define RED         0XFF0000
#define GREEN       0X00FF00
#define BLUE        0X0000FF
#define BLACK       0X000000
#define WHITE       0XFFFFFF
#define BLACK_BLUE  0X123456struct drm_device {uint32_t width;			//显示器的宽的像素点数量uint32_t height;		//显示器的高的像素点数量uint32_t pitch;			//每行占据的字节数uint32_t handle;		//drm_mode_create_dumb的返回句柄uint32_t size;			//显示器占据的总字节数uint32_t *vaddr;		//mmap的首地址uint32_t fb_id;			//创建的framebuffer的id号struct drm_mode_create_dumb create ;	//创建的dumbstruct drm_mode_map_dumb map;			//内存映射结构体
};drmModeConnector *conn;	    //connetor相关的结构体
drmModeRes *res;		    //资源
uint32_t conn_id;           //connetor的id号
uint32_t crtc_id;           //crtc的id号
int fd;					    //文件描述符#define RED 0XFF0000
#define GREEN 0X00FF00
#define BLUE 0X0000FFuint32_t color_table[6] = {RED,GREEN,BLUE,BLACK,WHITE,BLACK_BLUE};uint32_t plane_id[3];	//图层id数组struct drm_device buf;static int drm_create_fb(struct drm_device *bo)
{/* create a dumb-buffer, the pixel format is XRGB888 */bo->create.width = bo->width;bo->create.height = bo->height;bo->create.bpp = 32;/* handle, pitch, size will be returned */drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &bo->create);/* bind the dumb-buffer to an FB object */bo->pitch = bo->create.pitch;bo->size = bo->create.size;bo->handle = bo->create.handle;drmModeAddFB(fd, bo->width, bo->height, 24, 32, bo->pitch,bo->handle, &bo->fb_id);//每行占用字节数,共占用字节数,MAP_DUMB的句柄printf("pitch = %d ,size = %d, handle = %d \n",bo->pitch,bo->size,bo->handle);/* map the dumb-buffer to userspace */bo->map.handle = bo->create.handle;drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &bo->map);bo->vaddr = (uint32_t*)mmap(0, bo->create.size, PROT_READ | PROT_WRITE,MAP_SHARED, fd, bo->map.offset);/* initialize the dumb-buffer with white-color */memset(bo->vaddr, 0xff,bo->size);return 0;
}static void drm_destroy_fb(struct drm_device *bo)
{struct drm_mode_destroy_dumb destroy = {};drmModeRmFB(fd, bo->fb_id);munmap(bo->vaddr, bo->size);destroy.handle = bo->handle;drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
}int drm_init()
{//打开drm设备,设备会随设备树的更改而改变,多个设备时,请留一下每个屏幕设备对应的drm设备fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);if(fd < 0){printf("wrong\n");return 0;}//获取drm的信息res = drmModeGetResources(fd);crtc_id = res->crtcs[1];conn_id = res->connectors[1];//打印CRTCS,以及conneter的idprintf("crtc = %d , conneter = %d\n",crtc_id,conn_id);conn = drmModeGetConnector(fd, conn_id);buf.width = conn->modes[0].hdisplay;buf.height = conn->modes[0].vdisplay;//打印屏幕分辨率printf("width = %d , height = %d\n",buf.width,buf.height);//创建framebuffer层drm_create_fb(&buf);//设置CRTCSdrmModeSetCrtc(fd, crtc_id, buf.fb_id,0, 0, &conn_id, 1, &conn->modes[0]);return 0;
}void drm_exit()
{drm_destroy_fb(&buf);drmModeFreeConnector(conn);drmModeFreeResources(res);close(fd);
}int main(int argc, char **argv)
{int i,j;drm_init();sleep(2);printf("display colour\n");//显示三色for(j=0;j<3;j++){for(i =j*buf.width*buf.height/3;i< (j+1)*buf.width*buf.height/3;i++)buf.vaddr[i] = color_table[j];}getchar();printf("getchar\n");drm_exit();exit(0);
}

运行结果

程序需要注意一点。

  //获取drm的信息res = drmModeGetResources(fd);crtc_id = res->crtcs[1];conn_id = res->connectors[1];

接下来,实现采集视频显示。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.环境部署

1.虚拟机安装redhat8系统 这个其实很简单&#xff0c;但是有一点小细节需要注意。 因为我的电脑是 16核心的&#xff0c;所以选择内核16&#xff0c;可以最大发挥虚拟机的性能 磁盘选择SATA&#xff0c;便于后期学习 将一些没用的设备移除 选择安装redhat 8 时间选择上海 选择…

逻辑回归(解决分类问题)

定义&#xff1a;逻辑回归是一种用于解决分类问题的统计学习方法。它通过对数据进行建模&#xff0c;预测一个事件发生的概率。逻辑回归通常用于二元分类问题&#xff0c;即将数据分为两个类别。它基于线性回归模型&#xff0c;但使用了逻辑函数&#xff08;也称为S形函数&…

用Python“自动连发消息”

自动连发消息&#xff0c;基本上C和Python的思路都是不停的模拟“击键”操作&#xff0c;还有一种VB的脚本写法&#xff0c;反成每种语言都能写&#xff0c;更厉害的可以用java做出个GUI界面&#xff0c;先上代码。 一 代码 import pyautogui # 鼠标 import p…

C++I/O流——(2)预定义格式的输入/输出(第二节)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 含泪播种的人一定能含笑收获&#xff…

web前端第二次

第一题&#xff1a; <!DOCTYPE html> <html> <head><title>计算奇数和</title> </head> <body><label for"input">请输入一个正整数&#xff1a;</label><input type"number" id"input&qu…

vue2使用electron以及打包配置

1.创建项目 vue create vue-project 2.安装electron vue add electron-builder会自动安装相关依赖 安装成功后会在src下自动生成一个background.js文件就是相应的electron的配置信息 use strictimport { app, protocol, BrowserWindow } from electron import { createProto…

如何安装“MySQL在虚拟机ubuntu”win10系统?

1、 更新列表 sudo apt-get update 2、 安装MySQL服务器 sudo apt-get install mysql-server 3、 安装MySQL客户端 sudo apt-get install mysql-client 4、 配置MySQL sudo mysql_secure_installation 5、 测试MySQL systemctl status mysql.service MySQL数据库基本…

【Docker】centos中及自定义镜像,并且上传阿里云仓库可提供使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是平顶山大师&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《【Docker】centos中及自定义镜像&#xff0c;…

GRE隧道(初级VPN)配置步骤

一、拓朴图&#xff1a; 要求&#xff1a;1、PC1 和 PC2 能访问充当互联网接口地址的ISP环回口地址8.8.8.8 2、PC1 和 PC2 走GRE隧道互通 二、配置步骤&#xff1a; 1、配置IP 2、R1、R2 配置nat&#xff0c;代理内网地址通过G0/0/0口上外网 acl 2000rule permit source a…

Flutter首页框架搭建

1.下载flutter 2. 安装android 3.配置环境变量 关于环境搭建部分&#xff0c;哪天写一下&#xff0c;日志杂乱无章。 打开android studio 新建项目&#xff0c;选择flutter 新建文件夹创建 navigator和pages 文件夹下分别创建文件&#xff0c;tab_navigator.dart&#xff…

快速上手的 AI 工具-文心一言

简介 最近正打得火热的AIGC概念&#xff0c;相信大家肯定也都多少接触到了&#xff0c;那么AIGC概念股到底是什么呢&#xff1f;我个人最近也看了一些平台如&#xff1a;文心一言、通义千问、讯飞星火、豆包等等&#xff01;各位朋友也千万不要错过啦&#xff0c;真是各有各的特…

压缩编码之不同缩放参数对重建图像质量的影响的python实现——JPEG变换编码不同压缩率的模拟

原理 JPEG&#xff08;Joint Photographic Experts Group&#xff09;是一种常用的图像压缩标准&#xff0c;它通过采用离散余弦变换&#xff08;DCT&#xff09;和量化来实现图像的压缩。 离散余弦变换&#xff08;DCT&#xff09;&#xff1a; JPEG首先将图像分割成8x8的块…

跟着pink老师前端入门教程-day03

6. 表格标签 6.1 表格的主要作用 主要用于显示、展示数据&#xff0c;可以让数据显示的规整&#xff0c;可读性非常好&#xff0c;特别是后台展示数据时&#xff0c;能够熟练运用表格就显得很重要。 6.2 基本语法 <!--1. <table> </table> 是用于定义表格的标…

【图像分类】【深度学习】【轻量级网络】【Pytorch版本】EfficientNet_V1模型算法详解

【图像分类】【深度学习】【轻量级网络】【Pytorch版本】EfficientNet_V1模型算法详解 文章目录 【图像分类】【深度学习】【轻量级网络】【Pytorch版本】EfficientNet_V1模型算法详解前言EfficientNet_V1讲解问题辨析(Problem Formulation)缩放尺寸(Scaling Dimensions)复合缩…

生产力与生产关系 —— 浅析爱泼斯坦事件 之 弱电控制强电原理

据网络文字与视频资料&#xff0c;爱泼斯坦事件是犹太精英阶层&#xff0c;为了掌控美国国家机器为犹太利益集团服务&#xff0c;而精心设下的一个局。本文先假设这个结论成立&#xff0c;并基于此展开讨论。 我们知道&#xff0c;弱电管理强电是电气工程中的一门专门学问&…

135基于matlab的经验小波变换(EWT)的自适应信号处理方法

基于matlab的经验小波变换(EWT)的自适应信号处理方法.其核心思想是通过对信号的Fourier谱进行自适应划分,建立合适的小波滤波器组来提取信号不同的成分&#xff0c;EWT1D和EWT2D方法。程序已调通&#xff0c;可直接运行。 135matlab信号处理EWT (xiaohongshu.com)

HCIP之ISIS实验

华子目录 实验拓扑及要求规划IP地址规划Level1/2路由器实验步骤配置IP地址启动ISIS修改对应路由类型路由泄露&#xff1a;R1访问R5走R6测试 实验拓扑及要求 规划IP地址 规划Level1/2路由器 实验步骤 配置IP地址 R1-R8依次类推 [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip a…

设计模式-- 3.适配器模式

适配器模式 将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 角色和职责 请求者&#xff08;client&#xff09;&#xff1a;客户端角色,需要使用适配器的对象&#xff0c;不需要关心适配器内部的实现&#xff0c;…

Redis:原理速成+项目实战——Redis企业级项目实战终结篇(HyperLogLog实现UV统计)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理速成项目实战——Redis实战14&#xff08;BitMap实现用户签到功能&#xff09; &#x1f4da;订阅专栏&am…

Overleaf Docker编译复现计划

Overleaf Docker编译复现计划 Overleaf Pro可以支持不同年份的Latex镜像自由选择编译&#xff0c;这实在是一个让人看了心痒痒的功能。但是很抱歉&#xff0c;这属于Pro付费功能。但是我研究了一下&#xff0c;发现其实和Docker编译相关的代码&#xff0c;社区版的很多代码都没…