fb裝置驅動1 fb裝置的顯像原理和步驟

2021-09-25 14:45:55 字數 3669 閱讀 5865

lcd的顯像原理:將ddr記憶體的一部分劃分出來作為視訊記憶體,視訊記憶體與lcd顯示螢幕之間做乙個雙向的對映,然後使用者只需要將需要顯示的內容放入視訊記憶體之中,然後視訊記憶體中的內容就會重新整理到lcd的儲存器中進行顯示。

視訊記憶體:在核心之中申請一塊記憶體作為視訊記憶體,由於核心空間和使用者空間,也就是驅動和應用不能直接進行內容的複製,需要借助專門的介面函式copy_to_user和copy_from_user,而這兩個函式的效率很慢,所以我們將在核心空間中申請的這塊虛擬位址,而這個虛擬位址肯定會對應一塊真實的實體地址,然後應用層mmap申請一段記憶體,進而進行虛擬位址對映,與我們之前視訊記憶體對應的實體地址繫結,這樣應用對於視訊記憶體進行操作,驅動就可以將其顯示在lcd上。

freamebuffer裝置:

(1)由於lcd顯示裝置包括顯示器的驅動器,顯示卡,以及各種不同位數的顯示器,所以linux核心虛擬出來乙個framebuffer裝置向應用層提供乙個統一的標準介面的顯示裝置(一般在/dev/fb0),應用可以使用open、read、write等對裝置進行操作。

(2)fb裝置是乙個字元裝置,他的裝置框架自己建立了乙個類/sys/class/graphic;

對於fb裝置的簡單操作:

#include #include #include #include #include #include #include // 巨集定義

#define fbdevice "/dev/fb0"

#define width 1024 //開發板的lcd顯示屏的長寬

#define height 600

#define white 0xffffffff

#define black 0x00000000

#define red 0xffff0000

#define green 0xff00ff00

#define blue 0xff0000ff

#define greenp 0x0000ff00

// 函式宣告

void draw_back(unsigned int width, unsigned int height, unsigned int color);

void draw_line(unsigned int color);

// 全域性變數

unsigned int *pfb = null;

int main(void)

;

struct fb_var_screeninfo vinfo = ;

// 第1步:開啟裝置

fd = open(fbdevice, o_rdwr);

if (fd < 0)

printf("open %s success.\n", fbdevice);

// 第2步:獲取裝置的硬體資訊

ret = ioctl(fd, fbioget_fscreeninfo, &finfo);

if (ret < 0)

printf("smem_start = 0x%x, smem_len = %u.\n", finfo.smem_start, finfo.smem_len);

ret = ioctl(fd, fbioget_vscreeninfo, &vinfo);

if (ret < 0)

printf("xres = %u, yres = %u.\n", vinfo.xres, vinfo.yres);

printf("xres_virtual = %u, yres_virtual = %u.\n", vinfo.xres_virtual, vinfo.yres_virtual);

printf("bpp = %u.\n", vinfo.bits_per_pixel);

// 修改驅動中螢幕的解析度

vinfo.xres = 1024;

vinfo.yres = 600;

vinfo.xres_virtual = 1024;

vinfo.yres_virtual = 1200;

ret = ioctl(fd, fbioput_vscreeninfo, &vinfo);

if (ret < 0)

// 再次讀出來檢驗一下

ret = ioctl(fd, fbioget_vscreeninfo, &vinfo);

if (ret < 0)

printf("修改過之後的引數:\n");

printf("xres = %u, yres = %u.\n", vinfo.xres, vinfo.yres);

printf("xres_virtual = %u, yres_virtual = %u.\n", vinfo.xres_virtual, vinfo.yres_virtual);

printf("bpp = %u.\n", vinfo.bits_per_pixel);

// 第3步:進行mmap

unsigned long len = vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel / 8;

printf("len = %ld\n", len);

pfb = mmap(null, len, prot_read | prot_write, map_shared, fd, 0);

if (null == pfb)

printf("pfb = %p.\n", pfb);

draw_back(width, height, white);

draw_line(red);

close(fd);

return 0;

}void draw_back(unsigned int width, unsigned int height, unsigned int color)

{ unsigned int x, y;

for (y=0; y

(1)開啟fb裝置:

fd = open(fbdevice, o_rdwr);

(2)獲取lcd裝置的具體引數如:解析度資訊:

ret = ioctl(fd, fbioget_fscreeninfo, &finfo);
其中 fbioget_fscreeninfo 代表讀取引數,fbioput_vscreeninfo 代表設定引數。

pfb = mmap(null, len, prot_read | prot_write, map_shared, fd, 0);
mmap函式的原型為:

void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
第乙個引數:想要對映的虛擬位址,第二個引數:對映的長度、第三個:對映記憶體的許可權、第四個:開啟的fb裝置為檔案描述符、第五個:對映的位址的偏移量。

在這裡null表示使用系統分配的虛擬位址、prot_read | prot_write表示對映的位址可讀可寫、map_shared表示記憶體可被其他的程序共享開啟使用、0表示偏移位址量為0.

(4)接著可以進行freambuffer視訊記憶體內容的填充,之後就可以顯示了。

end。。。。。。

驅動雜記1 對驅動物件,裝置物件,裝置棧的理解

windows核心採用的是物件導向的程式設計方式,但使用的確是c語言。windows核心認為許多東西都是 物件 比如乙個驅動乙個檔案乙個裝置,物件 相當於乙個基類。乙個驅動物件代表了乙個驅動程式,或者說乙個核心模組。驅動物件結構如下 typedef struct driver objectdrive...

字元裝置驅動1 乙個簡單的字元裝置驅動示例

1.註冊主次裝置號 register chrdev region 和 alloc chrdev region 2.註冊字元裝置驅動 cdev init 初始化,cdev add 新增,註冊裝置驅動,cdev alloc 申請空間,cdev del 登出驅動 3.建立驅動的裝置檔案 class cre...

1 裝置驅動程式的概念

系統呼叫是作業系統核心和應用程式之間的介面,裝置驅動程式是作業系統核心和機器硬體之間的介面。裝置驅動程式為應用程式遮蔽了硬體的細節,這樣在應用程式看來,硬體裝置只是乙個裝置檔案,應用程式可以象操作普通檔案一樣對硬體裝置進行操作。裝置驅動程式是核心的一部分。linux將裝置主要分成兩大類 一類是塊裝置...