欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > libdrm移植到arm设备

libdrm移植到arm设备

2025/2/10 23:39:53 来源:https://blog.csdn.net/yuxipro/article/details/145456389  浏览:    关键词:libdrm移植到arm设备

一、环境资源要求

下载libdrm

Index of /libdrm

这边使用的是2.4.114版本,版本太高对meson版本要求也很高,为了省事用apt安装meson就不用太高版本了,1.x版本虽然使用makefile编译方便但是太老,对应用支持不太好。

https://dri.freedesktop.org/libdrm/libdrm-2.4.114.tar.xz

由于libdrm项目是基于meson构建的,所以需要安装meson

sudo apt install meson

二、代码编译

1、解压并cd到代码目录下 

cd libdrm-2.4.114

2、创建目录

#建立安装目录
mkdir install
#创建编译目录
mkdir build

3、创建cross_file.txt文件

#创建并编写cross_file.txt文件,用于配置交叉编译环境
vi cross_file.txt

在cross_file.txt添加如下配置项

[binaries]
c = 'arm-linux-gnueabihf-gcc'
cpp = 'arm-linux-gnueabihf-g++'
ar = 'arm-linux-gnueabihf-ar'
strip = 'arm-linux-gnueabihf-strip'[host_machine]
system = 'linux'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'[build_machine]
system = 'linux'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

4、配置编译选项

# cd到build目录
cd build
# 配置编译选项,根据自己平台将对应平台的false替换为true
meson --prefix=$(pwd)/../install \--cross-file=../cross_file.txt \-D amdgpu=false \       #amd集显平台-D etnaviv=false \      #vivante图芯gpu支持-D exynos=false \       #三星平台-D freedreno=false \    #高通平台-D freedreno-kgsl=false \ #高通平台-D intel=false \        #intel集显平台-D nouveau=false \      #nvdia平台-D omap=false \         #ti平台-D radeon=false \       #amd独显平台-D tegra=false \        #nvdia tegra(switch)平台-D vc4=false \          #博通VC4平台-D libkms=false \       #drm kms库-D man-pages=false \    #man手册-D udev=false \         #udev支持-D valgrind=false \     #内存测试-D cairo-tests=false \  #cairo语言测试-D vmwgfx=false         #VMWare图形驱动支持-D install-test-programs=true \    #安装测试程序,建议安装,便于检测排查问题。

5、编译安装

#编译并安装
ninja && ninja install
#完成后在../install目录可以能得到对应的文件

三、环境测试

1、modetest测试

#modetest 参数
modetest -h  #帮助Query options:#用于查询的参数选项-c      list connectors #列举出所有的connectors-e      list encoders   #列举出所有的encoders   -f      list framebuffers #列举出所有的framebuffers -p      list CRTCs and planes (pipes) #列举出所有的CRTCs和planes Test options:#用于测试的参数选项#-P给CRTC指定plane-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]  set a plane #-s 设置输出模式,选择connector和crtc-s <connector_id>[,<connector_id>][@<crtc_id>]:[#<mode index>]<mode>[-<vrefresh>][@<format>] set a mode -C      test hw cursor-v      test vsynced page flipping-r      set the preferred mode for all connectors-w <obj_id>:<prop_name>:<value> set property-a      use atomic API-F pattern1,pattern2    specify fill patternsGeneric options:#指定打开设备、驱动-d      drop master after mode set-M module       use the given driver-D device       use the given deviceDefault is to dump all info.#例子
#-s <connector_id>[,<connector_id>][@<crtc_id>]:[#<mode index>]<mode>[-<vrefresh>][@<format>]
#-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]  set a plane 
modetest  -s 37@35:1024x768  -P 33@35:1024x768  #运行成功会有屏幕彩块显示
#37是连接器号,通过modetest -c查询
#两个35都是crtc的号,通过modetest -p可以查询到带分辨率的接口crtc号,以及显示分辨率。

2、代码测试

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <xf86drm.h>
#include <xf86drmMode.h>#define WIDTH 800     //修改为屏幕对应分辨率宽度
#define HEIGHT 600    //修改为屏幕对应分辨率高度int main(int argc, char **argv) {int fd;drmModeRes *resources;drmModeConnector *connector;drmModeEncoder *encoder;drmModeCrtc *crtc;uint32_t *framebuffer;uint32_t handle;uint32_t stride;uint32_t size;int ret;// 打开DRM设备fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);if (fd < 0) {perror("Failed to open DRM device");return 1;}// 获取资源resources = drmModeGetResources(fd);if (!resources) {perror("Failed to get DRM resources");close(fd);return 1;}// 查找连接for (int i = 0; i < resources->count_connectors; i++) {connector = drmModeGetConnector(fd, resources->connectors[i]);if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) {break;}drmModeFreeConnector(connector);}if (!connector) {fprintf(stderr, "No connected connector found\n");drmModeFreeResources(resources);close(fd);return 1;}// 查找编码器encoder = drmModeGetEncoder(fd, connector->encoder_id);if (!encoder) {perror("Failed to get encoder");drmModeFreeConnector(connector);drmModeFreeResources(resources);close(fd);return 1;}// 获取CRTCcrtc = drmModeGetCrtc(fd, encoder->crtc_id);if (!crtc) {perror("Failed to get CRTC");drmModeFreeEncoder(encoder);drmModeFreeConnector(connector);drmModeFreeResources(resources);close(fd);return 1;}// 计算帧缓冲区大小stride = WIDTH * 4; // 假设每个像素4字节(32位颜色)size = stride * HEIGHT;// 创建帧缓冲区ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMMY, &handle);if (ret < 0) {perror("Failed to create dummy buffer");drmModeFreeCrtc(crtc);drmModeFreeEncoder(encoder);drmModeFreeConnector(connector);drmModeFreeResources(resources);close(fd);return 1;}// 映射帧缓冲区到内存framebuffer = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, handle);if (framebuffer == MAP_FAILED) {perror("Failed to map framebuffer");drmModeFreeCrtc(crtc);drmModeFreeEncoder(encoder);drmModeFreeConnector(connector);drmModeFreeResources(resources);close(fd);return 1;}// 填充帧缓冲区for (int y = 0; y < HEIGHT; y++) {for (int x = 0; x < WIDTH; x++) {uint32_t color = (x * 255 / WIDTH) << 16 | (y * 255 / HEIGHT) << 8 | 255;framebuffer[y * WIDTH + x] = color;}}// 设置CRTCret = drmModeSetCrtc(fd, crtc->crtc_id, handle, 0, 0, &connector->connector_id, 1, &connector->modes[0]);if (ret < 0) {perror("Failed to set CRTC");munmap(framebuffer, size);drmModeFreeCrtc(crtc);drmModeFreeEncoder(encoder);drmModeFreeConnector(connector);drmModeFreeResources(resources);close(fd);return 1;}// 等待用户输入printf("Press Enter to exit...\n");getchar();// 恢复原来的CRTCdrmModeSetCrtc(fd, crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, &connector->connector_id, 1, &crtc->mode);// 清理资源munmap(framebuffer, size);drmModeFreeCrtc(crtc);drmModeFreeEncoder(encoder);drmModeFreeConnector(connector);drmModeFreeResources(resources);close(fd);return 0;
}

编译代码

gcc -o drm_draw main.c -ldrm# 交叉编译 gcc可替换arm-linux-gnueabihf-gcc, -ldrm前加上drm库路径 -L /path/libdrm/lib/ 以及加上include路径 -I /path/libdrm/include/

 运行代码

sudo ./drm_draw

四、参考文章

DRM框架与libdrm移植-CSDN博客

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com