modetest 是由 libdrm 提供的測試程序,可以查詢顯示設(shè)備的特性,進行基本的顯示測試,以及設(shè)置顯示的模式。
我們可以借助該工具來學習 Linux DRM 應用編程,另外為了深入分析 Rockchip DRM driver,有必要先了解一下這個工具的使用方法和內(nèi)部實現(xiàn)。
本文目錄:
一、準備工作
二、modetest?使用示例
?1.?查看幫助信息
?2.?查看組件的信息
?3.?在?HDMI?上顯示
?4.?在?eDP?上顯示
三、編寫最簡單的?DRM?應用
四、DRM 應用如何呼叫到 Rockchip DRM driver?
五、相關(guān)參考
一、準備工作
在 NanoPC T4 + Linux-4.4 上:
接好 eDP 屏以及 HDMI 顯示器;
退出所有占用 /dev/dri/card0 的程序;
編譯 modetest
$?git?clone?https://gitlab.freedesktop.org/mesa/drm
$?apt-get?install?meson
$?meson?builddir/
$?ninja?-C?builddir/?install
二、modetest 使用示例
1. 查看幫助信息
$?modetest?-h
usage:?modetest?[-acDdefMPpsCvrw]
Query?options:
-c??????list?connectors
-e??????list?encoders
-f??????list?framebuffers
-p??????list?CRTCs?and?planes?(pipes)
Test?options:
????...
Generic?options:
-d??????drop?master?after?mode?set
-M?module???????use?the?given?driver
-D?device???????use?the?given?device
Default?is?to?dump?all?info.
2. 查看組件的信息
$?modetest?-M?rockchip
Encoders:
id??????crtc????type????possible?crtcs??possible?clones
76??????54??????TMDS????0x00000001??????0x00000000
78??????0???????TMDS????0x00000003??????0x00000000
80??????65??????TMDS????0x00000002??????0x00000000
Connectors:
????...
參數(shù)說明:
-M
:用于指定訪問 rockchip DRM driver
關(guān)鍵內(nèi)容:
Encoders / Connectors / CRTCs / Planes 的 id,modetest 通過 id 來用于引用這些組件。
Connectors 的 modes/props:
CRTCs 的 props;
Planes 的 formats/props;
- prop: 任何你想設(shè)置的參數(shù),都可以做成 property,是 DRM 驅(qū)動中最靈活、最方便的 Mode setting 機制;
modes: 顯示模式,mode 里包含分辨率 / 刷新率等顯示相關(guān)的信息;
各組件的 id:
$?modetest?-M?rockchip?|?cut?-f1?|?grep?-E?^[0-9A-Z]|id
Encoders:
?id
?90,?edp?encoder
?92,?hdmi?encoder
?100,?dp?encoder
Connectors:
?id
?91,?edp?connector
?93,?hdmi?connector
?101,?dp?connector
CRTCs:
?id
?64,?vop?crtc
?83,?vop?crtc
Planes:
?id
?58
?61
?65
?68
?80
?84
Frame?buffers:
?id
3. 在 HDMI 上顯示
$?modetest?-M?rockchip?-s?93@64:1920x1080
$?modetest?-M?rockchip?-s?93@64:#1???//?相同的效果
參數(shù)說明:
-s [,][@]:[#][-][@
]
:用于在指定的 pipeline 上以某個 mode 顯示某個 pattern 的畫面。
93
:HDMI connector id
64
:某個 VOP 的 crtc id
1920x1080
:顯示 mode;
HDMI connector 下其他可選的 mode:
#0?1920x1080?60.00
#1?1920x1080?59.94
#2?1920x1080i?30.00
#3?1920x1080i?29.97
...
#24?640x480?60.00
#25?640x480?59.94
#26?720x400?70.08
顯示效果:
點擊查看大圖
4. 在 eDP 上顯示
$?modetest?-M?rockchip?-s?91@83:1920x1080
參數(shù)說明:
91
:eDP connector id
83
:另外一個 VOP 的 crtc id
1920x1080
:顯示 mode;
顯示效果:
點擊查看大圖
三、編寫最簡單的 DRM 應用
主程序:
int?main(int?argc,?char?**argv)
{
?int?fd;
?drmModeConnector?*conn;
?drmModeRes?*res;
?uint32_t?conn_id;
?uint32_t?crtc_id;
????//?1.?打開設(shè)備
?fd?=?open("/dev/dri/card0",?O_RDWR?|?O_CLOEXEC);
????//?2.?獲得?crtc?和?connector?的?id
?res?=?drmModeGetResources(fd);
?crtc_id?=?res->crtcs[0];
?conn_id?=?res->connectors[0];
????//?3.?獲得?connector
?conn?=?drmModeGetConnector(fd,?conn_id);
?buf.width?=?conn->modes[0].hdisplay;
?buf.height?=?conn->modes[0].vdisplay;
????//?4.?創(chuàng)建?framebuffer
?modeset_create_fb(fd,?&buf);
????//?5.?Sets?a?CRTC?configuration,這之后就會開始在?crtc0?+?connector0?pipeline?上進行以?mode0?輸出顯示
?drmModeSetCrtc(fd,?crtc_id,?buf.fb_id,?0,?0,?&conn_id,?1,?&conn->modes[0]);
?getchar();
?//?6.?cleanup
?...
?return?0;
}
modeset_create_fb():
該函數(shù)用于分配 framebuffer,目前不需要太關(guān)心,大致就是 3 個步驟:
- Allocating memory;Preparing a mapping;Mapping memory;
運行效果:
程序運行后,eDP 屏顯示全屏白色,等待用戶輸入按鍵;當用戶按下任意按鍵后,程序退出,顯示黑屏。
四、DRM 應用如何呼叫到 Rockchip DRM driver?
drmModeSetCrtc() 到 CRTC driver:
點擊查看大圖
每一個 DRM CRTC Driver(例如 Rockchip VOP driver) 里都會定義一個 struct drm_crtc_funcs 結(jié)構(gòu)體,其中的 .set_config 都指向 drm_atomic_helper_set_config(),接下來就是 DRM core 開始工作了。
五、相關(guān)參考
《RK3399 探索之旅 / Display 子系統(tǒng) / 基礎(chǔ)概念》
小龍兄的博客:https://blog.csdn.net/hexiaolong2009/article/details/83721242
nvidia 的文檔:https://docs.nvidia.com/drive/nvvib_docs
Linux man 手冊:man 7 drm
思考技術(shù),也思考人生
要學習技術(shù),更要學習如何生活。
你和我各有一個蘋果,如果我們交換蘋果的話,我們還是只有一個蘋果。但當你和我各有一個想法,我們交換想法的話,我們就都有兩個想法了。
對 嵌入式系統(tǒng) (Linux、RTOS、OpenWrt、Android) 和 開源軟件 感興趣,關(guān)注公眾號:嵌入式 Hacker。
覺得文章對你有價值,不妨點個 在看和贊。