FRAMEBUFFER 显示原理及RGB显示
Framebuffer是把內(nèi)存中視頻數(shù)據(jù)輸出的設(shè)備驅(qū)動程序,Linux的framebuffer是獨(dú)立的硬件抽象層,它可以把顯示設(shè)備抽象為幀緩沖區(qū),并把自己當(dāng)作顯示內(nèi)存的一個映像,開發(fā)者可以通過這個映像映射到進(jìn)程地址空間,直接進(jìn)行讀寫操作。簡單的說它把硬件抽象化后,可使上層不再關(guān)心硬件是如何操作,只是完成圖像的顯示功能,該驅(qū)動的設(shè)備文件一般是/dev/fb0、/dev/fb1,framebuffer最多支持32個設(shè)備。下圖說明了Framebuffer在Linux系統(tǒng)的位置,它高于一般的驅(qū)動程序,在中間屏蔽下層驅(qū)動功能。
但是對程序員和Linux系統(tǒng)來是,framebuffer設(shè)備與其它的文件沒有區(qū)別,可以通過配置對framebuffer設(shè)備文件完成對硬件的參數(shù)設(shè)置,framebuffer映射可以通過read()和write()進(jìn)行數(shù)據(jù)的讀取,或者通過mmap()函數(shù)將內(nèi)部數(shù)據(jù)映射到應(yīng)用程序空間,通過ioctl()進(jìn)行其它操作或者設(shè)置其參數(shù),用mmap()函數(shù)把內(nèi)存中的圖像數(shù)據(jù)直接映射到framebuffer并顯示出來耗時短、效率高。內(nèi)存中圖像數(shù)據(jù)出來完后就可通過mmap()進(jìn)行映射。
Framebuffer在Linux系統(tǒng)中的位置
圖像顯示過程
屏幕顯示調(diào)用的是framebuffer,首先建立一個fb_dev結(jié)構(gòu)體,里邊有設(shè)備指針、內(nèi)存空間指針、橫豎像素數(shù)、顏色位數(shù)等信息:
| struct fb_dev { int fb; void *fb_mem; int fb_width, fb_height, fb_line_len, fb_size; int fb_bpp; } fbdev; |
?
初始化framebuffer設(shè)備,并進(jìn)行內(nèi)存地址映射,可以直接把處理后的數(shù)據(jù)映射到framebuffer的緩存中進(jìn)行顯示:
| int fb; ?if ((fb = open("/dev/fb0", O_RDWR)) < 0) { ?perror(__func__); ?return (-1); } fb_stat(fb); fbdev.fb_mem = mmap (NULL, fbdev.fb_size, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0); fbdev.fb = fb; |
?
?? 其中fb_stat(fb)函數(shù)如下定義,得到framebuffer的長、寬和位寬,成功則返回0,失敗返回-1:
| int fb_stat(int fd) { struct fb_fix_screeninfo fb_finfo; struct fb_var_screeninfo fb_vinfo; ?if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) { perror(__func__); ?return (-1); } if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) { perror(__func__); return (-1); } fbdev.fb_width = fb_vinfo.xres; fbdev.fb_height = fb_vinfo.yres; fbdev.fb_bpp = fb_vinfo.bits_per_pixel; bdev.fb_line_len = fb_finfo.line_length; fbdev.fb_size = fb_finfo.smem_len; ?return (0); } |
?
在屏幕上顯示數(shù)據(jù),需要直接對像素點(diǎn)上直接顯示像素顏色,因為原始解碼的數(shù)據(jù)是24位RGB數(shù)據(jù),而屏幕的顏色位數(shù)是16位,則需要將RGB888轉(zhuǎn)換為RGB565數(shù)據(jù):主要是對不用顏色位數(shù)進(jìn)行移位。
代碼如下
| color=(unsigned short) (((buffer[x3s]<<8) & 0xF800)|((buffer[x3s+1]<<3) & 0x07E0)|((buffer[x3s+2] >> 3) & 0x001F)); |
?
因為開發(fā)板自帶的NEC 3.5寸液晶屏分辨率是240×320,而攝像頭輸出的數(shù)據(jù)為320×240,故顯示時需進(jìn)行矩陣轉(zhuǎn)置,由fbmem基址 + x * width + y確定:
?
| if ((x > width) || (y > height) return (-1); unsigned short *dst = ((unsigned short *) fbmem + x * width + y); *dst = color; |
?
在程序最后,需要解除內(nèi)存映射和關(guān)閉設(shè)備:
???
| munmap(fbdev.fb_mem,fbdev.fb_size); close(fb); |
總結(jié)
以上是生活随笔為你收集整理的FRAMEBUFFER 显示原理及RGB显示的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: arm linux 显示屏 10钟黑屏
- 下一篇: Machine Learning 网络资