今天学习了linux系统中的framebuffer技术
framebuffer技术被称为"帧缓存"技术,是linux系统下应用层专门为方便图像
显示的一套接口,主要是通过内存映射的方式将对应的rgb颜色值写入到对
应的显存空间从而实现图像显示。
在linux环境下,系统会把显示设备抽象为字符设备文件,然后通过操作文件来实现设备控制:
主要有以下步骤:
- 打开字符设备文件。
- 获取设备相关参数(分辨率,像素深度等)
- 建立内存映射(mmap)
- 写入颜色值
- 解除映射
- 关闭字符设备文件
主要用到的函数接口有
c
int ioctl(int fd, unsigned long request, ...);
//通过该函数可以实现对设备进行一些控制
//进入内核源码中看看<linux/fb.h>,里面定义了一些ioctl的命令
#define FBIOGET_VSCREENINFO 0x4600 //获取应用程序可改变的参数(如设定的分辨率)
#define FBIOPUT_VSCREENINFO 0x4601
#define FBIOGET_FSCREENINFO 0x4602 //获取固定的参数(如屏幕的分辨率,一般只是拿来看看)
#define FBIOGETCMAP 0x4604
#define FBIOPUTCMAP 0x4605
#define FBIOPAN_DISPLAY 0x4606
c
/*以下两组函数的作用分别是建立内存映射和解除内存映射*/
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
int munmap(void *addr, size_t length);
以下是具体的代码操作:
c
int init_fb(const char *fbname)
{
creeninfo.fd = open(fbname, O_RDWR);
if(creeninfo.fd == -1)
{
perror("fail to open");
return -1;
}
int ret = ioctl(creeninfo.fd, FBIOGET_VSCREENINFO, &creeninfo.vinfo);
if(ret == -1)
{
perror("fail to ioctl");
return -1;
}
printf("xres = %d,yres = %d\n",creeninfo.vinfo.xres, creeninfo.vinfo.yres);
printf("xres_virtual = %d, yres_virtual = %d\n",creeninfo.vinfo.xres_virtual, creeninfo.vinfo.yres_virtual);
printf("bits_per_pixel = %d\n",creeninfo.vinfo.bits_per_pixel);
size_t size = creeninfo.vinfo.xres_virtual*creeninfo.vinfo.yres_virtual*creeninfo.vinfo.bits_per_pixel/8;
creeninfo.pmem = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, creeninfo.fd, 0);
if(creeninfo.pmem == (void *)-1)
{
perror("fail to mmap");
return -1;
}
return 0;
}
下列程序可以完成绘制出一个点:
c
int draw_point(int x, int y, unsigned int col)
{
if(x >= creeninfo.vinfo.xres_virtual || y >= creeninfo.vinfo.yres_virtual)
{
return -1;
}
if(creeninfo.vinfo.bits_per_pixel == RGB888)
{
unsigned int *p = creeninfo.pmem;
*(p+x*creeninfo.vinfo.xres_virtual+y) = col;
}
else if(creeninfo.vinfo.bits_per_pixel == RGB565)
{
unsigned short *p = creeninfo.pmem;
*(p+x*creeninfo.vinfo.xres_virtual+y) = col;
}
return 0;
}