framebuffer:帧缓冲,帧缓存
Linux内核为显示提供的一套应用程序接口。(驱动内核支持)
framebuffer本质上是一块显示缓存,往显示缓存中写入特定格式的数据就意味着向屏幕输出内容。framebuffer驱动程序控制LCD显示设备,通过映射framebuffer设备到用户空间,应用程序可以直接对显存进行操作,从而控制LCD显示内容
framebuffer使用
显示屏:800*600(横向有800个像素点,纵向有600个像素点)
显卡(显存(保存像素点的值))
RGB
888(R,G,B各占八个比特)
PC,4412:RGB888
S3C2440:RGB565
显存空间不允许用户直接访问
所以可以采用内存映射,将用户空间与显存空间建立起一一对应的关系
根据显存的大小的多少,来申请空间
1.打开显示设备(/dev/fb0)
2.获取显示设备相关参数(分辨率、位深度)
3.建立内存映射
4.写入RGB颜色值
5.解除映射
6.关闭显示设备
和硬件有关的接口都只能用open打开
获取显示设备相关文件
/usr/include/linux/fb.h
偏移量:从什么位置开始映射
framebuffer使用:
1.获取显示设备相关参数
cs
int init_fb(char *devname)
{
int fd = open(devname, O_RDWR);
if (-1 == fd)
{
perror("fail open fb");
return -1;
}
int ret = ioctl(fd, FBIOGET_VSCREENINFO, &vinf);
if (-1 ==ret)
{
perror("fail ioctl");
return -1;
}
printf("xres = %d, yres = %d\n", vinf.xres, vinf.yres);
printf("xres_virtual = %d, yres_virtual = %d\n", vinf.xres_virtual, vinf.yres_virtual);
printf("bits_per_pixel : %d\n", vinf.bits_per_pixel);
size_t len = vinf.xres_virtual * vinf.yres_virtual * vinf.bits_per_pixel/8;
pmem = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if ((void *)-1 == pmem)
{
perror("fail mmap");
return -1;
}
return fd;
}
2.画点
cs
void draw_point(int x, int y, unsigned int col)
{
if (x >= vinf.xres || y >= vinf.yres)
{
return ;
}
if (vinf.bits_per_pixel == RGB888_FMT)
{
unsigned int *p = pmem;
*(p + y * vinf.xres_virtual + x) = col;
}
else if (vinf.bits_per_pixel == RGB565_FMT)
{
unsigned short *p = pmem;
*(p + y * vinf.xres_virtual + x) = col;
}
return ;
}
3.清屏
cs
void screen_clear(int color)
{
int i = 0;
int j = 0;
for(i = 0;i < vinf.xres;++i)
{
for(j = 0;j < vinf.yres;++j)
{
draw_point(i,j,color);
}
}
}
4.划线
cs
void draw_line(int x1,int x2,int y1,int y2,int color)
{
if(x1 > 0 && x1 < vinf.xres_virtual && x2 > 0 && x2 < vinf.xres_virtual && y1 > 0 && y1 < vinf.yres_virtual && y2 > 0 && y2 < vinf.yres_virtual)
{
int xmax = x1 > x2 ? x1 : x2;
int xmin = x1 > x2 ? x2 : x1;
int x = 0;
int y = 0;
if(x1 == x2)
{
int ymax = y1 > y2 ? y1 : y2;
int ymin = y1 > y2 ? y2 : y1;
for(y = ymin;y < ymax;++y)
{
draw_point(x1,y,color);
}
}
for(x = xmin;x < xmax;x++)
{
y = (x - x1)*(y2 - y1) / (x1 - x2) + y1;
draw_point(x,y,color);
}
}
}
5.画圆
cs
void draw_circle(int a,int b,int r,int color)
{
int x = 0;
int y = 0;
int tmp;
for(x = a -r;x < a + r;++x)
{
tmp = sqrt(r*r - (x-a)*(x-a));
int ymax = b + tmp;
int ymin = b - tmp;
for(y = ymin;y < ymax;++y)
{
draw_point(x,y,color);
}
}
}