Linux Framebuffer 實驗
一、準備
- linux虛擬機或ARM開發板
- Ubuntu18.04
二、Framebuffer介紹
次筆記主要的目的是實驗,所以我不介紹了,有需要的小夥伴可以去看下面部落格
Linux LCD Frambuffer 基礎介紹和使用://blog.51cto.com/u_13064014/5079683
Linux應用開發【第一章】Framebuffer應用開發://zhuanlan.zhihu.com/p/443120506
Linux Framebuffer 技術://zhuanlan.zhihu.com/p/496623603
為了能直觀的看明白 Framebuffer 的原理,所以我從他們部落格中引用了幾張圖片,如下所示:
-
LCD 顯示原理
-
Framebuffer架構
從上面圖中很容易看明白Framebuffer是怎麼回事,接下來我們進行測試,分別在ubuntu和ARM開發板上進行測試。
三、Framebuffer 測試命令
為了方便測試 Framebuffer 可用,可以快速通過命令進行簡單測試,如下所示:
-
清屏命令
dd if=/dev/zero of=/dev/fb0 dd if=/dev/zero of=/dev/fb0 bs=1024 count=768
-
截屏命令
dd if=/dev/fb0 of=fbfile cp /dev/fb0 fbfile
注意:這裡的截屏其實就是拷貝 中的數據,所以只有當framebuffer中有數據存在時才能截屏成功
-
將保存的資訊顯示傳回framebuffer
dd if=fbfile of=/dev/fb0
-
往螢幕的左上角畫一個白色的像素點
echo -en '\xFF\xFF\xFF\x00' > /dev/fb0
四、Framebuffer 測試程式
fb_test_app.c文件
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
/* 顯示器相關頭文件 */
#include <linux/fb.h>
#include <sys/mman.h>
typedef struct lcd_color
{
unsigned char bule;
unsigned char green;
unsigned char red;
unsigned char alpha;
} lcd_color;
/**
* 更新螢幕顯示記憶體塊資訊,顏色格式為RGB8888
*/
void screen_refresh(char *fbp, lcd_color color_buff, long screen_size)
{
for(int i=0; i < screen_size; i+=4)
{
*((lcd_color*)(fbp + i)) = color_buff;
}
usleep(1000*2000);
}
int main()
{
int fp = 0;
int rgb_type = 0;
long screen_size = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
unsigned char *fbp = 0;
fp = open("/dev/fb0", O_RDWR);
if (fp < 0)
{
printf("Error : Can not open framebuffer device/n");
exit(1);
}
if (ioctl(fp, FBIOGET_FSCREENINFO, &finfo))
{
printf("Error reading fixed information/n");
exit(2);
}
if (ioctl(fp, FBIOGET_VSCREENINFO, &vinfo))
{
printf("Error reading variable information/n");
exit(3);
}
/* 列印獲取的螢幕資訊 */
printf("The mem is :%d\n", finfo.smem_len);
printf("The line_length is :%d\n", finfo.line_length);
printf("The xres is :%d\n", vinfo.xres);
printf("The yres is :%d\n", vinfo.yres);
printf("bits_per_pixel is :%d\n", vinfo.bits_per_pixel);
/* 獲取RGB的顏色顏色格式,比如RGB8888、RGB656 */
rgb_type = vinfo.bits_per_pixel / 8;
/* 螢幕的像素點 */
screen_size = vinfo.xres * vinfo.yres * rgb_type;
/* 映射 framebuffer 的緩衝空間,得到一個指向這塊空間的指針 */
fbp =(unsigned char *) mmap (NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fp, 0);
if (fbp == NULL)
{
printf ("Error: failed to map framebuffer device to memory./n");
exit (4);
}
/* 刷白屏 */
memset(fbp, 0xff, screen_size);
usleep(1000*2000);
/* 我的顯示器是RGDA的,所以縣色格式為32為,注意自己的顯示器資訊,對應修改 */
/* 刷紅色 */
screen_refresh(fbp, (lcd_color){0, 0, 255, 255}, screen_size);
/* 刷綠色 */
screen_refresh(fbp, (lcd_color){0, 255, 0, 255}, screen_size);
/* 刷藍色 */
screen_refresh(fbp, (lcd_color){255, 0, 0, 255}, screen_size);
/* 解除映射 */
munmap (fbp, screen_size);
close(fp);
return 0;
}
makefile 文件
out_file_name = "fb_test_app"
all: fb_test_app.c
# gcc $^ -o $(out_file_name)
arm-linux-gnueabihf-gcc $^ -o $(out_file_name)
.PHONY: clean
clean:
rm $(out_file_name)
五、ubuntu測試
-
驅動查看
測試之前先查看自己的虛擬機是否開啟了Framebuffer驅動,在設備中可以看到fbx
的驅動,並且主設備號為29ls /dev/fb* -l
-
關閉圖形顯示
因為在虛擬機中,不關閉圖形顯示會看不到現象,也有可能資訊會被其他顯示模組覆蓋# 關閉圖形顯示 systemctl set-default multi-user.target reboot # 打開圖形顯示 systemctl set-default graphical.target reboot
-
運行測試程式
./fb_test_app
注意:如果出現錯誤
Error : can not open framebuffer device
時,切換到root用戶執行即可 -
測試結果
注意:這裡顯示的影像會把命令窗口給覆蓋,所以看不到運行時列印的資訊
六、ARM開發板測試
從圖中可以看出執行後列印的資訊,到此我們測試就算完成了,說明LCD的驅動是沒問題的,可以進行GUI的開發。
注意:如果LCD的屏是RGB8888格式的,那麼可能出現黑屏不顯示的現象,這是需要適當調整一下數據格式,如下圖所示:
參考鏈接
Linux LCD Frambuffer 基礎介紹和使用://blog.51cto.com/u_13064014/5079683
Linux應用開發【第一章】Framebuffer應用開發://zhuanlan.zhihu.com/p/443120506
Linux Framebuffer 技術://zhuanlan.zhihu.com/p/496623603