【Linux】FrameBuffer操作入门

所有的这些操作,都是在控制台界面下,root登录。

一,先变一个魔法

         $ cat /dev/fb0 > sreensnap      /*获取一屏的数据*/  

         $ clear                                         /*清楚屏幕的输出*/

         $ cat sreensnap > /dev/fb0     /*将刚才的屏幕数据显示*/


二,操作/dev/fb0

        1)查看/dev/fb0 的信息

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>

int main () 
{
	 int fp=0;
	 struct fb_var_screeninfo vinfo;
	 struct fb_fix_screeninfo finfo;
	 fp = open ("/dev/fb0",O_RDWR);

	 if (fp < 0){
	  printf("Error : Can not open framebuffer device/n");
	  exit(1);
	 }

	 if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){
	  printf("Error reading fixed information/n");
	  exit(2);
	 }
	 
	 if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
	  printf("Error reading variable information/n");
	  exit(3);
	 }

	 printf("The mem is :%d\n",finfo.smem_len);
	 printf("The line_length is :%d\n",finfo.line_length);
	 printf("The xres is :%d\n",vinfo.xres);
	 printf("The yres is :%d\n",vinfo.yres);
	 printf("bits_per_pixel is :%d\n",vinfo.bits_per_pixel);
	 close (fp);
}

        2)改变屏幕上某一个点的颜色

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

int main () 
{
	 int fp=0;
	 struct fb_var_screeninfo  vinfo;
	 struct fb_fix_screeninfo  finfo;
	 long screensize=0;
	 char *fbp = 0;
	 int x = 0, y = 0;
	 long location = 0;
	 fp = open ("/dev/fb0",O_RDWR);

	 if (fp < 0)
	 {
		  printf("Error : Can not open framebuffer device/n");
		  exit(1);
	 }

	 if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo))
	 {
		  printf("Error reading fixed information/n");
		  exit(2);
	 }
	 
	 if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo))
	 {
		  printf("Error reading variable information/n");
		  exit(3);
	 }

	  screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
	 /*这就是把fp所指的文件中从开始到screensize大小的内容给映射出来,得到一个指向这块空间的指针*/
	 fbp =(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
	 if ((int) fbp == -1)
	 {
		printf ("Error: failed to map framebuffer device to memory./n");
		exit (4);
	 }
	 /*这是你想画的点的位置坐标,(0,0)点在屏幕左上角*/
	 x = 100;
	 y = 100;
	 location = x * (vinfo.bits_per_pixel / 8) + y  *  finfo.line_length;

	 *(fbp + location) = 100;  /* 蓝色的色深 */  /*直接赋值来改变屏幕上某点的颜色*/
	 *(fbp + location + 1) = 15; /* 绿色的色深*/  
	 *(fbp + location + 2) = 200; /* 红色的色深*/  
	 *(fbp + location + 3) = 0;  /* 是否透明*/ 

	 munmap (fbp, screensize); /*解除映射*/
	 close (fp);    /*关闭文件*/
	 return 0;

}


三,framebuffer 内部结构

    数据结构:framebuffer 设备很大程度上依靠了下面四个数据结构。这三个结构在fb.h 中声明。

                       Struct fb_var_screeninfo   //用来描述图形卡的特性的。通常是被用户设置的。

                       Struct fb_fix_screeninfo    // 定义了图形卡的硬件特性, 是不能改变的,用户选定了哪一个图形卡,那么它的硬件特性也就定下来了。

                       Struct fb_info                      //定义了当前图形卡framebuffer 设备的独立状态,一个图形卡可能有两个framebuffer, 在这种情况下,就需要两个fb_info 结构。这个结构是唯一在内核空间可见的。
   
  
    1)fb_var_screeninfo解析

 

struct fb_var_screeninfo {
	__u32 xres; /* visible resolution */
	__u32 yres;

	__u32 xres_virtual; /* virtual resolution */
	__u32 yres_virtual;

	__u32 xoffset; /* offset from virtual to visible */
	__u32 yoffset; /* resolution */

	__u32 bits_per_pixel; /* guess what */
	__u32 grayscale; /* != 0 Graylevels instead of colors*/

	struct fb_bitfield red; /*bitfield in fb mem if true color, */
	struct fb_bitfield green; /*else only length is significant */
	struct fb_bitfield blue;
	struct fb_bitfield transp; /*transparency */

	__u32 nonstd;     /* != 0 Non standard pixel format */
	__u32 activate; /* see FB_ACTIVATE_* */

	__u32 height; /* height of picture in mm???*/
	__u32 width; /* width of picture in mm????*/

	__u32 accel_flags; /* acceleration flags (hints) */

	/* Timing: All values in pixclocks, except pixclock (of course) */

	__u32 pixclock; /* pixel clock in ps (pico seconds) */

