zoukankan      html  css  js  c++  java
  • framebuffer应用编程实践

    framebuffer的使用主要包括4个部分:

    (1):首先需要打开设备文件 /dev/fb0。

    (2):获取设备的信息。包括可变信息和不可变信息,分别使用两个结构体来进行封装,这两个结构体在 <linux/fb.h> 头文件中定义,所以需要先包含这个头文件。

    (3):如果有需要可以对可变的参数进行修改。

    (4):做mmap映射。我们需要将驱动中给LCD分配的显存空间映射到我们的应用层来,这样才能在应用层对显存进行操作。

    (5):填充framebuffer。也就是上面说的操作显存。

     

    数据结构: (includelinuxfb.h)

    struct  fb_fix_screeninfo:(不可变信息)

     1 struct fb_fix_screeninfo {
     2     char id[16];               // 标识字符串
     3     unsigned long smem_start;       // FB显存的起始地址(物理地址) 
     4                     
     5     __u32 smem_len;                // FB显存的长度
     6     __u32 type;            /* see FB_TYPE_*        */
     7     __u32 type_aux;            
     8     __u32 visual;            /* see FB_VISUAL_*        */ 
     9     __u16 xpanstep;            /* zero if no hardware panning  */
    10     __u16 ypanstep;            /* zero if no hardware panning  */
    11     __u16 ywrapstep;        /* zero if no hardware ywrap    */
    12     __u32 line_length;        // 一行的长度(以字节为单位)
    13     unsigned long mmio_start;    /* Start of Memory Mapped I/O   */
    14                     /* (physical address) */
    15     __u32 mmio_len;            /* Length of Memory Mapped I/O  */
    16     __u32 accel;            /* Indicate to driver which    */
    17                     /*  specific chip/card we have    */
    18     __u16 reserved[3];        /* Reserved for future compatibility */
    19 };

    struct  fb_var_screeninfo:(可变信息)

     1 struct fb_var_screeninfo {
     2     __u32 xres;             // LCD的水平像素大小
     3     __u32 yres;             // LCD的垂直像素大小
     4     __u32 xres_virtual;     // LCD的虚拟水平像素大小
     5     __u32 yres_virtual;     // LCD的虚拟垂直像素大小
     6     __u32 xoffset;          // 水平像素偏移量
     7     __u32 yoffset;          // 垂直像素偏移量
     8 
     9     __u32 bits_per_pixel;            // 像素深度bpp
    10     __u32 grayscale;        /* != 0 Graylevels instead of colors */
    11 
    12     struct fb_bitfield red;        /* bitfield in fb mem if true color, */
    13     struct fb_bitfield green;    /* else only length is significant */
    14     struct fb_bitfield blue;
    15     struct fb_bitfield transp;    /* transparency            */    
    16 
    17     __u32 nonstd;            /* != 0 Non standard pixel format */
    18 
    19     __u32 activate;            /* see FB_ACTIVATE_*        */
    20 
    21     __u32 height;           // LCD的物理高度 mm
    22     __u32 width;            // LCD的物理宽度 mm
    23 
    24     __u32 accel_flags;        /* (OBSOLETE) see fb_info.flags */
    25 
    27     __u32 pixclock;            // 像素时钟
    28 
    29     /* 下面是六个时序参数 */
    30     __u32 left_margin;        /* time from sync to picture    */
    31     __u32 right_margin;        /* time from picture to sync    */  
    32     __u32 upper_margin;        /* time from sync to picture    */ 
    33     __u32 lower_margin;
    34     __u32 hsync_len;        /* length of horizontal sync    */
    35     __u32 vsync_len;        /* length of vertical sync    */
    36     
    37     __u32 sync;            /* see FB_SYNC_*        */
    38     __u32 vmode;            /* see FB_VMODE_*        */
    39     __u32 rotate;            /* angle we rotate counter clockwise */
    40     __u32 reserved[5];        /* Reserved for future compatibility */
    41 };

    相关宏定义: (includelinuxfb.h)

    #define FBIOGET_VSCREENINFO 0x4600      // 传给ioctl函数,用来获取可变参数信息,返回的是一个fb_var_screeninfo结构体
    #define FBIOPUT_VSCREENINFO 0x4601      // 传给ioctl函数,用来设置可变参数,需要传入一个fb_var_screeninfo结构体,
    #define FBIOGET_FSCREENINFO 0x4602      // 传给ioctl函数,用来获取不可变信息,返回的是一个fb_fix_screeninfo结构体

    /*************************************************************************************************************/

    测试代码:

    平台:s5pv210 

    内核版本:2.6.35.7

    /*************************************************************************************************************/

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <sys/stat.h>
      4 #include <fcntl.h>
      5 #include <linux/fb.h>
      6 #include <sys/ioctl.h>
      7 #include <sys/mman.h>
      8 
      9 
     10 #define  FILE  "/dev/fb0"      // 设备文件
     11 
     12 
     13 /*计算机颜色16进制表示符*/
     14 #define  WHITE    0xFFFFFF     //白色
     15 #define  RED      0xFF0000     //红色
     16 #define  GREEN    0x00FF00     //绿色
     17 #define  BLUE     0x0000FF     //蓝色
     18 #define  YELLOW   0xFFFF00     //黄色
     19 #define  BLACK    0x000000     //黑色
     20 #define  AQNA     0xAFDFE4     //水色
     21 #define  NAVE     0x23238E     //海军蓝
     22 #define  ORANGE   0xFF7F00     //橙色
     23 #define  PURPLE   0x871F78     //紫色
     24 #define  Qioke    0x6B4226     //巧克力色
     25 
     26 struct fb_fix_screeninfo finfo = {0};       // 不可变信息结构体
     27 struct fb_var_screeninfo vinfo = {0};       // 可变信息结构体
     28 static volatile unsigned int *pMap = NULL;  // 用来指向mmap映射得到的虚拟地址
     29 
     30 
     31 static inline void lcd_draw_pixel(unsigned int x, unsigned int y, unsigned int color);
     32 static void lcd_draw_background(unsigned int color);
     33 void lcd_draw_lline(const unsigned int x, const unsigned int y, const unsigned int length,   // 注意这个函数参数太多了,不应该这样设计,我们应该把这些参数放在一个结构体中,把结构体变量的指针传进来即可,这样效率高
     34                      const unsigned int width, const unsigned int color);
     35                      
     36 static void lcd_draw_image(const unsigned char *pData);      // pData是一个图片的数据数组: 这里是 1024*600 像素24位真彩色格式的图片,,数组的元素个数: 1024*600*3   我们需要将连续的3个1个字节长度的数据合成一个24位数据
     37 
     38 
     39 int main(void)
     40 {
     41     int fd = 0;
     42     
     43     /* 打开文件得到文件描述符 */
     44     fd = open(FILE, O_RDWR);
     45     if (0 > fd) {
     46         perror("open error");
     47         return -1;
     48     }
     49     printf("%s 打开成功
    ", FILE);
     50     
     51     /* 操作文件 */
     52     if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) {
     53         perror("ioctl error");
     54         close(fd);
     55         return -1;
     56     }    
     57 
     58     if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) {
     59         perror("ioctl error");
     60         close(fd);
     61         return -1;
     62     }
     63         
     64       // 打印信息
     65     printf("不可变信息smem_start = 0x%x
    ", finfo.smem_start);    
     66     printf("不可变信息smem_len = %ld
    ", finfo.smem_len);    
     67     printf("可变信息xres = %d, yres = %d
    ", vinfo.xres, vinfo.yres);
     68     printf("可变信息xres_virtual = %d, yres_virtual = %d
    ", vinfo.xres_virtual, vinfo.yres_virtual);
     69     printf("可变信息xoffset = %d, yoffset = %d
    ", vinfo.xoffset, vinfo.yoffset);
     70     
     71     /* 进行mmap映射 */
     72     pMap = mmap(NULL, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
     73     if (NULL == pMap) {
     74         perror("mmap error");
     75         return -1;
     76     }
     77     
     78     /* 背景填充 */
     79     lcd_draw_background(WHITE);
     80     
     81     /* 关闭文件 */
     82     close(fd);    
     83     
     84     return 0;
     85 }
     86 
     87 /*填充像素点*/
     88 static inline void lcd_draw_pixel(unsigned int x, unsigned int y, unsigned int color)
     89 {
     90     *(unsigned int *)((unsigned int)pMap + (vinfo.xres*x + y)*4) = color;
     91 }
     92 
     93 /*填充LCD背景*/
     94 static void lcd_draw_background(unsigned int color)
     95 {
     96      unsigned int i = 0;
     97      unsigned int j = 0;
     98      
     99      for (i = 1; i <= vinfo.yres; ++i)
    100      {
    101          for (j = 0; j <= vinfo.xres; ++j)
    102              lcd_draw_pixel(i, j, color);
    103      }
    104 }
    105 
    106 //  画线函数
    107 void lcd_draw_lline(const unsigned int x, const unsigned int y, const unsigned int length,
    108                      const unsigned int width, const unsigned int color)              
    109 {
    110     volatile unsigned int i = 0;
    111     volatile unsigned int j = 0;
    112     
    113     for (i = x; i < width+x; i++)
    114     {
    115         for (j = y; j < length+y; j++)
    116         {
    117             lcd_draw_pixel(i, j, color);
    118         }
    119     }    
    120 } 
    121 
    122 
    123 //  24位真彩色图片显示函数
    124 static void lcd_draw_image(const unsigned char *pData)
    125 {
    126     unsigned int i = 0;
    127     unsigned int j = 0;
    128     unsigned int color = 0;
    129     unsigned int p = 0;
    130     
    131     for (i = 0; i < vinfo.yres; i++)
    132     {
    133         for (j = 0; j < vinfo.xres; j++)
    134         {
    135             color = (pData[p+0] << 16) | (pData[p+1] << 8) | (pData[p+2] << 0);
    136             lcd_draw_pixel(i, j, color);
    137             p = p+3;
    138         }
    139     }
    140 }
  • 相关阅读:
    三路快排
    双路快排
    随机快排
    快速排序
    双向链表
    单向链表
    堆排序
    二分插入、bisect
    jmockit使用总结-MockUp重点介绍
    java拼接字符串、格式化字符串方式
  • 原文地址:https://www.cnblogs.com/deng-tao/p/6079704.html
Copyright © 2011-2022 走看看