Chinaunix首页 | 论坛 | 博客
  • 博客访问: 38895
  • 博文数量: 9
  • 博客积分: 221
  • 博客等级: 入伍新兵
  • 技术积分: 105
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-24 22:18
文章分类
文章存档

2012年(9)

我的朋友

分类: LINUX

2012-09-02 22:34:57

为了直观的表示LCD显示时,Framebuffer的参数,比如width,height,bpp,的工作原理,个人整理了一下代码,望大家指正。
图形系统开发基础可以参考:,很不错的入门指导。

点击(此处)折叠或打开

  1. /*
  2.  author:limosky
  3.  date:2012-09-03
  4.  description:This is a test program to tell you how your LCD work with some parameters,such as width,height and bpp.You can specify the parameter that you care,run the program,and look for the difference of black areas on your LCD.
  5.  */
  6. #include <stdio.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <sys/mman.h>
  11. #include <sys/ioctl.h>
  12. #include <linux/fb.h>
  13. #include <unistd.h>
  14. #include <string.h>
  15. #include <getopt.h>
  16. #include <stdlib.h>

  17. char *fb_addr;
  18. unsigned fb_size;
  19. int print_screen(char *buf, int width, int height, int bpp);


  20. const char *short_options = "w:h:b:";
  21. struct option long_options[] = { { "width", 1, NULL, 'w' }, { "height", 1, NULL,
  22.         'h' }, { "bpp", 1, NULL, 'b' }, { 0, 0, 0, 0 } };

  23. void print_usage(char *filename) {
  24.     printf("Usage:\n");
  25.     printf("    %s [options]\n", filename);
  26.     printf("options:\n-w --width value\n-h --height value\n-b --bpp value\n");

  27. }

  28. int main(int argc, char *argv[]) {
  29.     int fb_fd;
  30.     struct fb_var_screeninfo fbv;
  31.     struct fb_fix_screeninfo fbx;

  32.     char *picture;

  33.     int width, height, bpp;

  34.     if ((fb_fd = open("/dev/fb0", O_RDWR)) < 0) {
  35.         printf("fb device open failed!\n");
  36.         return -1;
  37.     }
  38.     if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &fbv) == -1) {
  39.         printf("FBIOGET_VSCREENINFO failed !\n");
  40.         return -1;
  41.     }

  42.     if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fbx) == -1) {
  43.         printf("FBIOGET_FSCREENINFO failed !\n");
  44.         return -1;
  45.     }

  46.     printf(
  47.             "fbv.xres = %u fbv.yres = %u \nfbv.xres_virtual = %u fbv.yres_virtual = %u \nfbv.bits_per_pixel = %u fbx.smem_len = %u fbx.line_length = %u.\n",
  48.             fbv.xres, fbv.yres, fbv.xres_virtual, fbv.yres_virtual,
  49.             fbv.bits_per_pixel, fbx.smem_len, fbx.line_length);

  50.     fb_size = fbv.yres * fbx.line_length;
  51.     fb_addr = (char *) mmap(NULL, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED,
  52.             fb_fd, 0);
  53.     printf("mmap OK.\n");

  54.     picture = (char *) malloc(fbv.yres * fbx.line_length); //分配足够显示的内存区域
  55.     printf("malloc OK.\n");

  56.     memset(picture, 0x00, fbv.yres * fbx.line_length); //0x00用RGB显示为黑色
  57.     printf("memset OK.\n");

  58.     width = fbv.xres;
  59.     height = fbv.yres;
  60.     bpp = fbv.bits_per_pixel;
  61.     int c;
  62.     while ((c = getopt_long(argc, argv, short_options, long_options, NULL))
  63.             != -1) {
  64.         switch (c) {
  65.         case 'w':
  66.             width = atoi(optarg);
  67.             break;
  68.         case 'h':
  69.             height = atoi(optarg);
  70.             break;
  71.         case 'b':
  72.             bpp = atoi(optarg);
  73.             break;
  74.         case '?':
  75.             print_usage(argv[0]);
  76.             return -1;
  77.         }
  78.     }
  79.     printf("width=%d,height=%d,bpp=%d.\n", width, height, bpp);

  80.     print_screen(picture, width, height, bpp);
  81.     printf("print screen OK.\n");

  82.     munmap(fb_addr, fb_size);
  83.     close(fb_fd);
  84.     return 0;
  85. }

  86. int print_screen(char *buf, int width, int height, int bpp) {
  87.     char *t_data = buf;
  88.     char *t_fb_addr = fb_addr;
  89.     int bytew = width * bpp / 8; //bytew实际上算出来总是等于fbx.line_length的
  90.     printf("get bytew done.\n");
  91.     while (--height >= 0) {
  92.         memcpy(t_fb_addr, t_data, bytew);
  93.         //printf( "one row down.\n");
  94.         t_fb_addr += bytew;
  95.         t_data += bytew;
  96.     }
  97.     return 0;
  98. }
使用方法是,在开发板上运行(由于PC上刷新机制的问题,所以本程序在PC上看不到效果。建议使用带LCD的ARM开发板测试,本人用的是友善的Tiny210,S70屏幕),自由设定各个参数,会看到黑色区域显示不同的位置和大小。大屏且低分辨率下,可以看到每条线扫描的区别。
阅读(2568) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~