	__u32 left_margin; /* time from sync to picture */
	__u32 right_margin; /* time from picture to sync */
	__u32 upper_margin; /* time from sync to picture */
	__u32 lower_margin;

	__u32 hsync_len; /* length of horizontal sync */
	__u32 vsync_len; /* length of vertical sync */

	__u32 sync; /* see FB_SYNC_* */
	__u32 vmode; /* see FB_VMODE_* */

	__u32 reserved[6]; /* Reserved for future compatibility*/

};


前几个成员决定了分辨率。

           xres和yres是在屏幕上可见的实际分辨率,

          xres-virtual决定了构建屏幕时视频卡读取屏幕内存的方式。

          bits_per_pixel 设为1,2,4,8,16,24或32来改变颜色深度


        2)  fb_fix_screeninfo

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; /* Type of acceleration available */

	__u16 reserved[3]; /* Reserved for future compatibility */

};

                  3) 显示说明


【双显示器例子】

           一个例子,可能就是双显示,最近刚刚看到实际某开发者的系统,就是两个显示器,鼠标移动超过单个显示器,到最右边的时候,就跑到另一个显示器了。对于常常用多系统或者需要打开很多东西的开发人员,这个功能很实用。

          帧缓冲可以用于 页面交换page flipping(也常叫做 双缓冲double buffering),许多游戏都是采用此技术,以实现更流畅的视频输出,以便用户获得更好的游戏体验。此技术也被用于3D图形加速。

【双缓冲的主要实现原理】

          假如你的显示器是VGA模式,640×400,也就是虚拟的分辨率是640X800,也就是800线(每一行的数据,称为一条线,也就是640X1的数据了)。800线的数据存储于Framebuffer,而实际的显示内容,只是400线,

         Linux内核中的Framebuffer模型中,对应有个变量yoffset,就是表示的这个具体的纵坐标,默认是0,所以显示的内容就是,0-399线,由于和实际显示 页面大小等同,所以此处可以简称为第一帧。

         如果yoffset改变了,比如此例中变为400,那就是显示剩余的部分,400-799线。此处简称为第二帧。

         在系统显示第一帧的时候,系统在后台悄悄地准备第二帧的数据,所以,等第一帧显示完成,多数时候,第二帧的数据也准备好了,就可以直接显示,同时系统又在准备接下来的一帧的数据,这样就可以大大提高显示效率。


【平滑地滚动页面的实现原理】

           同上,在显示完第一帧数据的时候,也就是0-399线的时候,将yoffset设置为1,就可以显示1-400线的数据了,显示完成后,再设置yoffset为2,就显示2-401线的数据,这样,就可以一点点地,平滑地显示整个滚动画面了。其实也就是画面在垂直方向的滚动。其中yoffset的增加,可以使用定时器,各个一段时间,比如10us,增加1,系统自动会更新显示对应的内容,这样我们所看到的内容就是滚动的画面了。

          此外,Linux中的Framebuffer模型中,提供了一些ioctl功能,给定一些参数,然后系统可以实现对应的功能,其中有个参数就是FBIOPAN_DISPLAY。具体也就是类似如下调用:

          ioctl (framebuffer_handler, FBIOPAN_DISPLAY, &variable_info);

          而这个调用,如果显示不支持framebuffer的双缓冲的话,那么其framebuffer的缓冲大小,就是和物理上的显示器大小等同,那么对应的yoffset也就不会像双缓冲那样变化了。

          也就是说,如果显卡/显示屏控制器不支持双缓冲,那么yoffset就应该一直为0,并且在运行时候,也不应该改变,也不应该去给FBIOPAN_DISPLAY的参数调用ioctl。


  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Qt is a popular cross-platform framework for developing graphical user interfaces (GUI) and applications. It provides support for Linux framebuffer, which allows you to create GUI applications that can run directly on the Linux framebuffer without the need for an X server. To use Qt with Linux framebuffer, you can follow these general steps: 1. Install the required dependencies: Make sure you have the necessary libraries and development packages installed on your Linux system. This may include framebuffer-related libraries like `libdrm` and `libgbm`. 2. Configure Qt with framebuffer support: When building Qt from source, you can enable framebuffer support by passing the `-qt-libinput` flag to the `configure` script. For example: ``` ./configure -qt-libinput ``` 3. Build your Qt application: Once Qt is configured with framebuffer support, you can build your application using the `qmake` and `make` commands as usual. Make sure to set the appropriate target platform, such as `linuxfb`. 4. Run your Qt application on the Linux framebuffer: After building your application, you can run it directly on the Linux framebuffer by setting the appropriate environment variables. For example: ``` export QT_QPA_PLATFORM=linuxfb export QT_QPA_FB_TTY=/dev/fb0 ./your_application ``` By following these steps, you should be able to develop and run Qt applications using the Linux framebuffer as the target platform. Keep in mind that framebuffer support may vary depending on your specific Linux distribution and hardware setup.
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值