1 /**************************************************
2 * example1.c
3 * Author: T-bagwell
4 *
5 * Compile:gcc -Wall example2.c -o example2
6 *************************************************/
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <linux/fb.h>
13 int main(int argc, char *argv[])
14 {
15 int screen_fbd=0;
16 struct fb_fix_screeninfo fb_fix;
17 struct fb_var_screeninfo fb_var;
18 char *env=NULL;
19
20 if(!(env = getenv("FRAMEBUFFER")))
21 {
22 env = "/dev/fb0";
23 }
24
25 screen_fbd = open(env, O_RDWR);
26
27 if(screen_fbd < 0)
28 {
29 printf("Error Opening FrameBuffer Device:%s\r\n", env);
30 return 0;
31 }
32 else
33 {
34 printf("Success Opening FrameBuffer Device:%s\r\n",env);
35 }
36
37 if(ioctl(screen_fbd, FBIOGET_FSCREENINFO, &fb_fix) == -1)
38 {
39 printf("Error Reading Screen Info FSCREENINFO.\n");
40
41 close(screen_fbd);
42
43 return 0;
44 }
45
46 printf("fb_fix.id=\"%s\"\r\n",fb_fix.id);
47 printf("fb_fix.smem_start=%#x\r\n",fb_fix.smem_start);
48 printf("fb_fix.mem_len=%d\r\n",fb_fix.smem_len);
49 printf("fb_fix.type=%d\r\n",fb_fix.type);
50 printf("fb_fix.type_aux=%d\r\n",fb_fix.type_aux);
51 printf("fb_fix.visual=%d\r\n",fb_fix.visual);
52 printf("fb_fix.xpanstep=%s\r\n",fb_fix.xpanstep);
53 printf("fb_fix.ypanstep=%d\r\n",fb_fix.ypanstep);
54 printf("fb_fix.ywrapstep=%d\r\n",fb_fix.ywrapstep);
55 printf("fb_fix.line_length=%d\r\n",fb_fix.line_length);
56 printf("fb_fix.mmio_start=%#x\r\n",fb_fix.mmio_start);
57 printf("fb_fix.mmio_len=%#x\r\n",fb_fix.mmio_len);
58 printf("fb_fix.accel=%d\r\n",fb_fix.accel);
59 printf("fb_fix.reserved[0]=%d\r\n",fb_fix.reserved[0]);
60 printf("fb_fix.reserved[1]=%d\r\n",fb_fix.reserved[1]);
61 printf("fb_fix.reserved[2]=%d\r\n",fb_fix.reserved[2]);
62 if(ioctl(screen_fbd, FBIOGET_VSCREENINFO, &fb_var) == -1)
63 {
64 printf("Error Reading Screen Info VSCREENINFO.\n");
65
66 close(screen_fbd);
67
68 return 0;
69 }
70 printf("fb_var.xres=%d\r\n",fb_var.xres);
71 printf("fb_var.yres=%d\r\n",fb_var.yres);
72 printf("fb_var.xres_virtual=%d\r\n",fb_var.xres_virtual);
73 printf("fb_var.yres_virtual=%d\r\n",fb_var.yres_virtual);
74 printf("fb_var.xoffset=%d\r\n",fb_var.xoffset);
75 printf("fb_var.yoffset=%d\r\n",fb_var.yoffset);
76 printf("fb_var.bits_per_pixel=%d\r\n",fb_var.bits_per_pixel);
77 printf("fb_var.grayscale=%d\r\n",fb_var.grayscale);
78 printf("fb_var.red=%#x\r\n",fb_var.red);
79 printf("fb_var.green=%#x\r\n",fb_var.green);
80 printf("fb_var.blue=%#x\r\n",fb_var.blue);
81 printf("fb_var.transp=%#x\r\n",fb_var.transp);
82 printf("fb_var.nonstd=%d\r\n",fb_var.nonstd);
83 printf("fb_var.activate=%d\r\n",fb_var.activate);
84 printf("fb_var.height=%d\r\n",fb_var.height);
85 printf("fb_var.width=%d\r\n",fb_var.width);
86 printf("fb_var.accel_flags=%d\r\n",fb_var.accel_flags);
87 printf("fb_var.pixclock=%d\r\n",fb_var.pixclock);
88 printf("fb_var.left_margin=%d\r\n",fb_var.left_margin);
89 printf("fb_var.right_margin=%d\r\n",fb_var.right_margin);
90 printf("fb_var.upper_margin=%d\r\n",fb_var.upper_margin);
91 printf("fb_var.lower_margin=%d\r\n",fb_var.lower_margin);
92 printf("fb_var.hsync_len=%d\r\n",fb_var.hsync_len);
93 printf("fb_var.vsync_len=%d\r\n",fb_var.vsync_len);
94 printf("fb_var.sync=%d\r\n",fb_var.sync);
95 printf("fb_var.vmode=%d\r\n",fb_var.vmode);
96 printf("fb_var.rotate=%d\r\n",fb_var.rotate);
97 printf("fb_var.reserved[0]=%d\r\n",fb_var.reserved[0]);
98 printf("fb_var.reserved[1]=%d\r\n",fb_var.reserved[1]);
99 printf("fb_var.reserved[2]=%d\r\n",fb_var.reserved[2]);
100 printf("fb_var.reserved[3]=%d\r\n",fb_var.reserved[3]);
101 printf("fb_var.reserved[4]=%d\r\n",fb_var.reserved[4]);
102
103 return 0;
104 }
105
代码看上去并不是很多,其目的主要是通过ioctl获得framebuffer参数,然后输出,输出结果为:
[Copy to clipboard] [ - ]
CODE:
Success Opening FrameBuffer Device:/dev/fb0
fb_fix.id="VESA VGA"
fb_fix.smem_start=0xf0000000
fb_fix.mem_len=1920000
fb_fix.type=0
fb_fix.type_aux=0
fb_fix.visual=2
fb_fix.xpanstep=0
fb_fix.ypanstep=0
fb_fix.ywrapstep=0
fb_fix.line_length=1600
fb_fix.mmio_start=0
fb_fix.mmio_len=0
fb_fix.accel=0
fb_fix.reserved[0]=0
fb_fix.reserved[1]=0
fb_fix.reserved[2]=0
fb_var.xres=800
fb_var.yres=600
fb_var.xres_virtual=800
fb_var.yres_virtual=600
fb_var.xoffset=0
fb_var.yoffset=0
fb_var.bits_per_pixel=16
fb_var.grayscale=0
fb_var.red=0xb
fb_var.green=0x5
fb_var.blue=0
fb_var.transp=0
fb_var.nonstd=0
fb_var.activate=0
fb_var.height=-1
fb_var.width=-1
fb_var.accel_flags=0
fb_var.pixclock=20833
fb_var.left_margin=96
fb_var.right_margin=32
fb_var.upper_margin=16
fb_var.lower_margin=4
fb_var.hsync_len=96
fb_var.vsync_len=4
fb_var.sync=0
fb_var.vmode=0
fb_var.rotate=0
fb_var.reserved[0]=0
fb_var.reserved[1]=0
fb_var.reserved[2]=0
fb_var.reserved[3]=0
fb_var.reserved[4]=0
虽然输出了很多的参数,读者可能会觉得这些参数看上去很眼花缭乱,不要紧,挑出一些关键的参数来使用即可,从输出信息中可以看到 fb_var.xres=800,fb_var.yres=600,说明这个framebuffer的x最大值可以为800,y最大值可以为600。
当得到所有需要得到的值以后,可以开辟一段内存:
[Copy to clipboard] [ - ]
CODE:
/**************************************************
* example3.c
* Author: T-bagwell
*
* Compile:gcc -Wall example3.c -o example3
*************************************************/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <errno.h>
#include <sys/mman.h>
char *fb_addr;
unsigned fb_size;
int main(int argc, char *argv[])
{
int screen_fbd=0;
struct fb_fix_screeninfo fb_fix;
struct fb_var_screeninfo fb_var;
char *env=NULL;
if(!(env = getenv("FRAMEBUFFER")))
{
env = "/dev/fb0";
}
screen_fbd = open(env, O_RDWR);
if(screen_fbd < 0)
{
printf("Error Opening FrameBuffer Device:%s\r\n", env);
return 0;
}
else
{
printf("Success Opening FrameBuffer Device:%s\r\n",env);
}
if(ioctl(screen_fbd, FBIOGET_FSCREENINFO, &fb_fix) == -1)
{
printf("Error Reading Screen Info FSCREENINFO.\n");
close(screen_fbd);
return 0;
}
if(ioctl(screen_fbd, FBIOGET_VSCREENINFO, &fb_var) == -1)
{
printf("Error Reading Screen Info VSCREENINFO.\n");
close(screen_fbd);
return 0;
}
fb_size = fb_var.yres * fb_fix.line_length;
fb_addr = (char *)mmap(NULL, fb_size, PROT_READ|PROT_WRITE,MAP_SHARED, screen_fbd, 0);
if (!fb_addr)
exit(1);
return 0;
}
首先得到整个framebuffer的大小 fb_size = fb_var.yres * fb_fix.line_length;然后映射framebuffer的内存,这样,当向指定的内存处写入数据的时候,framebuffer中就会写入对应的数据,也就会有对应的数据表示的图象显示在屏幕中。
以向屏幕中显示一个纯白色的页面为例,当RGB值为255、255、255时,颜色将为白色,代码如下:
[Copy to clipboard] [ - ]
CODE:
/**************************************************
* example4.c
* Author: T-bagwell
*
* Compile:gcc -Wall example4.c -o example4
*************************************************/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <errno.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
int print_screen(char *buf,int width,int height);
char *fb_addr;
unsigned fb_size;
int main(int argc, char *argv[])
{
int screen_fbd=0;
struct fb_fix_screeninfo fb_fix;
struct fb_var_screeninfo fb_var;
char *env=NULL;
short *color_white;
if(!(env = getenv("FRAMEBUFFER")))
{
env = "/dev/fb0";
}
screen_fbd = open(env, O_RDWR);
if(screen_fbd < 0)
{
printf("liuqi Error Opening FrameBuffer Device:%s\r\n", env);
return 0;
}
else
{
printf("Success Opening FrameBuffer Device:%s\r\n",env);
}
if(ioctl(screen_fbd, FBIOGET_FSCREENINFO, &fb_fix) == -1)
{
printf("Error Reading Screen Info FSCREENINFO.\n");
close(screen_fbd);
return 0;
}
if(ioctl(screen_fbd, FBIOGET_VSCREENINFO, &fb_var) == -1)
{
printf("Error Reading Screen Info VSCREENINFO.\n");
close(screen_fbd);
return 0;
}
fb_size = fb_var.yres * fb_fix.line_length;
fb_addr = (char *)mmap(NULL, fb_size, PROT_READ|PROT_WRITE,MAP_SHARED, screen_fbd, 0);
color_white=(short *)malloc(sizeof(short int)*fb_var.yres * fb_fix.line_length);
memset(color_white,0xFF,sizeof(short int)*fb_var.yres * fb_fix.line_length);
print_screen(color_white,fb_var.xres,fb_var.yres);
if (!fb_addr)
exit(1);
free(color_white);
return 0;
}
/*********************************************************
* function: print_screen
*args
* buf: the address of the buffer
* width: the width of the framebuffer
* short *t_data = (short *)buf;
short *t_fb_addr = (short *)fb_addr;
int bytew= width<<1;
while(--height >= 0)
{
memcpy(t_fb_addr,t_data,bytew);
t_fb_addr += width;
t_data += width;
}
}
这部分代码实现的是在屏幕中画出一个白色的界面,其中,最关键的部分是在print_screen函数中,从main到print_screen中需要将一个buffer,宽度和高度传给print_screen,当print_screen得到相关的参数后,将会在framebuffer中画对应的颜色,也就是memcpy(t_fb_addr,t_data,bytew);这句话是画一行的颜色,当然,这个前提是从main中传进来的buffer也是 16位色的值。当画完一行以后,将buffer指针下移一行,直到画完framebuffer最后一行为止。画出的图象会显示在屏幕中,如图:
接下来可以增加一些功能,例如画线功能:
[Copy to clipboard] [ - ]
CODE:
1 /**************************************************
2 * example5.c
3 * Author: T-bagwell
4 *
5 * Compile:gcc -Wall example5.c -o example5
6 *************************************************/
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <linux/fb.h>
13 #include <errno.h>
14 #include <sys/mman.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <sys/ioctl.h>
18
19 int print_screen(short *buf,int width,int height);
20 void draw_hline(short *buffer,int x,int y,int maxy,int maxx);
21 char *fb_addr;
22 unsigned fb_size;
23
24 int main(int argc, char *argv[])
25 {
26 int screen_fbd=0;
27 struct fb_fix_screeninfo fb_fix;
28 struct fb_var_screeninfo fb_var;
29 char *env=NULL;
30 short *color_white;
31
32 if(!(env = getenv("FRAMEBUFFER")))
33 {
34 env = "/dev/fb0";
35 }
36
37 screen_fbd = open(env, O_RDWR);
38
39 if(screen_fbd < 0)
40 {
41 return 0;
42 }
43
44 if(ioctl(screen_fbd, FBIOGET_FSCREENINFO, &fb_fix) == -1)
45 {
46 close(screen_fbd);
47 return 0;
48 }
49
50 if(ioctl(screen_fbd, FBIOGET_VSCREENINFO, &fb_var) == -1)
51 {
52 close(screen_fbd);
53 return 0;
54 }
55
56 fb_size = fb_var.yres * fb_fix.line_length;
57 fb_addr = (char *)mmap(NULL, fb_size, PROT_READ|PROT_WRITE,MAP_SHARED, screen_fbd, 0);
58 color_white=(short *)malloc(sizeof(short int)*fb_var.yres * fb_fix.line_length);
59 draw_hline(color_white,0,30,fb_var.yres,fb_var.xres);
60 print_screen(color_white,fb_var.xres,fb_var.yres);
61 if (!fb_addr)
62 exit(1);
63 free(color_white);
64 return 0;
65 }
66
67 /*********************************************************
68 * function: print_screen
69 *args
70 * buf: the address of the buffer
71 * width: the width of the framebuffer
72 * the height of the framebuffer
73 ********************************************************/
74 int print_screen(short *buf,int width,int height)
75 {
76 short *t_data = (short *)buf;
77 short *t_fb_addr = (short *)fb_addr;
78 int bytew= width<<1;
79 while(--height >= 0)
80 {
81 memcpy(t_fb_addr,t_data,bytew);
82 t_fb_addr += width;
83 t_data += width;
84 }
85 return 0;
86 }
87
88 /*********************************************************
89 * function: draw_hline
90 *args
91 * line_buffer: the address of the buffer
92 * x: the x of the line start point on the framebuffer
93 * y: the y of the line start point on the framebuffer
94 * maxy: the height of the framebuffer
95 * maxx: the width of the framebuffer
96 ********************************************************/
97 void draw_hline(short *line_buffer,int x,int y,int maxy,int maxx)
98 {
99 int i=0,j=0;
100
101 for(j=0;j<maxy;j++)
102 {
103 if(j==y)
104 {
105 for(i=0;i<maxx;i++)
106 {
107 *line_buffer++=0xf800;
108 }
109 }
110 else
111 {
112 for(i=0;i<maxx;i++)
113 {
114 *line_buffer++=0xffff;
115 }
116 }
117 }
118 return ;
119 }
上述代码实现了在屏幕中坐标为x坐标为0,y坐标为30处画一条红色的横线,当然,颜色值可以作为参数进行传递,只要对上面的函数进行少量的修改即可。手累了,先写这么点吧。