今天在宿主机上写了个framebuffer写屏的小程序,顺便了解了一下framebuffer在linux下的操作。
因为Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里
提供的中断调用来实现直接写屏,故Linux抽象出FrameBuffer这个设备来供用户态
进程实现直接写屏。
步骤:
1、打开一个FrameBuffer设备
2、通过mmap调用把显卡的物理内存空间映射到用户空间
3、直接写内存
code:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <sys/ioctl.h>
7 #include <sys/mman.h>
8 #include <linux/fb.h>
9
10 int fb_open;
11 char *fb_mem;
12 struct fb_var_screeninfo var_info;
13 struct fb_fix_screeninfo fix_info;
14 long int screensize=0;
15
16 int main()
17 {
18 fb_open=open("/dev/fb0",O_RDWR);
19 if(fb_open<0)
20 {
21 perror("open");
22 exit(1);
23 }
24 ioctl(fb_open,FBIOGET_VSCREENINFO,&var_info);
25 ioctl(fb_open,FBIOGET_FSCREENINFO,&fix_info);
26 printf("xres * yres * bpp: %d, %d, %d\n",var_info.xres,var_info.yres,var _info.bits_per_pixel);
27 screensize=var_info.xres*var_info.yres*var_info.bits_per_pixel/8;
28 printf("screensize = %d\n",screensize);
29 fb_mem=(char *)mmap(NULL,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fb_o pen,0);
30 memset(fb_mem,0,screensize);
31 close(fb_open);
32 exit(0);
33 }
在主机上用ARM-LINUX-GCC编译一下,然后通过NFS转移到板上运行,你会看到你的屏的属性以及屏的颜色变化.
这里面mmap是一个对文件映射到内存中的函数.
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
参数fd 通常是被open打开的文件描述符
len是从offset开始算起的字节数
prot表示访问权限PROT_READ,PROT_WRITE,PROT_EXEC,PROT_NONE
flags是标志位MAP_SHARED,MAP_PRIVATE,MAP_FIXED,其中MAP_SHARED表示对内存的操作直接影响文件,而MAP_PRIVATE则表示内存的操作不会影响文件,只是对进程影响
offset,通常设为0,表示从文件头开始映射
addr表示文件被映射到进程空间的起始地址,通常设为空指针NULL,意思是让内核来选择起始地址
函数返回文件被映射到内存中的起始地址。
mmap函数可以体现在对文件的快速操作上,如果你的程序需要反复的在一个文件内操作,移动,那么mmap会大大提高文件操作的效率.
因为Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里
提供的中断调用来实现直接写屏,故Linux抽象出FrameBuffer这个设备来供用户态
进程实现直接写屏。
步骤:
1、打开一个FrameBuffer设备
2、通过mmap调用把显卡的物理内存空间映射到用户空间
3、直接写内存
code:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <sys/ioctl.h>
7 #include <sys/mman.h>
8 #include <linux/fb.h>
9
10 int fb_open;
11 char *fb_mem;
12 struct fb_var_screeninfo var_info;
13 struct fb_fix_screeninfo fix_info;
14 long int screensize=0;
15
16 int main()
17 {
18 fb_open=open("/dev/fb0",O_RDWR);
19 if(fb_open<0)
20 {
21 perror("open");
22 exit(1);
23 }
24 ioctl(fb_open,FBIOGET_VSCREENINFO,&var_info);
25 ioctl(fb_open,FBIOGET_FSCREENINFO,&fix_info);
26 printf("xres * yres * bpp: %d, %d, %d\n",var_info.xres,var_info.yres,var _info.bits_per_pixel);
27 screensize=var_info.xres*var_info.yres*var_info.bits_per_pixel/8;
28 printf("screensize = %d\n",screensize);
29 fb_mem=(char *)mmap(NULL,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fb_o pen,0);
30 memset(fb_mem,0,screensize);
31 close(fb_open);
32 exit(0);
33 }
在主机上用ARM-LINUX-GCC编译一下,然后通过NFS转移到板上运行,你会看到你的屏的属性以及屏的颜色变化.
这里面mmap是一个对文件映射到内存中的函数.
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
参数fd 通常是被open打开的文件描述符
len是从offset开始算起的字节数
prot表示访问权限PROT_READ,PROT_WRITE,PROT_EXEC,PROT_NONE
flags是标志位MAP_SHARED,MAP_PRIVATE,MAP_FIXED,其中MAP_SHARED表示对内存的操作直接影响文件,而MAP_PRIVATE则表示内存的操作不会影响文件,只是对进程影响
offset,通常设为0,表示从文件头开始映射
addr表示文件被映射到进程空间的起始地址,通常设为空指针NULL,意思是让内核来选择起始地址
函数返回文件被映射到内存中的起始地址。
mmap函数可以体现在对文件的快速操作上,如果你的程序需要反复的在一个文件内操作,移动,那么mmap会大大提高文件操作的效率.