framebuffer显示设备。
在应用层直接抽象位向DDR中存放图片。
在操作系统中,将上图分为两个部分:驱动+应用。
使用复制的方法效率十分的低,所以有了内存映射方法实现图片的显示。
framebuffer帧(铺满一个屏幕)(fd)在linux在虚拟出一个设备/dev/fd,是向应用层提供的接口,也是同一接口,是一种直接抽象。
frambuffer使用方法:①打开设备/dev/fdn;②获取设备信息<linux/fd.h>;③mmp映射(原因是应用层工作在应用层空间,内核工作在内核空间,两块虚拟空间不同,但映射到了同一块物理空间)。多个进程可同时操作同一LCD,无非是谁覆盖谁;④填充framebuffer。
fb在应用层的使用:
#define FBDEVICE "/dev/fb0"
fd = open(FBDEVICE, O_RDWR);//①打开设备
if(fd<0)
{
//err
}
#define FBIOPUT_VSCREENINFO与#define FBIOGET_FSCREENINFO宏是位于linux/fb.h下的宏,其中FBIOPUT_VSCREENINFO是可变的fb信息而FBIOGET_FSCREENINFO是不可变信息。不可变信息:如硬件真实分辨率(分辨率最大值,1080p显示器可支持720p的显示);可变信息:可适分辨率、虚拟分辨率、参考点等。
struct fb_fix_screeninfo finfo = {0};//在<linux/fb.h>查看具体情况
struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */
unsigned long smem_start; /* Start of frame buffer mem */
/* (physical address) */
__u32 smem_len; /* Length of frame buffer mem */
__u32 type; /* see FB_TYPE_* */
__u32 type_aux; /* Interleave for interleaved Planes */
__u32 visual; /* see FB_VISUAL_* */
__u16 xpanstep; /* zero if no hardware panning */
__u16 ypanstep; /* zero if no hardware panning */
__u16 ywrapstep; /* zero if no hardware ywrap */
__u32 line_length; /* length of a line in bytes */
unsigned long mmio_start; /* Start of Memory Mapped I/O */
/* (physical address) */
__u32 mmio_len; /* Length of Memory Mapped I/O */
__u32 accel; /* Indicate to driver which */
/* specific chip/card we have */
__u16 reserved[3]; /* Reserved for future compatibility */
};//具体情况
ret = ioctl(fd, FBIOGET_FSCREENINFO, &finfo);//获取设备信息(不可变)
if(ret<0)
{
//err
}
fb大小是屏幕的一倍,用于做双缓冲(乒乓结构)。
smem_len(字节)=虚拟分辨率(x*y)*bpp(32/8) <=色彩位(aRGB)。
unsigned int *pfb = NULL;
unsigned long smem_len= vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel / 8;
pfb = mmap(NULL, smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
//NULL 自分配地址(应用层)
//smem_len长度
//PROT_READ | PROT_WRITE可读可写
//MAP_SHARED非排它
//0 偏移量
if (NULL == pfb)
{
//err
}
void draw_back(unsigned int width, unsigned int height, unsigned int color)//纯色填充
{
unsigned int x, y;
for (y=0; y<height; y++)
{
for (x=0; x<width; x++)
{
*(pfb + y * WIDTH + x) = color;
}
}
}
draw_back(WIDTH, HEIGHT, 0xffffffff);//白
在对vinfo进行修改后,使用ioctl写回:
ret=ioctl(fd,FBIOGET_VSCREENINFO,&vinfo);
可视分辨率只能在驱动中修改。
先介绍到这吧,下一章介绍framebuffer框架与fb驱动相关。