最近在学习与调试RK3399的DRM显示架构,网上有很多例程,其中介绍比较多的是来于David Herrmann’s Github的drm-howto.开源代码。
drm-howto.开源代码里面有三个测试代码,分别是:
modeset.c
modeset-double-buffered.c
modeset-vsync.c
这些源码下载后执行make编译出来的执行文件只能在PC机上测试运行,因为用的是PC机的gcc编译工具以及系统库。
为了能让drm-howto例程能运行在RK3399上,我们需要
(1). 修改为使用RK3399的交叉编译工具
(2). 使用rk3399的SDK包生成的libdrm.so库
(3). 增加一些依赖的头文件、以及一些RK3399的SDK依赖库
修改过程:
1. 对Makefile的修改,修改后Makefile的内容如下
ARM64_GCC = /home/server/RK3399_ANDROID7.1-Industry-SDK_V1.0/RK3399_SDK_V2.6.x_Repositories/lzt/RK3399_SDK_V2.6.x/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-gcc
SYS_ROOT = --sysroot=/home/server/RK3399_ANDROID7.1-Industry-SDK_V1.0/RK3399_SDK_V2.6.x_Repositories/lzt/RK3399_SDK_V2.6.x/prebuilts/ndk/current/platforms/android-24/arch-arm64/
FLAGS = -pie -fPIE -ldrm -lc -ldl -llog -lm -lc++ -L.
all:
$(ARM64_GCC) -o modeset modeset.c $(SYS_ROOT) $(FLAGS)
$(ARM64_GCC) -o modeset-double-buffered modeset-double-buffered.c $(SYS_ROOT) $(FLAGS)
$(ARM64_GCC) -o modeset-vsync modeset-vsync.c $(SYS_ROOT) $(FLAGS)
说明:
ARM64_GCC是我的RK3399的SDK包交叉编译链所在的目录;
SYS_ROOT是--sysroot指定的逻辑根目录(编译过程搜索头文件和库文件)
FLAGS是编译选项标志,-pie -fPIE组合生成为位置无关代码(否则RK3399会报错不能执行), -ldrm -lc -ldl -llog -lm -lc++ 表示依赖于libdrm.so、libc.so、libl.so、liblog.so、libm.so、libc++.so几个静态链接库,-L.是表示库所在的路径,请注意L后面的‘.’表示Makefile的同一个目录
这个Makefile修改是一个思路,表示编译此例程源的需要用到的编译链工具以及库文件,如果你已经把交叉编译链目录添加到了PC机的全局环境变量,那么不用定义ARM64_GCC,直接使用aarch64-linux-android-gcc代替$(ARM64_GCC)便可。
2. 添加需要的SDK依赖静态库
从Makefile文件的-ldrm -lc -ldl -llog -lm -lc++看出,缺少了库文件是libdrm.so、libc.so、libl.so、liblog.so、libm.so、libc++.so,将这些库文件拷贝到源码同一个目录中。
这些文件在SDK被完全编译后的\out\target\product\rk3399_firefly_face\obj\lib中可以找到,(别问我是怎么知道的,我是在一次次编译错误时,一个一个去找全的...)
3. 添加必须的头文件
编译过程一些函数及结构定义需要用到一些头文件,添加几个用到头文件即可
drm.h, drm_mode.h, libdrm_macros.h, xf86drm.h, xf86drmMode.h,这些头文件在SDK包的external\libdrm中可以找到
4. 其它一些修改
在几个源文件modeset.c,modeset-double-buffered.c,modeset-vsync.c中将
#include <xf86drm.h>
#include <xf86drmMode.h>
修改为
#include "xf86drm.h"
#include "xf86drmMode.h"
在xf86drm.h, xf86drmMode.h中将
#include <drm.h>
修改为
#include "drm.h"
因为尖括号<>会在逻辑根目录中(即--sysroot,亦可以理解为标准库)查找,而引号会用户目录下查找,而我们这几个头文件都拷贝到了源代码的用户目录,故此修改。
经过上面修改后,在例程代码目录下执行make
即可看到生成了三个可执行文件
将这三个文件拷贝到RK3399的开发板,我是adb push modeset /data, 利用adb push到开发板的/data目录进行测试。
拷贝到开发板,需要修改执行权限,如:
rk3399_firefly_face:/data # chmod 777 modeset
再执行,屏幕即可显示颜色变化:
rk3399_firefly_face:/data # ./modeset
using card '/dev/dri/card0'
mode for connector 88 is 800x1280
ignoring unused connector 90
exiting
rk3399_firefly_face:/data #
如需要参考代码,这里下载:https://download.csdn.net/download/xiaohua4758/14339621
参考:
最简单的DRM应用程序 (single-buffer)
https://blog.csdn.net/hexiaolong2009/article/details/83721242
David Herrmann’s Github: