Framebuffer使用测试

这两天拾起以前做过的Framebuffer,不相同的是以前在嵌入式上做的,现在在自己电脑上Debian上进行测试,不过都类似罢了,嵌入式里要初始化很多东西。下面具体列一下步骤。至于Framebuffer的原理,就我的理解是比较简单的,无非往mmap好的fb上填写显示数据罢了,不对这些数据进行处理,FrameBuffer 只是一个提供显示内存和显示芯片寄存器从物理内存映射到进程地址空间中的设备,它需要真正的显卡驱动的支持。在这次测试中,我用了默认就安装的vesafb,好像又被称为万能Fb驱动。

 

1、   首先在系统Grub启动时按e进入命令启动行的编辑模式,改为:kernel /boot/vmlinuz-2.6.18-5-686 root=/dev/sda6 ro vga=791vga=791表示fb1024 * 768 * 16bpp,其他模式的参数可以上网查查);

 

2、   进入系统的命令行模式,编译fb测试例子:gcc fb_test.c

 

3、   允许测试例子:sudo ./a.out >> fb.txt(必须要用超级用户权限,>>将屏幕打印写到fb.txt中),效果如下:

打印如下:

 


Fixed screen info:
    id: VESA VGA
    smem_start: 0xf0000000
    smem_len: 3145728
    type: 0
    type_aux: 0
    visual: 2
    xpanstep: 0
    ypanstep: 0
    ywrapstep: 0
    line_length: 2048
    mmio_start: 0x0
    mmio_len: 0
    accel: 0

Variable screen info:
    xres: 1024
    yres: 768
    xres_virtual: 1024
    yres_virtual: 768
    yoffset: 0
    xoffset: 0
    bits_per_pixel: 16
    grayscale: 0
    red: offset: 11, length: 5, msb_right: 0
    green: offset: 5, length: 6, msb_right: 0
    blue: offset: 0, length: 5, msb_right: 0
    transp: offset: 0, length: 0, msb_right: 0
    nonstd: 0
    activate: 0
    height: -1
    width: -1
    accel_flags: 0x0
    pixclock: 12714
    left_margin: 128
    right_margin: 32
    upper_margin: 16
    lower_margin: 4
    hsync_len: 128
    vsync_len: 4
    sync: 0
    vmode: 0

Frame Buffer Performance test...
        Average: 2508 usecs
        Bandwidth: 1196.172 MByte/Sec
        Max. FPS: 398.724 fps


