FRAMEBUFFER 显示原理及RGB显示

来源:互联网 发布:网络美工是做什么的 编辑:程序博客网 时间:2024/05/01 05:09

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);


0 0
原创粉丝点击