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將裝置主要分成兩大類 一類是塊裝置...