4、还可以通过fb在命令行模式下看视频,如:sudo mplayer –vo fbdev ./air_nessesity.mpg


 

  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <linux/fb.h>
  6. #include <linux/kd.h>
  7. #include <sys/mman.h>
  8. #include <sys/ioctl.h>
  9. #include <sys/time.h>
  10. #include <string.h>
  11. #include <errno.h>
  12. struct fb_var_screeninfo vinfo;
  13. struct fb_fix_screeninfo finfo;
  14. char *frameBuffer = 0;
  15. //打印fb驱动中fix结构信息,注:在fb驱动加载后,fix结构不可被修改。
  16. void
  17. printFixedInfo ()
  18. {
  19.     printf ("Fixed screen info:/n"
  20.             "/tid: %s/n"
  21.             "/tsmem_start: 0x%lx/n"
  22.             "/tsmem_len: %d/n"
  23.             "/ttype: %d/n"
  24.             "/ttype_aux: %d/n"
  25.             "/tvisual: %d/n"
  26.             "/txpanstep: %d/n"
  27.             "/typanstep: %d/n"
  28.             "/tywrapstep: %d/n"
  29.             "/tline_length: %d/n"
  30.             "/tmmio_start: 0x%lx/n"
  31.             "/tmmio_len: %d/n"
  32.             "/taccel: %d/n"
  33.             "/n",
  34.             finfo.id, finfo.smem_start, finfo.smem_len, finfo.type,
  35.             finfo.type_aux, finfo.visual, finfo.xpanstep, finfo.ypanstep,
  36.             finfo.ywrapstep, finfo.line_length, finfo.mmio_start,
  37.             finfo.mmio_len, finfo.accel);
  38. }
  39. //打印fb驱动中var结构信息,注:fb驱动加载后,var结构可根据实际需要被重置
  40. void
  41. printVariableInfo ()
  42. {
  43.     printf ("Variable screen info:/n"
  44.             "/txres: %d/n"
  45.             "/tyres: %d/n"
  46.             "/txres_virtual: %d/n"
  47.             "/tyres_virtual: %d/n"
  48.             "/tyoffset: %d/n"
  49.             "/txoffset: %d/n"
  50.             "/tbits_per_pixel: %d/n"
  51.             "/tgrayscale: %d/n"
  52.             "/tred: offset: %2d, length: %2d, msb_right: %2d/n"
  53.             "/tgreen: offset: %2d, length: %2d, msb_right: %2d/n"
  54.             "/tblue: offset: %2d, length: %2d, msb_right: %2d/n"
  55.             "/ttransp: offset: %2d, length: %2d, msb_right: %2d/n"
  56.             "/tnonstd: %d/n"
  57.             "/tactivate: %d/n"
  58.             "/theight: %d/n"
  59.             "/twidth: %d/n"
  60.             "/taccel_flags: 0x%x/n"
  61.             "/tpixclock: %d/n"
  62.             "/tleft_margin: %d/n"
  63.             "/tright_margin: %d/n"
  64.             "/tupper_margin: %d/n"
  65.             "/tlower_margin: %d/n"
  66.             "/thsync_len: %d/n"
  67.             "/tvsync_len: %d/n"
  68.             "/tsync: %d/n"
  69.             "/tvmode: %d/n"
  70.             "/n",
  71.             vinfo.xres, vinfo.yres, vinfo.xres_virtual, vinfo.yres_virtual,
  72.             vinfo.xoffset, vinfo.yoffset, vinfo.bits_per_pixel,
  73.             vinfo.grayscale, vinfo.red.offset, vinfo.red.length,
  74.             vinfo.red.msb_right, vinfo.green.offset, vinfo.green.length,
  75.             vinfo.green.msb_right, vinfo.blue.offset, vinfo.blue.length,
  76.             vinfo.blue.msb_right, vinfo.transp.offset, vinfo.transp.length,
  77.             vinfo.transp.msb_right, vinfo.nonstd, vinfo.activate,
  78.             vinfo.height, vinfo.width, vinfo.accel_flags, vinfo.pixclock,
  79.             vinfo.left_margin, vinfo.right_margin, vinfo.upper_margin,
  80.             vinfo.lower_margin, vinfo.hsync_len, vinfo.vsync_len,
  81.             vinfo.sync, vinfo.vmode);
  82. }
  83. //画大小为width*height的同色矩阵,8alpha+8reds+8greens+8blues
  84. void
  85. drawRect_rgb32 (int x0, int y0, int width, int height, int color)
  86. {
  87.     const int bytesPerPixel = 4;
  88.     const int stride = finfo.line_length / bytesPerPixel;
  89.     int *dest = (int *) (frameBuffer)
  90.         + (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
  91.     int x, y;
  92.     for (y = 0; y < height; ++y)
  93.     {
  94.         for (x = 0; x < width; ++x)
  95.         {
  96.             dest[x] = color;
  97.         }
  98.         dest += stride;
  99.     }
  100. }
  101. //画大小为width*height的同色矩阵,5reds+6greens+5blues
  102. void
  103. drawRect_rgb16 (int x0, int y0, int width, int height, int color)
  104. {
  105.     const int bytesPerPixel = 2;
  106.     const int stride = finfo.line_length / bytesPerPixel;
  107.     const int red = (color & 0xff0000) >> (16 + 3);
  108.     const int green = (color & 0xff00) >> (8 + 2);
  109.     const int blue = (color & 0xff) >> 3;
  110.     const short color16 = blue | (green << 5) | (red << (5 + 6));
  111.     short *dest = (short *) (frameBuffer)
  112.         + (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
  113.     int x, y;
  114.     for (y = 0; y < height; ++y)
  115.     {
  116.         for (x = 0; x < width; ++x)
  117.         {
  118.             dest[x] = color16;
  119.         }
  120.         dest += stride;
  121.     }
  122. }
  123. //画大小为width*height的同色矩阵,5reds+5greens+5blues
  124. void
  125. drawRect_rgb15 (int x0, int y0, int width, int height, int color)
  126. {
  127.     const int bytesPerPixel = 2;
  128.     const int stride = finfo.line_length / bytesPerPixel;
  129.     const int red = (color & 0xff0000) >> (16 + 3);
  130.     const int green = (color & 0xff00) >> (8 + 3);
  131.     const int blue = (color & 0xff) >> 3;
  132.     const short color15 = blue | (green << 5) | (red << (5 + 5)) | 0x8000;
  133.     short *dest = (short *) (frameBuffer)
  134.         + (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
  135.     int x, y;
  136.     for (y = 0; y < height; ++y)
  137.     {
  138.         for (x = 0; x < width; ++x)
  139.         {
  140.             dest[x] = color15;
  141.         }
  142.         dest += stride;
  143.     }
  144. }
  145. void
  146. drawRect (int x0, int y0, int width, int height, int color)
  147. {
  148.     switch (vinfo.bits_per_pixel)
  149.     {
  150.     case 32:
  151.         drawRect_rgb32 (x0, y0, width, height, color);
  152.         break;
  153.     case 16:
  154.         drawRect_rgb16 (x0, y0, width, height, color);
  155.         break;
  156.     case 15:
  157.         drawRect_rgb15 (x0, y0, width, height, color);
  158.         break;
  159.     default:
  160.         printf ("Warning: drawRect() not implemented for color depth %i/n",
  161.                 vinfo.bits_per_pixel);
  162.         break;
  163.     }
  164. }
  165. #define PERFORMANCE_RUN_COUNT 5
  166. void
  167. performSpeedTest (void *fb, int fbSize)
  168. {
  169.     int i, j, run;
  170.     struct timeval startTime, endTime;
  171.     unsigned long long results[PERFORMANCE_RUN_COUNT];
  172.     unsigned long long average;
  173.     unsigned int *testImage;
  174.     unsigned int randData[17] = {
  175.         0x3A428472, 0x724B84D3, 0x26B898AB, 0x7D980E3C, 0x5345A084,
  176.         0x6779B66B, 0x791EE4B4, 0x6E8EE3CC, 0x63AF504A, 0x18A21B33,
  177.         0x0E26EB73, 0x022F708E, 0x1740F3B0, 0x7E2C699D, 0x0E8A570B,
  178.         0x5F2C22FB, 0x6A742130
  179.     };
  180.     printf ("Frame Buffer Performance test.../n");
  181.     for (run = 0; run < PERFORMANCE_RUN_COUNT; ++run)
  182.     {
  183.         /* Generate test image with random(ish) data: */
  184.         testImage = (unsigned int *) malloc (fbSize);
  185.         j = run;
  186.         for (i = 0; i < (int) (fbSize / sizeof (int)); ++i)
  187.         {
  188.             testImage[i] = randData[j];
  189.             j++;
  190.             if (j >= 17)
  191.                 j = 0;
  192.         }
  193.         gettimeofday (&startTime, NULL);
  194.         memcpy (fb, testImage, fbSize);
  195.         gettimeofday (&endTime, NULL);
  196.         long secsDiff = endTime.tv_sec - startTime.tv_sec;
  197.         results[run] =
  198.             secsDiff * 1000000 + (endTime.tv_usec - startTime.tv_usec);
  199.         free (testImage);
  200.     }
  201.     average = 0;
  202.     for (i = 0; i < PERFORMANCE_RUN_COUNT; ++i)
  203.         average += results[i];
  204.     average = average / PERFORMANCE_RUN_COUNT;
  205.     printf (" Average: %llu usecs/n", average);
  206.     printf (" Bandwidth: %.03f MByte/Sec/n",
  207.             (fbSize / 1048576.0) / ((double) average / 1000000.0));
  208.     printf (" Max. FPS: %.03f fps/n/n",
  209.             1000000.0 / (double) average);
  210.     /* Clear the framebuffer back to black again: */
  211.     memset (fb, 0, fbSize);
  212. }
  213. int
  214. main (int argc, char **argv)
  215. {
  216.     const char *devfile = "/dev/fb0";
  217.     long int screensize = 0;
  218.     int fbFd = 0;
  219.     /* Open the file for reading and writing */
  220.     fbFd = open (devfile, O_RDWR);
  221.     if (fbFd == -1)
  222.     {
  223.         perror ("Error: cannot open framebuffer device");
  224.         exit (1);
  225.     }
  226.     //获取finfo信息并显示
  227.     if (ioctl (fbFd, FBIOGET_FSCREENINFO, &finfo) == -1)
  228.     {
  229.         perror ("Error reading fixed information");
  230.         exit (2);
  231.     }
  232.     printFixedInfo ();
  233.     //获取vinfo信息并显示
  234.     if (ioctl (fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1)
  235.     {
  236.         perror ("Error reading variable information");
  237.         exit (3);
  238.     }
  239.     printVariableInfo ();
  240.     /* Figure out the size of the screen in bytes */
  241.     screensize = finfo.smem_len;
  242.     /* Map the device to memory */
  243.     frameBuffer =
  244.         (char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
  245.                      fbFd, 0);
  246.     if (frameBuffer == MAP_FAILED)
  247.     {
  248.         perror ("Error: Failed to map framebuffer device to memory");
  249.         exit (4);
  250.     }
  251.     //测试virt fb的性能
  252.     performSpeedTest (frameBuffer, screensize);
  253.     printf ("Will draw 3 rectangles on the screen,/n"
  254.             "they should be colored red, green and blue (in that order)./n");
  255.     drawRect (vinfo.xres / 8, vinfo.yres / 8,
  256.              vinfo.xres / 4, vinfo.yres / 4, 0xffff0000);
  257.     drawRect (vinfo.xres * 3 / 8, vinfo.yres * 3 / 8,
  258.              vinfo.xres / 4, vinfo.yres / 4, 0xff00ff00);
  259.     drawRect (vinfo.xres * 5 / 8, vinfo.yres * 5 / 8,
  260.              vinfo.xres / 4, vinfo.yres / 4, 0xff0000ff);
  261.     sleep (5);
  262.     printf (" Done./n");
  263.     munmap (frameBuffer, screensize);    //解除内存映射,与mmap对应
  264.     close (fbFd);
  265.     return 0;
  266. }
复制代码

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值