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