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

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

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

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

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

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

 

 

数据结构: (include\linux\fb.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 };

 

相关宏定义: (include\linux\fb.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 打开成功\n", 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\n", finfo.smem_start);    
 66     printf("不可变信息smem_len = %ld\n", finfo.smem_len);    
 67     printf("可变信息xres = %d, yres = %d\n", vinfo.xres, vinfo.yres);
 68     printf("可变信息xres_virtual = %d, yres_virtual = %d\n", vinfo.xres_virtual, vinfo.yres_virtual);
 69     printf("可变信息xoffset = %d, yoffset = %d\n", 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 }